@lv-x-software-house/x_view 1.2.4-dev.22 → 1.2.4-dev.24

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.
Files changed (3) hide show
  1. package/dist/index.js +623 -282
  2. package/dist/index.mjs +563 -222
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -43,9 +43,9 @@ __export(index_exports, {
43
43
  module.exports = __toCommonJS(index_exports);
44
44
 
45
45
  // src/XViewScene.jsx
46
- var import_react25 = __toESM(require("react"));
46
+ var import_react26 = __toESM(require("react"));
47
47
  var import_navigation = require("next/navigation");
48
- var import_react26 = require("next-auth/react");
48
+ var import_react27 = require("next-auth/react");
49
49
  var import_crypto_js = __toESM(require("crypto-js"));
50
50
  var THREE3 = __toESM(require("three"));
51
51
  var import_OrbitControls = require("three/examples/jsm/controls/OrbitControls.js");
@@ -2893,7 +2893,9 @@ var IGNORED_KEYS = [
2893
2893
  "is_private",
2894
2894
  "abstraction_tree",
2895
2895
  "selectedAbstractionParentId",
2896
- "isAddingAbstractionNodes"
2896
+ "isAddingAbstractionNodes",
2897
+ "status",
2898
+ "is_quest"
2897
2899
  ];
2898
2900
  function extractCustomPropsFromNode(node) {
2899
2901
  const customPropTypes = node._customPropTypes || {};
@@ -8654,8 +8656,326 @@ function NodeDetailsPanel({
8654
8656
  ));
8655
8657
  }
8656
8658
 
8657
- // src/components/MultiNodeContextMenu.jsx
8659
+ // src/components/QuestDetailsPanel.jsx
8658
8660
  var import_react18 = __toESM(require("react"));
8661
+ var import_fi16 = require("react-icons/fi");
8662
+ var QUEST_STATUS_COLORS2 = {
8663
+ "Backlog": "#64748b",
8664
+ "In Progress": "#eab308",
8665
+ "Review": "#a855f7",
8666
+ "Done": "#22c55e"
8667
+ };
8668
+ function QuestDetailsPanel({
8669
+ node,
8670
+ onClose,
8671
+ onSave,
8672
+ onNameChange,
8673
+ onColorChange,
8674
+ onSizeChange,
8675
+ onDataUpdate,
8676
+ onOpenImageViewer,
8677
+ existingTypes = [],
8678
+ availableNodes = [],
8679
+ availableAncestries = [],
8680
+ onOpenReference,
8681
+ onMentionClick,
8682
+ onUploadFile,
8683
+ userRole,
8684
+ currentDatasetName
8685
+ }) {
8686
+ const [name, setName] = (0, import_react18.useState)((node == null ? void 0 : node.name) ?? "");
8687
+ const [types, setTypes] = (0, import_react18.useState)((node == null ? void 0 : node.type) ? Array.isArray(node.type) ? node.type : [node.type] : ["quest"]);
8688
+ const [typeInput, setTypeInput] = (0, import_react18.useState)("");
8689
+ const [status, setStatus] = (0, import_react18.useState)((node == null ? void 0 : node.status) ?? "Backlog");
8690
+ const [size, setSize] = (0, import_react18.useState)((node == null ? void 0 : node.size) ?? "medium");
8691
+ const [description, setDescription] = (0, import_react18.useState)((node == null ? void 0 : node.description) ?? "");
8692
+ const [intensity, setIntensity] = (0, import_react18.useState)((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
8693
+ const [isStatusDropdownOpen, setIsStatusDropdownOpen] = (0, import_react18.useState)(false);
8694
+ const [customProps, setCustomProps] = (0, import_react18.useState)(() => extractCustomPropsFromNode(node || {}));
8695
+ const [showTypeSuggestions, setShowTypeSuggestions] = (0, import_react18.useState)(false);
8696
+ const [filteredTypes, setFilteredTypes] = (0, import_react18.useState)([]);
8697
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react18.useState)(false);
8698
+ const [isReadMode, setIsReadMode] = (0, import_react18.useState)(false);
8699
+ const [existingSections, setExistingSections] = (0, import_react18.useState)((node == null ? void 0 : node.description_sections) || []);
8700
+ const [isSaving, setIsSaving] = (0, import_react18.useState)(false);
8701
+ const [isLinkCopied, setIsLinkCopied] = (0, import_react18.useState)(false);
8702
+ const maxPanelW = typeof window !== "undefined" ? window.innerWidth * 0.92 : 1200;
8703
+ const { width: panelWidth, isResizing, handlePointerDown: handleResize, setWidth } = useResizablePanel({
8704
+ initialWidth: isReadMode ? 700 : 440,
8705
+ minWidth: 320,
8706
+ maxWidth: maxPanelW
8707
+ });
8708
+ (0, import_react18.useEffect)(() => {
8709
+ setWidth(isReadMode ? 700 : 440);
8710
+ }, [isReadMode, setWidth]);
8711
+ const prevNodeIdRef = (0, import_react18.useRef)(null);
8712
+ const propsEndRef = (0, import_react18.useRef)(null);
8713
+ const canEdit = userRole !== "viewer";
8714
+ const availableImages = customProps.filter((p) => p.type === "images").flatMap((p) => Array.isArray(p.value) ? p.value : []).filter((img) => img.value && img.value.trim() !== "");
8715
+ const handleImageClickFromText = (url, name2) => {
8716
+ if (onOpenImageViewer) {
8717
+ onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
8718
+ }
8719
+ };
8720
+ (0, import_react18.useEffect)(() => {
8721
+ if ((node == null ? void 0 : node.id) !== prevNodeIdRef.current) {
8722
+ prevNodeIdRef.current = node == null ? void 0 : node.id;
8723
+ setName((node == null ? void 0 : node.name) ?? "");
8724
+ setTypes((node == null ? void 0 : node.type) ? Array.isArray(node.type) ? node.type : [node.type] : ["quest"]);
8725
+ setStatus((node == null ? void 0 : node.status) ?? "Backlog");
8726
+ setSize((node == null ? void 0 : node.size) ?? "medium");
8727
+ setDescription((node == null ? void 0 : node.description) ?? "");
8728
+ setIntensity((node == null ? void 0 : node.intensity) !== void 0 ? node.intensity : 0);
8729
+ setExistingSections((node == null ? void 0 : node.description_sections) || []);
8730
+ setCustomProps(extractCustomPropsFromNode(node || {}));
8731
+ }
8732
+ }, [node]);
8733
+ (0, import_react18.useEffect)(() => {
8734
+ if (typeInput.trim() === "") {
8735
+ setFilteredTypes(existingTypes.filter((t) => !types.includes(t)));
8736
+ } else {
8737
+ const lowercasedInput = typeInput.toLowerCase();
8738
+ setFilteredTypes(
8739
+ existingTypes.filter(
8740
+ (t) => t.toLowerCase().includes(lowercasedInput) && !types.includes(t)
8741
+ )
8742
+ );
8743
+ }
8744
+ }, [typeInput, existingTypes, types]);
8745
+ const handleCopyLink = () => {
8746
+ if (!(node == null ? void 0 : node.id)) return;
8747
+ const baseUrl = window.location.origin + window.location.pathname;
8748
+ const fullUrl = `${baseUrl}?focus=${node.id}`;
8749
+ navigator.clipboard.writeText(fullUrl).then(() => {
8750
+ setIsLinkCopied(true);
8751
+ setTimeout(() => setIsLinkCopied(false), 2e3);
8752
+ }).catch((err) => {
8753
+ console.error("Erro ao copiar link:", err);
8754
+ });
8755
+ };
8756
+ const swallow = (e) => e.stopPropagation();
8757
+ const handleNameChange = (e) => {
8758
+ const v = e.target.value;
8759
+ setName(v);
8760
+ onNameChange == null ? void 0 : onNameChange(node.id, v);
8761
+ };
8762
+ const handleSizeChange = (newSize) => {
8763
+ setSize(newSize);
8764
+ onSizeChange == null ? void 0 : onSizeChange(node.id, newSize);
8765
+ };
8766
+ const handleStatusChange = (newStatus) => {
8767
+ setStatus(newStatus);
8768
+ const newColor = QUEST_STATUS_COLORS2[newStatus];
8769
+ onColorChange == null ? void 0 : onColorChange(node.id, newColor);
8770
+ onDataUpdate == null ? void 0 : onDataUpdate({ ...node, status: newStatus, color: newColor });
8771
+ };
8772
+ const handleAddType = (newType) => {
8773
+ const trimmed = newType.trim();
8774
+ if (trimmed && !types.includes(trimmed)) {
8775
+ setTypes([...types, trimmed]);
8776
+ setTypeInput("");
8777
+ setShowTypeSuggestions(false);
8778
+ }
8779
+ };
8780
+ const handleRemoveType = (indexToRemove) => {
8781
+ if (types[indexToRemove] === "quest") return;
8782
+ setTypes(types.filter((_, index) => index !== indexToRemove));
8783
+ };
8784
+ const handleTypeInputKeyDown = (e) => {
8785
+ if (e.key === "Enter") {
8786
+ e.preventDefault();
8787
+ handleAddType(typeInput);
8788
+ } else if (e.key === "Backspace" && typeInput === "" && types.length > 1) {
8789
+ handleRemoveType(types.length - 1);
8790
+ }
8791
+ };
8792
+ const handleAddProp = () => {
8793
+ const newProp = createNewCustomProperty(customProps);
8794
+ setCustomProps((p) => [...p, newProp]);
8795
+ setTimeout(() => {
8796
+ var _a;
8797
+ (_a = propsEndRef.current) == null ? void 0 : _a.scrollIntoView({ behavior: "smooth", block: "center" });
8798
+ }, 100);
8799
+ };
8800
+ const handleRemoveProp = (i) => {
8801
+ const newProps = customProps.filter((_, idx) => idx !== i);
8802
+ setCustomProps(newProps);
8803
+ triggerAutoSave({ customProps: newProps });
8804
+ };
8805
+ const handleUpdateProp = (index, updatedProp) => {
8806
+ const newProps = [...customProps];
8807
+ newProps[index] = updatedProp;
8808
+ setCustomProps(newProps);
8809
+ if (!updatedProp.isEditing) {
8810
+ triggerAutoSave({ customProps: newProps });
8811
+ }
8812
+ };
8813
+ const handleSaveDescriptionInline = (newDescription) => {
8814
+ setDescription(newDescription);
8815
+ onDataUpdate({ ...node, description: newDescription });
8816
+ triggerAutoSave({ description: newDescription });
8817
+ };
8818
+ const handleSave = async (keepOpen = false, overrides = {}) => {
8819
+ const currentName = overrides.name !== void 0 ? overrides.name : name;
8820
+ const currentTypes = overrides.types !== void 0 ? overrides.types : types;
8821
+ const currentDescription = overrides.description !== void 0 ? overrides.description : description;
8822
+ const currentCustomProps = overrides.customProps !== void 0 ? overrides.customProps : customProps;
8823
+ const currentExistingSections = overrides.existingSections !== void 0 ? overrides.existingSections : existingSections;
8824
+ const currentStatus = overrides.status !== void 0 ? overrides.status : status;
8825
+ if (!currentName.trim() || currentTypes.length === 0) {
8826
+ alert("O campo 'Nome' e pelo menos um 'Tipo' s\xE3o obrigat\xF3rios.");
8827
+ return;
8828
+ }
8829
+ setIsSaving(true);
8830
+ try {
8831
+ const extrasObj = toObjectFromCustomProps(currentCustomProps.filter((p) => !p.isEditing));
8832
+ const processedSections = processDescriptionForSave(currentDescription, currentExistingSections);
8833
+ const dataToSave = {
8834
+ id: node.id,
8835
+ name: currentName.trim(),
8836
+ type: currentTypes,
8837
+ color: QUEST_STATUS_COLORS2[currentStatus],
8838
+ status: currentStatus,
8839
+ size,
8840
+ description: currentDescription,
8841
+ description_sections: processedSections,
8842
+ useImageAsTexture: false,
8843
+ textureImageUrl: null,
8844
+ intensity,
8845
+ is_quest: true,
8846
+ ...extrasObj,
8847
+ version_node: node.version_node
8848
+ };
8849
+ await onSave(dataToSave, keepOpen);
8850
+ onDataUpdate(dataToSave);
8851
+ if (!keepOpen) {
8852
+ onClose();
8853
+ }
8854
+ } finally {
8855
+ setIsSaving(false);
8856
+ }
8857
+ };
8858
+ const triggerAutoSave = (overrides = {}) => {
8859
+ handleSave(true, overrides);
8860
+ };
8861
+ const handleCancel = () => {
8862
+ if (node) {
8863
+ onNameChange == null ? void 0 : onNameChange(node.id, node.name);
8864
+ onColorChange == null ? void 0 : onColorChange(node.id, node.color);
8865
+ onSizeChange == null ? void 0 : onSizeChange(node.id, node.size || "medium");
8866
+ }
8867
+ onClose();
8868
+ };
8869
+ const currentUsedTypes = customProps.map((p) => p.type).filter((t) => UNIQUE_PROP_TYPES.includes(t));
8870
+ return /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement(
8871
+ "div",
8872
+ {
8873
+ className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col ${isResizing ? "transition-none" : "transition-all duration-300 ease-out"}`,
8874
+ style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${panelWidth}px`, maxWidth: "92vw" },
8875
+ onPointerDown: swallow,
8876
+ onPointerMove: swallow,
8877
+ onPointerUp: swallow,
8878
+ onClick: swallow,
8879
+ onWheel: swallow,
8880
+ onContextMenu: swallow,
8881
+ onDoubleClick: swallow
8882
+ },
8883
+ /* @__PURE__ */ import_react18.default.createElement("div", { onPointerDown: (e) => {
8884
+ e.stopPropagation();
8885
+ handleResize(e);
8886
+ }, className: "absolute left-0 top-0 bottom-0 w-2 cursor-col-resize hover:bg-indigo-500/50 z-[2000] transition-colors", title: "Arraste para redimensionar" }),
8887
+ isReadMode ? /* @__PURE__ */ import_react18.default.createElement(
8888
+ DescriptionReadModePanel,
8889
+ {
8890
+ title: name || (node == null ? void 0 : node.name),
8891
+ description,
8892
+ savedSections: existingSections,
8893
+ onBack: () => setIsReadMode(false),
8894
+ onEdit: () => {
8895
+ if (canEdit) {
8896
+ setIsReadMode(false);
8897
+ setIsDescriptionModalOpen(true);
8898
+ }
8899
+ },
8900
+ onClose: handleCancel,
8901
+ availableNodes,
8902
+ availableAncestries,
8903
+ onOpenReference,
8904
+ onMentionClick,
8905
+ onImageClick: handleImageClickFromText,
8906
+ onSaveDescription: handleSaveDescriptionInline
8907
+ }
8908
+ ) : /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "h-[2px]", style: { background: `linear-gradient(to right, transparent, ${QUEST_STATUS_COLORS2[status]}, transparent)` } }), /* @__PURE__ */ import_react18.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react18.default.createElement("div", null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiTarget, { className: "text-sky-400", size: 14 }), /* @__PURE__ */ import_react18.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Quest"), /* @__PURE__ */ import_react18.default.createElement("button", { onClick: handleCopyLink, className: `ml-1 p-1 transition-colors ${isLinkCopied ? "text-green-400" : "text-slate-400 hover:text-sky-400"}`, title: isLinkCopied ? "Link Copiado!" : "Copiar link para esta Quest" }, isLinkCopied ? /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiCheck, { size: 12 }) : /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiLink, { size: 12 }))), /* @__PURE__ */ import_react18.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || (node == null ? void 0 : node.name))), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Status da Quest"), /* @__PURE__ */ import_react18.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react18.default.createElement(
8909
+ "button",
8910
+ {
8911
+ type: "button",
8912
+ onClick: () => canEdit && setIsStatusDropdownOpen(!isStatusDropdownOpen),
8913
+ disabled: !canEdit,
8914
+ className: `w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 transition-colors flex items-center justify-between ${canEdit ? "hover:border-white/20 focus:ring-2 focus:ring-indigo-400/60 cursor-pointer" : "cursor-default opacity-80"}`
8915
+ },
8916
+ /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react18.default.createElement("span", { className: "w-3 h-3 rounded-full shadow-[0_0_8px_rgba(0,0,0,0.5)]", style: { backgroundColor: QUEST_STATUS_COLORS2[status] } }), /* @__PURE__ */ import_react18.default.createElement("span", { className: "text-slate-200 font-medium" }, status)),
8917
+ canEdit && /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiChevronDown, { className: `text-slate-400 transition-transform duration-200 ${isStatusDropdownOpen ? "rotate-180" : ""}` })
8918
+ ), isStatusDropdownOpen && canEdit && /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "fixed inset-0 z-40", onClick: () => setIsStatusDropdownOpen(false) }), /* @__PURE__ */ import_react18.default.createElement("ul", { className: "absolute top-full left-0 mt-1.5 w-full bg-slate-800 border border-white/10 rounded-lg shadow-[0_8px_30px_rgba(0,0,0,0.5)] z-50 overflow-hidden" }, Object.keys(QUEST_STATUS_COLORS2).map((s) => /* @__PURE__ */ import_react18.default.createElement(
8919
+ "li",
8920
+ {
8921
+ key: s,
8922
+ onClick: () => {
8923
+ handleStatusChange(s);
8924
+ setIsStatusDropdownOpen(false);
8925
+ },
8926
+ className: `px-3 py-2.5 text-sm cursor-pointer transition-colors flex items-center gap-2 ${status === s ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5 hover:text-white"}`
8927
+ },
8928
+ /* @__PURE__ */ import_react18.default.createElement("span", { className: "w-3 h-3 rounded-full", style: { backgroundColor: QUEST_STATUS_COLORS2[s] } }),
8929
+ s
8930
+ )))))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome"), /* @__PURE__ */ import_react18.default.createElement("input", { type: "text", value: name, onChange: handleNameChange, readOnly: !canEdit, className: `w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none ${canEdit ? "focus:ring-2 focus:ring-indigo-400/60" : "cursor-default text-slate-400"}` })), /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Tipos Adicionais"), /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement("span", { key: index, className: `flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-medium border ${t === "quest" ? "bg-sky-500/20 text-sky-200 border-sky-500/30" : "bg-indigo-500/30 text-indigo-100 border-indigo-500/20"}` }, t, canEdit && t !== "quest" && /* @__PURE__ */ import_react18.default.createElement("button", { type: "button", onClick: () => handleRemoveType(index), className: "hover:text-white transition-colors" }, /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiX, { size: 12 })))), canEdit && /* @__PURE__ */ import_react18.default.createElement(
8931
+ "input",
8932
+ {
8933
+ type: "text",
8934
+ value: typeInput,
8935
+ onChange: (e) => {
8936
+ setTypeInput(e.target.value);
8937
+ setShowTypeSuggestions(true);
8938
+ },
8939
+ onKeyDown: handleTypeInputKeyDown,
8940
+ onClick: () => setShowTypeSuggestions(true),
8941
+ onBlur: () => {
8942
+ if (typeInput.trim()) {
8943
+ handleAddType(typeInput);
8944
+ }
8945
+ setTimeout(() => setShowTypeSuggestions(false), 150);
8946
+ },
8947
+ className: "flex-1 bg-transparent text-sm min-w-[80px] focus:outline-none text-slate-200",
8948
+ placeholder: "",
8949
+ autoComplete: "off"
8950
+ }
8951
+ ), canEdit && showTypeSuggestions && filteredTypes.length > 0 && /* @__PURE__ */ import_react18.default.createElement("ul", { className: "custom-scrollbar absolute top-full left-0 z-10 w-full mt-1 max-h-40 overflow-y-auto rounded-lg bg-slate-800 border border-white/10 shadow-lg" }, filteredTypes.map((suggestedType, index) => /* @__PURE__ */ import_react18.default.createElement("li", { key: index, className: "px-3 py-2 text-sm text-slate-200 cursor-pointer hover:bg-indigo-600/50", onMouseDown: (e) => {
8952
+ e.preventDefault();
8953
+ handleAddType(suggestedType);
8954
+ } }, suggestedType))))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react18.default.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ import_react18.default.createElement(DescriptionDisplay, { description, savedSections: existingSections, availableNodes, availableAncestries, onOpenReference, onMentionClick, onImageClick: handleImageClickFromText, onSaveDescription: handleSaveDescriptionInline }), /* @__PURE__ */ import_react18.default.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react18.default.createElement("button", { type: "button", onClick: () => setIsReadMode(true), className: `p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors ${canEdit ? "border-r border-white/5" : ""}`, title: "Modo de Leitura" }, /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiBookOpen, { size: 14 })), canEdit && /* @__PURE__ */ import_react18.default.createElement("button", { type: "button", onClick: () => setIsDescriptionModalOpen(true), className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors", title: "Editar descri\xE7\xE3o (Modo de Escrita)" }, /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiEdit2, { size: 14 }))), canEdit && !description && /* @__PURE__ */ import_react18.default.createElement("div", { onClick: () => setIsDescriptionModalOpen(true), className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text" }, "Adicionar descri\xE7\xE3o..."))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react18.default.createElement("label", { className: "text-xs text-slate-300" }, "Tamanho no Node (Size)"), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-5" }, ["small", "medium", "large"].map((s) => {
8955
+ const isSelected = size === s;
8956
+ return /* @__PURE__ */ import_react18.default.createElement("button", { key: s, type: "button", onClick: () => canEdit && handleSizeChange(s), className: `flex items-center gap-2 group focus:outline-none ${canEdit ? "cursor-pointer" : "cursor-default opacity-80"}` }, /* @__PURE__ */ import_react18.default.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__ */ import_react18.default.createElement(import_fi16.FiCheck, { size: 12, className: "text-white" })), /* @__PURE__ */ import_react18.default.createElement("span", { className: `text-sm capitalize transition-colors ${isSelected ? "text-white font-medium" : "text-slate-400 " + (canEdit ? "group-hover:text-slate-300" : "")}` }, s));
8957
+ }))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react18.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react18.default.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react18.default.createElement(CustomPropertyDisplay, { key: prop.id, prop, onUpdate: canEdit ? (updatedProp) => handleUpdateProp(idx, updatedProp) : void 0, onRemove: canEdit ? () => handleRemoveProp(idx) : void 0, onOpenImageViewer, unavailableTypes: currentUsedTypes.filter((t) => t !== prop.type), isTextureMode: false, onUploadFile: canEdit ? onUploadFile : void 0, readOnly: !canEdit })), /* @__PURE__ */ import_react18.default.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ import_react18.default.createElement("div", { className: "pt-3 mt-4 border-t border-white/10 flex items-center justify-end gap-2 text-xs text-slate-400" }, /* @__PURE__ */ import_react18.default.createElement("span", { className: "truncate text-right" }, /* @__PURE__ */ import_react18.default.createElement("span", { className: "text-slate-200 font-medium" }, currentDatasetName)))), /* @__PURE__ */ import_react18.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react18.default.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => handleSave(false), disabled: isSaving, className: `px-4 py-2 rounded-lg transition-all font-semibold text-sm shadow-[0_8px_24px_rgba(99,102,241,0.35)] flex items-center gap-2 ${isSaving ? "bg-slate-700 text-slate-300 cursor-wait" : "bg-gradient-to-tr from-indigo-600 to-indigo-400 hover:from-indigo-500 hover:to-indigo-300 text-white"}` }, isSaving && /* @__PURE__ */ import_react18.default.createElement(import_fi16.FiLoader, { className: "animate-spin" }), isSaving ? "Salvando..." : "Salvar Quest")))
8958
+ ), isDescriptionModalOpen && canEdit && /* @__PURE__ */ import_react18.default.createElement(
8959
+ DescriptionEditModal,
8960
+ {
8961
+ isOpen: isDescriptionModalOpen,
8962
+ title: "Editar Descri\xE7\xE3o da Quest",
8963
+ initialValue: description,
8964
+ onSave: (newDescription) => {
8965
+ setDescription(newDescription);
8966
+ onDataUpdate((prev) => ({ ...prev, description: newDescription }));
8967
+ triggerAutoSave({ description: newDescription });
8968
+ },
8969
+ onClose: () => setIsDescriptionModalOpen(false),
8970
+ availableNodes,
8971
+ availableAncestries,
8972
+ availableImages
8973
+ }
8974
+ ));
8975
+ }
8976
+
8977
+ // src/components/MultiNodeContextMenu.jsx
8978
+ var import_react19 = __toESM(require("react"));
8659
8979
  function MultiNodeContextMenu({
8660
8980
  data,
8661
8981
  userRole,
@@ -8664,12 +8984,12 @@ function MultiNodeContextMenu({
8664
8984
  onDismissOtherNodes,
8665
8985
  onDeleteNodes
8666
8986
  }) {
8667
- const menuRef = (0, import_react18.useRef)(null);
8668
- const [menuPos, setMenuPos] = (0, import_react18.useState)({ left: 0, top: 0 });
8669
- const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react18.useState)(false);
8987
+ const menuRef = (0, import_react19.useRef)(null);
8988
+ const [menuPos, setMenuPos] = (0, import_react19.useState)({ left: 0, top: 0 });
8989
+ const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react19.useState)(false);
8670
8990
  const ability = defineAbilityFor(userRole);
8671
8991
  const canDelete = ability.can("delete", "Node");
8672
- (0, import_react18.useLayoutEffect)(() => {
8992
+ (0, import_react19.useLayoutEffect)(() => {
8673
8993
  if (!data.visible || !menuRef.current) return;
8674
8994
  const el = menuRef.current;
8675
8995
  const w = el.clientWidth;
@@ -8682,7 +9002,7 @@ function MultiNodeContextMenu({
8682
9002
  if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
8683
9003
  setMenuPos({ left, top });
8684
9004
  }, [data]);
8685
- (0, import_react18.useEffect)(() => {
9005
+ (0, import_react19.useEffect)(() => {
8686
9006
  if (data.visible) {
8687
9007
  setIsConfirmingDelete(false);
8688
9008
  }
@@ -8697,7 +9017,7 @@ function MultiNodeContextMenu({
8697
9017
  const baseButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-indigo-500/20 text-slate-200 hover:text-white transition-colors duration-150 truncate";
8698
9018
  const deleteButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-red-500/25 text-red-400 hover:text-red-300 transition-colors duration-150 truncate";
8699
9019
  const nodeCount = data.nodeIds.size;
8700
- return /* @__PURE__ */ import_react18.default.createElement(
9020
+ return /* @__PURE__ */ import_react19.default.createElement(
8701
9021
  "div",
8702
9022
  {
8703
9023
  ref: menuRef,
@@ -8711,28 +9031,28 @@ function MultiNodeContextMenu({
8711
9031
  onContextMenu: swallow,
8712
9032
  onDoubleClick: swallow
8713
9033
  },
8714
- /* @__PURE__ */ import_react18.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
8715
- /* @__PURE__ */ import_react18.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react18.default.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ import_react18.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react18.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react18.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_react18.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ import_react18.default.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ import_react18.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Esta a\xE7\xE3o \xE9 irrevers\xEDvel. Todas as conex\xF5es associadas a eles ser\xE3o apagadas.")), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react18.default.createElement(
9034
+ /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-indigo-400/0 via-indigo-400/70 to-indigo-400/0" }),
9035
+ /* @__PURE__ */ import_react19.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "w-10 h-10 rounded-full bg-red-500/20 flex items-center justify-center text-red-400 mb-1" }, /* @__PURE__ */ import_react19.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react19.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react19.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_react19.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir ", /* @__PURE__ */ import_react19.default.createElement("strong", null, nodeCount, " Nodes"), "?"), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight" }, "Esta a\xE7\xE3o \xE9 irrevers\xEDvel. Todas as conex\xF5es associadas a eles ser\xE3o apagadas.")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react19.default.createElement(
8716
9036
  "button",
8717
9037
  {
8718
9038
  onClick: () => setIsConfirmingDelete(false),
8719
9039
  className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
8720
9040
  },
8721
9041
  "Cancelar"
8722
- ), /* @__PURE__ */ import_react18.default.createElement(
9042
+ ), /* @__PURE__ */ import_react19.default.createElement(
8723
9043
  "button",
8724
9044
  {
8725
9045
  onClick: () => onDeleteNodes(data.nodeIds),
8726
9046
  className: "flex-1 px-2 py-2 text-xs font-medium bg-red-500 hover:bg-red-600 rounded-md text-white transition-colors"
8727
9047
  },
8728
9048
  "Excluir"
8729
- ))) : /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ import_react18.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react18.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_react18.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_react18.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react18.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ import_react18.default.createElement(import_react18.default.Fragment, null, /* @__PURE__ */ import_react18.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react18.default.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ import_react18.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_react18.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react18.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_react18.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react18.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react18.default.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
9049
+ ))) : /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react19.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_react19.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "A\xE7\xF5es em Grupo (", nodeCount, " Nodes)")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-1" }, /* @__PURE__ */ import_react19.default.createElement("button", { onClick: () => onDismissNodes(data.nodeIds), className: baseButtonClass, title: "Remover da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react19.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_react19.default.createElement("path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24" }), /* @__PURE__ */ import_react19.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_react19.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_react19.default.createElement("line", { x1: "2", y1: "2", x2: "22", y2: "22" })), /* @__PURE__ */ import_react19.default.createElement("span", null, "Dismiss (", nodeCount, ")")), /* @__PURE__ */ import_react19.default.createElement("button", { onClick: () => onDismissOtherNodes(data.nodeIds), className: baseButtonClass, title: "Remover outros da visualiza\xE7\xE3o" }, /* @__PURE__ */ import_react19.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_react19.default.createElement("circle", { cx: "12", cy: "12", r: "3" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }), /* @__PURE__ */ import_react19.default.createElement("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" })), /* @__PURE__ */ import_react19.default.createElement("span", null, "Dismiss other nodes")), canDelete && /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "my-1 h-px w-full bg-white/10" }), /* @__PURE__ */ import_react19.default.createElement("button", { onClick: () => setIsConfirmingDelete(true), className: deleteButtonClass, title: "Excluir Nodes" }, /* @__PURE__ */ import_react19.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_react19.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react19.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_react19.default.createElement("line", { x1: "10", y1: "11", x2: "10", y2: "17" }), /* @__PURE__ */ import_react19.default.createElement("line", { x1: "14", y1: "11", x2: "14", y2: "17" })), /* @__PURE__ */ import_react19.default.createElement("span", null, "Excluir Nodes (", nodeCount, ")"))))))
8730
9050
  );
8731
9051
  }
8732
9052
 
8733
9053
  // src/components/RelationshipDetailsPanel.jsx
8734
- var import_react19 = __toESM(require("react"));
8735
- var import_fi16 = require("react-icons/fi");
9054
+ var import_react20 = __toESM(require("react"));
9055
+ var import_fi17 = require("react-icons/fi");
8736
9056
  function RelationshipDetailsPanel({
8737
9057
  link,
8738
9058
  onClose,
@@ -8746,19 +9066,19 @@ function RelationshipDetailsPanel({
8746
9066
  onUploadFile,
8747
9067
  userRole
8748
9068
  }) {
8749
- const [name, setName] = (0, import_react19.useState)((link == null ? void 0 : link.name) ?? "");
8750
- const [description, setDescription] = (0, import_react19.useState)((link == null ? void 0 : link.description) ?? "");
8751
- const [customProps, setCustomProps] = (0, import_react19.useState)(() => extractCustomPropsFromNode(link || {}));
8752
- const [existingSections, setExistingSections] = (0, import_react19.useState)((link == null ? void 0 : link.description_sections) || []);
8753
- const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react19.useState)(false);
8754
- const [isSaving, setIsSaving] = (0, import_react19.useState)(false);
8755
- const [isReadMode, setIsReadMode] = (0, import_react19.useState)(false);
8756
- const propsEndRef = (0, import_react19.useRef)(null);
8757
- const canEdit = (0, import_react19.useMemo)(() => {
9069
+ const [name, setName] = (0, import_react20.useState)((link == null ? void 0 : link.name) ?? "");
9070
+ const [description, setDescription] = (0, import_react20.useState)((link == null ? void 0 : link.description) ?? "");
9071
+ const [customProps, setCustomProps] = (0, import_react20.useState)(() => extractCustomPropsFromNode(link || {}));
9072
+ const [existingSections, setExistingSections] = (0, import_react20.useState)((link == null ? void 0 : link.description_sections) || []);
9073
+ const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react20.useState)(false);
9074
+ const [isSaving, setIsSaving] = (0, import_react20.useState)(false);
9075
+ const [isReadMode, setIsReadMode] = (0, import_react20.useState)(false);
9076
+ const propsEndRef = (0, import_react20.useRef)(null);
9077
+ const canEdit = (0, import_react20.useMemo)(() => {
8758
9078
  const ability = defineAbilityFor(userRole);
8759
9079
  return ability.can("update", "Connection");
8760
9080
  }, [userRole]);
8761
- (0, import_react19.useEffect)(() => {
9081
+ (0, import_react20.useEffect)(() => {
8762
9082
  setName((link == null ? void 0 : link.name) ?? "");
8763
9083
  setDescription((link == null ? void 0 : link.description) ?? "");
8764
9084
  setExistingSections((link == null ? void 0 : link.description_sections) || []);
@@ -8833,7 +9153,7 @@ function RelationshipDetailsPanel({
8833
9153
  onOpenImageViewer([{ name: name2 || "Imagem", value: url }], 0);
8834
9154
  }
8835
9155
  };
8836
- return /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement(
9156
+ return /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement(
8837
9157
  "div",
8838
9158
  {
8839
9159
  className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden transition-all duration-300 ease-out
@@ -8848,7 +9168,7 @@ function RelationshipDetailsPanel({
8848
9168
  onContextMenu: swallow,
8849
9169
  onDoubleClick: swallow
8850
9170
  },
8851
- isReadMode ? /* @__PURE__ */ import_react19.default.createElement(
9171
+ isReadMode ? /* @__PURE__ */ import_react20.default.createElement(
8852
9172
  DescriptionReadModePanel,
8853
9173
  {
8854
9174
  title: name || "Rela\xE7\xE3o",
@@ -8869,7 +9189,7 @@ function RelationshipDetailsPanel({
8869
9189
  onImageClick: handleImageClickFromText,
8870
9190
  onSaveDescription: handleSaveDescriptionInline
8871
9191
  }
8872
- ) : /* @__PURE__ */ import_react19.default.createElement(import_react19.default.Fragment, null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ import_react19.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react19.default.createElement("div", null, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react19.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-teal-400/80 shadow-[0_0_18px_2px_rgba(45,212,191,0.55)]" }), /* @__PURE__ */ import_react19.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ import_react19.default.createElement("button", { onClick: onClose, 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: "Fechar" }, "\xD7")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react19.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react19.default.createElement(
9192
+ ) : /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }), /* @__PURE__ */ import_react20.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react20.default.createElement("div", null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react20.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-teal-400/80 shadow-[0_0_18px_2px_rgba(45,212,191,0.55)]" }), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Rela\xE7\xE3o")), /* @__PURE__ */ import_react20.default.createElement("h2", { className: "text-xl sm:text-2xl font-semibold tracking-tight" }, name || "Rela\xE7\xE3o")), /* @__PURE__ */ import_react20.default.createElement("button", { onClick: onClose, 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: "Fechar" }, "\xD7")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "px-6 pb-28 overflow-y-auto overscroll-contain space-y-4 max-h-[68vh] custom-scrollbar" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react20.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome da Rela\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react20.default.createElement(
8873
9193
  "input",
8874
9194
  {
8875
9195
  type: "text",
@@ -8881,7 +9201,7 @@ function RelationshipDetailsPanel({
8881
9201
  ${!canEdit ? "opacity-50 cursor-not-allowed" : ""}
8882
9202
  `
8883
9203
  }
8884
- )), /* @__PURE__ */ import_react19.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react19.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react19.default.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ import_react19.default.createElement(
9204
+ )), /* @__PURE__ */ import_react20.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react20.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react20.default.createElement("div", { className: "relative group min-h-[60px] bg-slate-800/40 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ import_react20.default.createElement(
8885
9205
  DescriptionDisplay,
8886
9206
  {
8887
9207
  description,
@@ -8893,7 +9213,7 @@ function RelationshipDetailsPanel({
8893
9213
  onImageClick: handleImageClickFromText,
8894
9214
  onSaveDescription: handleSaveDescriptionInline
8895
9215
  }
8896
- ), /* @__PURE__ */ import_react19.default.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react19.default.createElement(
9216
+ ), /* @__PURE__ */ import_react20.default.createElement("div", { className: "absolute top-0 right-0 flex bg-slate-900/50 rounded-bl-lg backdrop-blur-sm opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity overflow-hidden border-b border-l border-white/5" }, /* @__PURE__ */ import_react20.default.createElement(
8897
9217
  "button",
8898
9218
  {
8899
9219
  type: "button",
@@ -8901,8 +9221,8 @@ function RelationshipDetailsPanel({
8901
9221
  className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors border-r border-white/5",
8902
9222
  title: "Modo de Leitura"
8903
9223
  },
8904
- /* @__PURE__ */ import_react19.default.createElement(import_fi16.FiBookOpen, { size: 14 })
8905
- ), canEdit && /* @__PURE__ */ import_react19.default.createElement(
9224
+ /* @__PURE__ */ import_react20.default.createElement(import_fi17.FiBookOpen, { size: 14 })
9225
+ ), canEdit && /* @__PURE__ */ import_react20.default.createElement(
8906
9226
  "button",
8907
9227
  {
8908
9228
  type: "button",
@@ -8910,15 +9230,15 @@ function RelationshipDetailsPanel({
8910
9230
  className: "p-2 text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
8911
9231
  title: "Editar descri\xE7\xE3o"
8912
9232
  },
8913
- /* @__PURE__ */ import_react19.default.createElement(import_fi16.FiEdit2, { size: 14 })
8914
- )), !description && canEdit && /* @__PURE__ */ import_react19.default.createElement(
9233
+ /* @__PURE__ */ import_react20.default.createElement(import_fi17.FiEdit2, { size: 14 })
9234
+ )), !description && canEdit && /* @__PURE__ */ import_react20.default.createElement(
8915
9235
  "div",
8916
9236
  {
8917
9237
  onClick: () => setIsDescriptionModalOpen(true),
8918
9238
  className: "absolute inset-0 flex items-center justify-center text-xs text-slate-500 cursor-text"
8919
9239
  },
8920
9240
  "Adicionar descri\xE7\xE3o..."
8921
- ))), /* @__PURE__ */ import_react19.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react19.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react19.default.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ import_react19.default.createElement(import_fi16.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react19.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react19.default.createElement(
9241
+ ))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /* @__PURE__ */ import_react20.default.createElement("h3", { className: "text-sm font-medium" }, "Propriedades Adicionais"), canEdit && /* @__PURE__ */ import_react20.default.createElement("button", { type: "button", onClick: handleAddProp, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-md bg-slate-800/70 hover:bg-slate-700/70 border border-white/10 transition-colors" }, /* @__PURE__ */ import_react20.default.createElement(import_fi17.FiPlus, { size: 14 }), " Adicionar")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop, idx) => /* @__PURE__ */ import_react20.default.createElement(
8922
9242
  CustomPropertyDisplay,
8923
9243
  {
8924
9244
  key: prop.id,
@@ -8930,7 +9250,7 @@ function RelationshipDetailsPanel({
8930
9250
  onUploadFile,
8931
9251
  disabled: !canEdit
8932
9252
  }
8933
- )), /* @__PURE__ */ import_react19.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react19.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react19.default.createElement("button", { onClick: onClose, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react19.default.createElement(
9253
+ )), /* @__PURE__ */ import_react20.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react20.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react20.default.createElement("button", { onClick: onClose, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react20.default.createElement(
8934
9254
  "button",
8935
9255
  {
8936
9256
  onClick: () => handleSave(false),
@@ -8939,10 +9259,10 @@ function RelationshipDetailsPanel({
8939
9259
  ${isSaving ? "bg-slate-700 text-slate-300 cursor-wait" : "bg-gradient-to-tr from-teal-600 to-teal-400 hover:from-teal-500 hover:to-teal-300 text-white"}
8940
9260
  `
8941
9261
  },
8942
- isSaving && /* @__PURE__ */ import_react19.default.createElement(import_fi16.FiLoader, { className: "animate-spin" }),
9262
+ isSaving && /* @__PURE__ */ import_react20.default.createElement(import_fi17.FiLoader, { className: "animate-spin" }),
8943
9263
  isSaving ? "Salvando..." : "Salvar"
8944
9264
  )))
8945
- ), isDescriptionModalOpen && /* @__PURE__ */ import_react19.default.createElement(
9265
+ ), isDescriptionModalOpen && /* @__PURE__ */ import_react20.default.createElement(
8946
9266
  DescriptionEditModal,
8947
9267
  {
8948
9268
  isOpen: isDescriptionModalOpen,
@@ -8963,7 +9283,7 @@ function RelationshipDetailsPanel({
8963
9283
  }
8964
9284
 
8965
9285
  // src/components/RelationshipContextMenu.jsx
8966
- var import_react20 = __toESM(require("react"));
9286
+ var import_react21 = __toESM(require("react"));
8967
9287
  function RelationshipContextMenu({
8968
9288
  data,
8969
9289
  userRole,
@@ -8973,25 +9293,25 @@ function RelationshipContextMenu({
8973
9293
  onDelete,
8974
9294
  onClose
8975
9295
  }) {
8976
- const menuRef = (0, import_react20.useRef)(null);
8977
- const [menuPos, setMenuPos] = (0, import_react20.useState)({ left: 0, top: 0 });
8978
- const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react20.useState)(false);
8979
- const ability = (0, import_react20.useMemo)(() => defineAbilityFor(userRole), [userRole]);
8980
- const sourceName = (0, import_react20.useMemo)(
9296
+ const menuRef = (0, import_react21.useRef)(null);
9297
+ const [menuPos, setMenuPos] = (0, import_react21.useState)({ left: 0, top: 0 });
9298
+ const [isConfirmingDelete, setIsConfirmingDelete] = (0, import_react21.useState)(false);
9299
+ const ability = (0, import_react21.useMemo)(() => defineAbilityFor(userRole), [userRole]);
9300
+ const sourceName = (0, import_react21.useMemo)(
8981
9301
  () => {
8982
9302
  var _a, _b, _c, _d;
8983
9303
  return ((_d = (_c = (_b = (_a = data == null ? void 0 : data.linkObject) == null ? void 0 : _a.userData) == null ? void 0 : _b.sourceNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) ?? "(sem nome)";
8984
9304
  },
8985
9305
  [data == null ? void 0 : data.linkObject]
8986
9306
  );
8987
- const targetName = (0, import_react20.useMemo)(
9307
+ const targetName = (0, import_react21.useMemo)(
8988
9308
  () => {
8989
9309
  var _a, _b, _c, _d;
8990
9310
  return ((_d = (_c = (_b = (_a = data == null ? void 0 : data.linkObject) == null ? void 0 : _a.userData) == null ? void 0 : _b.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) ?? "(sem nome)";
8991
9311
  },
8992
9312
  [data == null ? void 0 : data.linkObject]
8993
9313
  );
8994
- (0, import_react20.useLayoutEffect)(() => {
9314
+ (0, import_react21.useLayoutEffect)(() => {
8995
9315
  if (!data.visible || !menuRef.current) return;
8996
9316
  const el = menuRef.current;
8997
9317
  const w = el.clientWidth;
@@ -9004,7 +9324,7 @@ function RelationshipContextMenu({
9004
9324
  if (top + h + 8 > vh) top = Math.max(8, vh - h - 8);
9005
9325
  setMenuPos({ left, top });
9006
9326
  }, [data]);
9007
- (0, import_react20.useEffect)(() => {
9327
+ (0, import_react21.useEffect)(() => {
9008
9328
  if (data.visible) {
9009
9329
  setIsConfirmingDelete(false);
9010
9330
  }
@@ -9020,7 +9340,7 @@ function RelationshipContextMenu({
9020
9340
  const dangerButtonClass = "w-full flex items-center gap-2.5 px-2 py-1.5 text-left text-sm rounded-md hover:bg-rose-500/20 text-rose-300 hover:text-rose-100 transition-colors duration-150 truncate";
9021
9341
  const canUpdate = ability.can("update", "Connection");
9022
9342
  const canDelete = ability.can("delete", "Connection");
9023
- return /* @__PURE__ */ import_react20.default.createElement(
9343
+ return /* @__PURE__ */ import_react21.default.createElement(
9024
9344
  "div",
9025
9345
  {
9026
9346
  ref: menuRef,
@@ -9034,29 +9354,29 @@ function RelationshipContextMenu({
9034
9354
  onContextMenu: swallow,
9035
9355
  onDoubleClick: swallow
9036
9356
  },
9037
- /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
9038
- /* @__PURE__ */ import_react20.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react20.default.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ import_react20.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react20.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ import_react20.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ import_react20.default.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ import_react20.default.createElement("strong", null, targetName), ".")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react20.default.createElement(
9357
+ /* @__PURE__ */ import_react21.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-teal-400/0 via-teal-400/70 to-teal-400/0" }),
9358
+ /* @__PURE__ */ import_react21.default.createElement("div", { className: "p-1.5" }, isConfirmingDelete ? /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex flex-col gap-3 p-2" }, /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex flex-col items-center text-center gap-2" }, /* @__PURE__ */ import_react21.default.createElement("div", { className: "w-10 h-10 rounded-full bg-rose-500/20 flex items-center justify-center text-rose-400 mb-1" }, /* @__PURE__ */ import_react21.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react21.default.createElement("polyline", { points: "3 6 5 6 21 6" }), /* @__PURE__ */ import_react21.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }), /* @__PURE__ */ import_react21.default.createElement("path", { d: "M10 11v6" }), /* @__PURE__ */ import_react21.default.createElement("path", { d: "M14 11v6" }), /* @__PURE__ */ import_react21.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" }))), /* @__PURE__ */ import_react21.default.createElement("p", { className: "text-sm text-slate-200" }, "Excluir rela\xE7\xE3o?"), /* @__PURE__ */ import_react21.default.createElement("p", { className: "text-[11px] text-slate-400 leading-tight break-words" }, "Desconectar ", /* @__PURE__ */ import_react21.default.createElement("strong", null, sourceName), " de ", /* @__PURE__ */ import_react21.default.createElement("strong", null, targetName), ".")), /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex gap-2 mt-1" }, /* @__PURE__ */ import_react21.default.createElement(
9039
9359
  "button",
9040
9360
  {
9041
9361
  onClick: () => setIsConfirmingDelete(false),
9042
9362
  className: "flex-1 px-2 py-2 text-xs font-medium bg-white/10 hover:bg-white/20 rounded-md text-white transition-colors"
9043
9363
  },
9044
9364
  "Cancelar"
9045
- ), /* @__PURE__ */ import_react20.default.createElement(
9365
+ ), /* @__PURE__ */ import_react21.default.createElement(
9046
9366
  "button",
9047
9367
  {
9048
9368
  onClick: () => onDelete == null ? void 0 : onDelete(data.linkObject),
9049
9369
  className: "flex-1 px-2 py-2 text-xs font-medium bg-rose-600 hover:bg-rose-500 rounded-md text-white transition-colors"
9050
9370
  },
9051
9371
  "Excluir"
9052
- ))) : /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react20.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ import_react20.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ import_react20.default.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement(
9372
+ ))) : /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex items-center gap-2 px-2 pt-1 pb-2" }, /* @__PURE__ */ import_react21.default.createElement("span", { className: "inline-flex h-2 w-2 rounded-full bg-teal-400/80 shadow-[0_0_12px_1px_rgba(45,212,191,0.5)]" }), /* @__PURE__ */ import_react21.default.createElement("p", { className: "text-[11px] uppercase tracking-wider text-slate-400" }, "Rela\xE7\xE3o")), /* @__PURE__ */ import_react21.default.createElement("div", { className: "flex flex-col gap-1" }, canUpdate && /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement(
9053
9373
  "button",
9054
9374
  {
9055
9375
  onClick: () => onRelinkSource == null ? void 0 : onRelinkSource(data.linkObject),
9056
9376
  className: baseButtonClass,
9057
9377
  title: "Desconectar ponta ligada ao Source"
9058
9378
  },
9059
- /* @__PURE__ */ import_react20.default.createElement(
9379
+ /* @__PURE__ */ import_react21.default.createElement(
9060
9380
  "svg",
9061
9381
  {
9062
9382
  xmlns: "http://www.w3.org/2000/svg",
@@ -9069,18 +9389,18 @@ function RelationshipContextMenu({
9069
9389
  strokeLinecap: "round",
9070
9390
  strokeLinejoin: "round"
9071
9391
  },
9072
- /* @__PURE__ */ import_react20.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" }),
9073
- /* @__PURE__ */ import_react20.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" })
9392
+ /* @__PURE__ */ import_react21.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" }),
9393
+ /* @__PURE__ */ import_react21.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" })
9074
9394
  ),
9075
- /* @__PURE__ */ import_react20.default.createElement("span", null, "Desconectar Source (", sourceName, ")")
9076
- ), /* @__PURE__ */ import_react20.default.createElement(
9395
+ /* @__PURE__ */ import_react21.default.createElement("span", null, "Desconectar Source (", sourceName, ")")
9396
+ ), /* @__PURE__ */ import_react21.default.createElement(
9077
9397
  "button",
9078
9398
  {
9079
9399
  onClick: () => onRelinkTarget == null ? void 0 : onRelinkTarget(data.linkObject),
9080
9400
  className: baseButtonClass,
9081
9401
  title: "Desconectar ponta ligada ao Target"
9082
9402
  },
9083
- /* @__PURE__ */ import_react20.default.createElement(
9403
+ /* @__PURE__ */ import_react21.default.createElement(
9084
9404
  "svg",
9085
9405
  {
9086
9406
  xmlns: "http://www.w3.org/2000/svg",
@@ -9093,21 +9413,21 @@ function RelationshipContextMenu({
9093
9413
  strokeLinecap: "round",
9094
9414
  strokeLinejoin: "round"
9095
9415
  },
9096
- /* @__PURE__ */ import_react20.default.createElement("polyline", { points: "16 3 21 3 21 8" }),
9097
- /* @__PURE__ */ import_react20.default.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
9098
- /* @__PURE__ */ import_react20.default.createElement("polyline", { points: "21 16 21 21 16 21" }),
9099
- /* @__PURE__ */ import_react20.default.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
9100
- /* @__PURE__ */ import_react20.default.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
9416
+ /* @__PURE__ */ import_react21.default.createElement("polyline", { points: "16 3 21 3 21 8" }),
9417
+ /* @__PURE__ */ import_react21.default.createElement("line", { x1: "4", y1: "20", x2: "21", y2: "3" }),
9418
+ /* @__PURE__ */ import_react21.default.createElement("polyline", { points: "21 16 21 21 16 21" }),
9419
+ /* @__PURE__ */ import_react21.default.createElement("line", { x1: "15", y1: "15", x2: "21", y2: "21" }),
9420
+ /* @__PURE__ */ import_react21.default.createElement("line", { x1: "4", y1: "4", x2: "9", y2: "9" })
9101
9421
  ),
9102
- /* @__PURE__ */ import_react20.default.createElement("span", null, "Desconectar Target (", targetName, ")")
9103
- ), /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ import_react20.default.createElement(
9422
+ /* @__PURE__ */ import_react21.default.createElement("span", null, "Desconectar Target (", targetName, ")")
9423
+ ), /* @__PURE__ */ import_react21.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" })), /* @__PURE__ */ import_react21.default.createElement(
9104
9424
  "button",
9105
9425
  {
9106
9426
  onClick: () => onOpenDetails == null ? void 0 : onOpenDetails(data.linkObject),
9107
9427
  className: baseButtonClass,
9108
9428
  title: "Abrir detalhes da rela\xE7\xE3o"
9109
9429
  },
9110
- /* @__PURE__ */ import_react20.default.createElement(
9430
+ /* @__PURE__ */ import_react21.default.createElement(
9111
9431
  "svg",
9112
9432
  {
9113
9433
  xmlns: "http://www.w3.org/2000/svg",
@@ -9120,19 +9440,19 @@ function RelationshipContextMenu({
9120
9440
  strokeLinecap: "round",
9121
9441
  strokeLinejoin: "round"
9122
9442
  },
9123
- /* @__PURE__ */ import_react20.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
9124
- /* @__PURE__ */ import_react20.default.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
9125
- /* @__PURE__ */ import_react20.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
9443
+ /* @__PURE__ */ import_react21.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
9444
+ /* @__PURE__ */ import_react21.default.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
9445
+ /* @__PURE__ */ import_react21.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "8" })
9126
9446
  ),
9127
- /* @__PURE__ */ import_react20.default.createElement("span", null, "Abrir Detalhes")
9128
- ), canDelete && /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ import_react20.default.createElement(
9447
+ /* @__PURE__ */ import_react21.default.createElement("span", null, "Abrir Detalhes")
9448
+ ), canDelete && /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("div", { className: "h-[1px] my-1 mx-1 bg-white/10" }), /* @__PURE__ */ import_react21.default.createElement(
9129
9449
  "button",
9130
9450
  {
9131
9451
  onClick: () => setIsConfirmingDelete(true),
9132
9452
  className: dangerButtonClass,
9133
9453
  title: "Excluir esta conex\xE3o"
9134
9454
  },
9135
- /* @__PURE__ */ import_react20.default.createElement(
9455
+ /* @__PURE__ */ import_react21.default.createElement(
9136
9456
  "svg",
9137
9457
  {
9138
9458
  xmlns: "http://www.w3.org/2000/svg",
@@ -9145,19 +9465,19 @@ function RelationshipContextMenu({
9145
9465
  strokeLinecap: "round",
9146
9466
  strokeLinejoin: "round"
9147
9467
  },
9148
- /* @__PURE__ */ import_react20.default.createElement("polyline", { points: "3 6 5 6 21 6" }),
9149
- /* @__PURE__ */ import_react20.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
9150
- /* @__PURE__ */ import_react20.default.createElement("path", { d: "M10 11v6" }),
9151
- /* @__PURE__ */ import_react20.default.createElement("path", { d: "M14 11v6" }),
9152
- /* @__PURE__ */ import_react20.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
9468
+ /* @__PURE__ */ import_react21.default.createElement("polyline", { points: "3 6 5 6 21 6" }),
9469
+ /* @__PURE__ */ import_react21.default.createElement("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
9470
+ /* @__PURE__ */ import_react21.default.createElement("path", { d: "M10 11v6" }),
9471
+ /* @__PURE__ */ import_react21.default.createElement("path", { d: "M14 11v6" }),
9472
+ /* @__PURE__ */ import_react21.default.createElement("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
9153
9473
  ),
9154
- /* @__PURE__ */ import_react20.default.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
9474
+ /* @__PURE__ */ import_react21.default.createElement("span", null, "Excluir conex\xE3o (", sourceName, " \u2192 ", targetName, ")")
9155
9475
  )))))
9156
9476
  );
9157
9477
  }
9158
9478
 
9159
9479
  // src/components/LoadingScreen.jsx
9160
- var import_react21 = __toESM(require("react"));
9480
+ var import_react22 = __toESM(require("react"));
9161
9481
  var styles = {
9162
9482
  loadingOverlay: {
9163
9483
  position: "fixed",
@@ -9189,11 +9509,11 @@ var styles = {
9189
9509
  `
9190
9510
  };
9191
9511
  function LoadingScreen() {
9192
- return /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("style", null, styles.keyframes), /* @__PURE__ */ import_react21.default.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ import_react21.default.createElement("div", { style: styles.spinner })));
9512
+ return /* @__PURE__ */ import_react22.default.createElement(import_react22.default.Fragment, null, /* @__PURE__ */ import_react22.default.createElement("style", null, styles.keyframes), /* @__PURE__ */ import_react22.default.createElement("div", { style: styles.loadingOverlay }, /* @__PURE__ */ import_react22.default.createElement("div", { style: styles.spinner })));
9193
9513
  }
9194
9514
 
9195
9515
  // src/components/ImportParentFileModal.jsx
9196
- var import_react22 = __toESM(require("react"));
9516
+ var import_react23 = __toESM(require("react"));
9197
9517
  function ImportParentFileModal({
9198
9518
  isOpen,
9199
9519
  onClose,
@@ -9204,12 +9524,12 @@ function ImportParentFileModal({
9204
9524
  onFetchAvailableFiles,
9205
9525
  currentViewName
9206
9526
  }) {
9207
- const [activeTab, setActiveTab] = (0, import_react22.useState)("databases");
9208
- const [availableDbs, setAvailableDbs] = (0, import_react22.useState)([]);
9209
- const [availableViews, setAvailableViews] = (0, import_react22.useState)([]);
9210
- const [selectedItem, setSelectedItem] = (0, import_react22.useState)(null);
9211
- const [isLoading, setIsLoading] = (0, import_react22.useState)(false);
9212
- (0, import_react22.useEffect)(() => {
9527
+ const [activeTab, setActiveTab] = (0, import_react23.useState)("databases");
9528
+ const [availableDbs, setAvailableDbs] = (0, import_react23.useState)([]);
9529
+ const [availableViews, setAvailableViews] = (0, import_react23.useState)([]);
9530
+ const [selectedItem, setSelectedItem] = (0, import_react23.useState)(null);
9531
+ const [isLoading, setIsLoading] = (0, import_react23.useState)(false);
9532
+ (0, import_react23.useEffect)(() => {
9213
9533
  if (isOpen && session && onFetchAvailableFiles) {
9214
9534
  const fetchData = async () => {
9215
9535
  setIsLoading(true);
@@ -9245,7 +9565,7 @@ function ImportParentFileModal({
9245
9565
  fetchData();
9246
9566
  }
9247
9567
  }, [isOpen, session, parentDbs, onFetchAvailableFiles, currentViewName]);
9248
- (0, import_react22.useEffect)(() => {
9568
+ (0, import_react23.useEffect)(() => {
9249
9569
  setSelectedItem(null);
9250
9570
  }, [activeTab]);
9251
9571
  if (!isOpen) {
@@ -9274,13 +9594,13 @@ function ImportParentFileModal({
9274
9594
  const swallow = (e) => e.stopPropagation();
9275
9595
  const currentList = activeTab === "databases" ? availableDbs : availableViews;
9276
9596
  const emptyMessage = activeTab === "databases" ? "Nenhum novo arquivo parent dispon\xEDvel." : "Nenhuma view dispon\xEDvel para importa\xE7\xE3o.";
9277
- return /* @__PURE__ */ import_react22.default.createElement(
9597
+ return /* @__PURE__ */ import_react23.default.createElement(
9278
9598
  "div",
9279
9599
  {
9280
9600
  className: "ui-overlay fixed inset-0 z-[1200] flex items-center justify-center bg-black/60 backdrop-blur-sm",
9281
9601
  onClick: onClose
9282
9602
  },
9283
- /* @__PURE__ */ import_react22.default.createElement(
9603
+ /* @__PURE__ */ import_react23.default.createElement(
9284
9604
  "div",
9285
9605
  {
9286
9606
  className: "ui-overlay relative rounded-2xl border border-white/10 bg-slate-950/80 shadow-[0_20px_80px_rgba(0,0,0,0.6)] text-white w-[min(92vw,500px)] flex flex-col max-h-[85vh]",
@@ -9292,14 +9612,14 @@ function ImportParentFileModal({
9292
9612
  onContextMenu: swallow,
9293
9613
  onDoubleClick: swallow
9294
9614
  },
9295
- /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ import_react22.default.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ import_react22.default.createElement(
9615
+ /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/10 flex-shrink-0" }, /* @__PURE__ */ import_react23.default.createElement("h2", { className: "text-lg font-semibold" }, "Importar"), /* @__PURE__ */ import_react23.default.createElement(
9296
9616
  "button",
9297
9617
  {
9298
9618
  onClick: onClose,
9299
9619
  className: "p-2 rounded-md text-slate-400 hover:text-white hover:bg-white/10 transition-colors",
9300
9620
  title: "Fechar"
9301
9621
  },
9302
- /* @__PURE__ */ import_react22.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react22.default.createElement(
9622
+ /* @__PURE__ */ import_react23.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react23.default.createElement(
9303
9623
  "path",
9304
9624
  {
9305
9625
  fillRule: "evenodd",
@@ -9308,14 +9628,14 @@ function ImportParentFileModal({
9308
9628
  }
9309
9629
  ))
9310
9630
  )),
9311
- /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ import_react22.default.createElement(
9631
+ /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex px-6 border-b border-white/10 bg-white/5 flex-shrink-0" }, /* @__PURE__ */ import_react23.default.createElement(
9312
9632
  "button",
9313
9633
  {
9314
9634
  onClick: () => setActiveTab("databases"),
9315
9635
  className: `flex-1 py-3 text-sm font-medium border-b-2 transition-colors ${activeTab === "databases" ? "border-indigo-500 text-white" : "border-transparent text-slate-400 hover:text-slate-200"}`
9316
9636
  },
9317
9637
  "Arquivos Parent"
9318
- ), /* @__PURE__ */ import_react22.default.createElement(
9638
+ ), /* @__PURE__ */ import_react23.default.createElement(
9319
9639
  "button",
9320
9640
  {
9321
9641
  onClick: () => setActiveTab("views"),
@@ -9323,24 +9643,24 @@ function ImportParentFileModal({
9323
9643
  },
9324
9644
  "Views (Ancestralidades)"
9325
9645
  )),
9326
- /* @__PURE__ */ import_react22.default.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ import_react22.default.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ import_react22.default.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ import_react22.default.createElement(
9646
+ /* @__PURE__ */ import_react23.default.createElement("div", { className: "p-6 overflow-y-auto custom-scrollbar flex-grow min-h-[200px]" }, isLoading ? /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-center h-40" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "w-8 h-8 border-4 border-t-indigo-500 border-slate-700 rounded-full animate-spin" })) : /* @__PURE__ */ import_react23.default.createElement("div", { className: "space-y-2" }, currentList.length > 0 ? currentList.map((item) => /* @__PURE__ */ import_react23.default.createElement(
9327
9647
  "div",
9328
9648
  {
9329
9649
  key: item.id,
9330
9650
  onClick: () => setSelectedItem(item),
9331
9651
  className: `px-4 py-3 rounded-lg border cursor-pointer transition-all duration-150 flex flex-col gap-1 ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "bg-indigo-600 border-indigo-500 shadow-lg" : "bg-slate-800/60 border-white/10 hover:border-white/20 hover:bg-slate-800"}`
9332
9652
  },
9333
- /* @__PURE__ */ import_react22.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react22.default.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ import_react22.default.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
9334
- item.description && /* @__PURE__ */ import_react22.default.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
9335
- )) : /* @__PURE__ */ import_react22.default.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
9336
- /* @__PURE__ */ import_react22.default.createElement("div", { className: "px-6 py-4 border-t border-white/10 flex justify-end gap-3 flex-shrink-0 bg-slate-900/50" }, /* @__PURE__ */ import_react22.default.createElement(
9653
+ /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react23.default.createElement("span", { className: "font-medium text-slate-100" }, item.name), activeTab === "views" && /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-[10px] px-1.5 py-0.5 rounded bg-black/30 text-indigo-300 border border-indigo-500/30" }, "VIEW")),
9654
+ item.description && /* @__PURE__ */ import_react23.default.createElement("p", { className: `text-xs ${(selectedItem == null ? void 0 : selectedItem.id) === item.id ? "text-indigo-200" : "text-slate-400"}` }, item.description)
9655
+ )) : /* @__PURE__ */ import_react23.default.createElement("p", { className: "text-slate-400 text-center py-10" }, emptyMessage))),
9656
+ /* @__PURE__ */ import_react23.default.createElement("div", { className: "px-6 py-4 border-t border-white/10 flex justify-end gap-3 flex-shrink-0 bg-slate-900/50" }, /* @__PURE__ */ import_react23.default.createElement(
9337
9657
  "button",
9338
9658
  {
9339
9659
  onClick: onClose,
9340
9660
  className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm text-slate-300"
9341
9661
  },
9342
9662
  "Cancelar"
9343
- ), /* @__PURE__ */ import_react22.default.createElement(
9663
+ ), /* @__PURE__ */ import_react23.default.createElement(
9344
9664
  "button",
9345
9665
  {
9346
9666
  onClick: handleConfirm,
@@ -9354,8 +9674,8 @@ function ImportParentFileModal({
9354
9674
  }
9355
9675
 
9356
9676
  // src/components/AncestryLinkDetailsPanel.jsx
9357
- var import_react23 = __toESM(require("react"));
9358
- var import_fi17 = require("react-icons/fi");
9677
+ var import_react24 = __toESM(require("react"));
9678
+ var import_fi18 = require("react-icons/fi");
9359
9679
  function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenReference, onMentionClick, onUploadFile }) {
9360
9680
  var _a, _b, _c, _d;
9361
9681
  const relationshipData = data.relationship || {};
@@ -9364,21 +9684,21 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9364
9684
  const customProps = extractCustomPropsFromNode(relationshipData);
9365
9685
  const sourceName = ((_b = (_a = data.sourceNode) == null ? void 0 : _a.userData) == null ? void 0 : _b.name) || "Origem";
9366
9686
  const targetName = ((_d = (_c = data.targetNode) == null ? void 0 : _c.userData) == null ? void 0 : _d.name) || "Destino";
9367
- const [isReadMode, setIsReadMode] = (0, import_react23.useState)(false);
9687
+ const [isReadMode, setIsReadMode] = (0, import_react24.useState)(false);
9368
9688
  const swallow = (e) => e.stopPropagation();
9369
9689
  const handleImageClickFromText = (url, name) => {
9370
9690
  if (onOpenImageViewer) {
9371
9691
  onOpenImageViewer([{ name: name || "Imagem", value: url }], 0);
9372
9692
  }
9373
9693
  };
9374
- return /* @__PURE__ */ import_react23.default.createElement(
9694
+ return /* @__PURE__ */ import_react24.default.createElement(
9375
9695
  "div",
9376
9696
  {
9377
9697
  className: "ui-overlay fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-[1200]",
9378
9698
  onClick: onClose,
9379
9699
  onPointerDown: swallow
9380
9700
  },
9381
- /* @__PURE__ */ import_react23.default.createElement(
9701
+ /* @__PURE__ */ import_react24.default.createElement(
9382
9702
  "div",
9383
9703
  {
9384
9704
  className: `relative group rounded-2xl border border-white/10 bg-slate-950/80 shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col max-h-[calc(100vh-4rem)] transition-all duration-300 ease-out
@@ -9386,7 +9706,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9386
9706
  `,
9387
9707
  onClick: swallow
9388
9708
  },
9389
- isReadMode ? /* @__PURE__ */ import_react23.default.createElement(
9709
+ isReadMode ? /* @__PURE__ */ import_react24.default.createElement(
9390
9710
  DescriptionReadModePanel,
9391
9711
  {
9392
9712
  title: `${sourceName} \u2794 ${targetName}`,
@@ -9398,15 +9718,15 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9398
9718
  onMentionClick,
9399
9719
  onImageClick: handleImageClickFromText
9400
9720
  }
9401
- ) : /* @__PURE__ */ import_react23.default.createElement(import_react23.default.Fragment, null, /* @__PURE__ */ import_react23.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ import_react23.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react23.default.createElement("div", null, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react23.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-blue-500/80 shadow-[0_0_18px_2px_rgba(59,130,246,0.55)]" }), /* @__PURE__ */ import_react23.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ import_react23.default.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ import_react23.default.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ import_react23.default.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ import_react23.default.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ import_react23.default.createElement("button", { onClick: onClose, 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", title: "Fechar" }, "\xD7")), /* @__PURE__ */ import_react23.default.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ import_react23.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react23.default.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react23.default.createElement(
9721
+ ) : /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("div", { className: "h-[2px] bg-gradient-to-r from-blue-500/0 via-blue-500/70 to-blue-500/0" }), /* @__PURE__ */ import_react24.default.createElement("div", { className: "px-6 pt-5 pb-3 flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react24.default.createElement("div", null, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-2 mb-1" }, /* @__PURE__ */ import_react24.default.createElement("span", { className: "inline-flex h-2.5 w-2.5 rounded-full bg-blue-500/80 shadow-[0_0_18px_2px_rgba(59,130,246,0.55)]" }), /* @__PURE__ */ import_react24.default.createElement("p", { className: "text-xs/relaxed text-slate-300" }, "Detalhes da Ancestralidade")), /* @__PURE__ */ import_react24.default.createElement("h2", { className: "text-lg font-semibold tracking-tight flex items-center gap-2" }, /* @__PURE__ */ import_react24.default.createElement("span", { className: "truncate max-w-[150px]" }, sourceName), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-slate-500 text-sm" }, "\u2794"), /* @__PURE__ */ import_react24.default.createElement("span", { className: "truncate max-w-[150px]" }, targetName))), /* @__PURE__ */ import_react24.default.createElement("button", { onClick: onClose, 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", title: "Fechar" }, "\xD7")), /* @__PURE__ */ import_react24.default.createElement("div", { className: "px-6 pb-6 overflow-y-auto overscroll-contain space-y-4 custom-scrollbar" }, description && /* @__PURE__ */ import_react24.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react24.default.createElement("label", { className: "text-xs text-slate-300 font-medium" }, "Descri\xE7\xE3o"), /* @__PURE__ */ import_react24.default.createElement(
9402
9722
  "button",
9403
9723
  {
9404
9724
  onClick: () => setIsReadMode(true),
9405
9725
  className: "p-1 text-slate-400 hover:text-white transition-colors",
9406
9726
  title: "Modo de Leitura"
9407
9727
  },
9408
- /* @__PURE__ */ import_react23.default.createElement(import_fi17.FiBookOpen, { size: 14 })
9409
- )), /* @__PURE__ */ import_react23.default.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ import_react23.default.createElement(
9728
+ /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiBookOpen, { size: 14 })
9729
+ )), /* @__PURE__ */ import_react24.default.createElement("div", { className: "bg-slate-800/40 rounded-lg border border-white/10 p-1 relative group" }, /* @__PURE__ */ import_react24.default.createElement(
9410
9730
  DescriptionDisplay,
9411
9731
  {
9412
9732
  description,
@@ -9415,7 +9735,7 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9415
9735
  onMentionClick,
9416
9736
  onImageClick: handleImageClickFromText
9417
9737
  }
9418
- ))), customProps.length > 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react23.default.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ import_react23.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ import_react23.default.createElement(
9738
+ ))), customProps.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "pt-2" }, /* @__PURE__ */ import_react24.default.createElement("label", { className: "text-xs text-slate-300 font-medium mb-2 block" }, "Propriedades"), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col gap-3" }, customProps.map((prop) => /* @__PURE__ */ import_react24.default.createElement(
9419
9739
  CustomPropertyDisplay,
9420
9740
  {
9421
9741
  key: prop.id,
@@ -9424,14 +9744,14 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
9424
9744
  onOpenImageViewer,
9425
9745
  onUploadFile
9426
9746
  }
9427
- )))), !description && customProps.length === 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "py-8 text-center text-slate-500 text-sm italic border border-dashed border-white/10 rounded-lg" }, "Nenhum detalhe adicional dispon\xEDvel para esta conex\xE3o."), /* @__PURE__ */ import_react23.default.createElement("div", { className: "mt-4 p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg text-xs text-blue-200/80 text-center" }, 'Para editar esta conex\xE3o, utilize o menu "Editar Ancestralidade".')))
9747
+ )))), !description && customProps.length === 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "py-8 text-center text-slate-500 text-sm italic border border-dashed border-white/10 rounded-lg" }, "Nenhum detalhe adicional dispon\xEDvel para esta conex\xE3o."), /* @__PURE__ */ import_react24.default.createElement("div", { className: "mt-4 p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg text-xs text-blue-200/80 text-center" }, 'Para editar esta conex\xE3o, utilize o menu "Editar Ancestralidade".')))
9428
9748
  )
9429
9749
  );
9430
9750
  }
9431
9751
 
9432
9752
  // src/components/AncestryBoard.jsx
9433
- var import_react24 = __toESM(require("react"));
9434
- var import_fi18 = require("react-icons/fi");
9753
+ var import_react25 = __toESM(require("react"));
9754
+ var import_fi19 = require("react-icons/fi");
9435
9755
  var GroupItem = ({
9436
9756
  group,
9437
9757
  index,
@@ -9451,7 +9771,7 @@ var GroupItem = ({
9451
9771
  }) => {
9452
9772
  const canIndent = index > 0;
9453
9773
  const isPickingForThisGroup = pickingGroupId === group.id;
9454
- const textareaRef = (0, import_react24.useRef)(null);
9774
+ const textareaRef = (0, import_react25.useRef)(null);
9455
9775
  const adjustHeight = () => {
9456
9776
  const textarea = textareaRef.current;
9457
9777
  if (textarea) {
@@ -9459,13 +9779,13 @@ var GroupItem = ({
9459
9779
  textarea.style.height = `${textarea.scrollHeight}px`;
9460
9780
  }
9461
9781
  };
9462
- (0, import_react24.useEffect)(() => {
9782
+ (0, import_react25.useEffect)(() => {
9463
9783
  adjustHeight();
9464
9784
  }, [group.text]);
9465
- return /* @__PURE__ */ import_react24.default.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__ */ import_react24.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react24.default.createElement("div", { className: `
9785
+ return /* @__PURE__ */ import_react25.default.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__ */ import_react25.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react25.default.createElement("div", { className: `
9466
9786
  flex flex-col gap-2 py-2 px-3 transition-all duration-200
9467
9787
  ${isPickingForThisGroup ? "bg-indigo-500/10 border-l-2 border-indigo-500" : "hover:bg-white/5 border-l-2 border-transparent hover:border-white/20"}
9468
- ` }, /* @__PURE__ */ import_react24.default.createElement(
9788
+ ` }, /* @__PURE__ */ import_react25.default.createElement(
9469
9789
  "textarea",
9470
9790
  {
9471
9791
  ref: textareaRef,
@@ -9482,9 +9802,9 @@ var GroupItem = ({
9482
9802
  if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
9483
9803
  }
9484
9804
  }
9485
- ), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
9805
+ ), group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
9486
9806
  const isValid = availableIds.has(String(anc.ancestry_id));
9487
- return /* @__PURE__ */ import_react24.default.createElement(
9807
+ return /* @__PURE__ */ import_react25.default.createElement(
9488
9808
  "div",
9489
9809
  {
9490
9810
  key: anc.ancestry_id,
@@ -9496,28 +9816,28 @@ var GroupItem = ({
9496
9816
  },
9497
9817
  isValid ? (
9498
9818
  // [MANTIDO] Botão Play visível para todos
9499
- /* @__PURE__ */ import_react24.default.createElement(
9819
+ /* @__PURE__ */ import_react25.default.createElement(
9500
9820
  "button",
9501
9821
  {
9502
9822
  onClick: () => onPlayAncestry(anc.ancestry_id),
9503
9823
  className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
9504
9824
  title: "Renderizar no cen\xE1rio"
9505
9825
  },
9506
- /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlay, { size: 10, className: "ml-0.5 fill-current" })
9826
+ /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlay, { size: 10, className: "ml-0.5 fill-current" })
9507
9827
  )
9508
- ) : /* @__PURE__ */ import_react24.default.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiAlertTriangle, { size: 10 })),
9509
- /* @__PURE__ */ import_react24.default.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
9510
- canEdit && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ import_react24.default.createElement(
9828
+ ) : /* @__PURE__ */ import_react25.default.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiAlertTriangle, { size: 10 })),
9829
+ /* @__PURE__ */ import_react25.default.createElement("span", { className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}` }, anc.name),
9830
+ canEdit && /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, /* @__PURE__ */ import_react25.default.createElement("div", { className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}` }), /* @__PURE__ */ import_react25.default.createElement(
9511
9831
  "button",
9512
9832
  {
9513
9833
  onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
9514
9834
  className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
9515
9835
  title: "Remover men\xE7\xE3o"
9516
9836
  },
9517
- /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiX, { size: 12 })
9837
+ /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiX, { size: 12 })
9518
9838
  ))
9519
9839
  );
9520
- })), canEdit && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-40 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react24.default.createElement(
9840
+ })), canEdit && /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-40 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react25.default.createElement(
9521
9841
  "button",
9522
9842
  {
9523
9843
  onClick: () => onRequestPickAncestry(group.id),
@@ -9527,17 +9847,17 @@ var GroupItem = ({
9527
9847
  `,
9528
9848
  title: "Adicionar Ancestralidade a este grupo"
9529
9849
  },
9530
- isPickingForThisGroup ? /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCheckCircle, { size: 12 }) : /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiSearch, { size: 12 }),
9850
+ isPickingForThisGroup ? /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiCheckCircle, { size: 12 }) : /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiSearch, { size: 12 }),
9531
9851
  isPickingForThisGroup ? "Selecionando..." : "Adicionar"
9532
- ), /* @__PURE__ */ import_react24.default.createElement(
9852
+ ), /* @__PURE__ */ import_react25.default.createElement(
9533
9853
  "button",
9534
9854
  {
9535
9855
  onClick: () => onAddSubgroup(group.id),
9536
9856
  className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
9537
9857
  title: "Criar Subgrupo"
9538
9858
  },
9539
- /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 14 })
9540
- )), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react24.default.createElement(
9859
+ /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlus, { size: 14 })
9860
+ )), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react25.default.createElement(
9541
9861
  "button",
9542
9862
  {
9543
9863
  onClick: () => onIndent(group.id),
@@ -9545,24 +9865,24 @@ var GroupItem = ({
9545
9865
  className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
9546
9866
  title: "Aninhar no grupo acima"
9547
9867
  },
9548
- /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiArrowRight, { size: 14 })
9549
- ), /* @__PURE__ */ import_react24.default.createElement(
9868
+ /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiArrowRight, { size: 14 })
9869
+ ), /* @__PURE__ */ import_react25.default.createElement(
9550
9870
  "button",
9551
9871
  {
9552
9872
  onClick: () => onOutdent(group.id),
9553
9873
  className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
9554
9874
  title: "Desaninhar"
9555
9875
  },
9556
- /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiArrowLeft, { size: 14 })
9557
- ), /* @__PURE__ */ import_react24.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react24.default.createElement(
9876
+ /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiArrowLeft, { size: 14 })
9877
+ ), /* @__PURE__ */ import_react25.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react25.default.createElement(
9558
9878
  "button",
9559
9879
  {
9560
9880
  onClick: () => onDelete(group.id),
9561
9881
  className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
9562
9882
  title: "Remover Grupo"
9563
9883
  },
9564
- /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiTrash2, { size: 14 })
9565
- )))), group.children && group.children.length > 0 && /* @__PURE__ */ import_react24.default.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ import_react24.default.createElement(
9884
+ /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiTrash2, { size: 14 })
9885
+ )))), group.children && group.children.length > 0 && /* @__PURE__ */ import_react25.default.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ import_react25.default.createElement(
9566
9886
  GroupItem,
9567
9887
  {
9568
9888
  key: childGroup.id,
@@ -9594,21 +9914,21 @@ function AncestryBoard({
9594
9914
  userRole
9595
9915
  // [NOVO] Recebe a role do usuário
9596
9916
  }) {
9597
- const [searchTerm, setSearchTerm] = (0, import_react24.useState)("");
9598
- const [groups, setGroups] = (0, import_react24.useState)([]);
9599
- const [isLoaded, setIsLoaded] = (0, import_react24.useState)(false);
9600
- const [pickingGroupId, setPickingGroupId] = (0, import_react24.useState)(null);
9601
- const [saveStatus, setSaveStatus] = (0, import_react24.useState)("idle");
9602
- const canEdit = (0, import_react24.useMemo)(() => {
9917
+ const [searchTerm, setSearchTerm] = (0, import_react25.useState)("");
9918
+ const [groups, setGroups] = (0, import_react25.useState)([]);
9919
+ const [isLoaded, setIsLoaded] = (0, import_react25.useState)(false);
9920
+ const [pickingGroupId, setPickingGroupId] = (0, import_react25.useState)(null);
9921
+ const [saveStatus, setSaveStatus] = (0, import_react25.useState)("idle");
9922
+ const canEdit = (0, import_react25.useMemo)(() => {
9603
9923
  return userRole !== "viewer";
9604
9924
  }, [userRole]);
9605
- (0, import_react24.useEffect)(() => {
9925
+ (0, import_react25.useEffect)(() => {
9606
9926
  if (initialGroups && !isLoaded) {
9607
9927
  setGroups(initialGroups);
9608
9928
  setIsLoaded(true);
9609
9929
  }
9610
9930
  }, [initialGroups, isLoaded]);
9611
- const nodeNamesMap = (0, import_react24.useMemo)(() => {
9931
+ const nodeNamesMap = (0, import_react25.useMemo)(() => {
9612
9932
  const map = /* @__PURE__ */ new Map();
9613
9933
  if (availableNodes && Array.isArray(availableNodes)) {
9614
9934
  availableNodes.forEach((node) => {
@@ -9619,7 +9939,7 @@ function AncestryBoard({
9619
9939
  }
9620
9940
  return map;
9621
9941
  }, [availableNodes]);
9622
- const availableIds = (0, import_react24.useMemo)(() => {
9942
+ const availableIds = (0, import_react25.useMemo)(() => {
9623
9943
  return new Set(availableAncestries.map((a) => String(a.ancestry_id)));
9624
9944
  }, [availableAncestries]);
9625
9945
  const sanitizeGroups = (groupList) => {
@@ -9633,7 +9953,7 @@ function AncestryBoard({
9633
9953
  children: sanitizeGroups(g.children || [])
9634
9954
  }));
9635
9955
  };
9636
- (0, import_react24.useEffect)(() => {
9956
+ (0, import_react25.useEffect)(() => {
9637
9957
  if (!isLoaded || !onSave) return;
9638
9958
  const timeoutId = setTimeout(async () => {
9639
9959
  setSaveStatus("saving");
@@ -9651,7 +9971,7 @@ function AncestryBoard({
9651
9971
  }, 3e3);
9652
9972
  return () => clearTimeout(timeoutId);
9653
9973
  }, [groups, isLoaded, onSave]);
9654
- (0, import_react24.useEffect)(() => {
9974
+ (0, import_react25.useEffect)(() => {
9655
9975
  if (!isOpen) return;
9656
9976
  const handleKeyDown = (e) => {
9657
9977
  if (e.key === "Escape") {
@@ -9667,7 +9987,7 @@ function AncestryBoard({
9667
9987
  window.addEventListener("keydown", handleKeyDown);
9668
9988
  return () => window.removeEventListener("keydown", handleKeyDown);
9669
9989
  }, [isOpen, onClose, pickingGroupId]);
9670
- const filtered = (0, import_react24.useMemo)(() => {
9990
+ const filtered = (0, import_react25.useMemo)(() => {
9671
9991
  const term = searchTerm.toLowerCase().trim();
9672
9992
  return availableAncestries.filter((a) => {
9673
9993
  if (!term) return true;
@@ -9806,27 +10126,27 @@ function AncestryBoard({
9806
10126
  });
9807
10127
  };
9808
10128
  if (!isOpen) return null;
9809
- return /* @__PURE__ */ import_react24.default.createElement(
10129
+ return /* @__PURE__ */ import_react25.default.createElement(
9810
10130
  "div",
9811
10131
  {
9812
10132
  className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
9813
10133
  onClick: onClose
9814
10134
  },
9815
- /* @__PURE__ */ import_react24.default.createElement(
10135
+ /* @__PURE__ */ import_react25.default.createElement(
9816
10136
  "div",
9817
10137
  {
9818
10138
  className: "bg-slate-950 border border-white/10 rounded-xl w-[98vw] h-[97vh] flex flex-col shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200",
9819
10139
  onClick: (e) => e.stopPropagation()
9820
10140
  },
9821
- /* @__PURE__ */ import_react24.default.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react24.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-slate-900/50 border border-white/5" }, saveStatus === "saving" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLoader, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, /* @__PURE__ */ import_react24.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ import_react24.default.createElement(
10141
+ /* @__PURE__ */ import_react25.default.createElement("div", { className: "h-14 px-4 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react25.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-slate-900/50 border border-white/5" }, saveStatus === "saving" && /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiLoader, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ import_react25.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react25.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, /* @__PURE__ */ import_react25.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react25.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ import_react25.default.createElement("span", { className: "text-xs text-indigo-300 font-medium animate-pulse hidden sm:inline-block mr-2" }, "Selecione na lateral..."), canEdit && /* @__PURE__ */ import_react25.default.createElement(
9822
10142
  "button",
9823
10143
  {
9824
10144
  onClick: handleAddRootGroup,
9825
10145
  className: "\n flex items-center gap-2 px-3 py-1.5 \n bg-white/5 hover:bg-white/10 \n border border-white/10 hover:border-white/20\n backdrop-blur-sm\n text-slate-200 hover:text-white\n rounded-md transition-all duration-200\n text-xs font-medium shadow-sm\n "
9826
10146
  },
9827
- /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 14, className: "text-indigo-400" }),
9828
- /* @__PURE__ */ import_react24.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
9829
- ), /* @__PURE__ */ import_react24.default.createElement(
10147
+ /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlus, { size: 14, className: "text-indigo-400" }),
10148
+ /* @__PURE__ */ import_react25.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
10149
+ ), /* @__PURE__ */ import_react25.default.createElement(
9830
10150
  "button",
9831
10151
  {
9832
10152
  onClick: onClose,
@@ -9834,11 +10154,11 @@ function AncestryBoard({
9834
10154
  },
9835
10155
  "\xD7"
9836
10156
  ))),
9837
- /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: `
10157
+ /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: `
9838
10158
  flex flex-col border-r border-white/10 transition-all duration-300 flex-none
9839
10159
  ${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
9840
10160
  min-w-[280px] max-w-[500px] bg-slate-900
9841
- ` }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiSearch, { className: `absolute left-3 top-1/2 -translate-y-1/2 transition-colors ${pickingGroupId ? "text-indigo-400" : "text-slate-500 group-focus-within:text-indigo-400"}` }), /* @__PURE__ */ import_react24.default.createElement(
10161
+ ` }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiSearch, { className: `absolute left-3 top-1/2 -translate-y-1/2 transition-colors ${pickingGroupId ? "text-indigo-400" : "text-slate-500 group-focus-within:text-indigo-400"}` }), /* @__PURE__ */ import_react25.default.createElement(
9842
10162
  "input",
9843
10163
  {
9844
10164
  type: "text",
@@ -9851,10 +10171,10 @@ function AncestryBoard({
9851
10171
  onChange: (e) => setSearchTerm(e.target.value),
9852
10172
  autoFocus: !pickingGroupId
9853
10173
  }
9854
- ))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
10174
+ ))), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
9855
10175
  const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
9856
10176
  const isPicking = !!pickingGroupId;
9857
- return /* @__PURE__ */ import_react24.default.createElement(
10177
+ return /* @__PURE__ */ import_react25.default.createElement(
9858
10178
  "div",
9859
10179
  {
9860
10180
  key: anc.ancestry_id,
@@ -9866,12 +10186,12 @@ function AncestryBoard({
9866
10186
  ${isPicking ? "border-indigo-500/30 bg-indigo-500/5 hover:bg-indigo-500/20 hover:border-indigo-400 cursor-pointer" : "border-white/5 bg-slate-800/40 hover:bg-indigo-600/10 hover:border-indigo-500/30 cursor-default"}
9867
10187
  `
9868
10188
  },
9869
- /* @__PURE__ */ import_react24.default.createElement("div", { className: `
10189
+ /* @__PURE__ */ import_react25.default.createElement("div", { className: `
9870
10190
  mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
9871
10191
  ${isPicking ? "bg-indigo-500 text-white border-indigo-400" : "bg-slate-800 text-indigo-400 border-white/5 group-hover:bg-indigo-500 group-hover:text-white"}
9872
- ` }, isPicking ? /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlus, { size: 16 }) : /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { size: 14 })),
9873
- /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react24.default.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.name || "Sem Nome"), anc.is_private && /* @__PURE__ */ import_react24.default.createElement("span", { className: "text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-300 border border-amber-500/20" }, "Priv")), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiCornerUpRight, { size: 10 }), /* @__PURE__ */ import_react24.default.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ import_react24.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
9874
- !isPicking && /* @__PURE__ */ import_react24.default.createElement(
10192
+ ` }, isPicking ? /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlus, { size: 16 }) : /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiLayers, { size: 14 })),
10193
+ /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react25.default.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.name || "Sem Nome"), anc.is_private && /* @__PURE__ */ import_react25.default.createElement("span", { className: "text-[9px] px-1 py-0.5 rounded bg-amber-500/10 text-amber-300 border border-amber-500/20" }, "Priv")), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex items-center gap-1.5 mt-0.5 text-[11px] text-slate-500 group-hover:text-indigo-200/70 transition-colors" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiCornerUpRight, { size: 10 }), /* @__PURE__ */ import_react25.default.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ import_react25.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
10194
+ !isPicking && /* @__PURE__ */ import_react25.default.createElement(
9875
10195
  "button",
9876
10196
  {
9877
10197
  onClick: (e) => {
@@ -9881,10 +10201,10 @@ function AncestryBoard({
9881
10201
  className: "absolute right-2 bottom-2 opacity-0 group-hover:opacity-100 transition-all duration-300 transform translate-y-2 group-hover:translate-y-0 z-10",
9882
10202
  title: "Renderizar Ancestralidade"
9883
10203
  },
9884
- /* @__PURE__ */ import_react24.default.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiPlay, { size: 14, className: "ml-0.5" }))
10204
+ /* @__PURE__ */ import_react25.default.createElement("div", { className: "bg-indigo-500 text-white p-2 rounded-full shadow-lg hover:bg-indigo-400 hover:scale-110 transition-all" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiPlay, { size: 14, className: "ml-0.5" }))
9885
10205
  )
9886
10206
  );
9887
- }))), /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ import_react24.default.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ import_react24.default.createElement(import_fi18.FiLayers, { size: 24, className: "opacity-20" }), /* @__PURE__ */ import_react24.default.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ import_react24.default.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ import_react24.default.createElement(import_react24.default.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ import_react24.default.createElement(
10207
+ }))), /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-3 border-2 border-dashed border-white/5 rounded-xl m-4 bg-slate-900/20" }, /* @__PURE__ */ import_react25.default.createElement(import_fi19.FiLayers, { size: 24, className: "opacity-20" }), /* @__PURE__ */ import_react25.default.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ import_react25.default.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ import_react25.default.createElement(import_react25.default.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ import_react25.default.createElement(
9888
10208
  GroupItem,
9889
10209
  {
9890
10210
  key: group.id,
@@ -9904,7 +10224,7 @@ function AncestryBoard({
9904
10224
  canEdit
9905
10225
  }
9906
10226
  ))))),
9907
- /* @__PURE__ */ import_react24.default.createElement("div", { className: "px-5 py-2 border-t border-white/10 bg-slate-950/50 text-xs text-slate-500 flex justify-between flex-shrink-0" }, /* @__PURE__ */ import_react24.default.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ import_react24.default.createElement("span", null, groups.length, " grupos raiz"))
10227
+ /* @__PURE__ */ import_react25.default.createElement("div", { className: "px-5 py-2 border-t border-white/10 bg-slate-950/50 text-xs text-slate-500 flex justify-between flex-shrink-0" }, /* @__PURE__ */ import_react25.default.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ import_react25.default.createElement("span", null, groups.length, " grupos raiz"))
9908
10228
  )
9909
10229
  );
9910
10230
  }
@@ -9984,12 +10304,12 @@ function XViewScene({
9984
10304
  check_user_permission
9985
10305
  }) {
9986
10306
  var _a, _b, _c, _d, _e, _f, _g;
9987
- const { data: session, status } = (0, import_react26.useSession)();
10307
+ const { data: session, status } = (0, import_react27.useSession)();
9988
10308
  const router = (0, import_navigation.useRouter)();
9989
10309
  const searchParams = (0, import_navigation.useSearchParams)();
9990
10310
  const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
9991
10311
  const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
9992
- const viewParams = (0, import_react25.useMemo)(() => {
10312
+ const viewParams = (0, import_react26.useMemo)(() => {
9993
10313
  if (encryptedConfig) {
9994
10314
  const data = decryptData(encryptedConfig);
9995
10315
  if (data) {
@@ -9998,7 +10318,7 @@ function XViewScene({
9998
10318
  }
9999
10319
  return null;
10000
10320
  }, [encryptedConfig, session]);
10001
- (0, import_react25.useEffect)(() => {
10321
+ (0, import_react26.useEffect)(() => {
10002
10322
  async function verifyPermission() {
10003
10323
  if (!viewParams || !session || !check_user_permission) return;
10004
10324
  const { id, type, owner_id } = viewParams;
@@ -10028,65 +10348,65 @@ function XViewScene({
10028
10348
  setIsLoading(false);
10029
10349
  }
10030
10350
  }, [viewParams, session, status, check_user_permission]);
10031
- const sceneConfigId = (0, import_react25.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
10032
- const ownerId = (0, import_react25.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
10033
- const dbSaveUrl = (0, import_react25.useMemo)(() => {
10351
+ const sceneConfigId = (0, import_react26.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
10352
+ const ownerId = (0, import_react26.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
10353
+ const dbSaveUrl = (0, import_react26.useMemo)(() => {
10034
10354
  if (ownerId && sceneConfigId) {
10035
10355
  return `x_view_dbs/${ownerId}/${sceneConfigId}`;
10036
10356
  }
10037
10357
  return null;
10038
10358
  }, [ownerId, sceneConfigId]);
10039
- const sceneSaveUrl = (0, import_react25.useMemo)(() => {
10359
+ const sceneSaveUrl = (0, import_react26.useMemo)(() => {
10040
10360
  if (ownerId && sceneConfigId) {
10041
10361
  return `x_view_scenes/${ownerId}/${sceneConfigId}`;
10042
10362
  }
10043
10363
  return null;
10044
10364
  }, [ownerId, sceneConfigId]);
10045
- const ancestry_save_url = (0, import_react25.useMemo)(() => {
10365
+ const ancestry_save_url = (0, import_react26.useMemo)(() => {
10046
10366
  if (ownerId && sceneConfigId) {
10047
10367
  return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
10048
10368
  }
10049
10369
  return null;
10050
10370
  }, [ownerId, sceneConfigId]);
10051
- const sceneDataRef = (0, import_react25.useRef)(null);
10052
- const parentDataRef = (0, import_react25.useRef)(null);
10053
- const ancestryDataRef = (0, import_react25.useRef)(null);
10054
- const [isLoading, setIsLoading] = (0, import_react25.useState)(true);
10055
- const [permissionStatus, setPermissionStatus] = (0, import_react25.useState)("loading");
10056
- const [userPermissionRole, setUserPermissionRole] = (0, import_react25.useState)(null);
10057
- const [isInitialized, setIsInitialized] = (0, import_react25.useState)(false);
10058
- const [sceneVersion, setSceneVersion] = (0, import_react25.useState)(0);
10059
- const [contextMenu, setContextMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, nodeData: null });
10060
- const [multiContextMenu, setMultiContextMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, nodeIds: null });
10061
- const [relationshipMenu, setRelationshipMenu] = (0, import_react25.useState)({ visible: false, x: 0, y: 0, linkObject: null });
10062
- const [creationMode, setCreationMode] = (0, import_react25.useState)({ isActive: false, sourceNodeData: null });
10063
- const [versionMode, setVersionMode] = (0, import_react25.useState)({ isActive: false, sourceNodeData: null });
10064
- const [questMode, setQuestMode] = (0, import_react25.useState)({ isActive: false });
10065
- const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react25.useState)(false);
10066
- const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react25.useState)(false);
10067
- const [ancestryMode, setAncestryMode] = (0, import_react25.useState)({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
10068
- const [readingMode, setReadingMode] = (0, import_react25.useState)({
10371
+ const sceneDataRef = (0, import_react26.useRef)(null);
10372
+ const parentDataRef = (0, import_react26.useRef)(null);
10373
+ const ancestryDataRef = (0, import_react26.useRef)(null);
10374
+ const [isLoading, setIsLoading] = (0, import_react26.useState)(true);
10375
+ const [permissionStatus, setPermissionStatus] = (0, import_react26.useState)("loading");
10376
+ const [userPermissionRole, setUserPermissionRole] = (0, import_react26.useState)(null);
10377
+ const [isInitialized, setIsInitialized] = (0, import_react26.useState)(false);
10378
+ const [sceneVersion, setSceneVersion] = (0, import_react26.useState)(0);
10379
+ const [contextMenu, setContextMenu] = (0, import_react26.useState)({ visible: false, x: 0, y: 0, nodeData: null });
10380
+ const [multiContextMenu, setMultiContextMenu] = (0, import_react26.useState)({ visible: false, x: 0, y: 0, nodeIds: null });
10381
+ const [relationshipMenu, setRelationshipMenu] = (0, import_react26.useState)({ visible: false, x: 0, y: 0, linkObject: null });
10382
+ const [creationMode, setCreationMode] = (0, import_react26.useState)({ isActive: false, sourceNodeData: null });
10383
+ const [versionMode, setVersionMode] = (0, import_react26.useState)({ isActive: false, sourceNodeData: null });
10384
+ const [questMode, setQuestMode] = (0, import_react26.useState)({ isActive: false });
10385
+ const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react26.useState)(false);
10386
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react26.useState)(false);
10387
+ const [ancestryMode, setAncestryMode] = (0, import_react26.useState)({ isActive: false, tree: null, selectedParentId: null, isEditMode: false, currentAncestryId: null, ancestryName: "", ancestryDescription: "", ancestryDescriptionSections: [], isAddingNodes: false });
10388
+ const [readingMode, setReadingMode] = (0, import_react26.useState)({
10069
10389
  isActive: false,
10070
10390
  ancestry: null,
10071
10391
  branchStack: [],
10072
10392
  autoAbstraction: false
10073
10393
  });
10074
- const [formPosition, setFormPosition] = (0, import_react25.useState)({ left: 16, top: 16, opacity: 0 });
10075
- const [detailsNode, setDetailsNode] = (0, import_react25.useState)(null);
10076
- const [detailsLink, setDetailsLink] = (0, import_react25.useState)(null);
10077
- const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react25.useState)(null);
10078
- const [imageViewer, setImageViewer] = (0, import_react25.useState)({ visible: false, images: [], startIndex: 0 });
10079
- const [editingAncestryRel, setEditingAncestryRel] = (0, import_react25.useState)({ visible: false, data: null, path: null });
10080
- const [isImportModalOpen, setIsImportModalOpen] = (0, import_react25.useState)(false);
10081
- const [importSuccessMessage, setImportSuccessMessage] = (0, import_react25.useState)("");
10082
- const [highlightedNodeId, setHighlightedNodeId] = (0, import_react25.useState)(null);
10083
- const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react25.useState)(false);
10084
- const [ancestryBoardData, setAncestryBoardData] = (0, import_react25.useState)([]);
10085
- const [isSidebarOpen, setIsSidebarOpen] = (0, import_react25.useState)(false);
10086
- const mountRef = (0, import_react25.useRef)(null);
10087
- const tooltipRef = (0, import_react25.useRef)(null);
10088
- const formRef = (0, import_react25.useRef)(null);
10089
- const stateRef = (0, import_react25.useRef)({
10394
+ const [formPosition, setFormPosition] = (0, import_react26.useState)({ left: 16, top: 16, opacity: 0 });
10395
+ const [detailsNode, setDetailsNode] = (0, import_react26.useState)(null);
10396
+ const [detailsLink, setDetailsLink] = (0, import_react26.useState)(null);
10397
+ const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react26.useState)(null);
10398
+ const [imageViewer, setImageViewer] = (0, import_react26.useState)({ visible: false, images: [], startIndex: 0 });
10399
+ const [editingAncestryRel, setEditingAncestryRel] = (0, import_react26.useState)({ visible: false, data: null, path: null });
10400
+ const [isImportModalOpen, setIsImportModalOpen] = (0, import_react26.useState)(false);
10401
+ const [importSuccessMessage, setImportSuccessMessage] = (0, import_react26.useState)("");
10402
+ const [highlightedNodeId, setHighlightedNodeId] = (0, import_react26.useState)(null);
10403
+ const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react26.useState)(false);
10404
+ const [ancestryBoardData, setAncestryBoardData] = (0, import_react26.useState)([]);
10405
+ const [isSidebarOpen, setIsSidebarOpen] = (0, import_react26.useState)(false);
10406
+ const mountRef = (0, import_react26.useRef)(null);
10407
+ const tooltipRef = (0, import_react26.useRef)(null);
10408
+ const formRef = (0, import_react26.useRef)(null);
10409
+ const stateRef = (0, import_react26.useRef)({
10090
10410
  readMode: {
10091
10411
  currentMaxIndex: 0,
10092
10412
  progressMap: {}
@@ -10131,10 +10451,10 @@ function XViewScene({
10131
10451
  minWidth: 320,
10132
10452
  maxWidth: maxReadPanelW
10133
10453
  });
10134
- (0, import_react25.useEffect)(() => {
10454
+ (0, import_react26.useEffect)(() => {
10135
10455
  stateRef.current.ancestry = ancestryMode;
10136
10456
  }, [ancestryMode]);
10137
- (0, import_react25.useEffect)(() => {
10457
+ (0, import_react26.useEffect)(() => {
10138
10458
  var _a2;
10139
10459
  if (!isInitialized) return;
10140
10460
  const map = /* @__PURE__ */ new Map();
@@ -10155,10 +10475,10 @@ function XViewScene({
10155
10475
  }
10156
10476
  stateRef.current.nodeIdToParentFileMap = map;
10157
10477
  }, [isInitialized, sceneVersion]);
10158
- const handleNavigateBack = (0, import_react25.useCallback)(() => {
10478
+ const handleNavigateBack = (0, import_react26.useCallback)(() => {
10159
10479
  router.push("/dashboard/scenes");
10160
10480
  }, [router]);
10161
- const handleConfirmImport = (0, import_react25.useCallback)(
10481
+ const handleConfirmImport = (0, import_react26.useCallback)(
10162
10482
  async (importPayload) => {
10163
10483
  var _a2, _b2;
10164
10484
  let files = [];
@@ -10256,7 +10576,7 @@ function XViewScene({
10256
10576
  const handleOpenImageViewer = (images, startIndex) => {
10257
10577
  setImageViewer({ visible: true, images, startIndex });
10258
10578
  };
10259
- const tweenToTarget = (0, import_react25.useCallback)((target, zoomFactor = 1, forcedDirection = null) => {
10579
+ const tweenToTarget = (0, import_react26.useCallback)((target, zoomFactor = 1, forcedDirection = null) => {
10260
10580
  const { camera, controls, tweenGroup } = stateRef.current;
10261
10581
  if (!camera || !controls || !tweenGroup) return;
10262
10582
  const targetPos = target instanceof THREE3.Mesh ? target.getWorldPosition(new THREE3.Vector3()) : target;
@@ -10279,7 +10599,7 @@ function XViewScene({
10279
10599
  if (!t || typeof t.closest !== "function") return false;
10280
10600
  return !!t.closest(".ui-overlay");
10281
10601
  };
10282
- const buildFullAncestryTree = (0, import_react25.useCallback)((idTree, nodes, ancestries = []) => {
10602
+ const buildFullAncestryTree = (0, import_react26.useCallback)((idTree, nodes, ancestries = []) => {
10283
10603
  if (!idTree) return null;
10284
10604
  const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
10285
10605
  const ancestryMap = new Map(ancestries.map((a) => [String(a.ancestry_id), a]));
@@ -10355,7 +10675,7 @@ function XViewScene({
10355
10675
  }
10356
10676
  return recursiveBuild(idTree);
10357
10677
  }, []);
10358
- const handleActivateTimeline = (0, import_react25.useCallback)(() => {
10678
+ const handleActivateTimeline = (0, import_react26.useCallback)(() => {
10359
10679
  const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
10360
10680
  if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
10361
10681
  while (timelineIntervalsGroup.children.length > 0) {
@@ -10508,7 +10828,7 @@ function XViewScene({
10508
10828
  }
10509
10829
  });
10510
10830
  }, []);
10511
- const handleVersionTimeline = (0, import_react25.useCallback)((sourceMesh, versionMeshes) => {
10831
+ const handleVersionTimeline = (0, import_react26.useCallback)((sourceMesh, versionMeshes) => {
10512
10832
  const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
10513
10833
  if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0) return;
10514
10834
  versionMeshes.forEach((mesh) => {
@@ -10631,7 +10951,7 @@ function XViewScene({
10631
10951
  }
10632
10952
  });
10633
10953
  }, []);
10634
- (0, import_react25.useEffect)(() => {
10954
+ (0, import_react26.useEffect)(() => {
10635
10955
  async function fetchAllData(configPath, ownerId2) {
10636
10956
  var _a2, _b2;
10637
10957
  if (!get_scene_view_data) {
@@ -10703,12 +11023,12 @@ function XViewScene({
10703
11023
  focusNodeId,
10704
11024
  focusAncestryId
10705
11025
  ]);
10706
- const isNodeInView = (0, import_react25.useCallback)((id) => {
11026
+ const isNodeInView = (0, import_react26.useCallback)((id) => {
10707
11027
  const key = String(id);
10708
11028
  const objs = stateRef.current.nodeObjects || {};
10709
11029
  return !!objs[key];
10710
11030
  }, []);
10711
- const addOrUpdateNodeMesh = (0, import_react25.useCallback)((nodeData, position, suppressVersionUpdate = false) => {
11031
+ const addOrUpdateNodeMesh = (0, import_react26.useCallback)((nodeData, position, suppressVersionUpdate = false) => {
10712
11032
  const { graphGroup, nodeObjects, clickableNodes, glowTexture, tweenGroup } = stateRef.current;
10713
11033
  const nodeId = String(nodeData.id);
10714
11034
  if (nodeObjects[nodeId]) {
@@ -10735,7 +11055,7 @@ function XViewScene({
10735
11055
  }
10736
11056
  return mesh;
10737
11057
  }, []);
10738
- (0, import_react25.useEffect)(() => {
11058
+ (0, import_react26.useEffect)(() => {
10739
11059
  if (!isInitialized || !sceneDataRef.current) return;
10740
11060
  const currentMount = mountRef.current;
10741
11061
  if (!currentMount) return;
@@ -11345,7 +11665,7 @@ function XViewScene({
11345
11665
  }
11346
11666
  };
11347
11667
  }, [isInitialized, tweenToTarget, dbSaveUrl, isNodeInView, addOrUpdateNodeMesh, handleActivateTimeline, get_scene_view_data, save_view_data]);
11348
- const handleGhostNodeImageChange = (0, import_react25.useCallback)((useImage, imageUrl) => {
11668
+ const handleGhostNodeImageChange = (0, import_react26.useCallback)((useImage, imageUrl) => {
11349
11669
  const { node: ghostNode, line: ghostLine, aura: ghostAura } = stateRef.current.ghostElements;
11350
11670
  const { graphGroup, glowTexture } = stateRef.current;
11351
11671
  if (!ghostNode || !graphGroup) return;
@@ -11387,7 +11707,7 @@ function XViewScene({
11387
11707
  aura: newGhostNode.getObjectByName("aura")
11388
11708
  };
11389
11709
  }, []);
11390
- const handleGhostNodeIntensityChange = (0, import_react25.useCallback)((newIntensity) => {
11710
+ const handleGhostNodeIntensityChange = (0, import_react26.useCallback)((newIntensity) => {
11391
11711
  const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
11392
11712
  if (!ghostNode) return;
11393
11713
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -11408,7 +11728,7 @@ function XViewScene({
11408
11728
  ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
11409
11729
  }
11410
11730
  }, []);
11411
- const handleDetailNodeIntensityChange = (0, import_react25.useCallback)((nodeId, newIntensity) => {
11731
+ const handleDetailNodeIntensityChange = (0, import_react26.useCallback)((nodeId, newIntensity) => {
11412
11732
  const mesh = stateRef.current.nodeObjects[String(nodeId)];
11413
11733
  if (!mesh) return;
11414
11734
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -11554,7 +11874,7 @@ function XViewScene({
11554
11874
  mountRef.current.style.cursor = "default";
11555
11875
  }
11556
11876
  };
11557
- const handleAncestryTreeUpdate = (0, import_react25.useCallback)((newTree, extraData = null) => {
11877
+ const handleAncestryTreeUpdate = (0, import_react26.useCallback)((newTree, extraData = null) => {
11558
11878
  setAncestryMode((prev) => {
11559
11879
  const prevTreeStr = JSON.stringify(prev.tree);
11560
11880
  const newTreeStr = JSON.stringify(newTree);
@@ -11574,7 +11894,7 @@ function XViewScene({
11574
11894
  };
11575
11895
  });
11576
11896
  }, []);
11577
- const actionHandlerContext = (0, import_react25.useMemo)(
11897
+ const actionHandlerContext = (0, import_react26.useMemo)(
11578
11898
  () => {
11579
11899
  var _a2;
11580
11900
  return {
@@ -11635,7 +11955,7 @@ function XViewScene({
11635
11955
  const handleStartVersioning = (nodeData) => {
11636
11956
  userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
11637
11957
  };
11638
- const handleCancelQuest = (0, import_react25.useCallback)(() => {
11958
+ const handleCancelQuest = (0, import_react26.useCallback)(() => {
11639
11959
  const { graphGroup, ghostElements } = stateRef.current;
11640
11960
  if (ghostElements.node && graphGroup) {
11641
11961
  if (ghostElements.node.userData.labelObject) {
@@ -11745,7 +12065,7 @@ function XViewScene({
11745
12065
  }
11746
12066
  userActionHandlers.handleCancelConnection(context);
11747
12067
  };
11748
- const handleClearAncestryVisuals = (0, import_react25.useCallback)((ancestryId) => {
12068
+ const handleClearAncestryVisuals = (0, import_react26.useCallback)((ancestryId) => {
11749
12069
  const { renderedAncestries, ancestryGroup } = stateRef.current;
11750
12070
  const renderIndex = renderedAncestries.findIndex((a) => String(a.id) === String(ancestryId));
11751
12071
  if (renderIndex !== -1) {
@@ -11759,7 +12079,7 @@ function XViewScene({
11759
12079
  stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
11760
12080
  }
11761
12081
  }, []);
11762
- const handleRenderAncestry = (0, import_react25.useCallback)(
12082
+ const handleRenderAncestry = (0, import_react26.useCallback)(
11763
12083
  async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
11764
12084
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
11765
12085
  if (!ancestryObject || !ancestryObject.tree) {
@@ -12175,7 +12495,7 @@ function XViewScene({
12175
12495
  },
12176
12496
  [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, readingMode.isActive, ancestryMode.isActive]
12177
12497
  );
12178
- const handleRenderAbstractionTree = (0, import_react25.useCallback)((ancestryObject, targetNodeId = null) => {
12498
+ const handleRenderAbstractionTree = (0, import_react26.useCallback)((ancestryObject, targetNodeId = null) => {
12179
12499
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
12180
12500
  if (!ancestryObject || !ancestryObject.abstraction_tree) return;
12181
12501
  const { ancestryGroup, nodeObjects, renderer, renderedAncestries } = stateRef.current;
@@ -12236,7 +12556,7 @@ function XViewScene({
12236
12556
  stateRef.current.ancestryLinks = renderedAncestries.flatMap((a) => a.lines);
12237
12557
  tweenToTarget(rootTargetPos, 0.7);
12238
12558
  }, [addOrUpdateNodeMesh, tweenToTarget, buildFullAncestryTree, handleClearAncestryVisuals]);
12239
- const handleReadModeBranchNav = (0, import_react25.useCallback)((nodeId, action, direction = "right") => {
12559
+ const handleReadModeBranchNav = (0, import_react26.useCallback)((nodeId, action, direction = "right") => {
12240
12560
  const { ancestry, branchStack } = readingMode;
12241
12561
  if (!ancestry || !ancestry.tree) return;
12242
12562
  const allAncestries = ancestryDataRef.current || [];
@@ -12377,13 +12697,13 @@ function XViewScene({
12377
12697
  }));
12378
12698
  }
12379
12699
  }, [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]);
12380
- const handleReadModeHighlight = (0, import_react25.useCallback)((nodeId) => {
12700
+ const handleReadModeHighlight = (0, import_react26.useCallback)((nodeId) => {
12381
12701
  if (stateRef.current.highlightedNodeId !== nodeId) {
12382
12702
  stateRef.current.highlightedNodeId = nodeId;
12383
12703
  }
12384
12704
  setHighlightedNodeId(nodeId);
12385
12705
  }, []);
12386
- const activeNodeBranches = (0, import_react25.useMemo)(() => {
12706
+ const activeNodeBranches = (0, import_react26.useMemo)(() => {
12387
12707
  if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree) return null;
12388
12708
  const fullTree = buildFullAncestryTree(
12389
12709
  readingMode.ancestry.tree,
@@ -12420,7 +12740,7 @@ function XViewScene({
12420
12740
  }
12421
12741
  return null;
12422
12742
  }, [highlightedNodeId, readingMode.ancestry, buildFullAncestryTree, readingMode.branchStack, ancestryDataRef.current]);
12423
- const backNavigationInfo = (0, import_react25.useMemo)(() => {
12743
+ const backNavigationInfo = (0, import_react26.useMemo)(() => {
12424
12744
  const { branchStack } = readingMode;
12425
12745
  if (!branchStack || branchStack.length === 0) return null;
12426
12746
  const lastStep = branchStack[branchStack.length - 1];
@@ -12431,7 +12751,7 @@ function XViewScene({
12431
12751
  name: "Voltar para anterior"
12432
12752
  };
12433
12753
  }, [readingMode.branchStack]);
12434
- const getReadModeDisplayContext = (0, import_react25.useMemo)(() => {
12754
+ const getReadModeDisplayContext = (0, import_react26.useMemo)(() => {
12435
12755
  const { ancestry, branchStack } = readingMode;
12436
12756
  if (!ancestry) return null;
12437
12757
  if (branchStack.length === 0) {
@@ -12472,7 +12792,7 @@ function XViewScene({
12472
12792
  customProperties: branchProps
12473
12793
  };
12474
12794
  }, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
12475
- const readModeAbstractionTree = (0, import_react25.useMemo)(() => {
12795
+ const readModeAbstractionTree = (0, import_react26.useMemo)(() => {
12476
12796
  if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
12477
12797
  return null;
12478
12798
  }
@@ -12484,7 +12804,7 @@ function XViewScene({
12484
12804
  allAncestries
12485
12805
  );
12486
12806
  }, [readingMode.isActive, readingMode.ancestry, buildFullAncestryTree, sceneVersion]);
12487
- const handleStartReadingAncestry = (0, import_react25.useCallback)(
12807
+ const handleStartReadingAncestry = (0, import_react26.useCallback)(
12488
12808
  async (ancestryObject) => {
12489
12809
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
12490
12810
  if (!ancestryObject || !ancestryObject.tree) {
@@ -12519,7 +12839,7 @@ function XViewScene({
12519
12839
  },
12520
12840
  [handleRenderAncestry, handleRenderAbstractionTree]
12521
12841
  );
12522
- const handleReadModeSectionChange = (0, import_react25.useCallback)((activeSectionId) => {
12842
+ const handleReadModeSectionChange = (0, import_react26.useCallback)((activeSectionId) => {
12523
12843
  const { ancestry, branchStack } = readingMode;
12524
12844
  if (!ancestry || !readingMode.isActive) return;
12525
12845
  let targetObj = ancestry;
@@ -12588,10 +12908,10 @@ function XViewScene({
12588
12908
  }, 0);
12589
12909
  handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
12590
12910
  }, [readingMode, handleRenderAncestry, buildFullAncestryTree, ancestryDataRef.current]);
12591
- const handleCloseReadMode = (0, import_react25.useCallback)(() => {
12911
+ const handleCloseReadMode = (0, import_react26.useCallback)(() => {
12592
12912
  setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
12593
12913
  }, []);
12594
- const handleAncestrySectionChange = (0, import_react25.useCallback)((activeSectionId, ancestryOverride = null, rotation = 0) => {
12914
+ const handleAncestrySectionChange = (0, import_react26.useCallback)((activeSectionId, ancestryOverride = null, rotation = 0) => {
12595
12915
  var _a2, _b2;
12596
12916
  const currentMode = stateRef.current.ancestry;
12597
12917
  let targetObj = ancestryOverride;
@@ -12643,7 +12963,7 @@ function XViewScene({
12643
12963
  const renderPayload = { ...targetObj, tree: treeToRender };
12644
12964
  handleRenderAncestry(renderPayload, allowedIds, focusTargetId, rotation);
12645
12965
  }, [handleRenderAncestry]);
12646
- const handleEditAncestry = (0, import_react25.useCallback)(
12966
+ const handleEditAncestry = (0, import_react26.useCallback)(
12647
12967
  async (ancestryObject) => {
12648
12968
  setContextMenu((prev) => prev.visible ? { ...prev, visible: false } : prev);
12649
12969
  if (!ancestryObject || !ancestryObject.tree) {
@@ -12682,7 +13002,7 @@ function XViewScene({
12682
13002
  const handleSelectAncestryParent = (nodeId) => {
12683
13003
  setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
12684
13004
  };
12685
- const handleRemoveFromAncestry = (0, import_react25.useCallback)((pathToRemove) => {
13005
+ const handleRemoveFromAncestry = (0, import_react26.useCallback)((pathToRemove) => {
12686
13006
  if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
12687
13007
  console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
12688
13008
  return;
@@ -12707,7 +13027,7 @@ function XViewScene({
12707
13027
  return { ...prev, tree: newTree };
12708
13028
  });
12709
13029
  }, []);
12710
- const handleSaveAncestry = (0, import_react25.useCallback)(
13030
+ const handleSaveAncestry = (0, import_react26.useCallback)(
12711
13031
  async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
12712
13032
  const treeToUse = treeOverride || ancestryMode.tree;
12713
13033
  const { isEditMode, currentAncestryId } = ancestryMode;
@@ -12911,7 +13231,7 @@ function XViewScene({
12911
13231
  });
12912
13232
  setEditingAncestryRel({ visible: false, data: null, path: null });
12913
13233
  };
12914
- const handleDeleteAncestry = (0, import_react25.useCallback)(
13234
+ const handleDeleteAncestry = (0, import_react26.useCallback)(
12915
13235
  async (ancestryIdToDelete) => {
12916
13236
  if (!ancestryIdToDelete) {
12917
13237
  alert("ID da ancestralidade n\xE3o encontrado.");
@@ -12973,20 +13293,20 @@ function XViewScene({
12973
13293
  },
12974
13294
  [save_view_data, delete_file_action]
12975
13295
  );
12976
- const handleOpenAncestryBoard = (0, import_react25.useCallback)(() => {
13296
+ const handleOpenAncestryBoard = (0, import_react26.useCallback)(() => {
12977
13297
  setIsAncestryBoardOpen(true);
12978
13298
  }, []);
12979
- const handleSelectAncestryFromBoard = (0, import_react25.useCallback)((ancestry) => {
13299
+ const handleSelectAncestryFromBoard = (0, import_react26.useCallback)((ancestry) => {
12980
13300
  setIsAncestryBoardOpen(false);
12981
13301
  setIsSidebarOpen(false);
12982
13302
  handleStartReadingAncestry(ancestry);
12983
13303
  }, [handleStartReadingAncestry]);
12984
- const handleSaveAncestryBoard = (0, import_react25.useCallback)(async (groups) => {
13304
+ const handleSaveAncestryBoard = (0, import_react26.useCallback)(async (groups) => {
12985
13305
  if (!sceneConfigId || !viewParams || !session) return;
12986
13306
  const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
12987
13307
  await save_ancestry_board_action(sceneConfigId, sceneType, groups, session, ownerId);
12988
13308
  }, [sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]);
12989
- const existingNodeTypes = (0, import_react25.useMemo)(() => {
13309
+ const existingNodeTypes = (0, import_react26.useMemo)(() => {
12990
13310
  if (!parentDataRef.current) {
12991
13311
  return [];
12992
13312
  }
@@ -12996,7 +13316,7 @@ function XViewScene({
12996
13316
  })).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
12997
13317
  return [...new Set(allTypes)];
12998
13318
  }, [parentDataRef.current, sceneVersion]);
12999
- const searchableDbNodes = (0, import_react25.useMemo)(() => {
13319
+ const searchableDbNodes = (0, import_react26.useMemo)(() => {
13000
13320
  if (!parentDataRef.current) {
13001
13321
  return [];
13002
13322
  }
@@ -13005,13 +13325,13 @@ function XViewScene({
13005
13325
  return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
13006
13326
  });
13007
13327
  }, [parentDataRef.current, sceneVersion]);
13008
- const handleAddExistingNode = (0, import_react25.useCallback)(
13328
+ const handleAddExistingNode = (0, import_react26.useCallback)(
13009
13329
  (nodeId) => {
13010
13330
  return userActionHandlers.handleAddExistingNodeById(actionHandlerContext, nodeId);
13011
13331
  },
13012
13332
  [actionHandlerContext]
13013
13333
  );
13014
- const handleSaveCurrentView = (0, import_react25.useCallback)(async () => {
13334
+ const handleSaveCurrentView = (0, import_react26.useCallback)(async () => {
13015
13335
  var _a2, _b2, _c2;
13016
13336
  const { nodeObjects, allLinks } = stateRef.current;
13017
13337
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
@@ -13050,14 +13370,14 @@ function XViewScene({
13050
13370
  console.error("Erro na chamada de save_view_data:", error);
13051
13371
  }
13052
13372
  }, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
13053
- const allAvailableNodes = (0, import_react25.useMemo)(() => {
13373
+ const allAvailableNodes = (0, import_react26.useMemo)(() => {
13054
13374
  if (!parentDataRef.current) return [];
13055
13375
  return Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
13056
13376
  }, [sceneVersion, isInitialized]);
13057
- const allAvailableAncestries = (0, import_react25.useMemo)(() => {
13377
+ const allAvailableAncestries = (0, import_react26.useMemo)(() => {
13058
13378
  return ancestryDataRef.current || [];
13059
13379
  }, [sceneVersion, isInitialized]);
13060
- const handleOpenReference = (0, import_react25.useCallback)((referenceData) => {
13380
+ const handleOpenReference = (0, import_react26.useCallback)((referenceData) => {
13061
13381
  const { type, id } = referenceData;
13062
13382
  if (type === "node") {
13063
13383
  const targetNode = allAvailableNodes.find((n) => String(n.id) === String(id));
@@ -13084,17 +13404,17 @@ function XViewScene({
13084
13404
  }
13085
13405
  }
13086
13406
  }, [allAvailableNodes, allAvailableAncestries, handleEditAncestry, tweenToTarget]);
13087
- const handleToggleAncestryAddMode = (0, import_react25.useCallback)(() => {
13407
+ const handleToggleAncestryAddMode = (0, import_react26.useCallback)(() => {
13088
13408
  setAncestryMode((prev) => ({ ...prev, isAddingNodes: !prev.isAddingNodes }));
13089
13409
  }, []);
13090
- const handleFocusNode = (0, import_react25.useCallback)((nodeData) => {
13410
+ const handleFocusNode = (0, import_react26.useCallback)((nodeData) => {
13091
13411
  if (!nodeData) return;
13092
13412
  const nodeMesh = stateRef.current.nodeObjects[String(nodeData.id)];
13093
13413
  if (nodeMesh) {
13094
13414
  tweenToTarget(nodeMesh, 1.2);
13095
13415
  }
13096
13416
  }, [tweenToTarget]);
13097
- const availableDatasets = (0, import_react25.useMemo)(() => {
13417
+ const availableDatasets = (0, import_react26.useMemo)(() => {
13098
13418
  if (!sceneDataRef.current || !parentDataRef.current) return [];
13099
13419
  return sceneDataRef.current.parent_dbs.map((db) => {
13100
13420
  var _a2;
@@ -13106,7 +13426,7 @@ function XViewScene({
13106
13426
  }, [sceneVersion, isInitialized]);
13107
13427
  const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
13108
13428
  const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
13109
- (0, import_react25.useEffect)(() => {
13429
+ (0, import_react26.useEffect)(() => {
13110
13430
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
13111
13431
  const nodeObjects = stateRef.current.nodeObjects || {};
13112
13432
  const targetMesh = nodeObjects[String(focusNodeId)];
@@ -13120,7 +13440,7 @@ function XViewScene({
13120
13440
  }
13121
13441
  }
13122
13442
  }, [isInitialized, sceneVersion, focusNodeId, hasFocusedInitial, tweenToTarget]);
13123
- (0, import_react25.useEffect)(() => {
13443
+ (0, import_react26.useEffect)(() => {
13124
13444
  if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
13125
13445
  const ancestries = ancestryDataRef.current || [];
13126
13446
  const targetAncestry = ancestries.find((a) => String(a.ancestry_id) === String(focusAncestryId));
@@ -13134,7 +13454,7 @@ function XViewScene({
13134
13454
  }
13135
13455
  }
13136
13456
  }, [isInitialized, sceneVersion, focusAncestryId, hasOpenedInitialAncestry, handleStartReadingAncestry]);
13137
- (0, import_react25.useEffect)(() => {
13457
+ (0, import_react26.useEffect)(() => {
13138
13458
  function handleKeyDown(event) {
13139
13459
  var _a2, _b2, _c2;
13140
13460
  const context = actionHandlerContext;
@@ -13235,20 +13555,20 @@ function XViewScene({
13235
13555
  // <-- handleCancelQuest adicionado aqui
13236
13556
  ]);
13237
13557
  if (isLoading || status === "loading" || permissionStatus === "loading") {
13238
- return /* @__PURE__ */ import_react25.default.createElement(LoadingScreen, null);
13558
+ return /* @__PURE__ */ import_react26.default.createElement(LoadingScreen, null);
13239
13559
  }
13240
13560
  if (permissionStatus === "denied") {
13241
- return /* @__PURE__ */ import_react25.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ import_react25.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react25.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "w-16 h-16 mx-auto" }, /* @__PURE__ */ import_react25.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" }))), /* @__PURE__ */ import_react25.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react25.default.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ import_react25.default.createElement(
13561
+ return /* @__PURE__ */ import_react26.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react26.default.createElement("div", { className: "bg-slate-900/50 p-8 rounded-2xl border border-slate-800 shadow-2xl text-center max-w-md" }, /* @__PURE__ */ import_react26.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react26.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", className: "w-16 h-16 mx-auto" }, /* @__PURE__ */ import_react26.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" }))), /* @__PURE__ */ import_react26.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react26.default.createElement("p", { className: "text-slate-400 mb-6" }, "Voc\xEA n\xE3o tem permiss\xE3o para acessar este conte\xFAdo. Solicite acesso ao propriet\xE1rio ou verifique se est\xE1 na conta correta."), /* @__PURE__ */ import_react26.default.createElement(
13242
13562
  "button",
13243
13563
  {
13244
13564
  onClick: () => router.push("/dashboard/scenes"),
13245
13565
  className: "flex items-center justify-center gap-2 w-full py-3 px-4 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors font-medium"
13246
13566
  },
13247
- /* @__PURE__ */ import_react25.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 2, stroke: "currentColor", className: "w-5 h-5" }, /* @__PURE__ */ import_react25.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
13567
+ /* @__PURE__ */ import_react26.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", strokeWidth: 2, stroke: "currentColor", className: "w-5 h-5" }, /* @__PURE__ */ import_react26.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" })),
13248
13568
  "Voltar para Scenes"
13249
13569
  )));
13250
13570
  }
13251
- return /* @__PURE__ */ import_react25.default.createElement(
13571
+ return /* @__PURE__ */ import_react26.default.createElement(
13252
13572
  "div",
13253
13573
  {
13254
13574
  ref: mountRef,
@@ -13260,7 +13580,7 @@ function XViewScene({
13260
13580
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
13261
13581
  }
13262
13582
  },
13263
- userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react25.default.createElement(
13583
+ userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react26.default.createElement(
13264
13584
  XViewSidebar,
13265
13585
  {
13266
13586
  dbNodes: searchableDbNodes,
@@ -13280,7 +13600,7 @@ function XViewScene({
13280
13600
  userRole: userPermissionRole
13281
13601
  }
13282
13602
  ),
13283
- creationMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
13603
+ creationMode.isActive && /* @__PURE__ */ import_react26.default.createElement(
13284
13604
  InSceneCreationForm,
13285
13605
  {
13286
13606
  onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
@@ -13305,7 +13625,7 @@ function XViewScene({
13305
13625
  availableAncestries: allAvailableAncestries
13306
13626
  }
13307
13627
  ),
13308
- versionMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
13628
+ versionMode.isActive && /* @__PURE__ */ import_react26.default.createElement(
13309
13629
  InSceneVersionForm,
13310
13630
  {
13311
13631
  onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
@@ -13324,7 +13644,7 @@ function XViewScene({
13324
13644
  availableAncestries: allAvailableAncestries
13325
13645
  }
13326
13646
  ),
13327
- questMode.isActive && /* @__PURE__ */ import_react25.default.createElement(
13647
+ questMode.isActive && /* @__PURE__ */ import_react26.default.createElement(
13328
13648
  InSceneQuestForm,
13329
13649
  {
13330
13650
  onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
@@ -13341,13 +13661,13 @@ function XViewScene({
13341
13661
  availableAncestries: allAvailableAncestries
13342
13662
  }
13343
13663
  ),
13344
- readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react25.default.createElement(
13664
+ readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react26.default.createElement(
13345
13665
  "div",
13346
13666
  {
13347
13667
  className: `ui-overlay absolute group rounded-2xl border border-white/10 bg-slate-950/70 backdrop-blur-xl shadow-[0_20px_80px_rgba(0,0,0,0.6)] ring-1 ring-white/10 text-white overflow-hidden flex flex-col ${isReadModeResizing ? "transition-none" : "transition-all duration-300 ease-out"}`,
13348
13668
  style: { top: 16, right: 16, zIndex: 1100, maxHeight: "calc(100vh - 32px)", width: `${readModeWidth}px`, maxWidth: "92vw" }
13349
13669
  },
13350
- /* @__PURE__ */ import_react25.default.createElement(
13670
+ /* @__PURE__ */ import_react26.default.createElement(
13351
13671
  "div",
13352
13672
  {
13353
13673
  onPointerDown: (e) => {
@@ -13358,7 +13678,7 @@ function XViewScene({
13358
13678
  title: "Arraste para redimensionar"
13359
13679
  }
13360
13680
  ),
13361
- /* @__PURE__ */ import_react25.default.createElement(
13681
+ /* @__PURE__ */ import_react26.default.createElement(
13362
13682
  DescriptionReadModePanel,
13363
13683
  {
13364
13684
  key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
@@ -13393,7 +13713,7 @@ function XViewScene({
13393
13713
  }
13394
13714
  )
13395
13715
  ),
13396
- ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react25.default.createElement(
13716
+ ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react26.default.createElement(
13397
13717
  CreateAncestryPanel,
13398
13718
  {
13399
13719
  ancestryMode,
@@ -13420,7 +13740,7 @@ function XViewScene({
13420
13740
  onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
13421
13741
  }
13422
13742
  ),
13423
- editingAncestryRel.visible && /* @__PURE__ */ import_react25.default.createElement(
13743
+ editingAncestryRel.visible && /* @__PURE__ */ import_react26.default.createElement(
13424
13744
  AncestryRelationshipPanel,
13425
13745
  {
13426
13746
  data: editingAncestryRel.data,
@@ -13434,7 +13754,28 @@ function XViewScene({
13434
13754
  onUploadFile: upload_file_action
13435
13755
  }
13436
13756
  ),
13437
- detailsNode && /* @__PURE__ */ import_react25.default.createElement(
13757
+ detailsNode && detailsNode.is_quest && /* @__PURE__ */ import_react26.default.createElement(
13758
+ QuestDetailsPanel,
13759
+ {
13760
+ node: detailsNode,
13761
+ onClose: () => setDetailsNode(null),
13762
+ onSave: (data) => userActionHandlers.handleSaveNodeDetails(actionHandlerContext, data),
13763
+ onNameChange: handleDetailNodeNameChange,
13764
+ onColorChange: handleDetailNodeColorChange,
13765
+ onSizeChange: handleDetailNodeSizeChange,
13766
+ onDataUpdate: setDetailsNode,
13767
+ onOpenImageViewer: handleOpenImageViewer,
13768
+ existingTypes: existingNodeTypes,
13769
+ availableNodes: allAvailableNodes,
13770
+ availableAncestries: allAvailableAncestries,
13771
+ onOpenReference: handleOpenReference,
13772
+ onMentionClick: handleAddExistingNode,
13773
+ onUploadFile: upload_file_action,
13774
+ userRole: userPermissionRole,
13775
+ currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
13776
+ }
13777
+ ),
13778
+ detailsNode && !detailsNode.is_quest && /* @__PURE__ */ import_react26.default.createElement(
13438
13779
  NodeDetailsPanel,
13439
13780
  {
13440
13781
  node: detailsNode,
@@ -13461,7 +13802,7 @@ function XViewScene({
13461
13802
  currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
13462
13803
  }
13463
13804
  ),
13464
- detailsLink && /* @__PURE__ */ import_react25.default.createElement(
13805
+ detailsLink && /* @__PURE__ */ import_react26.default.createElement(
13465
13806
  RelationshipDetailsPanel,
13466
13807
  {
13467
13808
  link: detailsLink,
@@ -13475,7 +13816,7 @@ function XViewScene({
13475
13816
  userRole: userPermissionRole
13476
13817
  }
13477
13818
  ),
13478
- ancestryLinkDetails && /* @__PURE__ */ import_react25.default.createElement(
13819
+ ancestryLinkDetails && /* @__PURE__ */ import_react26.default.createElement(
13479
13820
  AncestryLinkDetailsPanel,
13480
13821
  {
13481
13822
  data: ancestryLinkDetails,
@@ -13486,7 +13827,7 @@ function XViewScene({
13486
13827
  onUploadFile: upload_file_action
13487
13828
  }
13488
13829
  ),
13489
- /* @__PURE__ */ import_react25.default.createElement(
13830
+ /* @__PURE__ */ import_react26.default.createElement(
13490
13831
  "div",
13491
13832
  {
13492
13833
  ref: tooltipRef,
@@ -13513,7 +13854,7 @@ function XViewScene({
13513
13854
  }
13514
13855
  }
13515
13856
  ),
13516
- /* @__PURE__ */ import_react25.default.createElement(
13857
+ /* @__PURE__ */ import_react26.default.createElement(
13517
13858
  ContextMenu,
13518
13859
  {
13519
13860
  data: contextMenu,
@@ -13536,7 +13877,7 @@ function XViewScene({
13536
13877
  onFocusNode: handleFocusNode
13537
13878
  }
13538
13879
  ),
13539
- /* @__PURE__ */ import_react25.default.createElement(
13880
+ /* @__PURE__ */ import_react26.default.createElement(
13540
13881
  MultiNodeContextMenu,
13541
13882
  {
13542
13883
  data: multiContextMenu,
@@ -13547,7 +13888,7 @@ function XViewScene({
13547
13888
  onDeleteNodes: (ids) => userActionHandlers.handleDeleteMultipleNodes(actionHandlerContext, ids)
13548
13889
  }
13549
13890
  ),
13550
- /* @__PURE__ */ import_react25.default.createElement(
13891
+ /* @__PURE__ */ import_react26.default.createElement(
13551
13892
  RelationshipContextMenu,
13552
13893
  {
13553
13894
  data: relationshipMenu,
@@ -13565,8 +13906,8 @@ function XViewScene({
13565
13906
  onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
13566
13907
  }
13567
13908
  ),
13568
- /* @__PURE__ */ import_react25.default.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
13569
- /* @__PURE__ */ import_react25.default.createElement(
13909
+ /* @__PURE__ */ import_react26.default.createElement(ImageViewer, { data: imageViewer, onClose: () => setImageViewer({ ...imageViewer, visible: false }) }),
13910
+ /* @__PURE__ */ import_react26.default.createElement(
13570
13911
  AncestryBoard,
13571
13912
  {
13572
13913
  isOpen: isAncestryBoardOpen,
@@ -13579,7 +13920,7 @@ function XViewScene({
13579
13920
  userRole: userPermissionRole
13580
13921
  }
13581
13922
  ),
13582
- /* @__PURE__ */ import_react25.default.createElement(
13923
+ /* @__PURE__ */ import_react26.default.createElement(
13583
13924
  ImportParentFileModal,
13584
13925
  {
13585
13926
  isOpen: isImportModalOpen,