@lv-x-software-house/x_view 1.2.1-dev.7 → 1.2.1-dev.8

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.js CHANGED
@@ -290,7 +290,7 @@ function ContextMenu({
290
290
  return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ import_react.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es R\xE1pidas")), /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => {
291
291
  onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
292
292
  onClose();
293
- }, className: baseButtonClass, title: "Focar na c\xE2mera" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Focar neste Node")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: (e) => handleCopyLink(e, data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, isLinkCopied ? /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#4ade80", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "20 6 9 17 4 12" })) : /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", { className: isLinkCopied ? "text-green-400" : "" }, isLinkCopied ? "Copiado!" : "Copiar Link")), ability.can("create", "Connection") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartConnection == null ? void 0 : onStartConnection(data.nodeData), className: baseButtonClass, title: "Conectar" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conectar")), ability.can("create", "Node") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartCreation == null ? void 0 : onStartCreation(data.nodeData), className: baseButtonClass, title: "Criar e Conectar" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "16" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "8", y1: "12", x2: "16", y2: "12" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar e Conectar")), ability.can("create", "Ancestry") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartAncestryCreation == null ? void 0 : onStartAncestryCreation(data.nodeData), className: baseButtonClass, title: "Criar Ancestralidade" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 20.5c.5-.5.8-1.2.8-2s-.3-1.5-.8-2c-.5-.5-1.2-.8-2-.8s-1.5.3-2 .8c-.5.5-.8 1.2-.8 2s.3 1.5.8 2c.5.5 1.2-.8 2 .8s1.5-.3 2-.8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 16v-3a2 2 0 0 1 2-2h4" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 3.5c.5.5.8 1.2.8 2s-.3 1.5-.8 2c-.5-.5-1.2-.8-2 .8s1.5.3-2-.8c-.5-.5-.8-1.2-.8-2s.3-1.5.8-2c.5.5 1.2-.8 2 .8s1.5.3 2 .8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 8v3a2 2 0 0 0 2 2h4" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar Ancestralidade")), shouldShowVersioningBtn && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("versioning"), className: baseButtonClass, title: hasVersions ? "Versionamento" : "Criar Versionamento" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("line", { x1: "6", y1: "3", x2: "6", y2: "15" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "18", cy: "6", r: "3" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "6", cy: "18", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })), /* @__PURE__ */ import_react.default.createElement("span", null, hasVersions || !canCreateVersion ? "Versionamento" : "Criar Versionamento")), (connections.length > 0 || availableAncestries.length > 0) && ability.can("read", "Connection") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("connections"), className: baseButtonClass, title: "Conex\xF5es" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M8 12h8" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 8v8" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conex\xF5es (", totalConnectionsCount, ")"))), /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), ability.can("dismiss", "Node") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissNode == null ? void 0 : onDismissNode(data.nodeData), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissOtherNodes == null ? void 0 : onDismissOtherNodes(data.nodeData), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss other nodes"))), ability.can("delete", "Node") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDeleteNode == null ? void 0 : onDeleteNode(data.nodeData), className: deleteButtonClass, title: "Excluir Node" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Excluir Node"))));
293
+ }, className: baseButtonClass, title: "Focar na c\xE2mera" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Focar neste Node")), ability.can("create", "Connection") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartConnection == null ? void 0 : onStartConnection(data.nodeData), className: baseButtonClass, title: "Conectar" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conectar")), ability.can("create", "Node") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartCreation == null ? void 0 : onStartCreation(data.nodeData), className: baseButtonClass, title: "Criar e Conectar" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "16" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "8", y1: "12", x2: "16", y2: "12" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar e Conectar")), ability.can("create", "Ancestry") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onStartAncestryCreation == null ? void 0 : onStartAncestryCreation(data.nodeData), className: baseButtonClass, title: "Criar Ancestralidade" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 20.5c.5-.5.8-1.2.8-2s-.3-1.5-.8-2c-.5-.5-1.2-.8-2-.8s-1.5.3-2 .8c-.5.5-.8 1.2-.8 2s.3 1.5.8 2c.5.5 1.2-.8 2 .8s1.5-.3 2-.8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 16v-3a2 2 0 0 1 2-2h4" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 3.5c.5.5.8 1.2.8 2s-.3 1.5-.8 2c-.5-.5-1.2-.8-2 .8s1.5.3-2-.8c-.5-.5-.8-1.2-.8-2s.3-1.5.8-2c.5.5 1.2-.8 2 .8s1.5.3 2 .8Z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 8v3a2 2 0 0 0 2 2h4" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Criar Ancestralidade")), shouldShowVersioningBtn && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("versioning"), className: baseButtonClass, title: hasVersions ? "Versionamento" : "Criar Versionamento" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("line", { x1: "6", y1: "3", x2: "6", y2: "15" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "18", cy: "6", r: "3" }), /* @__PURE__ */ import_react.default.createElement("circle", { cx: "6", cy: "18", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })), /* @__PURE__ */ import_react.default.createElement("span", null, hasVersions || !canCreateVersion ? "Versionamento" : "Criar Versionamento")), (connections.length > 0 || availableAncestries.length > 0) && ability.can("read", "Connection") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => setMenuView("connections"), className: baseButtonClass, title: "Conex\xF5es" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M8 12h8" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M12 8v8" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Conex\xF5es (", totalConnectionsCount, ")"))), /* @__PURE__ */ import_react.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react.default.createElement("button", { onClick: (e) => handleCopyLink(e, data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, isLinkCopied ? /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#4ade80", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "20 6 9 17 4 12" })) : /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ import_react.default.createElement("span", { className: isLinkCopied ? "text-green-400" : "" }, isLinkCopied ? "Copiado!" : "Copiar Link")), ability.can("dismiss", "Node") && /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissNode == null ? void 0 : onDismissNode(data.nodeData), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss")), /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDismissOtherNodes == null ? void 0 : onDismissOtherNodes(data.nodeData), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Dismiss other nodes"))), ability.can("delete", "Node") && /* @__PURE__ */ import_react.default.createElement("button", { onClick: () => onDeleteNode == null ? void 0 : onDeleteNode(data.nodeData), className: deleteButtonClass, title: "Excluir Node" }, /* @__PURE__ */ import_react.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react.default.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react.default.createElement("span", null, "Excluir Node"))));
294
294
  };
295
295
  const renderVersionSubMenuView = () => {
296
296
  const group = versionSubMenu;
@@ -4548,6 +4548,8 @@ var ReadOnlyNodeItem = ({ nodeData, onViewSelect, highlightedPathIds = [], targe
4548
4548
  function DescriptionReadModePanel({
4549
4549
  title,
4550
4550
  description,
4551
+ ancestryId,
4552
+ // <-- NOVO: Prop recebida do XViewScene
4551
4553
  savedSections,
4552
4554
  onBack,
4553
4555
  onEdit,
@@ -4570,12 +4572,24 @@ function DescriptionReadModePanel({
4570
4572
  abstractionTree = null,
4571
4573
  onRenderAbstractionTree = null,
4572
4574
  initialShowAbstraction = false
4573
- // <--- NOVA PROP RECEBIDA
4574
4575
  }) {
4575
4576
  const [showProperties, setShowProperties] = (0, import_react7.useState)(false);
4576
4577
  const [showAbstraction, setShowAbstraction] = (0, import_react7.useState)(false);
4577
4578
  const [targetRenderNodeId, setTargetRenderNodeId] = (0, import_react7.useState)(null);
4578
- import_react7.default.useEffect(() => {
4579
+ const [isLinkCopied, setIsLinkCopied] = (0, import_react7.useState)(false);
4580
+ const handleCopyLink = (e) => {
4581
+ e.stopPropagation();
4582
+ if (!ancestryId) return;
4583
+ const baseUrl = window.location.origin + window.location.pathname;
4584
+ const fullUrl = `${baseUrl}?ancestry=${ancestryId}`;
4585
+ navigator.clipboard.writeText(fullUrl).then(() => {
4586
+ setIsLinkCopied(true);
4587
+ setTimeout(() => setIsLinkCopied(false), 2e3);
4588
+ }).catch((err) => {
4589
+ console.error("Erro ao copiar link:", err);
4590
+ });
4591
+ };
4592
+ (0, import_react7.useEffect)(() => {
4579
4593
  setShowAbstraction(initialShowAbstraction);
4580
4594
  if (initialShowAbstraction) {
4581
4595
  setShowProperties(false);
@@ -4664,7 +4678,15 @@ function DescriptionReadModePanel({
4664
4678
  title: "Voltar"
4665
4679
  },
4666
4680
  /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiArrowLeft, { size: 16 })
4667
- ), /* @__PURE__ */ import_react7.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react7.default.createElement("p", { className: "text-xs/relaxed text-slate-400 uppercase tracking-wider font-semibold" }, showAbstraction ? "Tree de Abstra\xE7\xE3o" : showProperties ? "Propriedades Adicionais" : "Modo de Leitura"), /* @__PURE__ */ import_react7.default.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ import_react7.default.createElement(
4681
+ ), /* @__PURE__ */ import_react7.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react7.default.createElement("p", { className: "text-xs/relaxed text-slate-400 uppercase tracking-wider font-semibold" }, showAbstraction ? "Tree de Abstra\xE7\xE3o" : showProperties ? "Propriedades Adicionais" : "Modo de Leitura"), ancestryId && /* @__PURE__ */ import_react7.default.createElement(
4682
+ "button",
4683
+ {
4684
+ onClick: handleCopyLink,
4685
+ className: `p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
4686
+ title: isLinkCopied ? "Link Copiado!" : "Copiar link para esta Ancestralidade"
4687
+ },
4688
+ isLinkCopied ? /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiCheck, { size: 12 }) : /* @__PURE__ */ import_react7.default.createElement(import_fi6.FiLink, { size: 12 })
4689
+ )), /* @__PURE__ */ import_react7.default.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ import_react7.default.createElement(
4668
4690
  "button",
4669
4691
  {
4670
4692
  onClick: handleToggleProperties,
@@ -5191,6 +5213,20 @@ function CreateAncestryPanel({
5191
5213
  currentAncestryId
5192
5214
  } = ancestryMode;
5193
5215
  const [isSaving, setIsSaving] = (0, import_react10.useState)(false);
5216
+ const [isLinkCopied, setIsLinkCopied] = (0, import_react10.useState)(false);
5217
+ const handleCopyLink = (e) => {
5218
+ e.stopPropagation();
5219
+ if (!currentAncestryId || currentAncestryId === "temp_root" || currentAncestryId === "temp_creating") {
5220
+ alert("Salve a ancestralidade primeiro para gerar um link.");
5221
+ return;
5222
+ }
5223
+ const baseUrl = window.location.origin + window.location.pathname;
5224
+ const fullUrl = `${baseUrl}?ancestry=${currentAncestryId}`;
5225
+ navigator.clipboard.writeText(fullUrl).then(() => {
5226
+ setIsLinkCopied(true);
5227
+ setTimeout(() => setIsLinkCopied(false), 2e3);
5228
+ }).catch((err) => console.error("Erro ao copiar link:", err));
5229
+ };
5194
5230
  const [isPickerOpen, setIsPickerOpen] = (0, import_react10.useState)(false);
5195
5231
  const [customProps, setCustomProps] = (0, import_react10.useState)([]);
5196
5232
  const propsEndRef = (0, import_react10.useRef)(null);
@@ -6220,7 +6256,15 @@ function CreateAncestryPanel({
6220
6256
  onHighlightNode,
6221
6257
  onImageClick: handleImageClickFromText
6222
6258
  }
6223
- ) : /* @__PURE__ */ import_react10.default.createElement(import_react10.default.Fragment, null, /* @__PURE__ */ import_react10.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0 flex-shrink-0" }), /* @__PURE__ */ import_react10.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4 flex-shrink-0" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "w-full" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react10.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ import_react10.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, branchStack.length > 0 ? `Ramifica\xE7\xE3o (N\xEDvel ${branchStack.length})` : isEditMode ? "Editar Ancestralidade" : "Criar Ancestralidade")), /* @__PURE__ */ import_react10.default.createElement(
6259
+ ) : /* @__PURE__ */ import_react10.default.createElement(import_react10.default.Fragment, null, /* @__PURE__ */ import_react10.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0 flex-shrink-0" }), /* @__PURE__ */ import_react10.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4 flex-shrink-0" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "w-full" }, /* @__PURE__ */ import_react10.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react10.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ import_react10.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, branchStack.length > 0 ? `Ramifica\xE7\xE3o (N\xEDvel ${branchStack.length})` : isEditMode ? "Editar Ancestralidade" : "Criar Ancestralidade"), currentAncestryId && currentAncestryId !== "temp_creating" && currentAncestryId !== "temp_root" && /* @__PURE__ */ import_react10.default.createElement(
6260
+ "button",
6261
+ {
6262
+ onClick: handleCopyLink,
6263
+ className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
6264
+ title: isLinkCopied ? "Link Copiado!" : "Copiar link para esta Ancestralidade"
6265
+ },
6266
+ isLinkCopied ? /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiCheck, { size: 12 }) : /* @__PURE__ */ import_react10.default.createElement(import_fi9.FiLink, { size: 12 })
6267
+ )), /* @__PURE__ */ import_react10.default.createElement(
6224
6268
  "input",
6225
6269
  {
6226
6270
  type: "text",
@@ -9010,6 +9054,7 @@ function XViewScene({
9010
9054
  const router = (0, import_navigation.useRouter)();
9011
9055
  const searchParams = (0, import_navigation.useSearchParams)();
9012
9056
  const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
9057
+ const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
9013
9058
  const viewParams = (0, import_react23.useMemo)(() => {
9014
9059
  if (encryptedConfig) {
9015
9060
  const data = decryptData(encryptedConfig);
@@ -9077,6 +9122,7 @@ function XViewScene({
9077
9122
  const [creationMode, setCreationMode] = (0, import_react23.useState)({ isActive: false, sourceNodeData: null });
9078
9123
  const [versionMode, setVersionMode] = (0, import_react23.useState)({ isActive: false, sourceNodeData: null });
9079
9124
  const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react23.useState)(false);
9125
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react23.useState)(false);
9080
9126
  const [ancestryMode, setAncestryMode] = (0, import_react23.useState)({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
9081
9127
  const [readingMode, setReadingMode] = (0, import_react23.useState)({
9082
9128
  isActive: false,
@@ -12004,6 +12050,20 @@ function XViewScene({
12004
12050
  }
12005
12051
  }
12006
12052
  }, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
12053
+ (0, import_react23.useEffect)(() => {
12054
+ if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
12055
+ const ancestries = ancestryDataRef.current || [];
12056
+ const targetAncestry = ancestries.find((a) => String(a.ancestry_id) === String(focusAncestryId));
12057
+ if (targetAncestry) {
12058
+ setTimeout(() => {
12059
+ handleStartReadingAncestry(targetAncestry);
12060
+ setHasOpenedInitialAncestry(true);
12061
+ }, 300);
12062
+ } else {
12063
+ setHasOpenedInitialAncestry(true);
12064
+ }
12065
+ }
12066
+ }, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
12007
12067
  if (isLoading || status === "loading" || permissionStatus === "loading") {
12008
12068
  return /* @__PURE__ */ import_react23.default.createElement(LoadingScreen, null);
12009
12069
  }
@@ -12098,6 +12158,7 @@ function XViewScene({
12098
12158
  DescriptionReadModePanel,
12099
12159
  {
12100
12160
  key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
12161
+ ancestryId: readingMode.ancestry.ancestry_id,
12101
12162
  title: (getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.name) || readingMode.ancestry.name || "Ancestralidade",
12102
12163
  initialSectionId: readingMode.initialSectionId,
12103
12164
  description: getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.description,
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/XViewScene.jsx
2
- import React23, { useCallback as useCallback3, useEffect as useEffect20, useRef as useRef17, useState as useState22, useMemo as useMemo12 } from "react";
2
+ import React23, { useCallback as useCallback3, useEffect as useEffect21, useRef as useRef17, useState as useState22, useMemo as useMemo12 } from "react";
3
3
  import { useRouter, useSearchParams } from "next/navigation";
4
4
  import { useSession } from "next-auth/react";
5
5
  import CryptoJS from "crypto-js";
@@ -246,7 +246,7 @@ function ContextMenu({
246
246
  return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ React.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-indigo-400/80 shadow-[0_0_12px_1px_rgba(99,102,241,0.5)]" }), /* @__PURE__ */ React.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es R\xE1pidas")), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React.createElement("button", { onClick: () => {
247
247
  onFocusNode == null ? void 0 : onFocusNode(data.nodeData);
248
248
  onClose();
249
- }, className: baseButtonClass, title: "Focar na c\xE2mera" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ React.createElement("span", null, "Focar neste Node")), /* @__PURE__ */ React.createElement("button", { onClick: (e) => handleCopyLink(e, data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, isLinkCopied ? /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#4ade80", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("polyline", { points: "20 6 9 17 4 12" })) : /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ React.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ React.createElement("span", { className: isLinkCopied ? "text-green-400" : "" }, isLinkCopied ? "Copiado!" : "Copiar Link")), ability.can("create", "Connection") && /* @__PURE__ */ React.createElement("button", { onClick: () => onStartConnection == null ? void 0 : onStartConnection(data.nodeData), className: baseButtonClass, title: "Conectar" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ React.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ React.createElement("span", null, "Conectar")), ability.can("create", "Node") && /* @__PURE__ */ React.createElement("button", { onClick: () => onStartCreation == null ? void 0 : onStartCreation(data.nodeData), className: baseButtonClass, title: "Criar e Conectar" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "16" }), /* @__PURE__ */ React.createElement("line", { x1: "8", y1: "12", x2: "16", y2: "12" })), /* @__PURE__ */ React.createElement("span", null, "Criar e Conectar")), ability.can("create", "Ancestry") && /* @__PURE__ */ React.createElement("button", { onClick: () => onStartAncestryCreation == null ? void 0 : onStartAncestryCreation(data.nodeData), className: baseButtonClass, title: "Criar Ancestralidade" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M10 20.5c.5-.5.8-1.2.8-2s-.3-1.5-.8-2c-.5-.5-1.2-.8-2-.8s-1.5.3-2 .8c-.5.5-.8 1.2-.8 2s.3 1.5.8 2c.5.5 1.2-.8 2 .8s1.5-.3 2-.8Z" }), /* @__PURE__ */ React.createElement("path", { d: "M10 16v-3a2 2 0 0 1 2-2h4" }), /* @__PURE__ */ React.createElement("path", { d: "M14 3.5c.5.5.8 1.2.8 2s-.3 1.5-.8 2c-.5-.5-1.2-.8-2 .8s1.5.3-2-.8c-.5-.5-.8-1.2-.8-2s.3-1.5.8-2c.5.5 1.2-.8 2 .8s1.5.3 2 .8Z" }), /* @__PURE__ */ React.createElement("path", { d: "M14 8v3a2 2 0 0 0 2 2h4" })), /* @__PURE__ */ React.createElement("span", null, "Criar Ancestralidade")), shouldShowVersioningBtn && /* @__PURE__ */ React.createElement("button", { onClick: () => setMenuView("versioning"), className: baseButtonClass, title: hasVersions ? "Versionamento" : "Criar Versionamento" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("line", { x1: "6", y1: "3", x2: "6", y2: "15" }), /* @__PURE__ */ React.createElement("circle", { cx: "18", cy: "6", r: "3" }), /* @__PURE__ */ React.createElement("circle", { cx: "6", cy: "18", r: "3" }), /* @__PURE__ */ React.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })), /* @__PURE__ */ React.createElement("span", null, hasVersions || !canCreateVersion ? "Versionamento" : "Criar Versionamento")), (connections.length > 0 || availableAncestries.length > 0) && ability.can("read", "Connection") && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React.createElement("button", { onClick: () => setMenuView("connections"), className: baseButtonClass, title: "Conex\xF5es" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z" }), /* @__PURE__ */ React.createElement("path", { d: "M8 12h8" }), /* @__PURE__ */ React.createElement("path", { d: "M12 8v8" })), /* @__PURE__ */ React.createElement("span", null, "Conex\xF5es (", totalConnectionsCount, ")"))), /* @__PURE__ */ React.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), ability.can("dismiss", "Node") && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("button", { onClick: () => onDismissNode == null ? void 0 : onDismissNode(data.nodeData), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ React.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ React.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React.createElement("span", null, "Dismiss")), /* @__PURE__ */ React.createElement("button", { onClick: () => onDismissOtherNodes == null ? void 0 : onDismissOtherNodes(data.nodeData), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React.createElement("span", null, "Dismiss other nodes"))), ability.can("delete", "Node") && /* @__PURE__ */ React.createElement("button", { onClick: () => onDeleteNode == null ? void 0 : onDeleteNode(data.nodeData), className: deleteButtonClass, title: "Excluir Node" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React.createElement("span", null, "Excluir Node"))));
249
+ }, className: baseButtonClass, title: "Focar na c\xE2mera" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" })), /* @__PURE__ */ React.createElement("span", null, "Focar neste Node")), ability.can("create", "Connection") && /* @__PURE__ */ React.createElement("button", { onClick: () => onStartConnection == null ? void 0 : onStartConnection(data.nodeData), className: baseButtonClass, title: "Conectar" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ React.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ React.createElement("span", null, "Conectar")), ability.can("create", "Node") && /* @__PURE__ */ React.createElement("button", { onClick: () => onStartCreation == null ? void 0 : onStartCreation(data.nodeData), className: baseButtonClass, title: "Criar e Conectar" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "10" }), /* @__PURE__ */ React.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "16" }), /* @__PURE__ */ React.createElement("line", { x1: "8", y1: "12", x2: "16", y2: "12" })), /* @__PURE__ */ React.createElement("span", null, "Criar e Conectar")), ability.can("create", "Ancestry") && /* @__PURE__ */ React.createElement("button", { onClick: () => onStartAncestryCreation == null ? void 0 : onStartAncestryCreation(data.nodeData), className: baseButtonClass, title: "Criar Ancestralidade" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M10 20.5c.5-.5.8-1.2.8-2s-.3-1.5-.8-2c-.5-.5-1.2-.8-2-.8s-1.5.3-2 .8c-.5.5-.8 1.2-.8 2s.3 1.5.8 2c.5.5 1.2-.8 2 .8s1.5-.3 2-.8Z" }), /* @__PURE__ */ React.createElement("path", { d: "M10 16v-3a2 2 0 0 1 2-2h4" }), /* @__PURE__ */ React.createElement("path", { d: "M14 3.5c.5.5.8 1.2.8 2s-.3 1.5-.8 2c-.5-.5-1.2-.8-2 .8s1.5.3-2-.8c-.5-.5-.8-1.2-.8-2s.3-1.5.8-2c.5.5 1.2-.8 2 .8s1.5.3 2 .8Z" }), /* @__PURE__ */ React.createElement("path", { d: "M14 8v3a2 2 0 0 0 2 2h4" })), /* @__PURE__ */ React.createElement("span", null, "Criar Ancestralidade")), shouldShowVersioningBtn && /* @__PURE__ */ React.createElement("button", { onClick: () => setMenuView("versioning"), className: baseButtonClass, title: hasVersions ? "Versionamento" : "Criar Versionamento" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("line", { x1: "6", y1: "3", x2: "6", y2: "15" }), /* @__PURE__ */ React.createElement("circle", { cx: "18", cy: "6", r: "3" }), /* @__PURE__ */ React.createElement("circle", { cx: "6", cy: "18", r: "3" }), /* @__PURE__ */ React.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })), /* @__PURE__ */ React.createElement("span", null, hasVersions || !canCreateVersion ? "Versionamento" : "Criar Versionamento")), (connections.length > 0 || availableAncestries.length > 0) && ability.can("read", "Connection") && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React.createElement("button", { onClick: () => setMenuView("connections"), className: baseButtonClass, title: "Conex\xF5es" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z" }), /* @__PURE__ */ React.createElement("path", { d: "M8 12h8" }), /* @__PURE__ */ React.createElement("path", { d: "M12 8v8" })), /* @__PURE__ */ React.createElement("span", null, "Conex\xF5es (", totalConnectionsCount, ")"))), /* @__PURE__ */ React.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ React.createElement("button", { onClick: (e) => handleCopyLink(e, data.nodeData), className: baseButtonClass, title: "Copiar Link para Compartilhar" }, isLinkCopied ? /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#4ade80", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("polyline", { points: "20 6 9 17 4 12" })) : /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.72" }), /* @__PURE__ */ React.createElement("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.72-1.72" })), /* @__PURE__ */ React.createElement("span", { className: isLinkCopied ? "text-green-400" : "" }, isLinkCopied ? "Copiado!" : "Copiar Link")), ability.can("dismiss", "Node") && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("button", { onClick: () => onDismissNode == null ? void 0 : onDismissNode(data.nodeData), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ React.createElement("path", { d: "M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68" }), /* @__PURE__ */ React.createElement("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }), /* @__PURE__ */ React.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ React.createElement("span", null, "Dismiss")), /* @__PURE__ */ React.createElement("button", { onClick: () => onDismissOtherNodes == null ? void 0 : onDismissOtherNodes(data.nodeData), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ React.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ React.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ React.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ React.createElement("span", null, "Dismiss other nodes"))), ability.can("delete", "Node") && /* @__PURE__ */ React.createElement("button", { onClick: () => onDeleteNode == null ? void 0 : onDeleteNode(data.nodeData), className: deleteButtonClass, title: "Excluir Node" }, /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ React.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ React.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ React.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ React.createElement("span", null, "Excluir Node"))));
250
250
  };
251
251
  const renderVersionSubMenuView = () => {
252
252
  const group = versionSubMenu;
@@ -735,7 +735,7 @@ function XViewSidebar({
735
735
  }
736
736
 
737
737
  // src/components/AncestryRelationshipPanel.jsx
738
- import React8, { useState as useState8, useEffect as useEffect7, useRef as useRef7 } from "react";
738
+ import React8, { useState as useState8, useEffect as useEffect8, useRef as useRef7 } from "react";
739
739
 
740
740
  // node_modules/uuid/dist/esm-node/rng.js
741
741
  import crypto from "crypto";
@@ -4440,7 +4440,7 @@ function DescriptionDisplay({
4440
4440
  }
4441
4441
 
4442
4442
  // src/components/DescriptionReadModePanel.jsx
4443
- import React7, { useState as useState7, useMemo as useMemo6 } from "react";
4443
+ import React7, { useState as useState7, useMemo as useMemo6, useEffect as useEffect7 } from "react";
4444
4444
  import {
4445
4445
  FiArrowLeft,
4446
4446
  FiEdit2,
@@ -4452,7 +4452,9 @@ import {
4452
4452
  FiList as FiList2,
4453
4453
  FiAlignLeft,
4454
4454
  FiGitBranch,
4455
- FiFolder
4455
+ FiFolder,
4456
+ FiLink as FiLink3,
4457
+ FiCheck as FiCheck4
4456
4458
  } from "react-icons/fi";
4457
4459
  var findNodePath = (tree, targetNodeId, currentPath = []) => {
4458
4460
  var _a;
@@ -4516,6 +4518,8 @@ var ReadOnlyNodeItem = ({ nodeData, onViewSelect, highlightedPathIds = [], targe
4516
4518
  function DescriptionReadModePanel({
4517
4519
  title,
4518
4520
  description,
4521
+ ancestryId,
4522
+ // <-- NOVO: Prop recebida do XViewScene
4519
4523
  savedSections,
4520
4524
  onBack,
4521
4525
  onEdit,
@@ -4538,12 +4542,24 @@ function DescriptionReadModePanel({
4538
4542
  abstractionTree = null,
4539
4543
  onRenderAbstractionTree = null,
4540
4544
  initialShowAbstraction = false
4541
- // <--- NOVA PROP RECEBIDA
4542
4545
  }) {
4543
4546
  const [showProperties, setShowProperties] = useState7(false);
4544
4547
  const [showAbstraction, setShowAbstraction] = useState7(false);
4545
4548
  const [targetRenderNodeId, setTargetRenderNodeId] = useState7(null);
4546
- React7.useEffect(() => {
4549
+ const [isLinkCopied, setIsLinkCopied] = useState7(false);
4550
+ const handleCopyLink = (e) => {
4551
+ e.stopPropagation();
4552
+ if (!ancestryId) return;
4553
+ const baseUrl = window.location.origin + window.location.pathname;
4554
+ const fullUrl = `${baseUrl}?ancestry=${ancestryId}`;
4555
+ navigator.clipboard.writeText(fullUrl).then(() => {
4556
+ setIsLinkCopied(true);
4557
+ setTimeout(() => setIsLinkCopied(false), 2e3);
4558
+ }).catch((err) => {
4559
+ console.error("Erro ao copiar link:", err);
4560
+ });
4561
+ };
4562
+ useEffect7(() => {
4547
4563
  setShowAbstraction(initialShowAbstraction);
4548
4564
  if (initialShowAbstraction) {
4549
4565
  setShowProperties(false);
@@ -4632,7 +4648,15 @@ function DescriptionReadModePanel({
4632
4648
  title: "Voltar"
4633
4649
  },
4634
4650
  /* @__PURE__ */ React7.createElement(FiArrowLeft, { size: 16 })
4635
- ), /* @__PURE__ */ React7.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React7.createElement("p", { className: "text-xs/relaxed text-slate-400 uppercase tracking-wider font-semibold" }, showAbstraction ? "Tree de Abstra\xE7\xE3o" : showProperties ? "Propriedades Adicionais" : "Modo de Leitura"), /* @__PURE__ */ React7.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ React7.createElement(
4651
+ ), /* @__PURE__ */ React7.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React7.createElement("p", { className: "text-xs/relaxed text-slate-400 uppercase tracking-wider font-semibold" }, showAbstraction ? "Tree de Abstra\xE7\xE3o" : showProperties ? "Propriedades Adicionais" : "Modo de Leitura"), ancestryId && /* @__PURE__ */ React7.createElement(
4652
+ "button",
4653
+ {
4654
+ onClick: handleCopyLink,
4655
+ className: `p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
4656
+ title: isLinkCopied ? "Link Copiado!" : "Copiar link para esta Ancestralidade"
4657
+ },
4658
+ isLinkCopied ? /* @__PURE__ */ React7.createElement(FiCheck4, { size: 12 }) : /* @__PURE__ */ React7.createElement(FiLink3, { size: 12 })
4659
+ )), /* @__PURE__ */ React7.createElement("h2", { className: "text-lg sm:text-xl font-semibold tracking-tight text-white truncate", title }, title || "Sem T\xEDtulo"))), /* @__PURE__ */ React7.createElement("div", { className: "flex items-center gap-2 flex-shrink-0" }, hasCustomProps && /* @__PURE__ */ React7.createElement(
4636
4660
  "button",
4637
4661
  {
4638
4662
  onClick: handleToggleProperties,
@@ -4783,7 +4807,7 @@ function AncestryRelationshipPanel({
4783
4807
  const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState8(false);
4784
4808
  const [isReadMode, setIsReadMode] = useState8(false);
4785
4809
  const propsEndRef = useRef7(null);
4786
- useEffect7(() => {
4810
+ useEffect8(() => {
4787
4811
  setDescription((data == null ? void 0 : data.description) ?? "");
4788
4812
  setExistingSections((data == null ? void 0 : data.description_sections) || []);
4789
4813
  setCustomProps(extractCustomPropsFromNode(data || {}));
@@ -4923,13 +4947,13 @@ function AncestryRelationshipPanel({
4923
4947
  }
4924
4948
 
4925
4949
  // src/components/CreateAncestryPanel.jsx
4926
- import React10, { useState as useState10, useEffect as useEffect9, useMemo as useMemo8, useRef as useRef8, useCallback } from "react";
4950
+ import React10, { useState as useState10, useEffect as useEffect10, useMemo as useMemo8, useRef as useRef8, useCallback } from "react";
4927
4951
  import {
4928
4952
  FiEdit2 as FiEdit23,
4929
4953
  FiBookOpen as FiBookOpen2,
4930
4954
  FiFolder as FiFolder2,
4931
4955
  FiMousePointer,
4932
- FiCheck as FiCheck4,
4956
+ FiCheck as FiCheck5,
4933
4957
  FiLayers as FiLayers5,
4934
4958
  FiArrowLeft as FiArrowLeft2,
4935
4959
  FiChevronLeft as FiChevronLeft2,
@@ -4938,11 +4962,12 @@ import {
4938
4962
  FiCornerUpRight as FiCornerUpRight3,
4939
4963
  FiGitBranch as FiGitBranch2,
4940
4964
  FiPlus as FiPlus2,
4941
- FiLock
4965
+ FiLock,
4966
+ FiLink as FiLink4
4942
4967
  } from "react-icons/fi";
4943
4968
 
4944
4969
  // src/components/AncestryPickerModal.jsx
4945
- import React9, { useState as useState9, useMemo as useMemo7, useEffect as useEffect8 } from "react";
4970
+ import React9, { useState as useState9, useMemo as useMemo7, useEffect as useEffect9 } from "react";
4946
4971
  import { FiSearch as FiSearch3, FiLayers as FiLayers4, FiCornerUpRight as FiCornerUpRight2 } from "react-icons/fi";
4947
4972
  function AncestryPickerModal({
4948
4973
  isOpen,
@@ -4953,7 +4978,7 @@ function AncestryPickerModal({
4953
4978
  currentAncestryId
4954
4979
  }) {
4955
4980
  const [searchTerm, setSearchTerm] = useState9("");
4956
- useEffect8(() => {
4981
+ useEffect9(() => {
4957
4982
  if (!isOpen) return;
4958
4983
  const handleKeyDown = (e) => {
4959
4984
  if (e.key === "Escape") {
@@ -5174,6 +5199,20 @@ function CreateAncestryPanel({
5174
5199
  currentAncestryId
5175
5200
  } = ancestryMode;
5176
5201
  const [isSaving, setIsSaving] = useState10(false);
5202
+ const [isLinkCopied, setIsLinkCopied] = useState10(false);
5203
+ const handleCopyLink = (e) => {
5204
+ e.stopPropagation();
5205
+ if (!currentAncestryId || currentAncestryId === "temp_root" || currentAncestryId === "temp_creating") {
5206
+ alert("Salve a ancestralidade primeiro para gerar um link.");
5207
+ return;
5208
+ }
5209
+ const baseUrl = window.location.origin + window.location.pathname;
5210
+ const fullUrl = `${baseUrl}?ancestry=${currentAncestryId}`;
5211
+ navigator.clipboard.writeText(fullUrl).then(() => {
5212
+ setIsLinkCopied(true);
5213
+ setTimeout(() => setIsLinkCopied(false), 2e3);
5214
+ }).catch((err) => console.error("Erro ao copiar link:", err));
5215
+ };
5177
5216
  const [isPickerOpen, setIsPickerOpen] = useState10(false);
5178
5217
  const [customProps, setCustomProps] = useState10([]);
5179
5218
  const propsEndRef = useRef8(null);
@@ -5381,7 +5420,7 @@ function CreateAncestryPanel({
5381
5420
  setCustomProps(newProps);
5382
5421
  };
5383
5422
  const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
5384
- useEffect9(() => {
5423
+ useEffect10(() => {
5385
5424
  if (!isContextLinked) return;
5386
5425
  const handleKeyDown = (e) => {
5387
5426
  if (branchStack.length === 0) return;
@@ -5399,7 +5438,7 @@ function CreateAncestryPanel({
5399
5438
  window.addEventListener("keydown", handleKeyDown);
5400
5439
  return () => window.removeEventListener("keydown", handleKeyDown);
5401
5440
  }, [isContextLinked, branchStack]);
5402
- useEffect9(() => {
5441
+ useEffect10(() => {
5403
5442
  const ctx = getCurrentContext();
5404
5443
  let sourceObject = {};
5405
5444
  if (ctx) {
@@ -6072,7 +6111,7 @@ function CreateAncestryPanel({
6072
6111
  }
6073
6112
  }
6074
6113
  };
6075
- useEffect9(() => {
6114
+ useEffect10(() => {
6076
6115
  if (!description && existingSections.length === 0) return;
6077
6116
  const newRootTree = applyDescriptionToTree(ancestryMode.tree, description, existingSections);
6078
6117
  const currentTreeString = JSON.stringify(ancestryMode.tree);
@@ -6203,7 +6242,15 @@ function CreateAncestryPanel({
6203
6242
  onHighlightNode,
6204
6243
  onImageClick: handleImageClickFromText
6205
6244
  }
6206
- ) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0 flex-shrink-0" }), /* @__PURE__ */ React10.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4 flex-shrink-0" }, /* @__PURE__ */ React10.createElement("div", { className: "w-full" }, /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React10.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ React10.createElement("p", { className: "text-xs/relaxed text-slate-300" }, branchStack.length > 0 ? `Ramifica\xE7\xE3o (N\xEDvel ${branchStack.length})` : isEditMode ? "Editar Ancestralidade" : "Criar Ancestralidade")), /* @__PURE__ */ React10.createElement(
6245
+ ) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0 flex-shrink-0" }), /* @__PURE__ */ React10.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4 flex-shrink-0" }, /* @__PURE__ */ React10.createElement("div", { className: "w-full" }, /* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ React10.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-indigo-400/80 shadow-[0_0_18px_2px_rgba(99,102,241,0.55)]" }), /* @__PURE__ */ React10.createElement("p", { className: "text-xs/relaxed text-slate-300" }, branchStack.length > 0 ? `Ramifica\xE7\xE3o (N\xEDvel ${branchStack.length})` : isEditMode ? "Editar Ancestralidade" : "Criar Ancestralidade"), currentAncestryId && currentAncestryId !== "temp_creating" && currentAncestryId !== "temp_root" && /* @__PURE__ */ React10.createElement(
6246
+ "button",
6247
+ {
6248
+ onClick: handleCopyLink,
6249
+ className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
6250
+ title: isLinkCopied ? "Link Copiado!" : "Copiar link para esta Ancestralidade"
6251
+ },
6252
+ isLinkCopied ? /* @__PURE__ */ React10.createElement(FiCheck5, { size: 12 }) : /* @__PURE__ */ React10.createElement(FiLink4, { size: 12 })
6253
+ )), /* @__PURE__ */ React10.createElement(
6207
6254
  "input",
6208
6255
  {
6209
6256
  type: "text",
@@ -6338,7 +6385,7 @@ function CreateAncestryPanel({
6338
6385
  className: `p-1.5 rounded-md transition-colors ${isAddingNodes ? "bg-cyan-500 text-white shadow-lg shadow-cyan-500/30" : "bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600"}`,
6339
6386
  title: isAddingNodes ? "Concluir edi\xE7\xE3o da estrutura" : "Editar estrutura e adicionar nodes"
6340
6387
  },
6341
- isAddingNodes ? /* @__PURE__ */ React10.createElement(FiCheck4, { size: 14 }) : /* @__PURE__ */ React10.createElement(FiEdit23, { size: 14 })
6388
+ isAddingNodes ? /* @__PURE__ */ React10.createElement(FiCheck5, { size: 14 }) : /* @__PURE__ */ React10.createElement(FiEdit23, { size: 14 })
6342
6389
  ))), /* @__PURE__ */ React10.createElement("div", { className: "p-4 space-y-2" }, isAddingNodes && /* @__PURE__ */ React10.createElement("div", { className: "mb-3 p-2 rounded bg-cyan-900/20 border border-cyan-500/20 text-xs text-cyan-200 flex items-start gap-2" }, /* @__PURE__ */ React10.createElement(FiMousePointer, { className: "mt-0.5 flex-shrink-0" }), /* @__PURE__ */ React10.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ React10.createElement("span", null, "Clique nos nodes do cen\xE1rio para adicion\xE1-los como filhos de: ", /* @__PURE__ */ React10.createElement("strong", { className: "text-white underline decoration-dashed" }, getSelectedParentName())), /* @__PURE__ */ React10.createElement("span", { className: "opacity-75" }, "Arraste e solte itens na lista para reorganizar a hierarquia."))), activeTree && /* @__PURE__ */ React10.createElement(
6343
6390
  NodeItem,
6344
6391
  {
@@ -6403,7 +6450,7 @@ function CreateAncestryPanel({
6403
6450
  className: `p-1.5 rounded-md transition-colors ${ancestryMode.isAddingAbstractionNodes ? "bg-purple-500 text-white shadow-lg shadow-purple-500/30" : "bg-slate-700 text-slate-400 hover:text-white hover:bg-slate-600"}`,
6404
6451
  title: "Editar estrutura da abstra\xE7\xE3o"
6405
6452
  },
6406
- ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ React10.createElement(FiCheck4, { size: 14 }) : /* @__PURE__ */ React10.createElement(FiEdit23, { size: 14 })
6453
+ ancestryMode.isAddingAbstractionNodes ? /* @__PURE__ */ React10.createElement(FiCheck5, { size: 14 }) : /* @__PURE__ */ React10.createElement(FiEdit23, { size: 14 })
6407
6454
  ))),
6408
6455
  /* @__PURE__ */ React10.createElement("div", { className: "p-4 space-y-2" }, ancestryMode.isAddingAbstractionNodes && /* @__PURE__ */ React10.createElement("div", { className: "mb-3 p-2 rounded bg-purple-900/20 border border-purple-500/20 text-xs text-purple-200 flex items-start gap-2" }, /* @__PURE__ */ React10.createElement(FiMousePointer, { className: "mt-0.5 flex-shrink-0" }), /* @__PURE__ */ React10.createElement("span", null, "Clique nos nodes do cen\xE1rio para adicion\xE1-los. Arraste e solte para organizar a hierarquia.")), /* @__PURE__ */ React10.createElement(
6409
6456
  NodeItem,
@@ -6423,7 +6470,7 @@ function CreateAncestryPanel({
6423
6470
  isEditable: ancestryMode.isAddingAbstractionNodes
6424
6471
  }
6425
6472
  ))
6426
- ), branchStack.length === 0 && /* @__PURE__ */ React10.createElement("div", { className: "mt-3 flex items-center justify-end px-1" }, /* @__PURE__ */ React10.createElement("label", { className: "flex items-center gap-2 cursor-pointer group select-none" }, /* @__PURE__ */ React10.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${isPrivate ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, isPrivate && /* @__PURE__ */ React10.createElement(FiCheck4, { size: 12, className: "text-white" })), /* @__PURE__ */ React10.createElement(
6473
+ ), branchStack.length === 0 && /* @__PURE__ */ React10.createElement("div", { className: "mt-3 flex items-center justify-end px-1" }, /* @__PURE__ */ React10.createElement("label", { className: "flex items-center gap-2 cursor-pointer group select-none" }, /* @__PURE__ */ React10.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${isPrivate ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, isPrivate && /* @__PURE__ */ React10.createElement(FiCheck5, { size: 12, className: "text-white" })), /* @__PURE__ */ React10.createElement(
6427
6474
  "input",
6428
6475
  {
6429
6476
  type: "checkbox",
@@ -6471,7 +6518,7 @@ function CreateAncestryPanel({
6471
6518
  }
6472
6519
 
6473
6520
  // src/components/ImageViewer.jsx
6474
- import React11, { useState as useState11, useEffect as useEffect10, useLayoutEffect as useLayoutEffect2, useCallback as useCallback2 } from "react";
6521
+ import React11, { useState as useState11, useEffect as useEffect11, useLayoutEffect as useLayoutEffect2, useCallback as useCallback2 } from "react";
6475
6522
  import { FiX as FiX2, FiChevronLeft as FiChevronLeft3, FiChevronRight as FiChevronRight5 } from "react-icons/fi";
6476
6523
  function ImageViewer({ data, onClose }) {
6477
6524
  var _a;
@@ -6494,7 +6541,7 @@ function ImageViewer({ data, onClose }) {
6494
6541
  setCurrentIndex((prev) => (prev - 1 + images.length) % images.length);
6495
6542
  }
6496
6543
  }, [images.length]);
6497
- useEffect10(() => {
6544
+ useEffect11(() => {
6498
6545
  if (!visible) return;
6499
6546
  const handleKeyDown = (e) => {
6500
6547
  if (e.key === "Escape") {
@@ -6507,7 +6554,7 @@ function ImageViewer({ data, onClose }) {
6507
6554
  window.addEventListener("keydown", handleKeyDown, { capture: true });
6508
6555
  return () => window.removeEventListener("keydown", handleKeyDown, { capture: true });
6509
6556
  }, [visible, onClose, handleNext, handlePrev]);
6510
- useEffect10(() => {
6557
+ useEffect11(() => {
6511
6558
  if (!visible || images.length === 0) return;
6512
6559
  const curr = images[currentIndex];
6513
6560
  const src = curr == null ? void 0 : curr.value;
@@ -6594,12 +6641,12 @@ function ImageViewer({ data, onClose }) {
6594
6641
  }
6595
6642
 
6596
6643
  // src/components/InSceneCreationForm.jsx
6597
- import React13, { useState as useState13, useEffect as useEffect12, useRef as useRef10 } from "react";
6644
+ import React13, { useState as useState13, useEffect as useEffect13, useRef as useRef10 } from "react";
6598
6645
 
6599
6646
  // src/components/ColorPicker.jsx
6600
- import React12, { useState as useState12, useEffect as useEffect11, useRef as useRef9 } from "react";
6647
+ import React12, { useState as useState12, useEffect as useEffect12, useRef as useRef9 } from "react";
6601
6648
  import { HexColorPicker } from "react-colorful";
6602
- import { FiHash, FiCheck as FiCheck5 } from "react-icons/fi";
6649
+ import { FiHash, FiCheck as FiCheck6 } from "react-icons/fi";
6603
6650
  var PRESET_COLORS = [
6604
6651
  "#ef4444",
6605
6652
  "#f97316",
@@ -6620,7 +6667,7 @@ var PRESET_COLORS = [
6620
6667
  function ColorPicker({ color, onChange, disabled }) {
6621
6668
  const [isOpen, setIsOpen] = useState12(false);
6622
6669
  const popoverRef = useRef9(null);
6623
- useEffect11(() => {
6670
+ useEffect12(() => {
6624
6671
  const handleClickOutside = (event) => {
6625
6672
  if (popoverRef.current && !popoverRef.current.contains(event.target)) {
6626
6673
  setIsOpen(false);
@@ -6668,7 +6715,7 @@ function ColorPicker({ color, onChange, disabled }) {
6668
6715
  style: { backgroundColor: preset },
6669
6716
  title: preset
6670
6717
  },
6671
- color.toLowerCase() === preset.toLowerCase() && /* @__PURE__ */ React12.createElement(FiCheck5, { className: `drop-shadow-md ${["#ffffff", "#4df5cb", "#84cc16", "#f59e0b"].includes(preset) ? "text-black" : "text-white"}`, size: 12 })
6718
+ color.toLowerCase() === preset.toLowerCase() && /* @__PURE__ */ React12.createElement(FiCheck6, { className: `drop-shadow-md ${["#ffffff", "#4df5cb", "#84cc16", "#f59e0b"].includes(preset) ? "text-black" : "text-white"}`, size: 12 })
6672
6719
  )))), /* @__PURE__ */ React12.createElement("style", null, `
6673
6720
  .custom-react-colorful .react-colorful {
6674
6721
  width: 100%;
@@ -6693,7 +6740,7 @@ function ColorPicker({ color, onChange, disabled }) {
6693
6740
  }
6694
6741
 
6695
6742
  // src/components/InSceneCreationForm.jsx
6696
- import { FiPlus as FiPlus3, FiMaximize2, FiX as FiX3, FiCheck as FiCheck6, FiEdit2 as FiEdit24, FiSun } from "react-icons/fi";
6743
+ import { FiPlus as FiPlus3, FiMaximize2, FiX as FiX3, FiCheck as FiCheck7, FiEdit2 as FiEdit24, FiSun } from "react-icons/fi";
6697
6744
  function InSceneCreationForm({
6698
6745
  onSave,
6699
6746
  onCancel,
@@ -6728,14 +6775,14 @@ function InSceneCreationForm({
6728
6775
  const [selectedImageUrl, setSelectedImageUrl] = useState13(null);
6729
6776
  const propsEndRef = useRef10(null);
6730
6777
  const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
6731
- useEffect12(() => {
6778
+ useEffect13(() => {
6732
6779
  if (!hasImages && useImageAsTexture) {
6733
6780
  setUseImageAsTexture(false);
6734
6781
  setSelectedImageUrl(null);
6735
6782
  onImageChange == null ? void 0 : onImageChange(false, null);
6736
6783
  }
6737
6784
  }, [hasImages, useImageAsTexture, onImageChange]);
6738
- useEffect12(() => {
6785
+ useEffect13(() => {
6739
6786
  let result = [];
6740
6787
  if (typeInput.trim() === "") {
6741
6788
  result = existingTypes.filter((t) => !types.includes(t));
@@ -6757,7 +6804,7 @@ function InSceneCreationForm({
6757
6804
  }
6758
6805
  setFilteredTypes(result);
6759
6806
  }, [typeInput, existingTypes, types, sourceTypes]);
6760
- useEffect12(() => {
6807
+ useEffect13(() => {
6761
6808
  if (initialColor) {
6762
6809
  onColorChange == null ? void 0 : onColorChange(initialColor);
6763
6810
  }
@@ -6956,10 +7003,10 @@ function InSceneCreationForm({
6956
7003
  onClick: () => handleSizeChange(s),
6957
7004
  className: "flex items-center gap-2 group cursor-pointer focus:outline-none"
6958
7005
  },
6959
- /* @__PURE__ */ React13.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, isSelected && /* @__PURE__ */ React13.createElement(FiCheck6, { size: 12, className: "text-white" })),
7006
+ /* @__PURE__ */ React13.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, isSelected && /* @__PURE__ */ React13.createElement(FiCheck7, { size: 12, className: "text-white" })),
6960
7007
  /* @__PURE__ */ React13.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s)
6961
7008
  );
6962
- }))), /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React13.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), hasImages && /* @__PURE__ */ React13.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ React13.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ React13.createElement(FiCheck6, { size: 12, className: "text-white" })), /* @__PURE__ */ React13.createElement(
7009
+ }))), /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React13.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), hasImages && /* @__PURE__ */ React13.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ React13.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ React13.createElement(FiCheck7, { size: 12, className: "text-white" })), /* @__PURE__ */ React13.createElement(
6963
7010
  "input",
6964
7011
  {
6965
7012
  type: "checkbox",
@@ -7019,8 +7066,8 @@ function InSceneCreationForm({
7019
7066
  }
7020
7067
 
7021
7068
  // src/components/InSceneVersionForm.jsx
7022
- import React14, { useState as useState14, useEffect as useEffect13, useRef as useRef11 } from "react";
7023
- import { FiPlus as FiPlus4, FiMaximize2 as FiMaximize22, FiCheck as FiCheck7, FiEdit2 as FiEdit25 } from "react-icons/fi";
7069
+ import React14, { useState as useState14, useEffect as useEffect14, useRef as useRef11 } from "react";
7070
+ import { FiPlus as FiPlus4, FiMaximize2 as FiMaximize22, FiCheck as FiCheck8, FiEdit2 as FiEdit25 } from "react-icons/fi";
7024
7071
  function InSceneVersionForm({
7025
7072
  onSave,
7026
7073
  onCancel,
@@ -7046,14 +7093,14 @@ function InSceneVersionForm({
7046
7093
  const [useImageAsTexture, setUseImageAsTexture] = useState14(false);
7047
7094
  const [selectedImageUrl, setSelectedImageUrl] = useState14(null);
7048
7095
  const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
7049
- useEffect13(() => {
7096
+ useEffect14(() => {
7050
7097
  if (!hasImages && useImageAsTexture) {
7051
7098
  setUseImageAsTexture(false);
7052
7099
  setSelectedImageUrl(null);
7053
7100
  onImageChange == null ? void 0 : onImageChange(false, null);
7054
7101
  }
7055
7102
  }, [hasImages, useImageAsTexture, onImageChange]);
7056
- useEffect13(() => {
7103
+ useEffect14(() => {
7057
7104
  if (fixedColor) {
7058
7105
  }
7059
7106
  }, [fixedColor]);
@@ -7193,10 +7240,10 @@ function InSceneVersionForm({
7193
7240
  onClick: () => handleSizeChange(s),
7194
7241
  className: "flex items-center gap-2 group cursor-pointer focus:outline-none"
7195
7242
  },
7196
- /* @__PURE__ */ React14.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, isSelected && /* @__PURE__ */ React14.createElement(FiCheck7, { size: 12, className: "text-white" })),
7243
+ /* @__PURE__ */ React14.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent group-hover:border-slate-500"}` }, isSelected && /* @__PURE__ */ React14.createElement(FiCheck8, { size: 12, className: "text-white" })),
7197
7244
  /* @__PURE__ */ React14.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 group-hover:text-slate-300"}` }, s)
7198
7245
  );
7199
- }))), /* @__PURE__ */ React14.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React14.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React14.createElement("label", { className: "text-xs text-slate-300" }, "Cor do Node (Fixa)"), hasImages && /* @__PURE__ */ React14.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ React14.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ React14.createElement(FiCheck7, { size: 12, className: "text-white" })), /* @__PURE__ */ React14.createElement(
7246
+ }))), /* @__PURE__ */ React14.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React14.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React14.createElement("label", { className: "text-xs text-slate-300" }, "Cor do Node (Fixa)"), hasImages && /* @__PURE__ */ React14.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ React14.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ React14.createElement(FiCheck8, { size: 12, className: "text-white" })), /* @__PURE__ */ React14.createElement(
7200
7247
  "input",
7201
7248
  {
7202
7249
  type: "checkbox",
@@ -7237,8 +7284,8 @@ function InSceneVersionForm({
7237
7284
  }
7238
7285
 
7239
7286
  // src/components/NodeDetailsPanel.jsx
7240
- import React15, { useState as useState15, useEffect as useEffect14, useRef as useRef12 } from "react";
7241
- import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck8, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink3 } from "react-icons/fi";
7287
+ import React15, { useState as useState15, useEffect as useEffect15, useRef as useRef12 } from "react";
7288
+ import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck9, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5 } from "react-icons/fi";
7242
7289
  function NodeDetailsPanel({
7243
7290
  node,
7244
7291
  onClose,
@@ -7288,7 +7335,7 @@ function NodeDetailsPanel({
7288
7335
  onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
7289
7336
  }
7290
7337
  };
7291
- useEffect14(() => {
7338
+ useEffect15(() => {
7292
7339
  if ((node == null ? void 0 : node.id) !== prevNodeIdRef.current) {
7293
7340
  prevNodeIdRef.current = node == null ? void 0 : node.id;
7294
7341
  setName((node == null ? void 0 : node.name) ?? "");
@@ -7310,13 +7357,13 @@ function NodeDetailsPanel({
7310
7357
  }
7311
7358
  }, [node]);
7312
7359
  const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
7313
- useEffect14(() => {
7360
+ useEffect15(() => {
7314
7361
  if (!hasImages && useImageAsTexture) {
7315
7362
  setUseImageAsTexture(false);
7316
7363
  setSelectedImageUrl(null);
7317
7364
  }
7318
7365
  }, [hasImages, useImageAsTexture]);
7319
- useEffect14(() => {
7366
+ useEffect15(() => {
7320
7367
  if (typeInput.trim() === "") {
7321
7368
  setFilteredTypes(existingTypes.filter((t) => !types.includes(t)));
7322
7369
  } else {
@@ -7525,7 +7572,7 @@ function NodeDetailsPanel({
7525
7572
  className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-indigo-400"}`,
7526
7573
  title: isLinkCopied ? "Link Copiado!" : "Copiar link para este Node"
7527
7574
  },
7528
- isLinkCopied ? /* @__PURE__ */ React15.createElement(FiCheck8, { size: 12 }) : /* @__PURE__ */ React15.createElement(FiLink3, { size: 12 })
7575
+ isLinkCopied ? /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12 }) : /* @__PURE__ */ React15.createElement(FiLink5, { size: 12 })
7529
7576
  )), /* @__PURE__ */ React15.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ React15.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "w-9 h-9 grid place-content-center rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-xl disabled:opacity-50", title: "Cancelar" }, "\xD7")), /* @__PURE__ */ React15.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Tipos"), /* @__PURE__ */ React15.createElement("div", { className: `relative w-full bg-slate-800/70 p-1.5 min-h-[42px] flex flex-wrap gap-1.5 rounded-lg border border-white/10 ${canEdit ? "focus-within:ring-2 focus-within:ring-indigo-400/60" : ""} transition-all` }, types.map((t, index) => /* @__PURE__ */ React15.createElement("span", { key: index, className: "flex items-center gap-1 bg-indigo-500/30 text-indigo-100 px-1.5 py-0.5 rounded-md text-xs font-medium border border-indigo-500/20" }, t, canEdit && /* @__PURE__ */ React15.createElement(
7530
7577
  "button",
7531
7578
  {
@@ -7621,10 +7668,10 @@ function NodeDetailsPanel({
7621
7668
  onClick: () => canEdit && handleSizeChange(s),
7622
7669
  className: `flex items-center gap-2 group focus:outline-none ${canEdit ? "cursor-pointer" : "cursor-default opacity-80"}`
7623
7670
  },
7624
- /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent " + (canEdit ? "group-hover:border-slate-500" : "")}` }, isSelected && /* @__PURE__ */ React15.createElement(FiCheck8, { size: 12, className: "text-white" })),
7671
+ /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded-[4px] border flex items-center justify-center transition-all duration-200 ${isSelected ? "bg-indigo-500 border-indigo-500 shadow-[0_0_10px_rgba(99,102,241,0.4)]" : "border-slate-600 bg-transparent " + (canEdit ? "group-hover:border-slate-500" : "")}` }, isSelected && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })),
7625
7672
  /* @__PURE__ */ React15.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s)
7626
7673
  );
7627
- }))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), canEdit && hasImages && /* @__PURE__ */ React15.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ React15.createElement(FiCheck8, { size: 12, className: "text-white" })), /* @__PURE__ */ React15.createElement(
7674
+ }))), /* @__PURE__ */ React15.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React15.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React15.createElement("label", { className: "text-xs text-slate-300" }, "Cor e Brilho"), canEdit && hasImages && /* @__PURE__ */ React15.createElement("label", { className: "flex items-center gap-2 cursor-pointer group" }, /* @__PURE__ */ React15.createElement("div", { className: `w-4 h-4 rounded border flex items-center justify-center transition-colors ${useImageAsTexture ? "bg-indigo-500 border-indigo-500" : "border-slate-500 bg-transparent"}` }, useImageAsTexture && /* @__PURE__ */ React15.createElement(FiCheck9, { size: 12, className: "text-white" })), /* @__PURE__ */ React15.createElement(
7628
7675
  "input",
7629
7676
  {
7630
7677
  type: "checkbox",
@@ -7699,7 +7746,7 @@ function NodeDetailsPanel({
7699
7746
  }
7700
7747
 
7701
7748
  // src/components/MultiNodeContextMenu.jsx
7702
- import React16, { useLayoutEffect as useLayoutEffect3, useRef as useRef13, useState as useState16, useEffect as useEffect15 } from "react";
7749
+ import React16, { useLayoutEffect as useLayoutEffect3, useRef as useRef13, useState as useState16, useEffect as useEffect16 } from "react";
7703
7750
  function MultiNodeContextMenu({
7704
7751
  data,
7705
7752
  userRole,
@@ -7726,7 +7773,7 @@ function MultiNodeContextMenu({
7726
7773
  if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
7727
7774
  setMenuPos({ left, top });
7728
7775
  }, [data]);
7729
- useEffect15(() => {
7776
+ useEffect16(() => {
7730
7777
  if (!data.visible) return;
7731
7778
  const handleClickOutside = (e) => {
7732
7779
  if (menuRef.current && !menuRef.current.contains(e.target)) onClose();
@@ -7759,7 +7806,7 @@ function MultiNodeContextMenu({
7759
7806
  }
7760
7807
 
7761
7808
  // src/components/RelationshipDetailsPanel.jsx
7762
- import React17, { useState as useState17, useEffect as useEffect16, useRef as useRef14, useMemo as useMemo9 } from "react";
7809
+ import React17, { useState as useState17, useEffect as useEffect17, useRef as useRef14, useMemo as useMemo9 } from "react";
7763
7810
  import { FiPlus as FiPlus6, FiEdit2 as FiEdit27, FiLoader as FiLoader3, FiBookOpen as FiBookOpen4 } from "react-icons/fi";
7764
7811
  function RelationshipDetailsPanel({
7765
7812
  link,
@@ -7787,7 +7834,7 @@ function RelationshipDetailsPanel({
7787
7834
  const ability = defineAbilityFor(userRole);
7788
7835
  return ability.can("update", "Connection");
7789
7836
  }, [userRole]);
7790
- useEffect16(() => {
7837
+ useEffect17(() => {
7791
7838
  setName((link == null ? void 0 : link.name) ?? "");
7792
7839
  setDescription((link == null ? void 0 : link.description) ?? "");
7793
7840
  setExistingSections((link == null ? void 0 : link.description_sections) || []);
@@ -7984,7 +8031,7 @@ function RelationshipDetailsPanel({
7984
8031
  }
7985
8032
 
7986
8033
  // src/components/RelationshipContextMenu.jsx
7987
- import React18, { useLayoutEffect as useLayoutEffect4, useRef as useRef15, useState as useState18, useEffect as useEffect17, useMemo as useMemo10 } from "react";
8034
+ import React18, { useLayoutEffect as useLayoutEffect4, useRef as useRef15, useState as useState18, useEffect as useEffect18, useMemo as useMemo10 } from "react";
7988
8035
  function RelationshipContextMenu({
7989
8036
  data,
7990
8037
  userRole,
@@ -8025,7 +8072,7 @@ function RelationshipContextMenu({
8025
8072
  if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
8026
8073
  setMenuPos({ left, top });
8027
8074
  }, [data]);
8028
- useEffect17(() => {
8075
+ useEffect18(() => {
8029
8076
  if (!data.visible) return;
8030
8077
  const handleClickOutside = (e) => {
8031
8078
  if (menuRef.current && !menuRef.current.contains(e.target)) onClose();
@@ -8198,7 +8245,7 @@ function LoadingScreen() {
8198
8245
  }
8199
8246
 
8200
8247
  // src/components/ImportParentFileModal.jsx
8201
- import React20, { useEffect as useEffect18, useState as useState19 } from "react";
8248
+ import React20, { useEffect as useEffect19, useState as useState19 } from "react";
8202
8249
  function ImportParentFileModal({
8203
8250
  isOpen,
8204
8251
  onClose,
@@ -8214,7 +8261,7 @@ function ImportParentFileModal({
8214
8261
  const [availableViews, setAvailableViews] = useState19([]);
8215
8262
  const [selectedItem, setSelectedItem] = useState19(null);
8216
8263
  const [isLoading, setIsLoading] = useState19(false);
8217
- useEffect18(() => {
8264
+ useEffect19(() => {
8218
8265
  if (isOpen && session && onFetchAvailableFiles) {
8219
8266
  const fetchData = async () => {
8220
8267
  setIsLoading(true);
@@ -8250,7 +8297,7 @@ function ImportParentFileModal({
8250
8297
  fetchData();
8251
8298
  }
8252
8299
  }, [isOpen, session, parentDbs, onFetchAvailableFiles, currentViewName]);
8253
- useEffect18(() => {
8300
+ useEffect19(() => {
8254
8301
  setSelectedItem(null);
8255
8302
  }, [activeTab]);
8256
8303
  if (!isOpen) {
@@ -8435,7 +8482,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
8435
8482
  }
8436
8483
 
8437
8484
  // src/components/AncestryBoard.jsx
8438
- import React22, { useState as useState21, useMemo as useMemo11, useEffect as useEffect19, useRef as useRef16 } from "react";
8485
+ import React22, { useState as useState21, useMemo as useMemo11, useEffect as useEffect20, useRef as useRef16 } from "react";
8439
8486
  import {
8440
8487
  FiSearch as FiSearch4,
8441
8488
  FiLayers as FiLayers6,
@@ -8477,7 +8524,7 @@ var GroupItem = ({
8477
8524
  textarea.style.height = `${textarea.scrollHeight}px`;
8478
8525
  }
8479
8526
  };
8480
- useEffect19(() => {
8527
+ useEffect20(() => {
8481
8528
  adjustHeight();
8482
8529
  }, [group.text]);
8483
8530
  return /* @__PURE__ */ React22.createElement("div", { className: "flex flex-col gap-2 mb-3 pl-3 border-l border-white/10 relative group/item animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ React22.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ React22.createElement("div", { className: `
@@ -8620,7 +8667,7 @@ function AncestryBoard({
8620
8667
  const canEdit = useMemo11(() => {
8621
8668
  return userRole !== "viewer";
8622
8669
  }, [userRole]);
8623
- useEffect19(() => {
8670
+ useEffect20(() => {
8624
8671
  if (initialGroups && !isLoaded) {
8625
8672
  setGroups(initialGroups);
8626
8673
  setIsLoaded(true);
@@ -8651,7 +8698,7 @@ function AncestryBoard({
8651
8698
  children: sanitizeGroups(g.children || [])
8652
8699
  }));
8653
8700
  };
8654
- useEffect19(() => {
8701
+ useEffect20(() => {
8655
8702
  if (!isLoaded || !onSave) return;
8656
8703
  const timeoutId = setTimeout(async () => {
8657
8704
  setSaveStatus("saving");
@@ -8669,7 +8716,7 @@ function AncestryBoard({
8669
8716
  }, 3e3);
8670
8717
  return () => clearTimeout(timeoutId);
8671
8718
  }, [groups, isLoaded, onSave]);
8672
- useEffect19(() => {
8719
+ useEffect20(() => {
8673
8720
  if (!isOpen) return;
8674
8721
  const handleKeyDown = (e) => {
8675
8722
  if (e.key === "Escape") {
@@ -9006,6 +9053,7 @@ function XViewScene({
9006
9053
  const router = useRouter();
9007
9054
  const searchParams = useSearchParams();
9008
9055
  const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
9056
+ const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
9009
9057
  const viewParams = useMemo12(() => {
9010
9058
  if (encryptedConfig) {
9011
9059
  const data = decryptData(encryptedConfig);
@@ -9015,7 +9063,7 @@ function XViewScene({
9015
9063
  }
9016
9064
  return null;
9017
9065
  }, [encryptedConfig, session]);
9018
- useEffect20(() => {
9066
+ useEffect21(() => {
9019
9067
  async function verifyPermission() {
9020
9068
  if (!viewParams || !session || !check_user_permission) return;
9021
9069
  const { id, type, owner_id } = viewParams;
@@ -9073,6 +9121,7 @@ function XViewScene({
9073
9121
  const [creationMode, setCreationMode] = useState22({ isActive: false, sourceNodeData: null });
9074
9122
  const [versionMode, setVersionMode] = useState22({ isActive: false, sourceNodeData: null });
9075
9123
  const [hasFocusedInitial, setHasFocusedInitial] = useState22(false);
9124
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = useState22(false);
9076
9125
  const [ancestryMode, setAncestryMode] = useState22({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
9077
9126
  const [readingMode, setReadingMode] = useState22({
9078
9127
  isActive: false,
@@ -9134,10 +9183,10 @@ function XViewScene({
9134
9183
  lastDescriptionLength: 0,
9135
9184
  highlightedNodeId: null
9136
9185
  });
9137
- useEffect20(() => {
9186
+ useEffect21(() => {
9138
9187
  stateRef.current.ancestry = ancestryMode;
9139
9188
  }, [ancestryMode]);
9140
- useEffect20(() => {
9189
+ useEffect21(() => {
9141
9190
  var _a2;
9142
9191
  if (!isInitialized) return;
9143
9192
  const map = /* @__PURE__ */ new Map();
@@ -9638,7 +9687,7 @@ function XViewScene({
9638
9687
  }
9639
9688
  });
9640
9689
  }, []);
9641
- useEffect20(() => {
9690
+ useEffect21(() => {
9642
9691
  async function fetchAllData(configPath, ownerId2) {
9643
9692
  var _a2, _b2;
9644
9693
  if (!get_scene_view_data) {
@@ -9736,7 +9785,7 @@ function XViewScene({
9736
9785
  }
9737
9786
  return mesh;
9738
9787
  }, []);
9739
- useEffect20(() => {
9788
+ useEffect21(() => {
9740
9789
  if (!isInitialized || !sceneDataRef.current) return;
9741
9790
  const currentMount = mountRef.current;
9742
9791
  if (!currentMount) return;
@@ -11986,7 +12035,7 @@ function XViewScene({
11986
12035
  tweenToTarget(nodeMesh, 1.2);
11987
12036
  }
11988
12037
  }, [tweenToTarget]);
11989
- useEffect20(() => {
12038
+ useEffect21(() => {
11990
12039
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
11991
12040
  const nodeObjects = stateRef.current.nodeObjects || {};
11992
12041
  const targetMesh = nodeObjects[String(focusNodeId)];
@@ -12000,6 +12049,20 @@ function XViewScene({
12000
12049
  }
12001
12050
  }
12002
12051
  }, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
12052
+ useEffect21(() => {
12053
+ if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
12054
+ const ancestries = ancestryDataRef.current || [];
12055
+ const targetAncestry = ancestries.find((a) => String(a.ancestry_id) === String(focusAncestryId));
12056
+ if (targetAncestry) {
12057
+ setTimeout(() => {
12058
+ handleStartReadingAncestry(targetAncestry);
12059
+ setHasOpenedInitialAncestry(true);
12060
+ }, 300);
12061
+ } else {
12062
+ setHasOpenedInitialAncestry(true);
12063
+ }
12064
+ }
12065
+ }, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
12003
12066
  if (isLoading || status === "loading" || permissionStatus === "loading") {
12004
12067
  return /* @__PURE__ */ React23.createElement(LoadingScreen, null);
12005
12068
  }
@@ -12094,6 +12157,7 @@ function XViewScene({
12094
12157
  DescriptionReadModePanel,
12095
12158
  {
12096
12159
  key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
12160
+ ancestryId: readingMode.ancestry.ancestry_id,
12097
12161
  title: (getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.name) || readingMode.ancestry.name || "Ancestralidade",
12098
12162
  initialSectionId: readingMode.initialSectionId,
12099
12163
  description: getReadModeDisplayContext == null ? void 0 : getReadModeDisplayContext.description,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lv-x-software-house/x_view",
3
- "version": "1.2.1-dev.7",
3
+ "version": "1.2.1-dev.8",
4
4
  "description": "Pacote privado contendo os componentes e lógica de renderização 3D do X View.",
5
5
  "author": "iv.x - Engenharia de Software - ivxsoftwarehouse@gmail.com",
6
6
  "license": "UNLICENSED",