@lv-x-software-house/x_view 1.2.5 → 1.2.6-dev.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -44,9 +44,9 @@ __export(index_exports, {
44
44
  module.exports = __toCommonJS(index_exports);
45
45
 
46
46
  // src/XViewScene.jsx
47
- var import_react29 = __toESM(require("react"));
47
+ var import_react31 = __toESM(require("react"));
48
48
  var import_navigation = require("next/navigation");
49
- var import_react30 = require("next-auth/react");
49
+ var import_react32 = require("next-auth/react");
50
50
  var import_crypto_js = __toESM(require("crypto-js"));
51
51
  var THREE3 = __toESM(require("three"));
52
52
  var import_OrbitControls = require("three/examples/jsm/controls/OrbitControls.js");
@@ -118,55 +118,7 @@ function defineAbilityFor(role) {
118
118
 
119
119
  // src/logic/x_view_utils.js
120
120
  var import_react = require("react");
121
-
122
- // node_modules/uuid/dist/esm-node/rng.js
123
- var import_crypto = __toESM(require("crypto"));
124
- var rnds8Pool = new Uint8Array(256);
125
- var poolPtr = rnds8Pool.length;
126
- function rng() {
127
- if (poolPtr > rnds8Pool.length - 16) {
128
- import_crypto.default.randomFillSync(rnds8Pool);
129
- poolPtr = 0;
130
- }
131
- return rnds8Pool.slice(poolPtr, poolPtr += 16);
132
- }
133
-
134
- // node_modules/uuid/dist/esm-node/stringify.js
135
- var byteToHex = [];
136
- for (let i = 0; i < 256; ++i) {
137
- byteToHex.push((i + 256).toString(16).slice(1));
138
- }
139
- function unsafeStringify(arr, offset = 0) {
140
- return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
141
- }
142
-
143
- // node_modules/uuid/dist/esm-node/native.js
144
- var import_crypto2 = __toESM(require("crypto"));
145
- var native_default = {
146
- randomUUID: import_crypto2.default.randomUUID
147
- };
148
-
149
- // node_modules/uuid/dist/esm-node/v4.js
150
- function v4(options, buf, offset) {
151
- if (native_default.randomUUID && !buf && !options) {
152
- return native_default.randomUUID();
153
- }
154
- options = options || {};
155
- const rnds = options.random || (options.rng || rng)();
156
- rnds[6] = rnds[6] & 15 | 64;
157
- rnds[8] = rnds[8] & 63 | 128;
158
- if (buf) {
159
- offset = offset || 0;
160
- for (let i = 0; i < 16; ++i) {
161
- buf[offset + i] = rnds[i];
162
- }
163
- return buf;
164
- }
165
- return unsafeStringify(rnds);
166
- }
167
- var v4_default = v4;
168
-
169
- // src/logic/x_view_utils.js
121
+ var import_uuid = require("uuid");
170
122
  var THREE2 = __toESM(require("three"));
171
123
 
172
124
  // src/logic/x_view_config.js
@@ -1140,6 +1092,8 @@ var userActionHandlers = {
1140
1092
  if (isCrossDataset) {
1141
1093
  graphDataRef.current[finalTargetDatasetId] = targetDataToUpdate;
1142
1094
  }
1095
+ if (sceneDataRef.current.parent_dbs.some((db) => String(db.db_id) === String(sourceParentInfo.parentFileId))) {
1096
+ }
1143
1097
  const finalPosition = stateRef.current.ghostElements.node.position.clone();
1144
1098
  addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
1145
1099
  stateRef.current.nodeIdToParentFileMap.set(String(newNode.id), {
@@ -1338,6 +1292,9 @@ var userActionHandlers = {
1338
1292
  );
1339
1293
  }
1340
1294
  graphDataRef.current[parentFileId] = specificParentData;
1295
+ if (isView && parentFileId === context.sceneConfigId) {
1296
+ sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
1297
+ }
1341
1298
  const finalPosition = stateRef.current.ghostElements.node.position.clone();
1342
1299
  addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
1343
1300
  setters.setSceneVersion((v) => v + 1);
@@ -2369,6 +2326,10 @@ var userActionHandlers = {
2369
2326
  );
2370
2327
  }
2371
2328
  graphDataRef.current[parentFileId] = specificParentData;
2329
+ if (isView && parentFileId === context.sceneConfigId) {
2330
+ sceneDataRef.current.quest_nodes = [...specificParentData.nodes];
2331
+ sceneDataRef.current.quest_counter = specificParentData.quest_counter || sceneDataRef.current.quest_counter;
2332
+ }
2372
2333
  updateExistingNodeVisuals(stateRef.current, nodeToSave);
2373
2334
  setters.setSceneVersion((v) => v + 1);
2374
2335
  if (!keepOpen) {
@@ -2517,15 +2478,15 @@ function createNewCustomProperty(existingProps = []) {
2517
2478
  switch (nextType) {
2518
2479
  case "links":
2519
2480
  nextKey = "Links";
2520
- nextValue = [{ id: v4_default(), name: "", value: "" }];
2481
+ nextValue = [{ id: (0, import_uuid.v4)(), name: "", value: "" }];
2521
2482
  break;
2522
2483
  case "images":
2523
2484
  nextKey = "Images";
2524
- nextValue = [{ id: v4_default(), name: "1", value: "" }];
2485
+ nextValue = [{ id: (0, import_uuid.v4)(), name: "1", value: "" }];
2525
2486
  break;
2526
2487
  case "documents":
2527
2488
  nextKey = "Documents";
2528
- nextValue = [{ id: v4_default(), name: "1", value: "" }];
2489
+ nextValue = [{ id: (0, import_uuid.v4)(), name: "1", value: "" }];
2529
2490
  break;
2530
2491
  case "date":
2531
2492
  nextKey = "Date";
@@ -2535,14 +2496,14 @@ function createNewCustomProperty(existingProps = []) {
2535
2496
  nextValue = 0;
2536
2497
  break;
2537
2498
  case "list":
2538
- nextValue = [{ id: v4_default(), name: "", value: "" }];
2499
+ nextValue = [{ id: (0, import_uuid.v4)(), name: "", value: "" }];
2539
2500
  break;
2540
2501
  default:
2541
2502
  nextValue = "";
2542
2503
  break;
2543
2504
  }
2544
2505
  return {
2545
- id: v4_default(),
2506
+ id: (0, import_uuid.v4)(),
2546
2507
  key: nextKey,
2547
2508
  type: nextType,
2548
2509
  value: nextValue,
@@ -2787,7 +2748,7 @@ function extractCustomPropsFromNode(node) {
2787
2748
  if (val && typeof val === "object") {
2788
2749
  if ("date_interval" in val) {
2789
2750
  return {
2790
- id: v4_default(),
2751
+ id: (0, import_uuid.v4)(),
2791
2752
  key,
2792
2753
  type: "date",
2793
2754
  value: {
@@ -2799,7 +2760,7 @@ function extractCustomPropsFromNode(node) {
2799
2760
  }
2800
2761
  if ("year" in val) {
2801
2762
  return {
2802
- id: v4_default(),
2763
+ id: (0, import_uuid.v4)(),
2803
2764
  key,
2804
2765
  type: "date",
2805
2766
  value: { type: "Ano", value: val.year || "" }
@@ -2807,7 +2768,7 @@ function extractCustomPropsFromNode(node) {
2807
2768
  }
2808
2769
  if ("date" in val) {
2809
2770
  return {
2810
- id: v4_default(),
2771
+ id: (0, import_uuid.v4)(),
2811
2772
  key,
2812
2773
  type: "date",
2813
2774
  value: { type: "Data", value: val.date || "" }
@@ -2815,7 +2776,7 @@ function extractCustomPropsFromNode(node) {
2815
2776
  }
2816
2777
  }
2817
2778
  return {
2818
- id: v4_default(),
2779
+ id: (0, import_uuid.v4)(),
2819
2780
  key,
2820
2781
  type: "date",
2821
2782
  value: { type: "Data", value: "" }
@@ -2823,14 +2784,14 @@ function extractCustomPropsFromNode(node) {
2823
2784
  }
2824
2785
  if (t === "list" || t === "links" || t === "images" || t === "documents") {
2825
2786
  const safeList = (val || []).map((item) => ({
2826
- id: item.id || v4_default(),
2787
+ id: item.id || (0, import_uuid.v4)(),
2827
2788
  name: item.name ?? "",
2828
2789
  value: item.value ?? ""
2829
2790
  }));
2830
- return { id: v4_default(), key, type: t, value: safeList };
2791
+ return { id: (0, import_uuid.v4)(), key, type: t, value: safeList };
2831
2792
  }
2832
2793
  return {
2833
- id: v4_default(),
2794
+ id: (0, import_uuid.v4)(),
2834
2795
  key,
2835
2796
  type: t,
2836
2797
  value: t === "number" ? Number(val) || 0 : String(val ?? "")
@@ -3103,16 +3064,16 @@ var processDescriptionForSave = (text, existingSections = []) => {
3103
3064
  if (existingMatch) {
3104
3065
  finalUuid = existingMatch.id;
3105
3066
  } else {
3106
- finalUuid = v4_default();
3067
+ finalUuid = (0, import_uuid.v4)();
3107
3068
  }
3108
3069
  } else {
3109
3070
  finalUuid = numericMap.get(numStr);
3110
3071
  if (!finalUuid) {
3111
- finalUuid = v4_default();
3072
+ finalUuid = (0, import_uuid.v4)();
3112
3073
  }
3113
3074
  }
3114
3075
  if (usedIds.has(finalUuid)) {
3115
- finalUuid = v4_default();
3076
+ finalUuid = (0, import_uuid.v4)();
3116
3077
  }
3117
3078
  usedIds.add(finalUuid);
3118
3079
  processedSections.push({
@@ -3223,18 +3184,18 @@ function useResizablePanel({ initialWidth, minWidth, maxWidth }) {
3223
3184
  function createTimelineEntry(actorId, description, type = "comment", extras = {}) {
3224
3185
  const { links = [], images = [], metadata = {} } = extras;
3225
3186
  return {
3226
- id: v4_default(),
3187
+ id: (0, import_uuid.v4)(),
3227
3188
  type,
3228
3189
  timestamp: Date.now(),
3229
3190
  actorId,
3230
3191
  description,
3231
3192
  links: links.map((l) => ({
3232
- id: l.id || v4_default(),
3193
+ id: l.id || (0, import_uuid.v4)(),
3233
3194
  name: l.name || "",
3234
3195
  value: l.value || ""
3235
3196
  })),
3236
3197
  images: images.map((img) => ({
3237
- id: img.id || v4_default(),
3198
+ id: img.id || (0, import_uuid.v4)(),
3238
3199
  name: img.name || "",
3239
3200
  value: img.value || ""
3240
3201
  }))
@@ -4461,6 +4422,7 @@ function XViewSidebar({
4461
4422
 
4462
4423
  // src/components/AncestryRelationshipPanel.jsx
4463
4424
  var import_react9 = __toESM(require("react"));
4425
+ var import_uuid3 = require("uuid");
4464
4426
 
4465
4427
  // src/components/CustomPropertyDisplay.jsx
4466
4428
  var import_react4 = __toESM(require("react"));
@@ -5220,6 +5182,7 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
5220
5182
  }
5221
5183
 
5222
5184
  // src/components/DescriptionEditModal.jsx
5185
+ var import_uuid2 = require("uuid");
5223
5186
  var getNextSectionNumber = (currentText) => {
5224
5187
  const regex = /\*\/\s*(\d+)(?::[a-zA-Z0-9-]+)?\s*\//g;
5225
5188
  let max = 0;
@@ -5351,7 +5314,7 @@ function DescriptionEditModal({
5351
5314
  const el = textareaRef.current;
5352
5315
  if (!el) return;
5353
5316
  const nextNum = getNextSectionNumber(text);
5354
- const uniqueSuffix = v4_default().slice(0, 4);
5317
+ const uniqueSuffix = (0, import_uuid2.v4)().slice(0, 4);
5355
5318
  insertAtCursor(`*/${nextNum}:${uniqueSuffix}/ `);
5356
5319
  };
5357
5320
  const handleImportSelect = (tags) => {
@@ -5362,7 +5325,7 @@ function DescriptionEditModal({
5362
5325
  let currentNum = getNextSectionNumber(currentText);
5363
5326
  let blockToInsert = "";
5364
5327
  tagsArray.forEach((tag) => {
5365
- const uniqueSuffix = v4_default().slice(0, 4);
5328
+ const uniqueSuffix = (0, import_uuid2.v4)().slice(0, 4);
5366
5329
  blockToInsert += `
5367
5330
  */${currentNum}:${uniqueSuffix}/ ${tag}
5368
5331
  `;
@@ -6691,6 +6654,7 @@ function AncestryRelationshipPanel({
6691
6654
  // src/components/CreateAncestryPanel.jsx
6692
6655
  var import_react11 = __toESM(require("react"));
6693
6656
  var import_fi10 = require("react-icons/fi");
6657
+ var import_uuid4 = require("uuid");
6694
6658
 
6695
6659
  // src/components/AncestryPickerModal.jsx
6696
6660
  var import_react10 = __toESM(require("react"));
@@ -7727,7 +7691,7 @@ function CreateAncestryPanel({
7727
7691
  const nodeData = availableNodes.find((n) => String(n.id) === String(nodeId));
7728
7692
  const dirSuffix = direction === "left" ? "(Esq)" : "(Dir)";
7729
7693
  branch = {
7730
- id: v4_default(),
7694
+ id: (0, import_uuid4.v4)(),
7731
7695
  name: `Ramifica\xE7\xE3o ${dirSuffix} de ${(nodeData == null ? void 0 : nodeData.name) || "Node"}`,
7732
7696
  description: "",
7733
7697
  description_sections: [],
@@ -8506,6 +8470,7 @@ function ImageViewer({ data, onClose }) {
8506
8470
 
8507
8471
  // src/components/InSceneCreationForm.jsx
8508
8472
  var import_react14 = __toESM(require("react"));
8473
+ var import_uuid5 = require("uuid");
8509
8474
 
8510
8475
  // src/components/ColorPicker.jsx
8511
8476
  var import_react13 = __toESM(require("react"));
@@ -9082,6 +9047,7 @@ function InSceneCreationForm({
9082
9047
 
9083
9048
  // src/components/InSceneVersionForm.jsx
9084
9049
  var import_react15 = __toESM(require("react"));
9050
+ var import_uuid6 = require("uuid");
9085
9051
  var import_fi14 = require("react-icons/fi");
9086
9052
  function InSceneVersionForm({
9087
9053
  onSave,
@@ -9104,7 +9070,7 @@ function InSceneVersionForm({
9104
9070
  const [description, setDescription] = (0, import_react15.useState)("");
9105
9071
  const [customProps, setCustomProps] = (0, import_react15.useState)([
9106
9072
  {
9107
- id: v4_default(),
9073
+ id: (0, import_uuid6.v4)(),
9108
9074
  key: "Date",
9109
9075
  type: "date",
9110
9076
  value: { type: "Data", value: "" },
@@ -9397,6 +9363,7 @@ function InSceneVersionForm({
9397
9363
 
9398
9364
  // src/components/InSceneQuestForm.jsx
9399
9365
  var import_react17 = __toESM(require("react"));
9366
+ var import_uuid7 = require("uuid");
9400
9367
  var import_fi16 = require("react-icons/fi");
9401
9368
 
9402
9369
  // src/components/QuestReviewStackEditor.jsx
@@ -10302,6 +10269,7 @@ function InSceneQuestForm({
10302
10269
 
10303
10270
  // src/components/NodeDetailsPanel.jsx
10304
10271
  var import_react18 = __toESM(require("react"));
10272
+ var import_uuid8 = require("uuid");
10305
10273
  var import_fi17 = require("react-icons/fi");
10306
10274
  function NodeDetailsPanel({
10307
10275
  node,
@@ -10816,6 +10784,7 @@ function NodeDetailsPanel({
10816
10784
 
10817
10785
  // src/components/QuestDetailsPanel.jsx
10818
10786
  var import_react20 = __toESM(require("react"));
10787
+ var import_uuid9 = require("uuid");
10819
10788
  var import_fi19 = require("react-icons/fi");
10820
10789
 
10821
10790
  // src/components/QuestTimeline.jsx
@@ -11254,7 +11223,7 @@ ${noteText}` : noteText : entry.notes,
11254
11223
  }, 100);
11255
11224
  };
11256
11225
  const addLinkToNote = () => {
11257
- setNoteLinks([...noteLinks, { id: v4_default(), name: "", value: "" }]);
11226
+ setNoteLinks([...noteLinks, { id: (0, import_uuid9.v4)(), name: "", value: "" }]);
11258
11227
  };
11259
11228
  const removeLinkFromNote = (id) => {
11260
11229
  setNoteLinks(noteLinks.filter((l) => l.id !== id));
@@ -11263,7 +11232,7 @@ ${noteText}` : noteText : entry.notes,
11263
11232
  setNoteLinks(noteLinks.map((l) => l.id === id ? { ...l, [field]: val } : l));
11264
11233
  };
11265
11234
  const addImageToNote = () => {
11266
- setNoteImages([...noteImages, { id: v4_default(), name: "Image", value: "" }]);
11235
+ setNoteImages([...noteImages, { id: (0, import_uuid9.v4)(), name: "Image", value: "" }]);
11267
11236
  };
11268
11237
  const removeImageFromNote = (id) => {
11269
11238
  setNoteImages(noteImages.filter((img) => img.id !== id));
@@ -12140,6 +12109,7 @@ function MultiNodeContextMenu({
12140
12109
 
12141
12110
  // src/components/RelationshipDetailsPanel.jsx
12142
12111
  var import_react22 = __toESM(require("react"));
12112
+ var import_uuid10 = require("uuid");
12143
12113
  var import_fi20 = require("react-icons/fi");
12144
12114
  function RelationshipDetailsPanel({
12145
12115
  link,
@@ -12949,173 +12919,416 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
12949
12919
  }
12950
12920
 
12951
12921
  // src/components/AncestryBoard.jsx
12922
+ var import_react29 = __toESM(require("react"));
12923
+ var import_fi23 = require("react-icons/fi");
12924
+ var import_uuid11 = require("uuid");
12925
+
12926
+ // src/components/RichGroupEditor.jsx
12927
+ var import_react28 = __toESM(require("react"));
12928
+
12929
+ // src/components/MentionPopover.jsx
12952
12930
  var import_react27 = __toESM(require("react"));
12953
12931
  var import_fi22 = require("react-icons/fi");
12932
+ var TYPE_CONFIG = {
12933
+ ancestry: { Icon: import_fi22.FiLayers, color: "text-indigo-400", label: "Ancestralidade" },
12934
+ quest: { Icon: import_fi22.FiCheckSquare, color: "text-emerald-400", label: "Quest" },
12935
+ version: { Icon: import_fi22.FiGitBranch, color: "text-amber-400", label: "Vers\xE3o" },
12936
+ node: { Icon: import_fi22.FiBox, color: "text-slate-400", label: "Node" }
12937
+ };
12938
+ function MentionPopover({ query, items, position, onSelect, onClose }) {
12939
+ const [activeIndex, setActiveIndex] = (0, import_react27.useState)(0);
12940
+ const listRef = (0, import_react27.useRef)(null);
12941
+ const filtered = (0, import_react27.useMemo)(() => {
12942
+ const term = (query || "").toLowerCase().trim();
12943
+ if (!term) return items.slice(0, 8);
12944
+ return items.filter(
12945
+ (item) => (item.searchLabel || "").toLowerCase().includes(term) || (item.searchDesc || "").toLowerCase().includes(term)
12946
+ ).slice(0, 8);
12947
+ }, [items, query]);
12948
+ (0, import_react27.useEffect)(() => {
12949
+ setActiveIndex(0);
12950
+ }, [query]);
12951
+ (0, import_react27.useEffect)(() => {
12952
+ const handleKeyDown = (e) => {
12953
+ if (e.key === "ArrowDown") {
12954
+ e.preventDefault();
12955
+ setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));
12956
+ } else if (e.key === "ArrowUp") {
12957
+ e.preventDefault();
12958
+ setActiveIndex((i) => Math.max(i - 1, 0));
12959
+ } else if (e.key === "Enter" || e.key === "Tab") {
12960
+ e.preventDefault();
12961
+ if (filtered[activeIndex]) onSelect(filtered[activeIndex]);
12962
+ } else if (e.key === "Escape") {
12963
+ e.preventDefault();
12964
+ onClose();
12965
+ }
12966
+ };
12967
+ window.addEventListener("keydown", handleKeyDown, true);
12968
+ return () => window.removeEventListener("keydown", handleKeyDown, true);
12969
+ }, [filtered, activeIndex, onSelect, onClose]);
12970
+ (0, import_react27.useEffect)(() => {
12971
+ if (listRef.current) {
12972
+ const el = listRef.current.children[activeIndex];
12973
+ if (el) el.scrollIntoView({ block: "nearest" });
12974
+ }
12975
+ }, [activeIndex]);
12976
+ return /* @__PURE__ */ import_react27.default.createElement(
12977
+ "div",
12978
+ {
12979
+ style: { top: position.top, left: position.left, position: "fixed", zIndex: 9999 },
12980
+ className: "bg-slate-900 border border-white/10 rounded-xl shadow-2xl py-1.5 min-w-[260px] max-h-[240px] overflow-y-auto custom-scrollbar animate-in fade-in zoom-in-95 duration-100",
12981
+ ref: listRef,
12982
+ onMouseDown: (e) => e.preventDefault()
12983
+ },
12984
+ filtered.length === 0 ? /* @__PURE__ */ import_react27.default.createElement("div", { className: "px-4 py-3 text-xs text-slate-500" }, "Nenhum resultado para", " ", /* @__PURE__ */ import_react27.default.createElement("span", { className: "text-slate-300 font-medium" }, '"', query, '"')) : filtered.map((item, idx) => {
12985
+ const config = TYPE_CONFIG[item.type] || TYPE_CONFIG.node;
12986
+ const { Icon } = config;
12987
+ return /* @__PURE__ */ import_react27.default.createElement(
12988
+ "div",
12989
+ {
12990
+ key: item.id,
12991
+ onMouseDown: (e) => {
12992
+ e.preventDefault();
12993
+ onSelect(item);
12994
+ },
12995
+ onMouseEnter: () => setActiveIndex(idx),
12996
+ className: `flex items-center gap-2.5 px-3 py-2 cursor-pointer text-sm transition-colors duration-100 ${idx === activeIndex ? "bg-indigo-500/20 text-white" : "text-slate-300 hover:bg-white/5"}`
12997
+ },
12998
+ /* @__PURE__ */ import_react27.default.createElement(Icon, { size: 13, className: config.color }),
12999
+ /* @__PURE__ */ import_react27.default.createElement("span", { className: "flex-1 truncate font-medium" }, item.searchLabel || "Sem Nome"),
13000
+ /* @__PURE__ */ import_react27.default.createElement("span", { className: "text-[9px] px-1.5 py-0.5 rounded-full bg-white/5 text-slate-500 border border-white/5 uppercase tracking-wide shrink-0" }, config.label)
13001
+ );
13002
+ })
13003
+ );
13004
+ }
13005
+
13006
+ // src/components/RichGroupEditor.jsx
13007
+ var MENTION_BASE_STYLE = "display:inline-flex;align-items:center;padding:1px 7px;border-radius:5px;margin:0 2px;font-size:0.78em;font-weight:600;cursor:pointer;white-space:nowrap;vertical-align:middle;user-select:none;line-height:1.6;";
13008
+ var MENTION_TYPE_STYLE = {
13009
+ ancestry: "background:rgba(99,102,241,0.18);color:#a5b4fc;border:1px solid rgba(99,102,241,0.35);",
13010
+ quest: "background:rgba(16,185,129,0.18);color:#6ee7b7;border:1px solid rgba(16,185,129,0.35);",
13011
+ version: "background:rgba(245,158,11,0.18);color:#fcd34d;border:1px solid rgba(245,158,11,0.35);",
13012
+ node: "background:rgba(100,116,139,0.18);color:#94a3b8;border:1px solid rgba(100,116,139,0.35);"
13013
+ };
13014
+ function mentionStyle(type) {
13015
+ return MENTION_BASE_STYLE + (MENTION_TYPE_STYLE[type] || MENTION_TYPE_STYLE.node);
13016
+ }
13017
+ function escapeHtml(str) {
13018
+ return String(str || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
13019
+ }
13020
+ function contentToHTML(content) {
13021
+ if (!content || content.length === 0) return "";
13022
+ return content.map((seg) => {
13023
+ if (seg.type === "text") {
13024
+ return escapeHtml(seg.value).replace(/\n/g, "<br>");
13025
+ }
13026
+ if (seg.type === "mention") {
13027
+ const style = mentionStyle(seg.mentionType);
13028
+ return `<span contenteditable="false" data-mention="true" data-id="${escapeHtml(String(seg.id))}" data-name="${escapeHtml(seg.name || "")}" data-mention-type="${escapeHtml(seg.mentionType || "node")}" style="${style}" title="Clique para focar na cena">@${escapeHtml(seg.name || "")}</span>`;
13029
+ }
13030
+ return "";
13031
+ }).join("");
13032
+ }
13033
+ function domToContent(el) {
13034
+ const segments = [];
13035
+ function pushText(text) {
13036
+ const clean = text.replace(/\u200B/g, "");
13037
+ if (!clean) return;
13038
+ const last = segments[segments.length - 1];
13039
+ if (last && last.type === "text") {
13040
+ last.value += clean;
13041
+ } else {
13042
+ segments.push({ type: "text", value: clean });
13043
+ }
13044
+ }
13045
+ function walk(node) {
13046
+ var _a;
13047
+ if (node.nodeType === Node.TEXT_NODE) {
13048
+ pushText(node.textContent);
13049
+ } else if (node.nodeType === Node.ELEMENT_NODE) {
13050
+ if (((_a = node.dataset) == null ? void 0 : _a.mention) === "true") {
13051
+ segments.push({
13052
+ type: "mention",
13053
+ id: node.dataset.id,
13054
+ name: node.dataset.name,
13055
+ mentionType: node.dataset.mentionType
13056
+ });
13057
+ } else if (node.tagName === "BR") {
13058
+ pushText("\n");
13059
+ } else {
13060
+ if (["DIV", "P"].includes(node.tagName) && segments.length > 0) {
13061
+ pushText("\n");
13062
+ }
13063
+ node.childNodes.forEach(walk);
13064
+ }
13065
+ }
13066
+ }
13067
+ el.childNodes.forEach(walk);
13068
+ return segments;
13069
+ }
13070
+ function RichGroupEditor({
13071
+ content,
13072
+ onChange,
13073
+ onMentionClick,
13074
+ searchItems,
13075
+ readOnly,
13076
+ placeholder
13077
+ }) {
13078
+ const editorRef = (0, import_react28.useRef)(null);
13079
+ const isMountedRef = (0, import_react28.useRef)(false);
13080
+ const [mentionState, setMentionState] = (0, import_react28.useState)(null);
13081
+ const [isEmpty, setIsEmpty] = (0, import_react28.useState)(true);
13082
+ (0, import_react28.useEffect)(() => {
13083
+ if (!isMountedRef.current && editorRef.current) {
13084
+ editorRef.current.innerHTML = contentToHTML(content);
13085
+ const hasContent = !!editorRef.current.innerText.replace(/\u200B/g, "").trim();
13086
+ const hasMentions = !!editorRef.current.querySelector("[data-mention]");
13087
+ setIsEmpty(!hasContent && !hasMentions);
13088
+ isMountedRef.current = true;
13089
+ }
13090
+ }, []);
13091
+ const getMentionContext = (0, import_react28.useCallback)(() => {
13092
+ const selection = window.getSelection();
13093
+ if (!selection || selection.rangeCount === 0) return null;
13094
+ const range = selection.getRangeAt(0);
13095
+ if (range.startContainer.nodeType !== Node.TEXT_NODE) return null;
13096
+ const textBefore = range.startContainer.textContent.substring(0, range.startOffset);
13097
+ const atIndex = textBefore.lastIndexOf("@");
13098
+ if (atIndex === -1) return null;
13099
+ const query = textBefore.substring(atIndex + 1);
13100
+ if (query.includes(" ") || query.includes(".") || query.includes(",") || query.length > 40) {
13101
+ return null;
13102
+ }
13103
+ const rect = range.getBoundingClientRect();
13104
+ return {
13105
+ query,
13106
+ position: { top: rect.bottom + 6, left: rect.left }
13107
+ };
13108
+ }, []);
13109
+ const handleInput = (0, import_react28.useCallback)(() => {
13110
+ if (!editorRef.current) return;
13111
+ const serialized = domToContent(editorRef.current);
13112
+ onChange(serialized);
13113
+ const text = editorRef.current.innerText.replace(/\u200B/g, "").trim();
13114
+ const hasMentions = !!editorRef.current.querySelector("[data-mention]");
13115
+ setIsEmpty(!text && !hasMentions);
13116
+ const ctx = getMentionContext();
13117
+ setMentionState(ctx);
13118
+ }, [onChange, getMentionContext]);
13119
+ const handleKeyDown = (0, import_react28.useCallback)(
13120
+ (e) => {
13121
+ if (mentionState && ["ArrowDown", "ArrowUp", "Enter", "Tab", "Escape"].includes(e.key)) {
13122
+ return;
13123
+ }
13124
+ if (e.key === "Enter") {
13125
+ e.preventDefault();
13126
+ const sel = window.getSelection();
13127
+ const range = sel.getRangeAt(0);
13128
+ const br = document.createElement("br");
13129
+ range.deleteContents();
13130
+ range.insertNode(br);
13131
+ const afterBr = br.nextSibling || (() => {
13132
+ const zws = document.createTextNode("\u200B");
13133
+ br.parentNode.insertBefore(zws, br.nextSibling);
13134
+ return zws;
13135
+ })();
13136
+ const newRange = document.createRange();
13137
+ newRange.setStartBefore(afterBr);
13138
+ newRange.collapse(true);
13139
+ sel.removeAllRanges();
13140
+ sel.addRange(newRange);
13141
+ handleInput();
13142
+ }
13143
+ },
13144
+ [mentionState, handleInput]
13145
+ );
13146
+ const insertMention = (0, import_react28.useCallback)(
13147
+ (item) => {
13148
+ if (!editorRef.current) return;
13149
+ const sel = window.getSelection();
13150
+ if (!sel || sel.rangeCount === 0) return;
13151
+ const range = sel.getRangeAt(0);
13152
+ const textNode = range.startContainer;
13153
+ if (textNode.nodeType !== Node.TEXT_NODE) {
13154
+ setMentionState(null);
13155
+ return;
13156
+ }
13157
+ const cursorPos = range.startOffset;
13158
+ const textContent = textNode.textContent;
13159
+ const atIndex = textContent.lastIndexOf("@", cursorPos - 1);
13160
+ if (atIndex === -1) {
13161
+ setMentionState(null);
13162
+ return;
13163
+ }
13164
+ const before = textContent.substring(0, atIndex);
13165
+ const after = textContent.substring(cursorPos);
13166
+ textNode.textContent = before;
13167
+ const parent = textNode.parentNode;
13168
+ const nextSib = textNode.nextSibling;
13169
+ const span = document.createElement("span");
13170
+ span.contentEditable = "false";
13171
+ span.dataset.mention = "true";
13172
+ span.dataset.id = item.id;
13173
+ span.dataset.name = item.searchLabel || item.name || "";
13174
+ span.dataset.mentionType = item.type;
13175
+ span.style.cssText = mentionStyle(item.type);
13176
+ span.title = "Clique para focar na cena";
13177
+ span.textContent = `@${item.searchLabel || item.name || ""}`;
13178
+ parent.insertBefore(span, nextSib);
13179
+ const trailing = document.createTextNode(after || "\u200B");
13180
+ parent.insertBefore(trailing, span.nextSibling);
13181
+ const newRange = document.createRange();
13182
+ newRange.setStart(trailing, after ? 0 : 1);
13183
+ newRange.collapse(true);
13184
+ sel.removeAllRanges();
13185
+ sel.addRange(newRange);
13186
+ const serialized = domToContent(editorRef.current);
13187
+ onChange(serialized);
13188
+ setMentionState(null);
13189
+ setIsEmpty(false);
13190
+ },
13191
+ [onChange]
13192
+ );
13193
+ const handlePaste = (0, import_react28.useCallback)(
13194
+ (e) => {
13195
+ e.preventDefault();
13196
+ const text = e.clipboardData.getData("text/plain");
13197
+ if (text) {
13198
+ document.execCommand("insertText", false, text);
13199
+ handleInput();
13200
+ }
13201
+ },
13202
+ [handleInput]
13203
+ );
13204
+ const handleClick = (0, import_react28.useCallback)(
13205
+ (e) => {
13206
+ const chip = e.target.closest("[data-mention='true']");
13207
+ if (chip && onMentionClick) {
13208
+ e.stopPropagation();
13209
+ const id = chip.dataset.id;
13210
+ const full = searchItems == null ? void 0 : searchItems.find((i) => String(i.id) === String(id));
13211
+ if (full) {
13212
+ onMentionClick(full);
13213
+ } else {
13214
+ onMentionClick({
13215
+ id,
13216
+ name: chip.dataset.name,
13217
+ type: chip.dataset.mentionType,
13218
+ searchLabel: chip.dataset.name
13219
+ });
13220
+ }
13221
+ return;
13222
+ }
13223
+ setTimeout(() => {
13224
+ const ctx = getMentionContext();
13225
+ setMentionState(ctx);
13226
+ }, 0);
13227
+ },
13228
+ [onMentionClick, getMentionContext, searchItems]
13229
+ );
13230
+ const handleBlur = (0, import_react28.useCallback)(() => {
13231
+ setTimeout(() => setMentionState(null), 200);
13232
+ }, []);
13233
+ return /* @__PURE__ */ import_react28.default.createElement("div", { className: "relative" }, isEmpty && !readOnly && /* @__PURE__ */ import_react28.default.createElement("div", { className: "absolute top-0 left-0 text-sm text-slate-600 pointer-events-none select-none" }, placeholder || "Escreva sobre este grupo\u2026 ou digite @ para mencionar"), /* @__PURE__ */ import_react28.default.createElement(
13234
+ "div",
13235
+ {
13236
+ ref: editorRef,
13237
+ contentEditable: readOnly ? "false" : "true",
13238
+ suppressContentEditableWarning: true,
13239
+ onInput: handleInput,
13240
+ onKeyDown: handleKeyDown,
13241
+ onPaste: handlePaste,
13242
+ onClick: handleClick,
13243
+ onBlur: handleBlur,
13244
+ className: `w-full min-h-[1.5rem] max-h-[250px] overflow-y-auto text-sm text-slate-200 focus:outline-none leading-relaxed ${!readOnly ? "cursor-text" : "cursor-default"}`,
13245
+ style: { overflowWrap: "break-word", wordBreak: "break-word" }
13246
+ }
13247
+ ), mentionState && !readOnly && /* @__PURE__ */ import_react28.default.createElement(
13248
+ MentionPopover,
13249
+ {
13250
+ query: mentionState.query,
13251
+ items: searchItems || [],
13252
+ position: mentionState.position,
13253
+ onSelect: insertMention,
13254
+ onClose: () => setMentionState(null)
13255
+ }
13256
+ ));
13257
+ }
13258
+
13259
+ // src/components/AncestryBoard.jsx
12954
13260
  var GroupItem = ({
12955
13261
  group,
12956
13262
  index,
12957
- siblings,
12958
13263
  onUpdate,
12959
13264
  onDelete,
12960
13265
  onAddSubgroup,
12961
13266
  onIndent,
12962
13267
  onOutdent,
12963
- onRemoveAncestry,
12964
- onRequestPickAncestry,
12965
- pickingGroupId,
12966
- onPlayAncestry,
12967
- availableIds,
13268
+ searchItems,
13269
+ onMentionClick,
12968
13270
  canEdit
12969
13271
  }) => {
12970
13272
  const canIndent = index > 0;
12971
- const isPickingForThisGroup = pickingGroupId === group.id;
12972
- const textareaRef = (0, import_react27.useRef)(null);
12973
- const adjustHeight = () => {
12974
- const textarea = textareaRef.current;
12975
- if (textarea) {
12976
- textarea.style.height = "auto";
12977
- textarea.style.height = `${textarea.scrollHeight}px`;
12978
- }
13273
+ const handleContentChange = (content) => {
13274
+ onUpdate(group.id, { ...group, content });
12979
13275
  };
12980
- (0, import_react27.useEffect)(() => {
12981
- adjustHeight();
12982
- }, [group.text]);
12983
- return /* @__PURE__ */ import_react27.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_react27.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react27.default.createElement(
12984
- "div",
13276
+ return /* @__PURE__ */ import_react29.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_react29.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex flex-col gap-2 py-2 px-3 transition-all duration-200 hover:bg-white/5 border-l-2 border-transparent hover:border-white/20" }, /* @__PURE__ */ import_react29.default.createElement(
13277
+ RichGroupEditor,
12985
13278
  {
12986
- className: `
12987
- flex flex-col gap-2 py-2 px-3 transition-all duration-200
12988
- ${isPickingForThisGroup ? "bg-indigo-500/10 border-l-2 border-indigo-500" : "hover:bg-white/5 border-l-2 border-transparent hover:border-white/20"}
12989
- `
13279
+ content: group.content,
13280
+ onChange: handleContentChange,
13281
+ onMentionClick,
13282
+ searchItems,
13283
+ readOnly: !canEdit,
13284
+ placeholder: "Escreva sobre este grupo\u2026 ou @ para mencionar"
13285
+ }
13286
+ ), canEdit && /* @__PURE__ */ import_react29.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_react29.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react29.default.createElement(
13287
+ "button",
13288
+ {
13289
+ onClick: () => onAddSubgroup(group.id),
13290
+ className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
13291
+ title: "Criar Subgrupo"
12990
13292
  },
12991
- /* @__PURE__ */ import_react27.default.createElement(
12992
- "textarea",
12993
- {
12994
- ref: textareaRef,
12995
- className: `w-full bg-transparent text-sm text-slate-200 placeholder-slate-600 resize-none focus:outline-none focus:placeholder-slate-500 overflow-y-auto ${!canEdit ? "cursor-default" : ""}`,
12996
- rows: 1,
12997
- style: {
12998
- minHeight: "1.5rem",
12999
- maxHeight: "250px"
13000
- },
13001
- placeholder: canEdit ? "Escreva sobre este grupo..." : "",
13002
- value: group.text,
13003
- readOnly: !canEdit,
13004
- onChange: (e) => {
13005
- if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
13006
- }
13007
- }
13008
- ),
13009
- group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
13010
- const isValid = availableIds.has(String(anc.ancestry_id));
13011
- return /* @__PURE__ */ import_react27.default.createElement(
13012
- "div",
13013
- {
13014
- key: anc.ancestry_id,
13015
- className: `
13016
- flex items-center gap-2 rounded-md px-3 py-1.5 text-xs transition-all group/card border
13017
- ${isValid ? "bg-slate-800/60 border-white/10 hover:border-indigo-500/30 text-slate-200" : "bg-red-900/10 border-red-500/30 text-red-300/70 hover:bg-red-900/20"}
13018
- `,
13019
- title: isValid ? "" : "Esta ancestralidade foi removida ou n\xE3o existe mais."
13020
- },
13021
- isValid ? (
13022
- // [MANTIDO] Botão Play visível para todos
13023
- /* @__PURE__ */ import_react27.default.createElement(
13024
- "button",
13025
- {
13026
- onClick: () => onPlayAncestry(anc.ancestry_id),
13027
- className: "text-indigo-400 hover:text-white hover:bg-indigo-500 p-1 rounded-full transition-colors",
13028
- title: "Renderizar no cen\xE1rio"
13029
- },
13030
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiPlay, { size: 10, className: "ml-0.5 fill-current" })
13031
- )
13032
- ) : /* @__PURE__ */ import_react27.default.createElement("div", { className: "p-1 text-red-500 cursor-not-allowed" }, /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiAlertTriangle, { size: 10 })),
13033
- /* @__PURE__ */ import_react27.default.createElement(
13034
- "span",
13035
- {
13036
- className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}`
13037
- },
13038
- anc.name
13039
- ),
13040
- canEdit && /* @__PURE__ */ import_react27.default.createElement(import_react27.default.Fragment, null, /* @__PURE__ */ import_react27.default.createElement(
13041
- "div",
13042
- {
13043
- className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}`
13044
- }
13045
- ), /* @__PURE__ */ import_react27.default.createElement(
13046
- "button",
13047
- {
13048
- onClick: () => onRemoveAncestry(group.id, anc.ancestry_id),
13049
- className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
13050
- title: "Remover men\xE7\xE3o"
13051
- },
13052
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiX, { size: 12 })
13053
- ))
13054
- );
13055
- })),
13056
- canEdit && /* @__PURE__ */ import_react27.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_react27.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react27.default.createElement(
13057
- "button",
13058
- {
13059
- onClick: () => onRequestPickAncestry(group.id),
13060
- className: `
13061
- flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium transition-colors
13062
- ${isPickingForThisGroup ? "text-indigo-300 animate-pulse" : "text-slate-500 hover:text-indigo-300 hover:bg-indigo-500/10"}
13063
- `,
13064
- title: "Adicionar Ancestralidade a este grupo"
13065
- },
13066
- isPickingForThisGroup ? /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiCheckCircle, { size: 12 }) : /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiSearch, { size: 12 }),
13067
- isPickingForThisGroup ? "Selecionando..." : "Adicionar"
13068
- ), /* @__PURE__ */ import_react27.default.createElement(
13069
- "button",
13070
- {
13071
- onClick: () => onAddSubgroup(group.id),
13072
- className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
13073
- title: "Criar Subgrupo"
13074
- },
13075
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiPlus, { size: 14 })
13076
- )), /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react27.default.createElement(
13077
- "button",
13078
- {
13079
- onClick: () => onIndent(group.id),
13080
- disabled: !canIndent,
13081
- className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
13082
- title: "Aninhar no grupo acima"
13083
- },
13084
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiArrowRight, { size: 14 })
13085
- ), /* @__PURE__ */ import_react27.default.createElement(
13086
- "button",
13087
- {
13088
- onClick: () => onOutdent(group.id),
13089
- className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
13090
- title: "Desaninhar"
13091
- },
13092
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiArrowLeft, { size: 14 })
13093
- ), /* @__PURE__ */ import_react27.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react27.default.createElement(
13094
- "button",
13095
- {
13096
- onClick: () => onDelete(group.id),
13097
- className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
13098
- title: "Remover Grupo"
13099
- },
13100
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiTrash2, { size: 14 })
13101
- )))
13102
- ), group.children && group.children.length > 0 && /* @__PURE__ */ import_react27.default.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ import_react27.default.createElement(
13293
+ /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiPlus, { size: 14 })
13294
+ )), /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react29.default.createElement(
13295
+ "button",
13296
+ {
13297
+ onClick: () => onIndent(group.id),
13298
+ disabled: !canIndent,
13299
+ className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
13300
+ title: "Aninhar no grupo acima"
13301
+ },
13302
+ /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiArrowRight, { size: 14 })
13303
+ ), /* @__PURE__ */ import_react29.default.createElement(
13304
+ "button",
13305
+ {
13306
+ onClick: () => onOutdent(group.id),
13307
+ className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
13308
+ title: "Desaninhar"
13309
+ },
13310
+ /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiArrowLeft, { size: 14 })
13311
+ ), /* @__PURE__ */ import_react29.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react29.default.createElement(
13312
+ "button",
13313
+ {
13314
+ onClick: () => onDelete(group.id),
13315
+ className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
13316
+ title: "Remover Grupo"
13317
+ },
13318
+ /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiTrash2, { size: 14 })
13319
+ )))), group.children && group.children.length > 0 && /* @__PURE__ */ import_react29.default.createElement("div", { className: "ml-2" }, group.children.map((child, idx) => /* @__PURE__ */ import_react29.default.createElement(
13103
13320
  GroupItem,
13104
13321
  {
13105
- key: childGroup.id,
13322
+ key: child.id,
13106
13323
  index: idx,
13107
- group: childGroup,
13108
- siblings: group.children,
13324
+ group: child,
13109
13325
  onUpdate,
13110
13326
  onDelete,
13111
13327
  onAddSubgroup,
13112
13328
  onIndent,
13113
13329
  onOutdent,
13114
- onRemoveAncestry,
13115
- onRequestPickAncestry,
13116
- pickingGroupId,
13117
- onPlayAncestry,
13118
- availableIds,
13330
+ searchItems,
13331
+ onMentionClick,
13119
13332
  canEdit
13120
13333
  }
13121
13334
  ))));
@@ -13129,141 +13342,127 @@ function AncestryBoard({
13129
13342
  initialGroups = [],
13130
13343
  onSave,
13131
13344
  userRole
13132
- // [NOVO] Recebe a role do usuário
13133
13345
  }) {
13134
- const [searchTerm, setSearchTerm] = (0, import_react27.useState)("");
13135
- const [groups, setGroups] = (0, import_react27.useState)([]);
13136
- const [isLoaded, setIsLoaded] = (0, import_react27.useState)(false);
13137
- const [pickingGroupId, setPickingGroupId] = (0, import_react27.useState)(null);
13138
- const [saveStatus, setSaveStatus] = (0, import_react27.useState)("idle");
13139
- const canEdit = (0, import_react27.useMemo)(() => {
13140
- return userRole !== "viewer";
13141
- }, [userRole]);
13142
- (0, import_react27.useEffect)(() => {
13346
+ const [searchTerm, setSearchTerm] = (0, import_react29.useState)("");
13347
+ const [groups, setGroups] = (0, import_react29.useState)([]);
13348
+ const [isLoaded, setIsLoaded] = (0, import_react29.useState)(false);
13349
+ const [saveStatus, setSaveStatus] = (0, import_react29.useState)("idle");
13350
+ const canEdit = (0, import_react29.useMemo)(() => userRole !== "viewer", [userRole]);
13351
+ (0, import_react29.useEffect)(() => {
13143
13352
  if (initialGroups && !isLoaded) {
13144
- setGroups(initialGroups);
13353
+ const migrate = (list) => list.map((g) => ({
13354
+ id: g.id || (0, import_uuid11.v4)(),
13355
+ content: Array.isArray(g.content) ? g.content : [],
13356
+ // descarta dados legados
13357
+ children: migrate(g.children || [])
13358
+ }));
13359
+ setGroups(migrate(initialGroups));
13145
13360
  setIsLoaded(true);
13146
13361
  }
13147
13362
  }, [initialGroups, isLoaded]);
13148
- const nodeNamesMap = (0, import_react27.useMemo)(() => {
13363
+ const nodeNamesMap = (0, import_react29.useMemo)(() => {
13149
13364
  const map = /* @__PURE__ */ new Map();
13150
- if (availableNodes && Array.isArray(availableNodes)) {
13151
- availableNodes.forEach((node) => {
13152
- if (node && node.id) {
13153
- map.set(String(node.id), node.name);
13154
- }
13155
- });
13156
- }
13365
+ availableNodes.forEach((n) => {
13366
+ if (n == null ? void 0 : n.id) map.set(String(n.id), n.name);
13367
+ });
13157
13368
  return map;
13158
13369
  }, [availableNodes]);
13159
- const availableIds = (0, import_react27.useMemo)(() => {
13160
- return new Set(availableAncestries.map((a) => String(a.ancestry_id)));
13161
- }, [availableAncestries]);
13162
- const sanitizeGroups = (groupList) => {
13163
- return groupList.map((g) => ({
13164
- id: g.id,
13165
- text: g.text || "",
13166
- ancestries: (g.ancestries || []).map((a) => ({
13167
- ancestry_id: a.ancestry_id,
13168
- name: a.name
13169
- })),
13170
- children: sanitizeGroups(g.children || [])
13171
- }));
13172
- };
13173
- (0, import_react27.useEffect)(() => {
13370
+ const allSearchableItems = (0, import_react29.useMemo)(() => {
13371
+ const items = [];
13372
+ availableAncestries.forEach((anc) => {
13373
+ items.push({
13374
+ ...anc,
13375
+ id: String(anc.ancestry_id),
13376
+ type: "ancestry",
13377
+ searchLabel: anc.name || "",
13378
+ searchDesc: anc.description || ""
13379
+ });
13380
+ });
13381
+ availableNodes.forEach((node) => {
13382
+ var _a;
13383
+ let type = "node";
13384
+ if (node.is_quest) type = "quest";
13385
+ else if ((_a = node.version_node) == null ? void 0 : _a.is_version) type = "version";
13386
+ items.push({
13387
+ ...node,
13388
+ id: String(node.id),
13389
+ type,
13390
+ searchLabel: node.name || node.raw_title || "",
13391
+ searchDesc: node.description || ""
13392
+ });
13393
+ });
13394
+ return items;
13395
+ }, [availableAncestries, availableNodes]);
13396
+ const filtered = (0, import_react29.useMemo)(() => {
13397
+ const term = searchTerm.toLowerCase().trim();
13398
+ return allSearchableItems.filter((item) => {
13399
+ if (!term) return true;
13400
+ const labelMatch = (item.searchLabel || "").toLowerCase().includes(term);
13401
+ const descMatch = (item.searchDesc || "").toLowerCase().includes(term);
13402
+ let parentMatch = false;
13403
+ if (item.type === "ancestry") {
13404
+ const parentName = nodeNamesMap.get(String(item.ancestral_node)) || "";
13405
+ parentMatch = parentName.toLowerCase().includes(term);
13406
+ }
13407
+ return labelMatch || descMatch || parentMatch;
13408
+ });
13409
+ }, [allSearchableItems, searchTerm, nodeNamesMap]);
13410
+ const sanitizeGroups = (list) => list.map((g) => ({
13411
+ id: g.id,
13412
+ content: g.content || [],
13413
+ children: sanitizeGroups(g.children || [])
13414
+ }));
13415
+ (0, import_react29.useEffect)(() => {
13174
13416
  if (!isLoaded || !onSave) return;
13175
- const timeoutId = setTimeout(async () => {
13417
+ const id = setTimeout(async () => {
13176
13418
  setSaveStatus("saving");
13177
- const cleanData = sanitizeGroups(groups);
13178
13419
  try {
13179
- await onSave(cleanData);
13420
+ await onSave(sanitizeGroups(groups));
13180
13421
  setSaveStatus("saved");
13181
- setTimeout(() => {
13182
- setSaveStatus("idle");
13183
- }, 3e3);
13184
- } catch (error) {
13185
- console.error("Erro ao salvar board:", error);
13422
+ setTimeout(() => setSaveStatus("idle"), 3e3);
13423
+ } catch (err) {
13424
+ console.error("Erro ao salvar board:", err);
13186
13425
  setSaveStatus("error");
13187
13426
  }
13188
13427
  }, 3e3);
13189
- return () => clearTimeout(timeoutId);
13428
+ return () => clearTimeout(id);
13190
13429
  }, [groups, isLoaded, onSave]);
13191
- (0, import_react27.useEffect)(() => {
13430
+ (0, import_react29.useEffect)(() => {
13192
13431
  if (!isOpen) return;
13193
- const handleKeyDown = (e) => {
13432
+ const handler = (e) => {
13194
13433
  if (e.key === "Escape") {
13195
- if (pickingGroupId) {
13196
- setPickingGroupId(null);
13197
- } else {
13198
- onClose();
13199
- }
13434
+ onClose();
13200
13435
  e.preventDefault();
13201
13436
  e.stopPropagation();
13202
13437
  }
13203
13438
  };
13204
- window.addEventListener("keydown", handleKeyDown);
13205
- return () => window.removeEventListener("keydown", handleKeyDown);
13206
- }, [isOpen, onClose, pickingGroupId]);
13207
- const filtered = (0, import_react27.useMemo)(() => {
13208
- const term = searchTerm.toLowerCase().trim();
13209
- return availableAncestries.filter((a) => {
13210
- if (!term) return true;
13211
- const nameMatch = a.name && a.name.toLowerCase().includes(term);
13212
- const descMatch = a.description && a.description.toLowerCase().includes(term);
13213
- const parentName = nodeNamesMap.get(String(a.ancestral_node)) || "";
13214
- const parentMatch = parentName.toLowerCase().includes(term);
13215
- return nameMatch || descMatch || parentMatch;
13216
- });
13217
- }, [availableAncestries, searchTerm, nodeNamesMap]);
13439
+ window.addEventListener("keydown", handler);
13440
+ return () => window.removeEventListener("keydown", handler);
13441
+ }, [isOpen, onClose]);
13218
13442
  const handleAddRootGroup = () => {
13219
- const newGroup = {
13220
- id: v4_default(),
13221
- text: "",
13222
- ancestries: [],
13223
- children: []
13224
- };
13225
- setGroups((prev) => [newGroup, ...prev]);
13443
+ setGroups((prev) => [{ id: (0, import_uuid11.v4)(), content: [], children: [] }, ...prev]);
13226
13444
  };
13227
13445
  const handleAddSubgroup = (parentId) => {
13228
- const newGroup = {
13229
- id: v4_default(),
13230
- text: "",
13231
- ancestries: [],
13232
- children: []
13233
- };
13234
- const addRecursive = (list) => {
13235
- return list.map((g) => {
13236
- if (g.id === parentId) {
13237
- return { ...g, children: [newGroup, ...g.children] };
13238
- }
13239
- return { ...g, children: addRecursive(g.children) };
13240
- });
13241
- };
13242
- setGroups((prev) => addRecursive(prev));
13446
+ const newGroup = { id: (0, import_uuid11.v4)(), content: [], children: [] };
13447
+ const add = (list) => list.map(
13448
+ (g) => g.id === parentId ? { ...g, children: [newGroup, ...g.children] } : { ...g, children: add(g.children) }
13449
+ );
13450
+ setGroups((prev) => add(prev));
13243
13451
  };
13244
13452
  const handleUpdateGroup = (id, newData) => {
13245
- const updateRecursive = (list) => {
13246
- return list.map((g) => {
13247
- if (g.id === id) return newData;
13248
- return { ...g, children: updateRecursive(g.children) };
13249
- });
13250
- };
13251
- setGroups((prev) => updateRecursive(prev));
13453
+ const update = (list) => list.map(
13454
+ (g) => g.id === id ? newData : { ...g, children: update(g.children) }
13455
+ );
13456
+ setGroups((prev) => update(prev));
13252
13457
  };
13253
13458
  const handleDeleteGroup = (id) => {
13254
- const deleteRecursive = (list) => {
13255
- return list.filter((g) => g.id !== id).map((g) => ({
13256
- ...g,
13257
- children: deleteRecursive(g.children)
13258
- }));
13259
- };
13260
- setGroups((prev) => deleteRecursive(prev));
13459
+ const del = (list) => list.filter((g) => g.id !== id).map((g) => ({ ...g, children: del(g.children) }));
13460
+ setGroups((prev) => del(prev));
13261
13461
  };
13262
13462
  const findGroupAndParent = (list, targetId, parent = null) => {
13263
13463
  for (let i = 0; i < list.length; i++) {
13264
- if (list[i].id === targetId) {
13464
+ if (list[i].id === targetId)
13265
13465
  return { group: list[i], parent, index: i, siblings: list };
13266
- }
13267
13466
  if (list[i].children.length > 0) {
13268
13467
  const found = findGroupAndParent(list[i].children, targetId, list[i]);
13269
13468
  if (found) return found;
@@ -13273,217 +13472,120 @@ function AncestryBoard({
13273
13472
  };
13274
13473
  const handleIndent = (id) => {
13275
13474
  setGroups((prev) => {
13276
- const newList = JSON.parse(JSON.stringify(prev));
13277
- const found = findGroupAndParent(newList, id);
13475
+ const next = JSON.parse(JSON.stringify(prev));
13476
+ const found = findGroupAndParent(next, id);
13278
13477
  if (!found || found.index === 0) return prev;
13279
13478
  const { group, siblings, index } = found;
13280
- const prevSibling = siblings[index - 1];
13281
13479
  siblings.splice(index, 1);
13282
- prevSibling.children.push(group);
13283
- return newList;
13480
+ siblings[index - 1].children.push(group);
13481
+ return next;
13284
13482
  });
13285
13483
  };
13286
13484
  const handleOutdent = (id) => {
13287
13485
  setGroups((prev) => {
13288
- const newList = JSON.parse(JSON.stringify(prev));
13289
- const found = findGroupAndParent(newList, id);
13486
+ const next = JSON.parse(JSON.stringify(prev));
13487
+ const found = findGroupAndParent(next, id);
13290
13488
  if (!found || !found.parent) return prev;
13291
13489
  const { group, siblings, index, parent } = found;
13292
13490
  siblings.splice(index, 1);
13293
- const parentFound = findGroupAndParent(newList, parent.id);
13491
+ const parentFound = findGroupAndParent(next, parent.id);
13294
13492
  if (parentFound) {
13295
13493
  parentFound.siblings.splice(parentFound.index + 1, 0, group);
13296
13494
  } else {
13297
- newList.push(group);
13495
+ next.push(group);
13298
13496
  }
13299
- return newList;
13497
+ return next;
13300
13498
  });
13301
13499
  };
13302
- const handleRequestPick = (groupId) => {
13303
- setPickingGroupId((prev) => prev === groupId ? null : groupId);
13304
- };
13305
- const handleSelectAncestry = (ancestry) => {
13306
- if (pickingGroupId) {
13307
- setGroups((prev) => {
13308
- const addRecursive = (list) => {
13309
- return list.map((g) => {
13310
- if (g.id === pickingGroupId) {
13311
- const exists = g.ancestries.some(
13312
- (a) => a.ancestry_id === ancestry.ancestry_id
13313
- );
13314
- if (exists) return g;
13315
- return { ...g, ancestries: [...g.ancestries, ancestry] };
13316
- }
13317
- return { ...g, children: addRecursive(g.children) };
13318
- });
13319
- };
13320
- return addRecursive(prev);
13321
- });
13322
- setPickingGroupId(null);
13323
- } else {
13324
- const fullAncestry = availableAncestries.find(
13325
- (a) => a.ancestry_id === ancestry.ancestry_id
13326
- ) || ancestry;
13327
- onSelect(fullAncestry);
13328
- }
13329
- };
13330
- const handlePlayFromGroup = (ancestryId) => {
13331
- const fullAncestry = availableAncestries.find(
13332
- (a) => a.ancestry_id === ancestryId
13333
- );
13334
- if (fullAncestry && onSelect) {
13335
- onSelect(fullAncestry);
13336
- }
13337
- };
13338
- const handleRemoveAncestryFromGroup = (groupId, ancestryId) => {
13339
- setGroups((prev) => {
13340
- const removeRecursive = (list) => {
13341
- return list.map((g) => {
13342
- if (g.id === groupId) {
13343
- return {
13344
- ...g,
13345
- ancestries: g.ancestries.filter(
13346
- (a) => a.ancestry_id !== ancestryId
13347
- )
13348
- };
13349
- }
13350
- return { ...g, children: removeRecursive(g.children) };
13351
- });
13352
- };
13353
- return removeRecursive(prev);
13354
- });
13500
+ const handleMentionClick = (item) => {
13501
+ if (onSelect) onSelect(item);
13355
13502
  };
13356
13503
  if (!isOpen) return null;
13357
- return /* @__PURE__ */ import_react27.default.createElement(
13504
+ return /* @__PURE__ */ import_react29.default.createElement(
13358
13505
  "div",
13359
13506
  {
13360
13507
  className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
13361
13508
  onClick: onClose
13362
13509
  },
13363
- /* @__PURE__ */ import_react27.default.createElement(
13510
+ /* @__PURE__ */ import_react29.default.createElement(
13364
13511
  "div",
13365
13512
  {
13366
13513
  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",
13367
13514
  onClick: (e) => e.stopPropagation()
13368
13515
  },
13369
- /* @__PURE__ */ import_react27.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_react27.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react27.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react27.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_react27.default.createElement(import_react27.default.Fragment, null, /* @__PURE__ */ import_react27.default.createElement(
13370
- import_fi22.FiLoader,
13371
- {
13372
- className: "animate-spin text-indigo-400",
13373
- size: 12
13374
- }
13375
- ), /* @__PURE__ */ import_react27.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react27.default.createElement(import_react27.default.Fragment, null, /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react27.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react27.default.createElement(import_react27.default.Fragment, null, /* @__PURE__ */ import_react27.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react27.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex items-center gap-3" }, pickingGroupId && /* @__PURE__ */ import_react27.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_react27.default.createElement(
13516
+ /* @__PURE__ */ import_react29.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_react29.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react29.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react29.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react29.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_react29.default.createElement(import_react29.default.Fragment, null, /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiLoader, { className: "animate-spin text-indigo-400", size: 12 }), /* @__PURE__ */ import_react29.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react29.default.createElement(import_react29.default.Fragment, null, /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react29.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react29.default.createElement(import_react29.default.Fragment, null, /* @__PURE__ */ import_react29.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react29.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex items-center gap-3" }, canEdit && /* @__PURE__ */ import_react29.default.createElement(
13376
13517
  "button",
13377
13518
  {
13378
13519
  onClick: handleAddRootGroup,
13379
- 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 "
13520
+ className: "flex items-center gap-2 px-3 py-1.5 bg-white/5 hover:bg-white/10 border border-white/10 hover:border-white/20 backdrop-blur-sm text-slate-200 hover:text-white rounded-md transition-all duration-200 text-xs font-medium shadow-sm"
13380
13521
  },
13381
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiPlus, { size: 14, className: "text-indigo-400" }),
13382
- /* @__PURE__ */ import_react27.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
13383
- ), /* @__PURE__ */ import_react27.default.createElement(
13522
+ /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiPlus, { size: 14, className: "text-indigo-400" }),
13523
+ /* @__PURE__ */ import_react29.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
13524
+ ), /* @__PURE__ */ import_react29.default.createElement(
13384
13525
  "button",
13385
13526
  {
13386
13527
  onClick: onClose,
13387
13528
  className: "w-8 h-8 rounded-lg flex items-center justify-center text-slate-400 hover:text-white hover:bg-white/10 transition-colors"
13388
13529
  },
13389
- "\xD7"
13530
+ /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiX, { size: 16 })
13390
13531
  ))),
13391
- /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react27.default.createElement(
13392
- "div",
13532
+ /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex flex-col border-r border-white/10 w-[20%] min-w-[280px] max-w-[460px] bg-slate-900 flex-none" }, /* @__PURE__ */ import_react29.default.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ import_react29.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiSearch, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-slate-500 group-focus-within:text-indigo-400 transition-colors" }), /* @__PURE__ */ import_react29.default.createElement(
13533
+ "input",
13393
13534
  {
13394
- className: `
13395
- flex flex-col border-r border-white/10 transition-all duration-300 flex-none
13396
- ${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
13397
- min-w-[280px] max-w-[500px] bg-slate-900
13398
- `
13399
- },
13400
- /* @__PURE__ */ import_react27.default.createElement("div", { className: "p-3 border-b border-white/5 bg-slate-900/50" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react27.default.createElement(
13401
- import_fi22.FiSearch,
13402
- {
13403
- 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"}`
13404
- }
13405
- ), /* @__PURE__ */ import_react27.default.createElement(
13406
- "input",
13535
+ type: "text",
13536
+ placeholder: "Navegar nas ancestralidades e nodes\u2026",
13537
+ className: "w-full rounded-md pl-9 pr-4 py-2 text-sm bg-slate-950 border border-white/10 text-slate-200 placeholder-slate-600 focus:outline-none focus:ring-1 focus:ring-indigo-500 transition-all",
13538
+ value: searchTerm,
13539
+ onChange: (e) => setSearchTerm(e.target.value),
13540
+ autoFocus: true
13541
+ }
13542
+ ))), /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
13543
+ const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
13544
+ return /* @__PURE__ */ import_react29.default.createElement(
13545
+ "div",
13407
13546
  {
13408
- type: "text",
13409
- placeholder: pickingGroupId ? "Pesquise para adicionar..." : "Pesquisar ancestralidade...",
13410
- className: `
13411
- w-full rounded-md pl-9 pr-4 py-2 text-sm transition-all focus:outline-none focus:ring-1 focus:ring-indigo-500 border
13412
- ${pickingGroupId ? "bg-indigo-950/30 border-indigo-500/30 text-white placeholder-indigo-300/50" : "bg-slate-950 border-white/10 text-slate-200 placeholder-slate-600"}
13413
- `,
13414
- value: searchTerm,
13415
- onChange: (e) => setSearchTerm(e.target.value),
13416
- autoFocus: !pickingGroupId
13417
- }
13418
- ))),
13419
- /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((anc) => {
13420
- const parentNodeName = nodeNamesMap.get(String(anc.ancestral_node)) || "Node Desconhecido";
13421
- const isPicking = !!pickingGroupId;
13422
- return /* @__PURE__ */ import_react27.default.createElement(
13423
- "div",
13547
+ key: anc.id,
13548
+ className: "group relative flex items-start gap-3 p-3 text-left rounded-lg border border-white/5 bg-slate-800/40 hover:bg-indigo-600/10 hover:border-indigo-500/30 cursor-default transition-all duration-200"
13549
+ },
13550
+ /* @__PURE__ */ import_react29.default.createElement("div", { className: "mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border bg-slate-800 border-white/5 group-hover:bg-indigo-500 group-hover:text-white transition-all shadow-lg" }, anc.type === "quest" ? /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiCheckSquare, { size: 14, className: "text-emerald-400 group-hover:text-white" }) : anc.type === "version" ? /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiGitBranch, { size: 14, className: "text-amber-400 group-hover:text-white" }) : anc.type === "node" ? /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiBox, { size: 14, className: "text-slate-400 group-hover:text-white" }) : /* @__PURE__ */ import_react29.default.createElement(import_fi23.FiLayers, { size: 14, className: "text-indigo-400 group-hover:text-white" })),
13551
+ /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react29.default.createElement("h4", { className: "text-sm font-medium text-slate-200 group-hover:text-white truncate transition-colors" }, anc.searchLabel || "Sem Nome"), /* @__PURE__ */ import_react29.default.createElement("span", { className: "text-[9px] px-1.5 py-0.5 rounded-full bg-white/5 text-slate-500 border border-white/5 uppercase tracking-tighter" }, anc.type)), anc.type === "ancestry" && /* @__PURE__ */ import_react29.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_react29.default.createElement(import_fi23.FiCornerUpRight, { size: 10 }), /* @__PURE__ */ import_react29.default.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.searchDesc && /* @__PURE__ */ import_react29.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.searchDesc)),
13552
+ /* @__PURE__ */ import_react29.default.createElement(
13553
+ "button",
13424
13554
  {
13425
- key: anc.ancestry_id,
13426
- onClick: () => {
13427
- if (isPicking) handleSelectAncestry(anc);
13555
+ onClick: (e) => {
13556
+ e.stopPropagation();
13557
+ if (onSelect) onSelect(anc);
13428
13558
  },
13429
- className: `
13430
- group relative flex items-start gap-3 p-3 text-left rounded-lg border transition-all duration-200
13431
- ${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"}
13432
- `
13559
+ 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",
13560
+ title: "Focar no cen\xE1rio"
13433
13561
  },
13434
- /* @__PURE__ */ import_react27.default.createElement(
13435
- "div",
13436
- {
13437
- className: `
13438
- mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
13439
- ${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"}
13440
- `
13441
- },
13442
- isPicking ? /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiPlus, { size: 16 }) : /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiLayers, { size: 14 })
13443
- ),
13444
- /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex-1 min-w-0 pb-2" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react27.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_react27.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_react27.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_react27.default.createElement(import_fi22.FiCornerUpRight, { size: 10 }), /* @__PURE__ */ import_react27.default.createElement("span", { className: "truncate max-w-[120px]" }, parentNodeName)), anc.description && /* @__PURE__ */ import_react27.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, anc.description)),
13445
- !isPicking && /* @__PURE__ */ import_react27.default.createElement(
13446
- "button",
13447
- {
13448
- onClick: (e) => {
13449
- e.stopPropagation();
13450
- handleSelectAncestry(anc);
13451
- },
13452
- 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",
13453
- title: "Renderizar Ancestralidade"
13454
- },
13455
- /* @__PURE__ */ import_react27.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_react27.default.createElement(import_fi22.FiPlay, { size: 14, className: "ml-0.5" }))
13456
- )
13457
- );
13458
- }))
13459
- ), /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ import_react27.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_react27.default.createElement(import_fi22.FiLayers, { size: 24, className: "opacity-20" }), /* @__PURE__ */ import_react27.default.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ import_react27.default.createElement(import_react27.default.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ import_react27.default.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ import_react27.default.createElement(import_react27.default.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ import_react27.default.createElement(
13562
+ /* @__PURE__ */ import_react29.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_react29.default.createElement(import_fi23.FiPlay, { size: 14, className: "ml-0.5" }))
13563
+ )
13564
+ );
13565
+ }))), /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex flex-col flex-1 bg-slate-950/30" }, /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4" }, groups.length === 0 ? /* @__PURE__ */ import_react29.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_react29.default.createElement(import_fi23.FiLayers, { size: 24, className: "opacity-20" }), /* @__PURE__ */ import_react29.default.createElement("p", { className: "text-xs text-center px-4" }, canEdit ? /* @__PURE__ */ import_react29.default.createElement(import_react29.default.Fragment, null, "Nenhum grupo criado.", /* @__PURE__ */ import_react29.default.createElement("br", null), 'Use o bot\xE3o "Novo Grupo" acima.') : /* @__PURE__ */ import_react29.default.createElement(import_react29.default.Fragment, null, "Nenhum grupo dispon\xEDvel para visualiza\xE7\xE3o."))) : groups.map((group, index) => /* @__PURE__ */ import_react29.default.createElement(
13460
13566
  GroupItem,
13461
13567
  {
13462
13568
  key: group.id,
13463
13569
  index,
13464
13570
  group,
13465
- siblings: groups,
13466
13571
  onUpdate: handleUpdateGroup,
13467
13572
  onDelete: handleDeleteGroup,
13468
13573
  onAddSubgroup: handleAddSubgroup,
13469
13574
  onIndent: handleIndent,
13470
13575
  onOutdent: handleOutdent,
13471
- onRemoveAncestry: handleRemoveAncestryFromGroup,
13472
- onRequestPickAncestry: handleRequestPick,
13473
- pickingGroupId,
13474
- onPlayAncestry: handlePlayFromGroup,
13475
- availableIds,
13576
+ searchItems: allSearchableItems,
13577
+ onMentionClick: handleMentionClick,
13476
13578
  canEdit
13477
13579
  }
13478
13580
  ))))),
13479
- /* @__PURE__ */ import_react27.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_react27.default.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ import_react27.default.createElement("span", null, groups.length, " grupos raiz"))
13581
+ /* @__PURE__ */ import_react29.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_react29.default.createElement("span", null, filtered.length, " itens encontrados"), /* @__PURE__ */ import_react29.default.createElement("span", null, groups.length, " grupos raiz"))
13480
13582
  )
13481
13583
  );
13482
13584
  }
13483
13585
 
13484
13586
  // src/components/MilestoneManager.jsx
13485
- var import_react28 = __toESM(require("react"));
13486
- var import_fi23 = require("react-icons/fi");
13587
+ var import_react30 = __toESM(require("react"));
13588
+ var import_fi24 = require("react-icons/fi");
13487
13589
  function MilestoneManager({
13488
13590
  isOpen,
13489
13591
  onClose,
@@ -13491,7 +13593,7 @@ function MilestoneManager({
13491
13593
  onUpdateMilestones = () => {
13492
13594
  }
13493
13595
  }) {
13494
- const [newMilestoneName, setNewMilestoneName] = (0, import_react28.useState)("");
13596
+ const [newMilestoneName, setNewMilestoneName] = (0, import_react30.useState)("");
13495
13597
  const handleAddMilestone = () => {
13496
13598
  if (!newMilestoneName.trim()) return;
13497
13599
  const newMilestone = {
@@ -13516,27 +13618,27 @@ function MilestoneManager({
13516
13618
  };
13517
13619
  if (!isOpen) return null;
13518
13620
  const swallow = (e) => e.stopPropagation();
13519
- return /* @__PURE__ */ import_react28.default.createElement(
13621
+ return /* @__PURE__ */ import_react30.default.createElement(
13520
13622
  "div",
13521
13623
  {
13522
13624
  className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-950/40 backdrop-blur-sm animate-in fade-in duration-300",
13523
13625
  onClick: onClose
13524
13626
  },
13525
- /* @__PURE__ */ import_react28.default.createElement(
13627
+ /* @__PURE__ */ import_react30.default.createElement(
13526
13628
  "div",
13527
13629
  {
13528
13630
  className: "w-full max-w-lg bg-slate-900/90 backdrop-blur-xl border border-white/10 rounded-2xl shadow-2xl flex flex-col max-h-[85vh] animate-in zoom-in-95 duration-300",
13529
13631
  onClick: swallow
13530
13632
  },
13531
- /* @__PURE__ */ import_react28.default.createElement("div", { className: "px-6 py-4 border-b border-white/10 flex items-center justify-between" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "p-2 rounded-lg bg-indigo-500/20 text-indigo-400" }, /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiTarget, { size: 20 })), /* @__PURE__ */ import_react28.default.createElement("div", null, /* @__PURE__ */ import_react28.default.createElement("h2", { className: "text-lg font-semibold text-slate-100" }, "Milestones"), /* @__PURE__ */ import_react28.default.createElement("p", { className: "text-xs text-slate-400" }, "Gerencie os marcos do seu cen\xE1rio"))), /* @__PURE__ */ import_react28.default.createElement(
13633
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "px-6 py-4 border-b border-white/10 flex items-center justify-between" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "p-2 rounded-lg bg-indigo-500/20 text-indigo-400" }, /* @__PURE__ */ import_react30.default.createElement(import_fi24.FiTarget, { size: 20 })), /* @__PURE__ */ import_react30.default.createElement("div", null, /* @__PURE__ */ import_react30.default.createElement("h2", { className: "text-lg font-semibold text-slate-100" }, "Milestones"), /* @__PURE__ */ import_react30.default.createElement("p", { className: "text-xs text-slate-400" }, "Gerencie os marcos do seu cen\xE1rio"))), /* @__PURE__ */ import_react30.default.createElement(
13532
13634
  "button",
13533
13635
  {
13534
13636
  onClick: onClose,
13535
13637
  className: "p-2 rounded-full hover:bg-white/10 text-slate-400 hover:text-white transition-colors"
13536
13638
  },
13537
- /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiX, { size: 20 })
13639
+ /* @__PURE__ */ import_react30.default.createElement(import_fi24.FiX, { size: 20 })
13538
13640
  )),
13539
- /* @__PURE__ */ import_react28.default.createElement("div", { className: "px-6 py-5 bg-white/5 border-b border-white/5" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ import_react28.default.createElement(
13641
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "px-6 py-5 bg-white/5 border-b border-white/5" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ import_react30.default.createElement(
13540
13642
  "input",
13541
13643
  {
13542
13644
  type: "text",
@@ -13546,47 +13648,47 @@ function MilestoneManager({
13546
13648
  placeholder: "Adicionar novo milestone...",
13547
13649
  className: "flex-1 bg-slate-800/50 border border-white/10 rounded-xl px-4 py-2.5 text-sm text-slate-100 placeholder:text-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/40 focus:border-indigo-500/50 transition-all shadow-inner"
13548
13650
  }
13549
- ), /* @__PURE__ */ import_react28.default.createElement(
13651
+ ), /* @__PURE__ */ import_react30.default.createElement(
13550
13652
  "button",
13551
13653
  {
13552
13654
  onClick: handleAddMilestone,
13553
13655
  disabled: !newMilestoneName.trim(),
13554
13656
  className: "px-4 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 disabled:opacity-30 disabled:cursor-not-allowed text-white text-sm font-medium transition-all flex items-center gap-2 shadow-lg shadow-indigo-500/20 active:scale-95"
13555
13657
  },
13556
- /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiPlus, { size: 18 }),
13658
+ /* @__PURE__ */ import_react30.default.createElement(import_fi24.FiPlus, { size: 18 }),
13557
13659
  "Adicionar"
13558
13660
  ))),
13559
- /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex-1 overflow-y-auto px-6 py-4 custom-scrollbar" }, milestones.length > 0 ? /* @__PURE__ */ import_react28.default.createElement("div", { className: "space-y-3" }, milestones.map((ms) => /* @__PURE__ */ import_react28.default.createElement(
13661
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex-1 overflow-y-auto px-6 py-4 custom-scrollbar" }, milestones.length > 0 ? /* @__PURE__ */ import_react30.default.createElement("div", { className: "space-y-3" }, milestones.map((ms) => /* @__PURE__ */ import_react30.default.createElement(
13560
13662
  "div",
13561
13663
  {
13562
13664
  key: ms.id,
13563
13665
  className: `group flex items-center justify-between p-4 rounded-xl border transition-all duration-200 ${ms.status === "active" ? "bg-slate-800/40 border-indigo-500/20 hover:border-indigo-500/40" : "bg-slate-900/40 border-white/5 opacity-60 grayscale-[0.3]"}`
13564
13666
  },
13565
- /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ import_react28.default.createElement(
13667
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ import_react30.default.createElement(
13566
13668
  "div",
13567
13669
  {
13568
13670
  className: `w-2 h-2 rounded-full shrink-0 ${ms.status === "active" ? "bg-indigo-400 shadow-[0_0_8px_rgba(129,140,248,0.6)]" : "bg-slate-600"}`
13569
13671
  }
13570
- ), /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react28.default.createElement("span", { className: `text-sm font-medium truncate ${ms.status === "active" ? "text-slate-100" : "text-slate-400 line-through"}` }, ms.name), /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wider" }, ms.status === "active" ? "Ativo" : "Inativo"))),
13571
- /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react28.default.createElement(
13672
+ ), /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react30.default.createElement("span", { className: `text-sm font-medium truncate ${ms.status === "active" ? "text-slate-100" : "text-slate-400 line-through"}` }, ms.name), /* @__PURE__ */ import_react30.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wider" }, ms.status === "active" ? "Ativo" : "Inativo"))),
13673
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react30.default.createElement(
13572
13674
  "button",
13573
13675
  {
13574
13676
  onClick: () => handleToggleMilestoneStatus(ms.id),
13575
13677
  className: `p-2 rounded-lg transition-all ${ms.status === "active" ? "hover:bg-slate-700 text-slate-400" : "hover:bg-indigo-500/20 text-indigo-400"}`,
13576
13678
  title: ms.status === "active" ? "Inativar" : "Ativar"
13577
13679
  },
13578
- ms.status === "active" ? /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiPauseCircle, { size: 18 }) : /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiPlayCircle, { size: 18 })
13579
- ), /* @__PURE__ */ import_react28.default.createElement(
13680
+ ms.status === "active" ? /* @__PURE__ */ import_react30.default.createElement(import_fi24.FiPauseCircle, { size: 18 }) : /* @__PURE__ */ import_react30.default.createElement(import_fi24.FiPlayCircle, { size: 18 })
13681
+ ), /* @__PURE__ */ import_react30.default.createElement(
13580
13682
  "button",
13581
13683
  {
13582
13684
  onClick: () => handleRemoveMilestone(ms.id),
13583
13685
  className: "p-2 rounded-lg hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-all",
13584
13686
  title: "Remover"
13585
13687
  },
13586
- /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiTrash2, { size: 18 })
13688
+ /* @__PURE__ */ import_react30.default.createElement(import_fi24.FiTrash2, { size: 18 })
13587
13689
  ))
13588
- ))) : /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex flex-col items-center justify-center py-12 text-center" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "p-4 rounded-full bg-slate-800/30 text-slate-600 mb-4" }, /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiTarget, { size: 40 })), /* @__PURE__ */ import_react28.default.createElement("h3", { className: "text-slate-400 font-medium" }, "Nenhum milestone definido"), /* @__PURE__ */ import_react28.default.createElement("p", { className: "text-xs text-slate-600 max-w-[200px] mt-1 italic" }, "Defina marcos importantes para orientar o progresso do projeto."))),
13589
- /* @__PURE__ */ import_react28.default.createElement("div", { className: "px-6 py-4 border-t border-white/5 bg-slate-900/50 flex items-center justify-between rounded-b-2xl" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex gap-4" }, /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Total:"), /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-xs font-bold text-slate-300" }, milestones.length)), /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Ativos:"), /* @__PURE__ */ import_react28.default.createElement("span", { className: "text-xs font-bold text-indigo-400" }, milestones.filter((m) => m.status === "active").length))))
13690
+ ))) : /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex flex-col items-center justify-center py-12 text-center" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "p-4 rounded-full bg-slate-800/30 text-slate-600 mb-4" }, /* @__PURE__ */ import_react30.default.createElement(import_fi24.FiTarget, { size: 40 })), /* @__PURE__ */ import_react30.default.createElement("h3", { className: "text-slate-400 font-medium" }, "Nenhum milestone definido"), /* @__PURE__ */ import_react30.default.createElement("p", { className: "text-xs text-slate-600 max-w-[200px] mt-1 italic" }, "Defina marcos importantes para orientar o progresso do projeto."))),
13691
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "px-6 py-4 border-t border-white/5 bg-slate-900/50 flex items-center justify-between rounded-b-2xl" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex gap-4" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react30.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Total:"), /* @__PURE__ */ import_react30.default.createElement("span", { className: "text-xs font-bold text-slate-300" }, milestones.length)), /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react30.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Ativos:"), /* @__PURE__ */ import_react30.default.createElement("span", { className: "text-xs font-bold text-indigo-400" }, milestones.filter((m) => m.status === "active").length))))
13590
13692
  )
13591
13693
  );
13592
13694
  }
@@ -13673,12 +13775,12 @@ function XViewScene({
13673
13775
  get_view_members
13674
13776
  }) {
13675
13777
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
13676
- const { data: session, status } = (0, import_react30.useSession)();
13778
+ const { data: session, status } = (0, import_react32.useSession)();
13677
13779
  const router = (0, import_navigation.useRouter)();
13678
13780
  const searchParams = (0, import_navigation.useSearchParams)();
13679
13781
  const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
13680
13782
  const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
13681
- const viewParams = (0, import_react29.useMemo)(() => {
13783
+ const viewParams = (0, import_react31.useMemo)(() => {
13682
13784
  if (encryptedConfig) {
13683
13785
  const data = decryptData(encryptedConfig);
13684
13786
  if (data) {
@@ -13687,7 +13789,7 @@ function XViewScene({
13687
13789
  }
13688
13790
  return null;
13689
13791
  }, [encryptedConfig, session]);
13690
- (0, import_react29.useEffect)(() => {
13792
+ (0, import_react31.useEffect)(() => {
13691
13793
  async function verifyPermission() {
13692
13794
  if (!viewParams || !session || !check_user_permission) return;
13693
13795
  const { id, type, owner_id } = viewParams;
@@ -13724,65 +13826,65 @@ function XViewScene({
13724
13826
  setIsLoading(false);
13725
13827
  }
13726
13828
  }, [viewParams, session, status, check_user_permission]);
13727
- const sceneConfigId = (0, import_react29.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
13728
- const ownerId = (0, import_react29.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
13729
- const dbSaveUrl = (0, import_react29.useMemo)(() => {
13829
+ const sceneConfigId = (0, import_react31.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
13830
+ const ownerId = (0, import_react31.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
13831
+ const dbSaveUrl = (0, import_react31.useMemo)(() => {
13730
13832
  if (ownerId && sceneConfigId) {
13731
13833
  return `x_view_dbs/${ownerId}/${sceneConfigId}`;
13732
13834
  }
13733
13835
  return null;
13734
13836
  }, [ownerId, sceneConfigId]);
13735
- const sceneSaveUrl = (0, import_react29.useMemo)(() => {
13837
+ const sceneSaveUrl = (0, import_react31.useMemo)(() => {
13736
13838
  if (ownerId && sceneConfigId) {
13737
13839
  return `x_view_scenes/${ownerId}/${sceneConfigId}`;
13738
13840
  }
13739
13841
  return null;
13740
13842
  }, [ownerId, sceneConfigId]);
13741
- const ancestry_save_url = (0, import_react29.useMemo)(() => {
13843
+ const ancestry_save_url = (0, import_react31.useMemo)(() => {
13742
13844
  if (ownerId && sceneConfigId) {
13743
13845
  return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
13744
13846
  }
13745
13847
  return null;
13746
13848
  }, [ownerId, sceneConfigId]);
13747
- const sceneDataRef = (0, import_react29.useRef)(null);
13748
- const parentDataRef = (0, import_react29.useRef)(null);
13749
- const ancestryDataRef = (0, import_react29.useRef)(null);
13750
- const [isLoading, setIsLoading] = (0, import_react29.useState)(true);
13751
- const [permissionStatus, setPermissionStatus] = (0, import_react29.useState)("loading");
13752
- const [userPermissionRole, setUserPermissionRole] = (0, import_react29.useState)(null);
13753
- const [viewMembers, setViewMembers] = (0, import_react29.useState)([]);
13754
- const [isInitialized, setIsInitialized] = (0, import_react29.useState)(false);
13755
- const [sceneVersion, setSceneVersion] = (0, import_react29.useState)(0);
13756
- const [contextMenu, setContextMenu] = (0, import_react29.useState)({
13849
+ const sceneDataRef = (0, import_react31.useRef)(null);
13850
+ const parentDataRef = (0, import_react31.useRef)(null);
13851
+ const ancestryDataRef = (0, import_react31.useRef)(null);
13852
+ const [isLoading, setIsLoading] = (0, import_react31.useState)(true);
13853
+ const [permissionStatus, setPermissionStatus] = (0, import_react31.useState)("loading");
13854
+ const [userPermissionRole, setUserPermissionRole] = (0, import_react31.useState)(null);
13855
+ const [viewMembers, setViewMembers] = (0, import_react31.useState)([]);
13856
+ const [isInitialized, setIsInitialized] = (0, import_react31.useState)(false);
13857
+ const [sceneVersion, setSceneVersion] = (0, import_react31.useState)(0);
13858
+ const [contextMenu, setContextMenu] = (0, import_react31.useState)({
13757
13859
  visible: false,
13758
13860
  x: 0,
13759
13861
  y: 0,
13760
13862
  nodeData: null
13761
13863
  });
13762
- const [multiContextMenu, setMultiContextMenu] = (0, import_react29.useState)({
13864
+ const [multiContextMenu, setMultiContextMenu] = (0, import_react31.useState)({
13763
13865
  visible: false,
13764
13866
  x: 0,
13765
13867
  y: 0,
13766
13868
  nodeIds: null
13767
13869
  });
13768
- const [relationshipMenu, setRelationshipMenu] = (0, import_react29.useState)({
13870
+ const [relationshipMenu, setRelationshipMenu] = (0, import_react31.useState)({
13769
13871
  visible: false,
13770
13872
  x: 0,
13771
13873
  y: 0,
13772
13874
  linkObject: null
13773
13875
  });
13774
- const [creationMode, setCreationMode] = (0, import_react29.useState)({
13876
+ const [creationMode, setCreationMode] = (0, import_react31.useState)({
13775
13877
  isActive: false,
13776
13878
  sourceNodeData: null
13777
13879
  });
13778
- const [versionMode, setVersionMode] = (0, import_react29.useState)({
13880
+ const [versionMode, setVersionMode] = (0, import_react31.useState)({
13779
13881
  isActive: false,
13780
13882
  sourceNodeData: null
13781
13883
  });
13782
- const [questMode, setQuestMode] = (0, import_react29.useState)({ isActive: false });
13783
- const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react29.useState)(false);
13784
- const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react29.useState)(false);
13785
- const [ancestryMode, setAncestryMode] = (0, import_react29.useState)({
13884
+ const [questMode, setQuestMode] = (0, import_react31.useState)({ isActive: false });
13885
+ const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react31.useState)(false);
13886
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react31.useState)(false);
13887
+ const [ancestryMode, setAncestryMode] = (0, import_react31.useState)({
13786
13888
  isActive: false,
13787
13889
  tree: null,
13788
13890
  selectedParentId: null,
@@ -13793,42 +13895,42 @@ function XViewScene({
13793
13895
  ancestryDescriptionSections: [],
13794
13896
  isAddingNodes: false
13795
13897
  });
13796
- const [readingMode, setReadingMode] = (0, import_react29.useState)({
13898
+ const [readingMode, setReadingMode] = (0, import_react31.useState)({
13797
13899
  isActive: false,
13798
13900
  ancestry: null,
13799
13901
  branchStack: [],
13800
13902
  autoAbstraction: false
13801
13903
  });
13802
- const [formPosition, setFormPosition] = (0, import_react29.useState)({
13904
+ const [formPosition, setFormPosition] = (0, import_react31.useState)({
13803
13905
  left: 16,
13804
13906
  top: 16,
13805
13907
  opacity: 0
13806
13908
  });
13807
- const [detailsNode, setDetailsNode] = (0, import_react29.useState)(null);
13808
- const [detailsLink, setDetailsLink] = (0, import_react29.useState)(null);
13809
- const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react29.useState)(null);
13810
- const [imageViewer, setImageViewer] = (0, import_react29.useState)({
13909
+ const [detailsNode, setDetailsNode] = (0, import_react31.useState)(null);
13910
+ const [detailsLink, setDetailsLink] = (0, import_react31.useState)(null);
13911
+ const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react31.useState)(null);
13912
+ const [imageViewer, setImageViewer] = (0, import_react31.useState)({
13811
13913
  visible: false,
13812
13914
  images: [],
13813
13915
  startIndex: 0
13814
13916
  });
13815
- const [editingAncestryRel, setEditingAncestryRel] = (0, import_react29.useState)({
13917
+ const [editingAncestryRel, setEditingAncestryRel] = (0, import_react31.useState)({
13816
13918
  visible: false,
13817
13919
  data: null,
13818
13920
  path: null
13819
13921
  });
13820
- const [isImportModalOpen, setIsImportModalOpen] = (0, import_react29.useState)(false);
13821
- const [importSuccessMessage, setImportSuccessMessage] = (0, import_react29.useState)("");
13822
- const [invalidTargetError, setInvalidTargetError] = (0, import_react29.useState)(null);
13823
- const [highlightedNodeId, setHighlightedNodeId] = (0, import_react29.useState)(null);
13824
- const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react29.useState)(false);
13825
- const [ancestryBoardData, setAncestryBoardData] = (0, import_react29.useState)([]);
13826
- const [isSidebarOpen, setIsSidebarOpen] = (0, import_react29.useState)(false);
13827
- const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = (0, import_react29.useState)(false);
13828
- const mountRef = (0, import_react29.useRef)(null);
13829
- const tooltipRef = (0, import_react29.useRef)(null);
13830
- const formRef = (0, import_react29.useRef)(null);
13831
- const stateRef = (0, import_react29.useRef)({
13922
+ const [isImportModalOpen, setIsImportModalOpen] = (0, import_react31.useState)(false);
13923
+ const [importSuccessMessage, setImportSuccessMessage] = (0, import_react31.useState)("");
13924
+ const [invalidTargetError, setInvalidTargetError] = (0, import_react31.useState)(null);
13925
+ const [highlightedNodeId, setHighlightedNodeId] = (0, import_react31.useState)(null);
13926
+ const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react31.useState)(false);
13927
+ const [ancestryBoardData, setAncestryBoardData] = (0, import_react31.useState)([]);
13928
+ const [isSidebarOpen, setIsSidebarOpen] = (0, import_react31.useState)(false);
13929
+ const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = (0, import_react31.useState)(false);
13930
+ const mountRef = (0, import_react31.useRef)(null);
13931
+ const tooltipRef = (0, import_react31.useRef)(null);
13932
+ const formRef = (0, import_react31.useRef)(null);
13933
+ const stateRef = (0, import_react31.useRef)({
13832
13934
  readMode: {
13833
13935
  currentMaxIndex: 0,
13834
13936
  progressMap: {}
@@ -13892,10 +13994,10 @@ function XViewScene({
13892
13994
  minWidth: 320,
13893
13995
  maxWidth: maxReadPanelW
13894
13996
  });
13895
- (0, import_react29.useEffect)(() => {
13997
+ (0, import_react31.useEffect)(() => {
13896
13998
  stateRef.current.ancestry = ancestryMode;
13897
13999
  }, [ancestryMode]);
13898
- (0, import_react29.useEffect)(() => {
14000
+ (0, import_react31.useEffect)(() => {
13899
14001
  var _a2;
13900
14002
  if (!isInitialized) return;
13901
14003
  const map = /* @__PURE__ */ new Map();
@@ -13918,10 +14020,10 @@ function XViewScene({
13918
14020
  }
13919
14021
  stateRef.current.nodeIdToParentFileMap = map;
13920
14022
  }, [isInitialized, sceneVersion]);
13921
- const handleNavigateBack = (0, import_react29.useCallback)(() => {
14023
+ const handleNavigateBack = (0, import_react31.useCallback)(() => {
13922
14024
  router.push("/dashboard/scenes");
13923
14025
  }, [router]);
13924
- const handleConfirmImport = (0, import_react29.useCallback)(
14026
+ const handleConfirmImport = (0, import_react31.useCallback)(
13925
14027
  async (importPayload) => {
13926
14028
  var _a2, _b2;
13927
14029
  let files = [];
@@ -14049,7 +14151,7 @@ function XViewScene({
14049
14151
  const handleOpenImageViewer = (images, startIndex) => {
14050
14152
  setImageViewer({ visible: true, images, startIndex });
14051
14153
  };
14052
- const tweenToTarget = (0, import_react29.useCallback)(
14154
+ const tweenToTarget = (0, import_react31.useCallback)(
14053
14155
  (target, zoomFactor = 1, forcedDirection = null) => {
14054
14156
  const { camera, controls, tweenGroup } = stateRef.current;
14055
14157
  if (!camera || !controls || !tweenGroup) return;
@@ -14075,7 +14177,7 @@ function XViewScene({
14075
14177
  if (!t || typeof t.closest !== "function") return false;
14076
14178
  return !!t.closest(".ui-overlay");
14077
14179
  };
14078
- const buildFullAncestryTree = (0, import_react29.useCallback)(
14180
+ const buildFullAncestryTree = (0, import_react31.useCallback)(
14079
14181
  (idTree, nodes, ancestries = []) => {
14080
14182
  if (!idTree) return null;
14081
14183
  const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
@@ -14160,7 +14262,7 @@ function XViewScene({
14160
14262
  },
14161
14263
  []
14162
14264
  );
14163
- const handleActivateTimeline = (0, import_react29.useCallback)(() => {
14265
+ const handleActivateTimeline = (0, import_react31.useCallback)(() => {
14164
14266
  const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
14165
14267
  if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
14166
14268
  while (timelineIntervalsGroup.children.length > 0) {
@@ -14320,7 +14422,7 @@ function XViewScene({
14320
14422
  }
14321
14423
  });
14322
14424
  }, []);
14323
- const handleVersionTimeline = (0, import_react29.useCallback)((sourceMesh, versionMeshes) => {
14425
+ const handleVersionTimeline = (0, import_react31.useCallback)((sourceMesh, versionMeshes) => {
14324
14426
  const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
14325
14427
  if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0)
14326
14428
  return;
@@ -14457,7 +14559,7 @@ function XViewScene({
14457
14559
  }
14458
14560
  });
14459
14561
  }, []);
14460
- (0, import_react29.useEffect)(() => {
14562
+ (0, import_react31.useEffect)(() => {
14461
14563
  async function fetchAllData(configPath, ownerId2) {
14462
14564
  var _a2, _b2;
14463
14565
  if (!get_scene_view_data) {
@@ -14562,12 +14664,12 @@ function XViewScene({
14562
14664
  focusNodeId,
14563
14665
  focusAncestryId
14564
14666
  ]);
14565
- const isNodeInView = (0, import_react29.useCallback)((id) => {
14667
+ const isNodeInView = (0, import_react31.useCallback)((id) => {
14566
14668
  const key = String(id);
14567
14669
  const objs = stateRef.current.nodeObjects || {};
14568
14670
  return !!objs[key];
14569
14671
  }, []);
14570
- const addOrUpdateNodeMesh = (0, import_react29.useCallback)(
14672
+ const addOrUpdateNodeMesh = (0, import_react31.useCallback)(
14571
14673
  (nodeData, position, suppressVersionUpdate = false, forceShowQuestDate = false) => {
14572
14674
  const {
14573
14675
  graphGroup,
@@ -14608,7 +14710,7 @@ function XViewScene({
14608
14710
  },
14609
14711
  []
14610
14712
  );
14611
- const handleActivateQuestLens = (0, import_react29.useCallback)(({ assigneeId, status: status2, milestoneId }) => {
14713
+ const handleActivateQuestLens = (0, import_react31.useCallback)(({ assigneeId, status: status2, milestoneId }) => {
14612
14714
  var _a2;
14613
14715
  const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
14614
14716
  if (!nodeObjects || !tweenGroup || !graphGroup) return;
@@ -14822,7 +14924,7 @@ function XViewScene({
14822
14924
  camTween.start();
14823
14925
  }
14824
14926
  }, [addOrUpdateNodeMesh]);
14825
- (0, import_react29.useEffect)(() => {
14927
+ (0, import_react31.useEffect)(() => {
14826
14928
  if (!isInitialized || !sceneDataRef.current) return;
14827
14929
  const currentMount = mountRef.current;
14828
14930
  if (!currentMount) return;
@@ -15578,7 +15680,7 @@ function XViewScene({
15578
15680
  get_scene_view_data,
15579
15681
  save_view_data
15580
15682
  ]);
15581
- const handleGhostNodeImageChange = (0, import_react29.useCallback)((useImage, imageUrl) => {
15683
+ const handleGhostNodeImageChange = (0, import_react31.useCallback)((useImage, imageUrl) => {
15582
15684
  const {
15583
15685
  node: ghostNode,
15584
15686
  line: ghostLine,
@@ -15626,7 +15728,7 @@ function XViewScene({
15626
15728
  aura: newGhostNode.getObjectByName("aura")
15627
15729
  };
15628
15730
  }, []);
15629
- const handleGhostNodeIntensityChange = (0, import_react29.useCallback)((newIntensity) => {
15731
+ const handleGhostNodeIntensityChange = (0, import_react31.useCallback)((newIntensity) => {
15630
15732
  const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
15631
15733
  if (!ghostNode) return;
15632
15734
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -15647,7 +15749,7 @@ function XViewScene({
15647
15749
  ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
15648
15750
  }
15649
15751
  }, []);
15650
- const handleDetailNodeIntensityChange = (0, import_react29.useCallback)(
15752
+ const handleDetailNodeIntensityChange = (0, import_react31.useCallback)(
15651
15753
  (nodeId, newIntensity) => {
15652
15754
  const mesh = stateRef.current.nodeObjects[String(nodeId)];
15653
15755
  if (!mesh) return;
@@ -15803,7 +15905,7 @@ function XViewScene({
15803
15905
  mountRef.current.style.cursor = "default";
15804
15906
  }
15805
15907
  };
15806
- const handleAncestryTreeUpdate = (0, import_react29.useCallback)((newTree, extraData = null) => {
15908
+ const handleAncestryTreeUpdate = (0, import_react31.useCallback)((newTree, extraData = null) => {
15807
15909
  setAncestryMode((prev) => {
15808
15910
  const prevTreeStr = JSON.stringify(prev.tree);
15809
15911
  const newTreeStr = JSON.stringify(newTree);
@@ -15826,7 +15928,7 @@ function XViewScene({
15826
15928
  };
15827
15929
  });
15828
15930
  }, []);
15829
- const actionHandlerContext = (0, import_react29.useMemo)(
15931
+ const actionHandlerContext = (0, import_react31.useMemo)(
15830
15932
  () => {
15831
15933
  var _a2;
15832
15934
  return {
@@ -15887,7 +15989,7 @@ function XViewScene({
15887
15989
  const handleStartVersioning = (nodeData) => {
15888
15990
  userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
15889
15991
  };
15890
- const handleStartQuestQuick = (0, import_react29.useCallback)((questNode) => {
15992
+ const handleStartQuestQuick = (0, import_react31.useCallback)((questNode) => {
15891
15993
  var _a2, _b2, _c2;
15892
15994
  if (!questNode || !actionHandlerContext) return;
15893
15995
  const allParentNodes = Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
@@ -15922,7 +16024,7 @@ function XViewScene({
15922
16024
  }
15923
16025
  setDetailsNode(updatedNode);
15924
16026
  }, [session, actionHandlerContext]);
15925
- const handleFinishQuestQuick = (0, import_react29.useCallback)((questNode) => {
16027
+ const handleFinishQuestQuick = (0, import_react31.useCallback)((questNode) => {
15926
16028
  var _a2, _b2, _c2, _d2;
15927
16029
  if (!questNode || !actionHandlerContext) return;
15928
16030
  const {
@@ -15996,7 +16098,7 @@ function XViewScene({
15996
16098
  setDetailsNode(null);
15997
16099
  }
15998
16100
  }, [session, actionHandlerContext, viewMembers, detailsNode]);
15999
- const handleCancelQuest = (0, import_react29.useCallback)(() => {
16101
+ const handleCancelQuest = (0, import_react31.useCallback)(() => {
16000
16102
  const { graphGroup, ghostElements } = stateRef.current;
16001
16103
  if (ghostElements.node && graphGroup) {
16002
16104
  if (ghostElements.node.userData.labelObject) {
@@ -16060,6 +16162,10 @@ function XViewScene({
16060
16162
  ownerId: ownerId2,
16061
16163
  datasetName: "Quests Internas (View)"
16062
16164
  });
16165
+ sceneDataRef2.current.quest_nodes = [...graphDataRef.current[sceneConfigId2].nodes];
16166
+ if (parentDataRef.current[sceneConfigId2]) {
16167
+ parentDataRef.current[sceneConfigId2].nodes = [...graphDataRef.current[sceneConfigId2].nodes];
16168
+ }
16063
16169
  const finalPosition = stateRef2.current.ghostElements.node ? stateRef2.current.ghostElements.node.position.clone() : stateRef2.current.controls.target.clone();
16064
16170
  const { graphGroup, ghostElements } = stateRef2.current;
16065
16171
  if (ghostElements.node && graphGroup) {
@@ -16149,7 +16255,7 @@ function XViewScene({
16149
16255
  }
16150
16256
  userActionHandlers.handleCancelConnection(context);
16151
16257
  };
16152
- const handleClearAncestryVisuals = (0, import_react29.useCallback)((ancestryId) => {
16258
+ const handleClearAncestryVisuals = (0, import_react31.useCallback)((ancestryId) => {
16153
16259
  const { renderedAncestries, ancestryGroup } = stateRef.current;
16154
16260
  const renderIndex = renderedAncestries.findIndex(
16155
16261
  (a) => String(a.id) === String(ancestryId)
@@ -16167,7 +16273,7 @@ function XViewScene({
16167
16273
  );
16168
16274
  }
16169
16275
  }, []);
16170
- const handleRenderAncestry = (0, import_react29.useCallback)(
16276
+ const handleRenderAncestry = (0, import_react31.useCallback)(
16171
16277
  async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
16172
16278
  setContextMenu(
16173
16279
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -16661,7 +16767,7 @@ function XViewScene({
16661
16767
  ancestryMode.isActive
16662
16768
  ]
16663
16769
  );
16664
- const handleRenderAbstractionTree = (0, import_react29.useCallback)(
16770
+ const handleRenderAbstractionTree = (0, import_react31.useCallback)(
16665
16771
  (ancestryObject, targetNodeId = null) => {
16666
16772
  setContextMenu(
16667
16773
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -16749,7 +16855,7 @@ function XViewScene({
16749
16855
  handleClearAncestryVisuals
16750
16856
  ]
16751
16857
  );
16752
- const handleReadModeBranchNav = (0, import_react29.useCallback)(
16858
+ const handleReadModeBranchNav = (0, import_react31.useCallback)(
16753
16859
  (nodeId, action, direction = "right") => {
16754
16860
  const { ancestry, branchStack } = readingMode;
16755
16861
  if (!ancestry || !ancestry.tree) return;
@@ -16927,13 +17033,13 @@ function XViewScene({
16927
17033
  },
16928
17034
  [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]
16929
17035
  );
16930
- const handleReadModeHighlight = (0, import_react29.useCallback)((nodeId) => {
17036
+ const handleReadModeHighlight = (0, import_react31.useCallback)((nodeId) => {
16931
17037
  if (stateRef.current.highlightedNodeId !== nodeId) {
16932
17038
  stateRef.current.highlightedNodeId = nodeId;
16933
17039
  }
16934
17040
  setHighlightedNodeId(nodeId);
16935
17041
  }, []);
16936
- const activeNodeBranches = (0, import_react29.useMemo)(() => {
17042
+ const activeNodeBranches = (0, import_react31.useMemo)(() => {
16937
17043
  if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree)
16938
17044
  return null;
16939
17045
  const fullTree = buildFullAncestryTree(
@@ -16977,7 +17083,7 @@ function XViewScene({
16977
17083
  readingMode.branchStack,
16978
17084
  ancestryDataRef.current
16979
17085
  ]);
16980
- const backNavigationInfo = (0, import_react29.useMemo)(() => {
17086
+ const backNavigationInfo = (0, import_react31.useMemo)(() => {
16981
17087
  const { branchStack } = readingMode;
16982
17088
  if (!branchStack || branchStack.length === 0) return null;
16983
17089
  const lastStep = branchStack[branchStack.length - 1];
@@ -16988,7 +17094,7 @@ function XViewScene({
16988
17094
  name: "Voltar para anterior"
16989
17095
  };
16990
17096
  }, [readingMode.branchStack]);
16991
- const getReadModeDisplayContext = (0, import_react29.useMemo)(() => {
17097
+ const getReadModeDisplayContext = (0, import_react31.useMemo)(() => {
16992
17098
  const { ancestry, branchStack } = readingMode;
16993
17099
  if (!ancestry) return null;
16994
17100
  if (branchStack.length === 0) {
@@ -17031,7 +17137,7 @@ function XViewScene({
17031
17137
  customProperties: branchProps
17032
17138
  };
17033
17139
  }, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
17034
- const readModeAbstractionTree = (0, import_react29.useMemo)(() => {
17140
+ const readModeAbstractionTree = (0, import_react31.useMemo)(() => {
17035
17141
  if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
17036
17142
  return null;
17037
17143
  }
@@ -17050,7 +17156,7 @@ function XViewScene({
17050
17156
  buildFullAncestryTree,
17051
17157
  sceneVersion
17052
17158
  ]);
17053
- const handleStartReadingAncestry = (0, import_react29.useCallback)(
17159
+ const handleStartReadingAncestry = (0, import_react31.useCallback)(
17054
17160
  async (ancestryObject, renderMode = "full") => {
17055
17161
  setContextMenu(
17056
17162
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -17093,7 +17199,7 @@ function XViewScene({
17093
17199
  },
17094
17200
  [handleRenderAncestry, handleRenderAbstractionTree]
17095
17201
  );
17096
- const handleReadModeSectionChange = (0, import_react29.useCallback)(
17202
+ const handleReadModeSectionChange = (0, import_react31.useCallback)(
17097
17203
  (activeSectionId) => {
17098
17204
  const { ancestry, branchStack } = readingMode;
17099
17205
  if (!ancestry || !readingMode.isActive) return;
@@ -17178,10 +17284,10 @@ function XViewScene({
17178
17284
  ancestryDataRef.current
17179
17285
  ]
17180
17286
  );
17181
- const handleCloseReadMode = (0, import_react29.useCallback)(() => {
17287
+ const handleCloseReadMode = (0, import_react31.useCallback)(() => {
17182
17288
  setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
17183
17289
  }, []);
17184
- const handleAncestrySectionChange = (0, import_react29.useCallback)(
17290
+ const handleAncestrySectionChange = (0, import_react31.useCallback)(
17185
17291
  (activeSectionId, ancestryOverride = null, rotation = 0) => {
17186
17292
  var _a2, _b2;
17187
17293
  const currentMode = stateRef.current.ancestry;
@@ -17243,7 +17349,7 @@ function XViewScene({
17243
17349
  },
17244
17350
  [handleRenderAncestry]
17245
17351
  );
17246
- const handleEditAncestry = (0, import_react29.useCallback)(
17352
+ const handleEditAncestry = (0, import_react31.useCallback)(
17247
17353
  async (ancestryObject) => {
17248
17354
  setContextMenu(
17249
17355
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -17298,7 +17404,7 @@ function XViewScene({
17298
17404
  const handleSelectAncestryParent = (nodeId) => {
17299
17405
  setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
17300
17406
  };
17301
- const handleRemoveFromAncestry = (0, import_react29.useCallback)((pathToRemove) => {
17407
+ const handleRemoveFromAncestry = (0, import_react31.useCallback)((pathToRemove) => {
17302
17408
  if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
17303
17409
  console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
17304
17410
  return;
@@ -17323,7 +17429,7 @@ function XViewScene({
17323
17429
  return { ...prev, tree: newTree };
17324
17430
  });
17325
17431
  }, []);
17326
- const handleSaveAncestry = (0, import_react29.useCallback)(
17432
+ const handleSaveAncestry = (0, import_react31.useCallback)(
17327
17433
  async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
17328
17434
  const treeToUse = treeOverride || ancestryMode.tree;
17329
17435
  const { isEditMode, currentAncestryId } = ancestryMode;
@@ -17559,7 +17665,7 @@ function XViewScene({
17559
17665
  });
17560
17666
  setEditingAncestryRel({ visible: false, data: null, path: null });
17561
17667
  };
17562
- const handleDeleteAncestry = (0, import_react29.useCallback)(
17668
+ const handleDeleteAncestry = (0, import_react31.useCallback)(
17563
17669
  async (ancestryIdToDelete) => {
17564
17670
  if (!ancestryIdToDelete) {
17565
17671
  alert("ID da ancestralidade n\xE3o encontrado.");
@@ -17641,18 +17747,70 @@ function XViewScene({
17641
17747
  },
17642
17748
  [save_view_data, delete_file_action]
17643
17749
  );
17644
- const handleOpenAncestryBoard = (0, import_react29.useCallback)(() => {
17750
+ const handleOpenAncestryBoard = (0, import_react31.useCallback)(() => {
17645
17751
  setIsAncestryBoardOpen(true);
17646
17752
  }, []);
17647
- const handleSelectAncestryFromBoard = (0, import_react29.useCallback)(
17648
- (ancestry) => {
17753
+ const allAvailableNodes = (0, import_react31.useMemo)(() => {
17754
+ if (!parentDataRef.current) return [];
17755
+ return Object.values(parentDataRef.current).flatMap(
17756
+ (fileData) => fileData.nodes || []
17757
+ );
17758
+ }, [sceneVersion, isInitialized]);
17759
+ const allAvailableAncestries = (0, import_react31.useMemo)(() => {
17760
+ return ancestryDataRef.current || [];
17761
+ }, [sceneVersion, isInitialized]);
17762
+ const handleOpenReference = (0, import_react31.useCallback)(
17763
+ (referenceData) => {
17764
+ const { type, id } = referenceData;
17765
+ if (type === "node") {
17766
+ const targetNode = allAvailableNodes.find(
17767
+ (n) => String(n.id) === String(id)
17768
+ );
17769
+ if (targetNode) {
17770
+ setAncestryLinkDetails(null);
17771
+ setDetailsLink(null);
17772
+ setDetailsNode(targetNode);
17773
+ const sceneMesh = stateRef.current.nodeObjects[String(id)];
17774
+ if (sceneMesh) {
17775
+ tweenToTarget(sceneMesh);
17776
+ }
17777
+ } else {
17778
+ alert("Node original n\xE3o encontrado neste contexto.");
17779
+ }
17780
+ } else if (type === "ancestry") {
17781
+ const targetAncestry = allAvailableAncestries.find(
17782
+ (a) => String(a.ancestry_id) === String(id)
17783
+ );
17784
+ if (targetAncestry) {
17785
+ setDetailsNode(null);
17786
+ setDetailsLink(null);
17787
+ setAncestryLinkDetails(null);
17788
+ handleEditAncestry(targetAncestry);
17789
+ } else {
17790
+ alert("Ancestralidade original n\xE3o encontrada neste contexto.");
17791
+ }
17792
+ }
17793
+ },
17794
+ [
17795
+ allAvailableNodes,
17796
+ allAvailableAncestries,
17797
+ handleEditAncestry,
17798
+ tweenToTarget
17799
+ ]
17800
+ );
17801
+ const handleSelectAncestryFromBoard = (0, import_react31.useCallback)(
17802
+ (item) => {
17649
17803
  setIsAncestryBoardOpen(false);
17650
17804
  setIsSidebarOpen(false);
17651
- handleStartReadingAncestry(ancestry);
17805
+ if (item.type === "ancestry") {
17806
+ handleStartReadingAncestry(item);
17807
+ } else {
17808
+ handleOpenReference({ type: "node", id: item.id });
17809
+ }
17652
17810
  },
17653
- [handleStartReadingAncestry]
17811
+ [handleStartReadingAncestry, handleOpenReference]
17654
17812
  );
17655
- const handleSaveAncestryBoard = (0, import_react29.useCallback)(
17813
+ const handleSaveAncestryBoard = (0, import_react31.useCallback)(
17656
17814
  async (groups) => {
17657
17815
  if (!sceneConfigId || !viewParams || !session) return;
17658
17816
  const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
@@ -17666,7 +17824,7 @@ function XViewScene({
17666
17824
  },
17667
17825
  [sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]
17668
17826
  );
17669
- const existingNodeTypes = (0, import_react29.useMemo)(() => {
17827
+ const existingNodeTypes = (0, import_react31.useMemo)(() => {
17670
17828
  if (!parentDataRef.current) {
17671
17829
  return [];
17672
17830
  }
@@ -17678,7 +17836,7 @@ function XViewScene({
17678
17836
  ).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
17679
17837
  return [...new Set(allTypes)];
17680
17838
  }, [parentDataRef.current, sceneVersion]);
17681
- const searchableDbNodes = (0, import_react29.useMemo)(() => {
17839
+ const searchableDbNodes = (0, import_react31.useMemo)(() => {
17682
17840
  if (!parentDataRef.current) {
17683
17841
  return [];
17684
17842
  }
@@ -17693,7 +17851,7 @@ function XViewScene({
17693
17851
  return !((_a2 = node.version_node) == null ? void 0 : _a2.is_version);
17694
17852
  });
17695
17853
  }, [parentDataRef.current, sceneVersion]);
17696
- const handleAddExistingNode = (0, import_react29.useCallback)(
17854
+ const handleAddExistingNode = (0, import_react31.useCallback)(
17697
17855
  (nodeId) => {
17698
17856
  return userActionHandlers.handleAddExistingNodeById(
17699
17857
  actionHandlerContext,
@@ -17702,7 +17860,7 @@ function XViewScene({
17702
17860
  },
17703
17861
  [actionHandlerContext]
17704
17862
  );
17705
- const handleUpdateMilestones = (0, import_react29.useCallback)(
17863
+ const handleUpdateMilestones = (0, import_react31.useCallback)(
17706
17864
  async (newMilestones) => {
17707
17865
  var _a2, _b2, _c2;
17708
17866
  if (!sceneDataRef.current) return;
@@ -17748,7 +17906,7 @@ function XViewScene({
17748
17906
  viewParams == null ? void 0 : viewParams.type
17749
17907
  ]
17750
17908
  );
17751
- const handleSaveCurrentView = (0, import_react29.useCallback)(async () => {
17909
+ const handleSaveCurrentView = (0, import_react31.useCallback)(async () => {
17752
17910
  var _a2, _b2, _c2;
17753
17911
  const { nodeObjects, allLinks } = stateRef.current;
17754
17912
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
@@ -17791,61 +17949,13 @@ function XViewScene({
17791
17949
  console.error("Erro na chamada de save_view_data:", error);
17792
17950
  }
17793
17951
  }, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
17794
- const allAvailableNodes = (0, import_react29.useMemo)(() => {
17795
- if (!parentDataRef.current) return [];
17796
- return Object.values(parentDataRef.current).flatMap(
17797
- (fileData) => fileData.nodes || []
17798
- );
17799
- }, [sceneVersion, isInitialized]);
17800
- const allAvailableAncestries = (0, import_react29.useMemo)(() => {
17801
- return ancestryDataRef.current || [];
17802
- }, [sceneVersion, isInitialized]);
17803
- const handleOpenReference = (0, import_react29.useCallback)(
17804
- (referenceData) => {
17805
- const { type, id } = referenceData;
17806
- if (type === "node") {
17807
- const targetNode = allAvailableNodes.find(
17808
- (n) => String(n.id) === String(id)
17809
- );
17810
- if (targetNode) {
17811
- setAncestryLinkDetails(null);
17812
- setDetailsLink(null);
17813
- setDetailsNode(targetNode);
17814
- const sceneMesh = stateRef.current.nodeObjects[String(id)];
17815
- if (sceneMesh) {
17816
- tweenToTarget(sceneMesh);
17817
- }
17818
- } else {
17819
- alert("Node original n\xE3o encontrado neste contexto.");
17820
- }
17821
- } else if (type === "ancestry") {
17822
- const targetAncestry = allAvailableAncestries.find(
17823
- (a) => String(a.ancestry_id) === String(id)
17824
- );
17825
- if (targetAncestry) {
17826
- setDetailsNode(null);
17827
- setDetailsLink(null);
17828
- setAncestryLinkDetails(null);
17829
- handleEditAncestry(targetAncestry);
17830
- } else {
17831
- alert("Ancestralidade original n\xE3o encontrada neste contexto.");
17832
- }
17833
- }
17834
- },
17835
- [
17836
- allAvailableNodes,
17837
- allAvailableAncestries,
17838
- handleEditAncestry,
17839
- tweenToTarget
17840
- ]
17841
- );
17842
- const handleToggleAncestryAddMode = (0, import_react29.useCallback)(() => {
17952
+ const handleToggleAncestryAddMode = (0, import_react31.useCallback)(() => {
17843
17953
  setAncestryMode((prev) => ({
17844
17954
  ...prev,
17845
17955
  isAddingNodes: !prev.isAddingNodes
17846
17956
  }));
17847
17957
  }, []);
17848
- const handleFocusNode = (0, import_react29.useCallback)(
17958
+ const handleFocusNode = (0, import_react31.useCallback)(
17849
17959
  (nodeData) => {
17850
17960
  var _a2;
17851
17961
  if (!nodeData) return;
@@ -17861,7 +17971,7 @@ function XViewScene({
17861
17971
  },
17862
17972
  [tweenToTarget]
17863
17973
  );
17864
- const availableDatasets = (0, import_react29.useMemo)(() => {
17974
+ const availableDatasets = (0, import_react31.useMemo)(() => {
17865
17975
  if (!sceneDataRef.current || !parentDataRef.current) return [];
17866
17976
  return sceneDataRef.current.parent_dbs.map((db) => {
17867
17977
  var _a2;
@@ -17875,7 +17985,7 @@ function XViewScene({
17875
17985
  String(creationMode.sourceNodeData.id)
17876
17986
  )) == null ? void 0 : _b.parentFileId : null;
17877
17987
  const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
17878
- (0, import_react29.useEffect)(() => {
17988
+ (0, import_react31.useEffect)(() => {
17879
17989
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
17880
17990
  const nodeObjects = stateRef.current.nodeObjects || {};
17881
17991
  const targetMesh = nodeObjects[String(focusNodeId)];
@@ -17898,7 +18008,7 @@ function XViewScene({
17898
18008
  hasFocusedInitial,
17899
18009
  tweenToTarget
17900
18010
  ]);
17901
- (0, import_react29.useEffect)(() => {
18011
+ (0, import_react31.useEffect)(() => {
17902
18012
  if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
17903
18013
  const ancestries = ancestryDataRef.current || [];
17904
18014
  const targetAncestry = ancestries.find(
@@ -17923,7 +18033,7 @@ function XViewScene({
17923
18033
  hasOpenedInitialAncestry,
17924
18034
  handleStartReadingAncestry
17925
18035
  ]);
17926
- (0, import_react29.useEffect)(() => {
18036
+ (0, import_react31.useEffect)(() => {
17927
18037
  function handleKeyDown(event) {
17928
18038
  var _a2, _b2, _c2;
17929
18039
  const context = actionHandlerContext;
@@ -18046,10 +18156,10 @@ function XViewScene({
18046
18156
  // <-- handleCancelQuest adicionado aqui
18047
18157
  ]);
18048
18158
  if (isLoading || status === "loading" || permissionStatus === "loading") {
18049
- return /* @__PURE__ */ import_react29.default.createElement(LoadingScreen, null);
18159
+ return /* @__PURE__ */ import_react31.default.createElement(LoadingScreen, null);
18050
18160
  }
18051
18161
  if (permissionStatus === "denied") {
18052
- return /* @__PURE__ */ import_react29.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react29.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_react29.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react29.default.createElement(
18162
+ return /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react31.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_react31.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react31.default.createElement(
18053
18163
  "svg",
18054
18164
  {
18055
18165
  xmlns: "http://www.w3.org/2000/svg",
@@ -18059,7 +18169,7 @@ function XViewScene({
18059
18169
  stroke: "currentColor",
18060
18170
  className: "w-16 h-16 mx-auto"
18061
18171
  },
18062
- /* @__PURE__ */ import_react29.default.createElement(
18172
+ /* @__PURE__ */ import_react31.default.createElement(
18063
18173
  "path",
18064
18174
  {
18065
18175
  strokeLinecap: "round",
@@ -18067,13 +18177,13 @@ function XViewScene({
18067
18177
  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"
18068
18178
  }
18069
18179
  )
18070
- )), /* @__PURE__ */ import_react29.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react29.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_react29.default.createElement(
18180
+ )), /* @__PURE__ */ import_react31.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react31.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_react31.default.createElement(
18071
18181
  "button",
18072
18182
  {
18073
18183
  onClick: () => router.push("/dashboard/scenes"),
18074
18184
  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"
18075
18185
  },
18076
- /* @__PURE__ */ import_react29.default.createElement(
18186
+ /* @__PURE__ */ import_react31.default.createElement(
18077
18187
  "svg",
18078
18188
  {
18079
18189
  xmlns: "http://www.w3.org/2000/svg",
@@ -18083,7 +18193,7 @@ function XViewScene({
18083
18193
  stroke: "currentColor",
18084
18194
  className: "w-5 h-5"
18085
18195
  },
18086
- /* @__PURE__ */ import_react29.default.createElement(
18196
+ /* @__PURE__ */ import_react31.default.createElement(
18087
18197
  "path",
18088
18198
  {
18089
18199
  strokeLinecap: "round",
@@ -18095,7 +18205,7 @@ function XViewScene({
18095
18205
  "Voltar para Scenes"
18096
18206
  )));
18097
18207
  }
18098
- return /* @__PURE__ */ import_react29.default.createElement(
18208
+ return /* @__PURE__ */ import_react31.default.createElement(
18099
18209
  "div",
18100
18210
  {
18101
18211
  ref: mountRef,
@@ -18107,7 +18217,7 @@ function XViewScene({
18107
18217
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
18108
18218
  }
18109
18219
  },
18110
- userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react29.default.createElement(
18220
+ userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react31.default.createElement(
18111
18221
  XViewSidebar,
18112
18222
  {
18113
18223
  dbNodes: searchableDbNodes,
@@ -18131,7 +18241,7 @@ function XViewScene({
18131
18241
  onOpenMilestoneManager: () => setIsMilestoneManagerOpen(true)
18132
18242
  }
18133
18243
  ),
18134
- creationMode.isActive && /* @__PURE__ */ import_react29.default.createElement(
18244
+ creationMode.isActive && /* @__PURE__ */ import_react31.default.createElement(
18135
18245
  InSceneCreationForm,
18136
18246
  {
18137
18247
  onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
@@ -18163,7 +18273,7 @@ function XViewScene({
18163
18273
  availableAncestries: allAvailableAncestries
18164
18274
  }
18165
18275
  ),
18166
- versionMode.isActive && /* @__PURE__ */ import_react29.default.createElement(
18276
+ versionMode.isActive && /* @__PURE__ */ import_react31.default.createElement(
18167
18277
  InSceneVersionForm,
18168
18278
  {
18169
18279
  onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
@@ -18189,7 +18299,7 @@ function XViewScene({
18189
18299
  availableAncestries: allAvailableAncestries
18190
18300
  }
18191
18301
  ),
18192
- questMode.isActive && /* @__PURE__ */ import_react29.default.createElement(
18302
+ questMode.isActive && /* @__PURE__ */ import_react31.default.createElement(
18193
18303
  InSceneQuestForm,
18194
18304
  {
18195
18305
  onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
@@ -18217,7 +18327,7 @@ function XViewScene({
18217
18327
  onUpdateMilestones: handleUpdateMilestones
18218
18328
  }
18219
18329
  ),
18220
- readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react29.default.createElement(
18330
+ readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react31.default.createElement(
18221
18331
  "div",
18222
18332
  {
18223
18333
  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"}`,
@@ -18230,7 +18340,7 @@ function XViewScene({
18230
18340
  maxWidth: "92vw"
18231
18341
  }
18232
18342
  },
18233
- /* @__PURE__ */ import_react29.default.createElement(
18343
+ /* @__PURE__ */ import_react31.default.createElement(
18234
18344
  "div",
18235
18345
  {
18236
18346
  onPointerDown: (e) => {
@@ -18241,7 +18351,7 @@ function XViewScene({
18241
18351
  title: "Arraste para redimensionar"
18242
18352
  }
18243
18353
  ),
18244
- /* @__PURE__ */ import_react29.default.createElement(
18354
+ /* @__PURE__ */ import_react31.default.createElement(
18245
18355
  DescriptionReadModePanel,
18246
18356
  {
18247
18357
  key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
@@ -18276,7 +18386,7 @@ function XViewScene({
18276
18386
  }
18277
18387
  )
18278
18388
  ),
18279
- ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react29.default.createElement(
18389
+ ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react31.default.createElement(
18280
18390
  CreateAncestryPanel,
18281
18391
  {
18282
18392
  ancestryMode,
@@ -18312,7 +18422,7 @@ function XViewScene({
18312
18422
  onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
18313
18423
  }
18314
18424
  ),
18315
- editingAncestryRel.visible && /* @__PURE__ */ import_react29.default.createElement(
18425
+ editingAncestryRel.visible && /* @__PURE__ */ import_react31.default.createElement(
18316
18426
  AncestryRelationshipPanel,
18317
18427
  {
18318
18428
  data: editingAncestryRel.data,
@@ -18326,7 +18436,7 @@ function XViewScene({
18326
18436
  onUploadFile: upload_file_action
18327
18437
  }
18328
18438
  ),
18329
- detailsNode && detailsNode.is_quest && /* @__PURE__ */ import_react29.default.createElement(
18439
+ detailsNode && detailsNode.is_quest && /* @__PURE__ */ import_react31.default.createElement(
18330
18440
  QuestDetailsPanel,
18331
18441
  {
18332
18442
  node: detailsNode,
@@ -18352,7 +18462,7 @@ function XViewScene({
18352
18462
  onUpdateMilestones: handleUpdateMilestones
18353
18463
  }
18354
18464
  ),
18355
- detailsNode && !detailsNode.is_quest && /* @__PURE__ */ import_react29.default.createElement(
18465
+ detailsNode && !detailsNode.is_quest && /* @__PURE__ */ import_react31.default.createElement(
18356
18466
  NodeDetailsPanel,
18357
18467
  {
18358
18468
  node: detailsNode,
@@ -18384,7 +18494,7 @@ function XViewScene({
18384
18494
  currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
18385
18495
  }
18386
18496
  ),
18387
- detailsLink && /* @__PURE__ */ import_react29.default.createElement(
18497
+ detailsLink && /* @__PURE__ */ import_react31.default.createElement(
18388
18498
  RelationshipDetailsPanel,
18389
18499
  {
18390
18500
  link: detailsLink,
@@ -18398,7 +18508,7 @@ function XViewScene({
18398
18508
  userRole: userPermissionRole
18399
18509
  }
18400
18510
  ),
18401
- ancestryLinkDetails && /* @__PURE__ */ import_react29.default.createElement(
18511
+ ancestryLinkDetails && /* @__PURE__ */ import_react31.default.createElement(
18402
18512
  AncestryLinkDetailsPanel,
18403
18513
  {
18404
18514
  data: ancestryLinkDetails,
@@ -18409,7 +18519,7 @@ function XViewScene({
18409
18519
  onUploadFile: upload_file_action
18410
18520
  }
18411
18521
  ),
18412
- /* @__PURE__ */ import_react29.default.createElement(
18522
+ /* @__PURE__ */ import_react31.default.createElement(
18413
18523
  "div",
18414
18524
  {
18415
18525
  ref: tooltipRef,
@@ -18436,7 +18546,7 @@ function XViewScene({
18436
18546
  }
18437
18547
  }
18438
18548
  ),
18439
- /* @__PURE__ */ import_react29.default.createElement(
18549
+ /* @__PURE__ */ import_react31.default.createElement(
18440
18550
  ContextMenu,
18441
18551
  {
18442
18552
  data: contextMenu,
@@ -18469,7 +18579,7 @@ function XViewScene({
18469
18579
  onFinishQuest: handleFinishQuestQuick
18470
18580
  }
18471
18581
  ),
18472
- /* @__PURE__ */ import_react29.default.createElement(
18582
+ /* @__PURE__ */ import_react31.default.createElement(
18473
18583
  MultiNodeContextMenu,
18474
18584
  {
18475
18585
  data: multiContextMenu,
@@ -18489,7 +18599,7 @@ function XViewScene({
18489
18599
  )
18490
18600
  }
18491
18601
  ),
18492
- /* @__PURE__ */ import_react29.default.createElement(
18602
+ /* @__PURE__ */ import_react31.default.createElement(
18493
18603
  RelationshipContextMenu,
18494
18604
  {
18495
18605
  data: relationshipMenu,
@@ -18507,14 +18617,14 @@ function XViewScene({
18507
18617
  onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
18508
18618
  }
18509
18619
  ),
18510
- /* @__PURE__ */ import_react29.default.createElement(
18620
+ /* @__PURE__ */ import_react31.default.createElement(
18511
18621
  ImageViewer,
18512
18622
  {
18513
18623
  data: imageViewer,
18514
18624
  onClose: () => setImageViewer({ ...imageViewer, visible: false })
18515
18625
  }
18516
18626
  ),
18517
- /* @__PURE__ */ import_react29.default.createElement(
18627
+ /* @__PURE__ */ import_react31.default.createElement(
18518
18628
  AncestryBoard,
18519
18629
  {
18520
18630
  isOpen: isAncestryBoardOpen,
@@ -18527,7 +18637,7 @@ function XViewScene({
18527
18637
  userRole: userPermissionRole
18528
18638
  }
18529
18639
  ),
18530
- /* @__PURE__ */ import_react29.default.createElement(
18640
+ /* @__PURE__ */ import_react31.default.createElement(
18531
18641
  MilestoneManager,
18532
18642
  {
18533
18643
  isOpen: isMilestoneManagerOpen,
@@ -18536,7 +18646,7 @@ function XViewScene({
18536
18646
  onUpdateMilestones: handleUpdateMilestones
18537
18647
  }
18538
18648
  ),
18539
- /* @__PURE__ */ import_react29.default.createElement(
18649
+ /* @__PURE__ */ import_react31.default.createElement(
18540
18650
  ImportParentFileModal,
18541
18651
  {
18542
18652
  isOpen: isImportModalOpen,
@@ -18549,7 +18659,7 @@ function XViewScene({
18549
18659
  currentAncestries: ancestryDataRef.current || []
18550
18660
  }
18551
18661
  ),
18552
- invalidTargetError && /* @__PURE__ */ import_react29.default.createElement(
18662
+ invalidTargetError && /* @__PURE__ */ import_react31.default.createElement(
18553
18663
  "div",
18554
18664
  {
18555
18665
  className: "ui-overlay",
@@ -18574,13 +18684,13 @@ function XViewScene({
18574
18684
  animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
18575
18685
  }
18576
18686
  },
18577
- /* @__PURE__ */ import_react29.default.createElement("style", null, `
18687
+ /* @__PURE__ */ import_react31.default.createElement("style", null, `
18578
18688
  @keyframes fadeInDown {
18579
18689
  from { opacity: 0; transform: translate(-50%, -20px); }
18580
18690
  to { opacity: 1; transform: translate(-50%, 0); }
18581
18691
  }
18582
18692
  `),
18583
- /* @__PURE__ */ import_react29.default.createElement(
18693
+ /* @__PURE__ */ import_react31.default.createElement(
18584
18694
  "svg",
18585
18695
  {
18586
18696
  width: "20",
@@ -18592,12 +18702,12 @@ function XViewScene({
18592
18702
  strokeLinecap: "round",
18593
18703
  strokeLinejoin: "round"
18594
18704
  },
18595
- /* @__PURE__ */ import_react29.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
18596
- /* @__PURE__ */ import_react29.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
18597
- /* @__PURE__ */ import_react29.default.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
18705
+ /* @__PURE__ */ import_react31.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
18706
+ /* @__PURE__ */ import_react31.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
18707
+ /* @__PURE__ */ import_react31.default.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
18598
18708
  ),
18599
- /* @__PURE__ */ import_react29.default.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
18600
- /* @__PURE__ */ import_react29.default.createElement(
18709
+ /* @__PURE__ */ import_react31.default.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
18710
+ /* @__PURE__ */ import_react31.default.createElement(
18601
18711
  "button",
18602
18712
  {
18603
18713
  onClick: () => setInvalidTargetError(null),