@lv-x-software-house/x_view 1.2.6-dev.1 → 1.2.6-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +506 -561
  2. package/dist/index.mjs +475 -519
  3. package/package.json +12 -3
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_react32 = __toESM(require("react"));
48
48
  var import_navigation = require("next/navigation");
49
- var import_react30 = require("next-auth/react");
49
+ var import_react33 = 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
@@ -2519,15 +2471,15 @@ function createNewCustomProperty(existingProps = []) {
2519
2471
  switch (nextType) {
2520
2472
  case "links":
2521
2473
  nextKey = "Links";
2522
- nextValue = [{ id: v4_default(), name: "", value: "" }];
2474
+ nextValue = [{ id: (0, import_uuid.v4)(), name: "", value: "" }];
2523
2475
  break;
2524
2476
  case "images":
2525
2477
  nextKey = "Images";
2526
- nextValue = [{ id: v4_default(), name: "1", value: "" }];
2478
+ nextValue = [{ id: (0, import_uuid.v4)(), name: "1", value: "" }];
2527
2479
  break;
2528
2480
  case "documents":
2529
2481
  nextKey = "Documents";
2530
- nextValue = [{ id: v4_default(), name: "1", value: "" }];
2482
+ nextValue = [{ id: (0, import_uuid.v4)(), name: "1", value: "" }];
2531
2483
  break;
2532
2484
  case "date":
2533
2485
  nextKey = "Date";
@@ -2537,14 +2489,14 @@ function createNewCustomProperty(existingProps = []) {
2537
2489
  nextValue = 0;
2538
2490
  break;
2539
2491
  case "list":
2540
- nextValue = [{ id: v4_default(), name: "", value: "" }];
2492
+ nextValue = [{ id: (0, import_uuid.v4)(), name: "", value: "" }];
2541
2493
  break;
2542
2494
  default:
2543
2495
  nextValue = "";
2544
2496
  break;
2545
2497
  }
2546
2498
  return {
2547
- id: v4_default(),
2499
+ id: (0, import_uuid.v4)(),
2548
2500
  key: nextKey,
2549
2501
  type: nextType,
2550
2502
  value: nextValue,
@@ -2789,7 +2741,7 @@ function extractCustomPropsFromNode(node) {
2789
2741
  if (val && typeof val === "object") {
2790
2742
  if ("date_interval" in val) {
2791
2743
  return {
2792
- id: v4_default(),
2744
+ id: (0, import_uuid.v4)(),
2793
2745
  key,
2794
2746
  type: "date",
2795
2747
  value: {
@@ -2801,7 +2753,7 @@ function extractCustomPropsFromNode(node) {
2801
2753
  }
2802
2754
  if ("year" in val) {
2803
2755
  return {
2804
- id: v4_default(),
2756
+ id: (0, import_uuid.v4)(),
2805
2757
  key,
2806
2758
  type: "date",
2807
2759
  value: { type: "Ano", value: val.year || "" }
@@ -2809,7 +2761,7 @@ function extractCustomPropsFromNode(node) {
2809
2761
  }
2810
2762
  if ("date" in val) {
2811
2763
  return {
2812
- id: v4_default(),
2764
+ id: (0, import_uuid.v4)(),
2813
2765
  key,
2814
2766
  type: "date",
2815
2767
  value: { type: "Data", value: val.date || "" }
@@ -2817,7 +2769,7 @@ function extractCustomPropsFromNode(node) {
2817
2769
  }
2818
2770
  }
2819
2771
  return {
2820
- id: v4_default(),
2772
+ id: (0, import_uuid.v4)(),
2821
2773
  key,
2822
2774
  type: "date",
2823
2775
  value: { type: "Data", value: "" }
@@ -2825,14 +2777,14 @@ function extractCustomPropsFromNode(node) {
2825
2777
  }
2826
2778
  if (t === "list" || t === "links" || t === "images" || t === "documents") {
2827
2779
  const safeList = (val || []).map((item) => ({
2828
- id: item.id || v4_default(),
2780
+ id: item.id || (0, import_uuid.v4)(),
2829
2781
  name: item.name ?? "",
2830
2782
  value: item.value ?? ""
2831
2783
  }));
2832
- return { id: v4_default(), key, type: t, value: safeList };
2784
+ return { id: (0, import_uuid.v4)(), key, type: t, value: safeList };
2833
2785
  }
2834
2786
  return {
2835
- id: v4_default(),
2787
+ id: (0, import_uuid.v4)(),
2836
2788
  key,
2837
2789
  type: t,
2838
2790
  value: t === "number" ? Number(val) || 0 : String(val ?? "")
@@ -3105,16 +3057,16 @@ var processDescriptionForSave = (text, existingSections = []) => {
3105
3057
  if (existingMatch) {
3106
3058
  finalUuid = existingMatch.id;
3107
3059
  } else {
3108
- finalUuid = v4_default();
3060
+ finalUuid = (0, import_uuid.v4)();
3109
3061
  }
3110
3062
  } else {
3111
3063
  finalUuid = numericMap.get(numStr);
3112
3064
  if (!finalUuid) {
3113
- finalUuid = v4_default();
3065
+ finalUuid = (0, import_uuid.v4)();
3114
3066
  }
3115
3067
  }
3116
3068
  if (usedIds.has(finalUuid)) {
3117
- finalUuid = v4_default();
3069
+ finalUuid = (0, import_uuid.v4)();
3118
3070
  }
3119
3071
  usedIds.add(finalUuid);
3120
3072
  processedSections.push({
@@ -3225,18 +3177,18 @@ function useResizablePanel({ initialWidth, minWidth, maxWidth }) {
3225
3177
  function createTimelineEntry(actorId, description, type = "comment", extras = {}) {
3226
3178
  const { links = [], images = [], metadata = {} } = extras;
3227
3179
  return {
3228
- id: v4_default(),
3180
+ id: (0, import_uuid.v4)(),
3229
3181
  type,
3230
3182
  timestamp: Date.now(),
3231
3183
  actorId,
3232
3184
  description,
3233
3185
  links: links.map((l) => ({
3234
- id: l.id || v4_default(),
3186
+ id: l.id || (0, import_uuid.v4)(),
3235
3187
  name: l.name || "",
3236
3188
  value: l.value || ""
3237
3189
  })),
3238
3190
  images: images.map((img) => ({
3239
- id: img.id || v4_default(),
3191
+ id: img.id || (0, import_uuid.v4)(),
3240
3192
  name: img.name || "",
3241
3193
  value: img.value || ""
3242
3194
  }))
@@ -4463,6 +4415,7 @@ function XViewSidebar({
4463
4415
 
4464
4416
  // src/components/AncestryRelationshipPanel.jsx
4465
4417
  var import_react9 = __toESM(require("react"));
4418
+ var import_uuid3 = require("uuid");
4466
4419
 
4467
4420
  // src/components/CustomPropertyDisplay.jsx
4468
4421
  var import_react4 = __toESM(require("react"));
@@ -5222,6 +5175,7 @@ function SectionImportModal({ isOpen, onClose, onSelect, availableNodes = [], av
5222
5175
  }
5223
5176
 
5224
5177
  // src/components/DescriptionEditModal.jsx
5178
+ var import_uuid2 = require("uuid");
5225
5179
  var getNextSectionNumber = (currentText) => {
5226
5180
  const regex = /\*\/\s*(\d+)(?::[a-zA-Z0-9-]+)?\s*\//g;
5227
5181
  let max = 0;
@@ -5353,7 +5307,7 @@ function DescriptionEditModal({
5353
5307
  const el = textareaRef.current;
5354
5308
  if (!el) return;
5355
5309
  const nextNum = getNextSectionNumber(text);
5356
- const uniqueSuffix = v4_default().slice(0, 4);
5310
+ const uniqueSuffix = (0, import_uuid2.v4)().slice(0, 4);
5357
5311
  insertAtCursor(`*/${nextNum}:${uniqueSuffix}/ `);
5358
5312
  };
5359
5313
  const handleImportSelect = (tags) => {
@@ -5364,7 +5318,7 @@ function DescriptionEditModal({
5364
5318
  let currentNum = getNextSectionNumber(currentText);
5365
5319
  let blockToInsert = "";
5366
5320
  tagsArray.forEach((tag) => {
5367
- const uniqueSuffix = v4_default().slice(0, 4);
5321
+ const uniqueSuffix = (0, import_uuid2.v4)().slice(0, 4);
5368
5322
  blockToInsert += `
5369
5323
  */${currentNum}:${uniqueSuffix}/ ${tag}
5370
5324
  `;
@@ -6693,6 +6647,7 @@ function AncestryRelationshipPanel({
6693
6647
  // src/components/CreateAncestryPanel.jsx
6694
6648
  var import_react11 = __toESM(require("react"));
6695
6649
  var import_fi10 = require("react-icons/fi");
6650
+ var import_uuid4 = require("uuid");
6696
6651
 
6697
6652
  // src/components/AncestryPickerModal.jsx
6698
6653
  var import_react10 = __toESM(require("react"));
@@ -7729,7 +7684,7 @@ function CreateAncestryPanel({
7729
7684
  const nodeData = availableNodes.find((n) => String(n.id) === String(nodeId));
7730
7685
  const dirSuffix = direction === "left" ? "(Esq)" : "(Dir)";
7731
7686
  branch = {
7732
- id: v4_default(),
7687
+ id: (0, import_uuid4.v4)(),
7733
7688
  name: `Ramifica\xE7\xE3o ${dirSuffix} de ${(nodeData == null ? void 0 : nodeData.name) || "Node"}`,
7734
7689
  description: "",
7735
7690
  description_sections: [],
@@ -8508,6 +8463,7 @@ function ImageViewer({ data, onClose }) {
8508
8463
 
8509
8464
  // src/components/InSceneCreationForm.jsx
8510
8465
  var import_react14 = __toESM(require("react"));
8466
+ var import_uuid5 = require("uuid");
8511
8467
 
8512
8468
  // src/components/ColorPicker.jsx
8513
8469
  var import_react13 = __toESM(require("react"));
@@ -9084,6 +9040,7 @@ function InSceneCreationForm({
9084
9040
 
9085
9041
  // src/components/InSceneVersionForm.jsx
9086
9042
  var import_react15 = __toESM(require("react"));
9043
+ var import_uuid6 = require("uuid");
9087
9044
  var import_fi14 = require("react-icons/fi");
9088
9045
  function InSceneVersionForm({
9089
9046
  onSave,
@@ -9106,7 +9063,7 @@ function InSceneVersionForm({
9106
9063
  const [description, setDescription] = (0, import_react15.useState)("");
9107
9064
  const [customProps, setCustomProps] = (0, import_react15.useState)([
9108
9065
  {
9109
- id: v4_default(),
9066
+ id: (0, import_uuid6.v4)(),
9110
9067
  key: "Date",
9111
9068
  type: "date",
9112
9069
  value: { type: "Data", value: "" },
@@ -9399,6 +9356,7 @@ function InSceneVersionForm({
9399
9356
 
9400
9357
  // src/components/InSceneQuestForm.jsx
9401
9358
  var import_react17 = __toESM(require("react"));
9359
+ var import_uuid7 = require("uuid");
9402
9360
  var import_fi16 = require("react-icons/fi");
9403
9361
 
9404
9362
  // src/components/QuestReviewStackEditor.jsx
@@ -10304,6 +10262,7 @@ function InSceneQuestForm({
10304
10262
 
10305
10263
  // src/components/NodeDetailsPanel.jsx
10306
10264
  var import_react18 = __toESM(require("react"));
10265
+ var import_uuid8 = require("uuid");
10307
10266
  var import_fi17 = require("react-icons/fi");
10308
10267
  function NodeDetailsPanel({
10309
10268
  node,
@@ -10818,6 +10777,7 @@ function NodeDetailsPanel({
10818
10777
 
10819
10778
  // src/components/QuestDetailsPanel.jsx
10820
10779
  var import_react20 = __toESM(require("react"));
10780
+ var import_uuid9 = require("uuid");
10821
10781
  var import_fi19 = require("react-icons/fi");
10822
10782
 
10823
10783
  // src/components/QuestTimeline.jsx
@@ -11256,7 +11216,7 @@ ${noteText}` : noteText : entry.notes,
11256
11216
  }, 100);
11257
11217
  };
11258
11218
  const addLinkToNote = () => {
11259
- setNoteLinks([...noteLinks, { id: v4_default(), name: "", value: "" }]);
11219
+ setNoteLinks([...noteLinks, { id: (0, import_uuid9.v4)(), name: "", value: "" }]);
11260
11220
  };
11261
11221
  const removeLinkFromNote = (id) => {
11262
11222
  setNoteLinks(noteLinks.filter((l) => l.id !== id));
@@ -11265,7 +11225,7 @@ ${noteText}` : noteText : entry.notes,
11265
11225
  setNoteLinks(noteLinks.map((l) => l.id === id ? { ...l, [field]: val } : l));
11266
11226
  };
11267
11227
  const addImageToNote = () => {
11268
- setNoteImages([...noteImages, { id: v4_default(), name: "Image", value: "" }]);
11228
+ setNoteImages([...noteImages, { id: (0, import_uuid9.v4)(), name: "Image", value: "" }]);
11269
11229
  };
11270
11230
  const removeImageFromNote = (id) => {
11271
11231
  setNoteImages(noteImages.filter((img) => img.id !== id));
@@ -12142,6 +12102,7 @@ function MultiNodeContextMenu({
12142
12102
 
12143
12103
  // src/components/RelationshipDetailsPanel.jsx
12144
12104
  var import_react22 = __toESM(require("react"));
12105
+ var import_uuid10 = require("uuid");
12145
12106
  var import_fi20 = require("react-icons/fi");
12146
12107
  function RelationshipDetailsPanel({
12147
12108
  link,
@@ -12951,149 +12912,309 @@ function AncestryLinkDetailsPanel({ data, onClose, onOpenImageViewer, onOpenRefe
12951
12912
  }
12952
12913
 
12953
12914
  // src/components/AncestryBoard.jsx
12915
+ var import_react30 = __toESM(require("react"));
12916
+ var import_fi23 = require("react-icons/fi");
12917
+ var import_uuid11 = require("uuid");
12918
+
12919
+ // src/components/MentionEditor.jsx
12920
+ var import_react28 = __toESM(require("react"));
12921
+ var import_react29 = require("@tiptap/react");
12922
+ var import_starter_kit = __toESM(require("@tiptap/starter-kit"));
12923
+ var import_extension_mention = __toESM(require("@tiptap/extension-mention"));
12924
+ var import_tippy = __toESM(require("tippy.js"));
12925
+
12926
+ // src/components/MentionList.jsx
12954
12927
  var import_react27 = __toESM(require("react"));
12955
12928
  var import_fi22 = require("react-icons/fi");
12929
+ var MentionList = (0, import_react27.forwardRef)((props, ref) => {
12930
+ const [selectedIndex, setSelectedIndex] = (0, import_react27.useState)(0);
12931
+ const selectItem = (index) => {
12932
+ const item = props.items[index];
12933
+ if (item) {
12934
+ props.command({ id: item.id, label: item.name, type: item.type });
12935
+ }
12936
+ };
12937
+ const upHandler = () => {
12938
+ setSelectedIndex(
12939
+ (selectedIndex + props.items.length - 1) % props.items.length
12940
+ );
12941
+ };
12942
+ const downHandler = () => {
12943
+ setSelectedIndex((selectedIndex + 1) % props.items.length);
12944
+ };
12945
+ const enterHandler = () => {
12946
+ selectItem(selectedIndex);
12947
+ };
12948
+ (0, import_react27.useEffect)(() => setSelectedIndex(0), [props.items]);
12949
+ (0, import_react27.useImperativeHandle)(ref, () => ({
12950
+ onKeyDown: ({ event }) => {
12951
+ if (event.key === "ArrowUp") {
12952
+ upHandler();
12953
+ return true;
12954
+ }
12955
+ if (event.key === "ArrowDown") {
12956
+ downHandler();
12957
+ return true;
12958
+ }
12959
+ if (event.key === "Enter") {
12960
+ enterHandler();
12961
+ return true;
12962
+ }
12963
+ return false;
12964
+ }
12965
+ }));
12966
+ return /* @__PURE__ */ import_react27.default.createElement("div", { className: "z-[3000] bg-slate-900 border border-white/10 rounded-lg shadow-2xl overflow-hidden min-w-[280px] max-w-[400px] animate-in fade-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "p-2 border-b border-white/5 bg-slate-950/50 flex items-center gap-2" }, /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiSearch, { className: "text-indigo-400", size: 14 }), /* @__PURE__ */ import_react27.default.createElement("span", { className: "text-[10px] uppercase tracking-wider font-bold text-slate-500" }, "Mencionar Recurso")), /* @__PURE__ */ import_react27.default.createElement("div", { className: "p-1 max-h-[300px] overflow-y-auto custom-scrollbar" }, props.items.length ? props.items.map((item, index) => {
12967
+ const isQuest = item.type === "quest";
12968
+ const isVersion = item.type === "version";
12969
+ const isNode = item.type === "node";
12970
+ let Icon = import_fi22.FiLayers;
12971
+ let colorClass = "text-indigo-400";
12972
+ let badgeText = "Ancestralidade";
12973
+ if (isQuest) {
12974
+ Icon = import_fi22.FiCheckSquare;
12975
+ colorClass = "text-amber-400";
12976
+ badgeText = "Quest";
12977
+ } else if (isVersion) {
12978
+ Icon = import_fi22.FiGitBranch;
12979
+ colorClass = "text-purple-400";
12980
+ badgeText = "Vers\xE3o";
12981
+ } else if (isNode) {
12982
+ Icon = import_fi22.FiBox;
12983
+ colorClass = "text-emerald-400";
12984
+ badgeText = "Node";
12985
+ }
12986
+ return /* @__PURE__ */ import_react27.default.createElement(
12987
+ "button",
12988
+ {
12989
+ className: `
12990
+ w-full flex items-center gap-3 px-3 py-2 text-left rounded-md transition-all
12991
+ ${index === selectedIndex ? "bg-indigo-500/20 border border-indigo-500/30 text-white" : "text-slate-400 hover:bg-white/5 border border-transparent"}
12992
+ `,
12993
+ key: item.id,
12994
+ onClick: () => selectItem(index)
12995
+ },
12996
+ /* @__PURE__ */ import_react27.default.createElement("div", { className: `shrink-0 w-8 h-8 rounded border border-white/5 flex items-center justify-center bg-slate-800/50 ${colorClass}` }, /* @__PURE__ */ import_react27.default.createElement(Icon, { size: 14 })),
12997
+ /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex items-center justify-between gap-2" }, /* @__PURE__ */ import_react27.default.createElement("span", { className: "text-sm font-medium truncate" }, item.name), /* @__PURE__ */ import_react27.default.createElement("span", { className: `text-[9px] px-1 py-0.5 rounded border border-current opacity-60 ${colorClass}` }, badgeText)))
12998
+ );
12999
+ }) : /* @__PURE__ */ import_react27.default.createElement("div", { className: "p-4 text-center text-slate-500 text-sm italic" }, "Nenhum resultado encontrado...")));
13000
+ });
13001
+ MentionList.displayName = "MentionList";
13002
+ var MentionList_default = MentionList;
13003
+
13004
+ // src/components/MentionEditor.jsx
13005
+ var CustomMention = import_extension_mention.default.extend({
13006
+ addAttributes() {
13007
+ var _a;
13008
+ return {
13009
+ ...(_a = this.parent) == null ? void 0 : _a.call(this),
13010
+ type: {
13011
+ default: null,
13012
+ parseHTML: (element) => element.getAttribute("data-mention-type"),
13013
+ renderHTML: (attributes) => {
13014
+ if (!attributes.type) {
13015
+ return {};
13016
+ }
13017
+ return {
13018
+ "data-mention-type": attributes.type
13019
+ };
13020
+ }
13021
+ }
13022
+ };
13023
+ }
13024
+ });
13025
+ var MentionEditor = ({
13026
+ initialValue = "",
13027
+ onChange,
13028
+ onPlay,
13029
+ // Mantido para futura expansão se quisermos badges clicáveis reais no editor
13030
+ availableItems = [],
13031
+ canEdit = true,
13032
+ placeholder = "Escreva algo... use @ para mencionar"
13033
+ }) => {
13034
+ const parseInitialContent = (text) => {
13035
+ if (!text) return "<p></p>";
13036
+ const parts = text.split(/(\[\[MENTION:[^\]]+\]\])/g);
13037
+ return parts.map((part) => {
13038
+ const match = part.match(/\[\[MENTION:([^:]+):([^:]+):([^\]]+)\]\]/);
13039
+ if (match) {
13040
+ const [, type, id, label] = match;
13041
+ return `<span data-type="mention" data-id="${id}" data-mention-type="${type}" data-label="${label}">@${label}</span>`;
13042
+ }
13043
+ return part;
13044
+ }).join("");
13045
+ };
13046
+ const content = (0, import_react28.useMemo)(() => parseInitialContent(initialValue), [initialValue]);
13047
+ const editor = (0, import_react29.useEditor)({
13048
+ extensions: [
13049
+ import_starter_kit.default.configure({
13050
+ heading: false,
13051
+ bulletList: false,
13052
+ orderedList: false,
13053
+ codeBlock: false,
13054
+ blockquote: false
13055
+ }),
13056
+ CustomMention.configure({
13057
+ HTMLAttributes: {
13058
+ class: "mention"
13059
+ },
13060
+ suggestion: {
13061
+ items: ({ query }) => {
13062
+ return availableItems.filter(
13063
+ (item) => item.name.toLowerCase().includes(query.toLowerCase())
13064
+ ).slice(0, 10);
13065
+ },
13066
+ render: () => {
13067
+ let component;
13068
+ let popup;
13069
+ return {
13070
+ onStart: (props) => {
13071
+ component = new import_react29.ReactRenderer(MentionList_default, {
13072
+ props,
13073
+ editor: props.editor
13074
+ });
13075
+ if (!props.clientRect) {
13076
+ return;
13077
+ }
13078
+ popup = (0, import_tippy.default)("body", {
13079
+ getReferenceClientRect: props.clientRect,
13080
+ appendTo: () => document.body,
13081
+ content: component.element,
13082
+ showOnCreate: true,
13083
+ interactive: true,
13084
+ trigger: "manual",
13085
+ placement: "bottom-start"
13086
+ });
13087
+ },
13088
+ onUpdate(props) {
13089
+ component.updateProps(props);
13090
+ if (!props.clientRect) {
13091
+ return;
13092
+ }
13093
+ popup[0].setProps({
13094
+ getReferenceClientRect: props.clientRect
13095
+ });
13096
+ },
13097
+ onKeyDown(props) {
13098
+ var _a;
13099
+ if (props.event.key === "Escape") {
13100
+ popup[0].hide();
13101
+ return true;
13102
+ }
13103
+ return (_a = component == null ? void 0 : component.ref) == null ? void 0 : _a.onKeyDown(props);
13104
+ },
13105
+ onExit() {
13106
+ if (popup && popup[0]) popup[0].destroy();
13107
+ if (component) component.destroy();
13108
+ }
13109
+ };
13110
+ }
13111
+ }
13112
+ })
13113
+ ],
13114
+ content,
13115
+ editable: canEdit,
13116
+ onUpdate: ({ editor: editor2 }) => {
13117
+ const serialize = (json) => {
13118
+ if (!json.content) return "";
13119
+ return json.content.map((block) => {
13120
+ if (block.type === "paragraph") {
13121
+ const inner = block.content ? block.content.map((node) => {
13122
+ if (node.type === "text") return node.text;
13123
+ if (node.type === "mention") {
13124
+ return `[[MENTION:${node.attrs.type}:${node.attrs.id}:${node.attrs.label}]]`;
13125
+ }
13126
+ return "";
13127
+ }).join("") : "";
13128
+ return inner;
13129
+ }
13130
+ return "";
13131
+ }).join("\n").trim();
13132
+ };
13133
+ const serialized = serialize(editor2.getJSON());
13134
+ onChange(serialized);
13135
+ }
13136
+ });
13137
+ if (!editor) {
13138
+ return null;
13139
+ }
13140
+ return /* @__PURE__ */ import_react28.default.createElement("div", { className: "relative group/editor min-h-[1.5rem] w-full" }, /* @__PURE__ */ import_react28.default.createElement(
13141
+ import_react29.EditorContent,
13142
+ {
13143
+ editor,
13144
+ className: "text-sm text-slate-200 placeholder-slate-600 focus:outline-none"
13145
+ }
13146
+ ), /* @__PURE__ */ import_react28.default.createElement("style", null, `
13147
+ .tiptap p {
13148
+ margin: 0;
13149
+ min-height: 1.2em;
13150
+ }
13151
+ .tiptap .mention {
13152
+ display: inline-flex;
13153
+ align-items: center;
13154
+ background-color: rgba(99, 102, 241, 0.15);
13155
+ border: 1px solid rgba(99, 102, 241, 0.3);
13156
+ border-radius: 4px;
13157
+ padding: 0 4px;
13158
+ color: #a5b4fc;
13159
+ font-weight: 500;
13160
+ cursor: pointer;
13161
+ margin: 0 2px;
13162
+ transition: all 0.2s;
13163
+ }
13164
+ .tiptap .mention:hover {
13165
+ background-color: rgba(99, 102, 241, 0.25);
13166
+ border-color: rgba(99, 102, 241, 0.5);
13167
+ color: white;
13168
+ }
13169
+ .tiptap:focus {
13170
+ outline: none;
13171
+ }
13172
+ `));
13173
+ };
13174
+ var MentionEditor_default = MentionEditor;
13175
+
13176
+ // src/components/AncestryBoard.jsx
12956
13177
  var GroupItem = ({
12957
13178
  group,
12958
13179
  index,
12959
- siblings,
12960
13180
  onUpdate,
12961
13181
  onDelete,
12962
13182
  onAddSubgroup,
12963
13183
  onIndent,
12964
13184
  onOutdent,
12965
- onRemoveAncestry,
12966
- onRequestPickAncestry,
12967
- pickingGroupId,
12968
13185
  onPlayAncestry,
12969
- availableIds,
13186
+ availableMentionItems,
12970
13187
  canEdit
12971
13188
  }) => {
12972
13189
  const canIndent = index > 0;
12973
- const isPickingForThisGroup = pickingGroupId === group.id;
12974
- const textareaRef = (0, import_react27.useRef)(null);
12975
- const adjustHeight = () => {
12976
- const textarea = textareaRef.current;
12977
- if (textarea) {
12978
- textarea.style.height = "auto";
12979
- textarea.style.height = `${textarea.scrollHeight}px`;
12980
- }
12981
- };
12982
- (0, import_react27.useEffect)(() => {
12983
- adjustHeight();
12984
- }, [group.text]);
12985
- 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(
13190
+ return /* @__PURE__ */ import_react30.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_react30.default.createElement("div", { className: "absolute -left-[1px] top-4 w-2 h-px bg-white/20" }), /* @__PURE__ */ import_react30.default.createElement(
12986
13191
  "div",
12987
13192
  {
12988
- className: `
12989
- flex flex-col gap-2 py-2 px-3 transition-all duration-200
12990
- ${isPickingForThisGroup ? "bg-indigo-500/10 border-l-2 border-indigo-500" : "hover:bg-white/5 border-l-2 border-transparent hover:border-white/20"}
12991
- `
13193
+ 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"
12992
13194
  },
12993
- /* @__PURE__ */ import_react27.default.createElement(
12994
- "textarea",
13195
+ /* @__PURE__ */ import_react30.default.createElement(
13196
+ MentionEditor_default,
12995
13197
  {
12996
- ref: textareaRef,
12997
- 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" : ""}`,
12998
- rows: 1,
12999
- style: {
13000
- minHeight: "1.5rem",
13001
- maxHeight: "250px"
13198
+ initialValue: group.text,
13199
+ onChange: (newText) => {
13200
+ if (canEdit) onUpdate(group.id, { ...group, text: newText });
13002
13201
  },
13003
- placeholder: canEdit ? "Escreva sobre este grupo..." : "",
13004
- value: group.text,
13005
- readOnly: !canEdit,
13006
- onChange: (e) => {
13007
- if (canEdit) onUpdate(group.id, { ...group, text: e.target.value });
13008
- }
13202
+ onPlay: onPlayAncestry,
13203
+ availableItems: availableMentionItems,
13204
+ canEdit,
13205
+ placeholder: "Escreva sobre este grupo... use @ para mencionar"
13009
13206
  }
13010
13207
  ),
13011
- group.ancestries && group.ancestries.length > 0 && /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex flex-wrap gap-2 mt-1" }, group.ancestries.map((anc) => {
13012
- const isValid = anc.type === "ancestry" || !anc.type ? availableIds.has(String(anc.ancestry_id || anc.id)) : true;
13013
- const isAncestry = anc.type === "ancestry" || !anc.type;
13014
- const itemId = isAncestry ? anc.ancestry_id : anc.id;
13015
- let Icon = import_fi22.FiLayers;
13016
- let colorClass = "text-indigo-400";
13017
- if (anc.type === "quest") {
13018
- Icon = import_fi22.FiCheckSquare;
13019
- colorClass = "text-amber-400";
13020
- } else if (anc.type === "version") {
13021
- Icon = import_fi22.FiGitBranch;
13022
- colorClass = "text-purple-400";
13023
- } else if (anc.type === "node") {
13024
- Icon = import_fi22.FiBox;
13025
- colorClass = "text-emerald-400";
13026
- }
13027
- return /* @__PURE__ */ import_react27.default.createElement(
13028
- "div",
13029
- {
13030
- key: `${anc.type || "ancestry"}-${itemId}`,
13031
- className: `
13032
- flex items-center gap-2 rounded-md px-3 py-1.5 text-xs transition-all group/card border
13033
- ${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"}
13034
- `,
13035
- title: isValid ? "" : "Esta informa\xE7\xE3o n\xE3o est\xE1 mais dispon\xEDvel neste contexto."
13036
- },
13037
- isValid ? /* @__PURE__ */ import_react27.default.createElement(
13038
- "button",
13039
- {
13040
- onClick: () => onPlayAncestry(anc),
13041
- className: `${colorClass} hover:text-white hover:bg-current/20 p-1 rounded transition-colors flex items-center justify-center`,
13042
- title: "Focar no cen\xE1rio"
13043
- },
13044
- /* @__PURE__ */ import_react27.default.createElement(Icon, { size: 12 }),
13045
- /* @__PURE__ */ import_react27.default.createElement(
13046
- import_fi22.FiPlay,
13047
- {
13048
- size: 8,
13049
- className: "ml-0.5 fill-current opacity-0 group-hover/card:opacity-100 transition-opacity"
13050
- }
13051
- )
13052
- ) : /* @__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 })),
13053
- /* @__PURE__ */ import_react27.default.createElement(
13054
- "span",
13055
- {
13056
- className: `font-medium truncate max-w-[150px] ${!isValid && "line-through decoration-red-500/50"}`
13057
- },
13058
- anc.name
13059
- ),
13060
- canEdit && /* @__PURE__ */ import_react27.default.createElement(import_react27.default.Fragment, null, /* @__PURE__ */ import_react27.default.createElement(
13061
- "div",
13062
- {
13063
- className: `w-px h-3 mx-0.5 ${isValid ? "bg-white/10" : "bg-red-500/20"}`
13064
- }
13065
- ), /* @__PURE__ */ import_react27.default.createElement(
13066
- "button",
13067
- {
13068
- onClick: () => onRemoveAncestry(group.id, itemId),
13069
- className: `${isValid ? "text-slate-500 hover:text-red-400" : "text-red-400 hover:text-red-200"} p-0.5 rounded transition-colors`,
13070
- title: "Remover men\xE7\xE3o"
13071
- },
13072
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiX, { size: 12 })
13073
- ))
13074
- );
13075
- })),
13076
- 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(
13077
- "button",
13078
- {
13079
- onClick: () => onRequestPickAncestry(group.id),
13080
- className: `
13081
- flex items-center gap-1.5 px-2 py-1 rounded text-xs font-medium transition-colors
13082
- ${isPickingForThisGroup ? "text-indigo-300 animate-pulse" : "text-slate-500 hover:text-indigo-300 hover:bg-indigo-500/10"}
13083
- `,
13084
- title: "Adicionar Men\xE7\xE3o a este grupo"
13085
- },
13086
- isPickingForThisGroup ? /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiCheckCircle, { size: 12 }) : /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiSearch, { size: 12 }),
13087
- isPickingForThisGroup ? "Selecionando..." : "Adicionar"
13088
- ), /* @__PURE__ */ import_react27.default.createElement(
13208
+ canEdit && /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center justify-between pt-2 mt-1 border-t border-white/5 opacity-0 group-hover/item:opacity-100 transition-opacity" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react30.default.createElement(
13089
13209
  "button",
13090
13210
  {
13091
13211
  onClick: () => onAddSubgroup(group.id),
13092
- className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
13212
+ className: "flex items-center gap-1.5 px-3 py-1.5 text-xs text-slate-500 hover:text-white hover:bg-white/10 rounded-md transition-colors",
13093
13213
  title: "Criar Subgrupo"
13094
13214
  },
13095
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiPlus, { size: 14 })
13096
- )), /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react27.default.createElement(
13215
+ /* @__PURE__ */ import_react30.default.createElement(import_fi23.FiPlus, { size: 14 }),
13216
+ /* @__PURE__ */ import_react30.default.createElement("span", null, "Adicionar Subgrupo")
13217
+ )), /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-1" }, /* @__PURE__ */ import_react30.default.createElement(
13097
13218
  "button",
13098
13219
  {
13099
13220
  onClick: () => onIndent(group.id),
@@ -13101,25 +13222,25 @@ var GroupItem = ({
13101
13222
  className: `p-1.5 rounded transition-colors ${!canIndent ? "text-slate-800 cursor-not-allowed" : "text-slate-500 hover:text-white hover:bg-white/10"}`,
13102
13223
  title: "Aninhar no grupo acima"
13103
13224
  },
13104
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiArrowRight, { size: 14 })
13105
- ), /* @__PURE__ */ import_react27.default.createElement(
13225
+ /* @__PURE__ */ import_react30.default.createElement(import_fi23.FiArrowRight, { size: 14 })
13226
+ ), /* @__PURE__ */ import_react30.default.createElement(
13106
13227
  "button",
13107
13228
  {
13108
13229
  onClick: () => onOutdent(group.id),
13109
13230
  className: "p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-colors",
13110
13231
  title: "Desaninhar"
13111
13232
  },
13112
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiArrowLeft, { size: 14 })
13113
- ), /* @__PURE__ */ import_react27.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react27.default.createElement(
13233
+ /* @__PURE__ */ import_react30.default.createElement(import_fi23.FiArrowLeft, { size: 14 })
13234
+ ), /* @__PURE__ */ import_react30.default.createElement("div", { className: "w-px h-3 bg-white/10 mx-1" }), /* @__PURE__ */ import_react30.default.createElement(
13114
13235
  "button",
13115
13236
  {
13116
13237
  onClick: () => onDelete(group.id),
13117
13238
  className: "p-1.5 text-slate-600 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors",
13118
13239
  title: "Remover Grupo"
13119
13240
  },
13120
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiTrash2, { size: 14 })
13241
+ /* @__PURE__ */ import_react30.default.createElement(import_fi23.FiTrash2, { size: 14 })
13121
13242
  )))
13122
- ), 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(
13243
+ ), group.children && group.children.length > 0 && /* @__PURE__ */ import_react30.default.createElement("div", { className: "ml-2" }, group.children.map((childGroup, idx) => /* @__PURE__ */ import_react30.default.createElement(
13123
13244
  GroupItem,
13124
13245
  {
13125
13246
  key: childGroup.id,
@@ -13131,11 +13252,8 @@ var GroupItem = ({
13131
13252
  onAddSubgroup,
13132
13253
  onIndent,
13133
13254
  onOutdent,
13134
- onRemoveAncestry,
13135
- onRequestPickAncestry,
13136
- pickingGroupId,
13137
13255
  onPlayAncestry,
13138
- availableIds,
13256
+ availableMentionItems,
13139
13257
  canEdit
13140
13258
  }
13141
13259
  ))));
@@ -13150,21 +13268,19 @@ function AncestryBoard({
13150
13268
  onSave,
13151
13269
  userRole
13152
13270
  }) {
13153
- const [searchTerm, setSearchTerm] = (0, import_react27.useState)("");
13154
- const [groups, setGroups] = (0, import_react27.useState)([]);
13155
- const [isLoaded, setIsLoaded] = (0, import_react27.useState)(false);
13156
- const [pickingGroupId, setPickingGroupId] = (0, import_react27.useState)(null);
13157
- const [saveStatus, setSaveStatus] = (0, import_react27.useState)("idle");
13158
- const canEdit = (0, import_react27.useMemo)(() => {
13271
+ const [groups, setGroups] = (0, import_react30.useState)([]);
13272
+ const [isLoaded, setIsLoaded] = (0, import_react30.useState)(false);
13273
+ const [saveStatus, setSaveStatus] = (0, import_react30.useState)("idle");
13274
+ const canEdit = (0, import_react30.useMemo)(() => {
13159
13275
  return userRole !== "viewer";
13160
13276
  }, [userRole]);
13161
- (0, import_react27.useEffect)(() => {
13277
+ (0, import_react30.useEffect)(() => {
13162
13278
  if (initialGroups && !isLoaded) {
13163
13279
  setGroups(initialGroups);
13164
13280
  setIsLoaded(true);
13165
13281
  }
13166
13282
  }, [initialGroups, isLoaded]);
13167
- const nodeNamesMap = (0, import_react27.useMemo)(() => {
13283
+ const nodeNamesMap = (0, import_react30.useMemo)(() => {
13168
13284
  const map = /* @__PURE__ */ new Map();
13169
13285
  if (availableNodes && Array.isArray(availableNodes)) {
13170
13286
  availableNodes.forEach((node) => {
@@ -13175,10 +13291,10 @@ function AncestryBoard({
13175
13291
  }
13176
13292
  return map;
13177
13293
  }, [availableNodes]);
13178
- const availableIds = (0, import_react27.useMemo)(() => {
13294
+ const availableIds = (0, import_react30.useMemo)(() => {
13179
13295
  return new Set(availableAncestries.map((a) => String(a.ancestry_id)));
13180
13296
  }, [availableAncestries]);
13181
- const allMentionableItems = (0, import_react27.useMemo)(() => {
13297
+ const availableMentionItems = (0, import_react30.useMemo)(() => {
13182
13298
  const ancestries = availableAncestries.map((a) => ({
13183
13299
  id: String(a.ancestry_id),
13184
13300
  ancestry_id: a.ancestry_id,
@@ -13206,16 +13322,10 @@ function AncestryBoard({
13206
13322
  return groupList.map((g) => ({
13207
13323
  id: g.id,
13208
13324
  text: g.text || "",
13209
- ancestries: (g.ancestries || []).map((a) => ({
13210
- id: a.id || a.ancestry_id,
13211
- ancestry_id: a.ancestry_id,
13212
- name: a.name,
13213
- type: a.type || "ancestry"
13214
- })),
13215
13325
  children: sanitizeGroups(g.children || [])
13216
13326
  }));
13217
13327
  };
13218
- (0, import_react27.useEffect)(() => {
13328
+ (0, import_react30.useEffect)(() => {
13219
13329
  if (!isLoaded || !onSave) return;
13220
13330
  const timeoutId = setTimeout(async () => {
13221
13331
  setSaveStatus("saving");
@@ -13233,50 +13343,30 @@ function AncestryBoard({
13233
13343
  }, 3e3);
13234
13344
  return () => clearTimeout(timeoutId);
13235
13345
  }, [groups, isLoaded, onSave]);
13236
- (0, import_react27.useEffect)(() => {
13346
+ (0, import_react30.useEffect)(() => {
13237
13347
  if (!isOpen) return;
13238
13348
  const handleKeyDown = (e) => {
13239
13349
  if (e.key === "Escape") {
13240
- if (pickingGroupId) {
13241
- setPickingGroupId(null);
13242
- } else {
13243
- onClose();
13244
- }
13350
+ onClose();
13245
13351
  e.preventDefault();
13246
13352
  e.stopPropagation();
13247
13353
  }
13248
13354
  };
13249
13355
  window.addEventListener("keydown", handleKeyDown);
13250
13356
  return () => window.removeEventListener("keydown", handleKeyDown);
13251
- }, [isOpen, onClose, pickingGroupId]);
13252
- const filtered = (0, import_react27.useMemo)(() => {
13253
- const term = searchTerm.toLowerCase().trim();
13254
- return allMentionableItems.filter((item) => {
13255
- if (!term) return true;
13256
- const nameMatch = item.name && item.name.toLowerCase().includes(term);
13257
- const descMatch = item.description && item.description.toLowerCase().includes(term);
13258
- let parentMatch = false;
13259
- if (item.type === "ancestry") {
13260
- const parentName = nodeNamesMap.get(String(item.ancestral_node)) || "";
13261
- parentMatch = parentName.toLowerCase().includes(term);
13262
- }
13263
- return nameMatch || descMatch || parentMatch;
13264
- });
13265
- }, [allMentionableItems, searchTerm, nodeNamesMap]);
13357
+ }, [isOpen, onClose]);
13266
13358
  const handleAddRootGroup = () => {
13267
13359
  const newGroup = {
13268
- id: v4_default(),
13360
+ id: (0, import_uuid11.v4)(),
13269
13361
  text: "",
13270
- ancestries: [],
13271
13362
  children: []
13272
13363
  };
13273
13364
  setGroups((prev) => [newGroup, ...prev]);
13274
13365
  };
13275
13366
  const handleAddSubgroup = (parentId) => {
13276
13367
  const newGroup = {
13277
- id: v4_default(),
13368
+ id: (0, import_uuid11.v4)(),
13278
13369
  text: "",
13279
- ancestries: [],
13280
13370
  children: []
13281
13371
  };
13282
13372
  const addRecursive = (list) => {
@@ -13347,42 +13437,6 @@ function AncestryBoard({
13347
13437
  return newList;
13348
13438
  });
13349
13439
  };
13350
- const handleRequestPick = (groupId) => {
13351
- setPickingGroupId((prev) => prev === groupId ? null : groupId);
13352
- };
13353
- const handleSelectAncestry = (item) => {
13354
- if (pickingGroupId) {
13355
- setGroups((prev) => {
13356
- const addRecursive = (list) => {
13357
- return list.map((g) => {
13358
- if (g.id === pickingGroupId) {
13359
- const currentId = item.id;
13360
- const exists = g.ancestries.some(
13361
- (a) => (a.id || a.ancestry_id) === currentId && a.type === item.type
13362
- );
13363
- if (exists) return g;
13364
- return { ...g, ancestries: [...g.ancestries, item] };
13365
- }
13366
- return { ...g, children: addRecursive(g.children) };
13367
- });
13368
- };
13369
- return addRecursive(prev);
13370
- });
13371
- setPickingGroupId(null);
13372
- } else {
13373
- let fullItem = item;
13374
- if (item.type === "ancestry" || !item.type) {
13375
- fullItem = availableAncestries.find(
13376
- (a) => String(a.ancestry_id) === String(item.id || item.ancestry_id)
13377
- ) || item;
13378
- } else {
13379
- fullItem = availableNodes.find(
13380
- (n) => String(n.id) === String(item.id)
13381
- ) || item;
13382
- }
13383
- onSelect(fullItem);
13384
- }
13385
- };
13386
13440
  const handlePlayFromGroup = (item) => {
13387
13441
  let fullItem = item;
13388
13442
  if (item.type === "ancestry" || !item.type) {
@@ -13398,52 +13452,34 @@ function AncestryBoard({
13398
13452
  onSelect(fullItem);
13399
13453
  }
13400
13454
  };
13401
- const handleRemoveAncestryFromGroup = (groupId, itemId) => {
13402
- setGroups((prev) => {
13403
- const removeRecursive = (list) => {
13404
- return list.map((g) => {
13405
- if (g.id === groupId) {
13406
- return {
13407
- ...g,
13408
- ancestries: g.ancestries.filter(
13409
- (a) => (a.id || a.ancestry_id) !== itemId
13410
- )
13411
- };
13412
- }
13413
- return { ...g, children: removeRecursive(g.children) };
13414
- });
13415
- };
13416
- return removeRecursive(prev);
13417
- });
13418
- };
13419
13455
  if (!isOpen) return null;
13420
- return /* @__PURE__ */ import_react27.default.createElement(
13456
+ return /* @__PURE__ */ import_react30.default.createElement(
13421
13457
  "div",
13422
13458
  {
13423
13459
  className: "fixed inset-0 z-[2200] bg-black/80 backdrop-blur-sm flex items-center justify-center p-2",
13424
13460
  onClick: onClose
13425
13461
  },
13426
- /* @__PURE__ */ import_react27.default.createElement(
13462
+ /* @__PURE__ */ import_react30.default.createElement(
13427
13463
  "div",
13428
13464
  {
13429
- 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",
13465
+ className: "bg-slate-950 border border-white/10 rounded-xl w-[90vw] max-w-[1200px] h-[90vh] flex flex-col shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200",
13430
13466
  onClick: (e) => e.stopPropagation()
13431
13467
  },
13432
- /* @__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(
13433
- import_fi22.FiLoader,
13468
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "h-14 px-6 border-b border-white/10 bg-slate-900/90 flex items-center justify-between shrink-0" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react30.default.createElement("h3", { className: "text-base font-semibold text-white flex items-center gap-2 whitespace-nowrap" }, /* @__PURE__ */ import_react30.default.createElement(import_fi23.FiLayers, { className: "text-indigo-400" }), "Ancestry Board"), saveStatus !== "idle" && /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-2 animate-in fade-in slide-in-from-left-2 duration-300" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "w-px h-4 bg-white/10 mx-1" }), /* @__PURE__ */ import_react30.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_react30.default.createElement(import_react30.default.Fragment, null, /* @__PURE__ */ import_react30.default.createElement(
13469
+ import_fi23.FiLoader,
13434
13470
  {
13435
13471
  className: "animate-spin text-indigo-400",
13436
13472
  size: 12
13437
13473
  }
13438
- ), /* @__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(
13474
+ ), /* @__PURE__ */ import_react30.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-indigo-300" }, "Salvando")), saveStatus === "saved" && /* @__PURE__ */ import_react30.default.createElement(import_react30.default.Fragment, null, /* @__PURE__ */ import_react30.default.createElement(import_fi23.FiCheckCircle, { className: "text-emerald-400", size: 12 }), /* @__PURE__ */ import_react30.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-slate-400" }, "Salvo")), saveStatus === "error" && /* @__PURE__ */ import_react30.default.createElement(import_react30.default.Fragment, null, /* @__PURE__ */ import_react30.default.createElement("span", { className: "w-2 h-2 rounded-full bg-red-500" }), /* @__PURE__ */ import_react30.default.createElement("span", { className: "text-[10px] uppercase tracking-wide font-medium text-red-400" }, "Erro"))))), /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-3" }, canEdit && /* @__PURE__ */ import_react30.default.createElement(
13439
13475
  "button",
13440
13476
  {
13441
13477
  onClick: handleAddRootGroup,
13442
13478
  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 "
13443
13479
  },
13444
- /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiPlus, { size: 14, className: "text-indigo-400" }),
13445
- /* @__PURE__ */ import_react27.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
13446
- ), /* @__PURE__ */ import_react27.default.createElement(
13480
+ /* @__PURE__ */ import_react30.default.createElement(import_fi23.FiPlus, { size: 14, className: "text-indigo-400" }),
13481
+ /* @__PURE__ */ import_react30.default.createElement("span", { className: "hidden sm:inline" }, "Novo Grupo")
13482
+ ), /* @__PURE__ */ import_react30.default.createElement(
13447
13483
  "button",
13448
13484
  {
13449
13485
  onClick: onClose,
@@ -13451,128 +13487,37 @@ function AncestryBoard({
13451
13487
  },
13452
13488
  "\xD7"
13453
13489
  ))),
13454
- /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, /* @__PURE__ */ import_react27.default.createElement(
13455
- "div",
13490
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex flex-1 overflow-hidden bg-slate-900/20" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex flex-col flex-1" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-8 max-w-[900px] mx-auto w-full space-y-6" }, groups.length === 0 ? /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex flex-col items-center justify-center h-full text-slate-500 gap-4 border-2 border-dashed border-white/5 rounded-2xl bg-slate-900/40 p-12" }, /* @__PURE__ */ import_react30.default.createElement(import_fi23.FiLayers, { size: 40, className: "opacity-10 text-indigo-400" }), /* @__PURE__ */ import_react30.default.createElement("div", { className: "text-center space-y-1" }, /* @__PURE__ */ import_react30.default.createElement("p", { className: "text-sm font-medium text-slate-300" }, "Nenhum grupo criado"), /* @__PURE__ */ import_react30.default.createElement("p", { className: "text-xs text-slate-500 max-w-[200px]" }, canEdit ? "Comece organizando sua narrativa criando o primeiro grupo." : "Este board ainda n\xE3o possui conte\xFAdo.")), canEdit && /* @__PURE__ */ import_react30.default.createElement(
13491
+ "button",
13456
13492
  {
13457
- className: `
13458
- flex flex-col border-r border-white/10 transition-all duration-300 flex-none
13459
- ${pickingGroupId ? "w-[25%] border-indigo-500/30" : "w-[20%]"}
13460
- min-w-[280px] max-w-[500px] bg-slate-900
13461
- `
13493
+ onClick: handleAddRootGroup,
13494
+ className: "mt-2 px-4 py-2 bg-indigo-500/10 hover:bg-indigo-500/20 text-indigo-400 rounded-lg border border-indigo-500/20 transition-all text-xs font-bold uppercase tracking-wider"
13462
13495
  },
13463
- /* @__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(
13464
- import_fi22.FiSearch,
13465
- {
13466
- 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"}`
13467
- }
13468
- ), /* @__PURE__ */ import_react27.default.createElement(
13469
- "input",
13470
- {
13471
- type: "text",
13472
- placeholder: pickingGroupId ? "Pesquise para adicionar..." : "Pesquisar (Ancestralidades e Nodes)",
13473
- className: `
13474
- 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
13475
- ${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"}
13476
- `,
13477
- value: searchTerm,
13478
- onChange: (e) => setSearchTerm(e.target.value),
13479
- autoFocus: !pickingGroupId
13480
- }
13481
- ))),
13482
- /* @__PURE__ */ import_react27.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3 space-y-2" }, filtered.map((item) => {
13483
- const isPicking = !!pickingGroupId;
13484
- const isQuest = item.type === "quest";
13485
- const isVersion = item.type === "version";
13486
- const isNode = item.type === "node";
13487
- let Icon = import_fi22.FiLayers;
13488
- let colorClass = "bg-slate-800 text-indigo-400 border-white/5";
13489
- let pickingColorClass = "bg-indigo-500 text-white border-indigo-400";
13490
- let hoverClass = "hover:bg-indigo-600/10 hover:border-indigo-500/30";
13491
- let badge = null;
13492
- if (isQuest) {
13493
- Icon = import_fi22.FiCheckSquare;
13494
- colorClass = "bg-slate-800 text-amber-400 border-white/5";
13495
- pickingColorClass = "bg-amber-500 text-white border-amber-400";
13496
- hoverClass = "hover:bg-amber-500/10 hover:border-amber-500/30";
13497
- badge = "Quest";
13498
- } else if (isVersion) {
13499
- Icon = import_fi22.FiGitBranch;
13500
- colorClass = "bg-slate-800 text-purple-400 border-white/5";
13501
- pickingColorClass = "bg-purple-500 text-white border-purple-400";
13502
- hoverClass = "hover:bg-purple-500/10 hover:border-purple-500/30";
13503
- badge = "Ver";
13504
- } else if (isNode) {
13505
- Icon = import_fi22.FiBox;
13506
- colorClass = "bg-slate-800 text-emerald-400 border-white/5";
13507
- pickingColorClass = "bg-emerald-500 text-white border-emerald-400";
13508
- hoverClass = "hover:bg-emerald-500/10 hover:border-emerald-500/30";
13509
- badge = "Node";
13510
- }
13511
- return /* @__PURE__ */ import_react27.default.createElement(
13512
- "div",
13513
- {
13514
- key: `${item.type}-${item.id}`,
13515
- onClick: () => {
13516
- if (isPicking) handleSelectAncestry(item);
13517
- },
13518
- className: `
13519
- group relative flex items-start gap-3 p-3 text-left rounded-lg border transition-all duration-200
13520
- ${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 ${hoverClass} cursor-default`}
13521
- `
13522
- },
13523
- /* @__PURE__ */ import_react27.default.createElement(
13524
- "div",
13525
- {
13526
- className: `
13527
- mt-0.5 w-8 h-8 rounded-md grid place-content-center shrink-0 border transition-all shadow-lg
13528
- ${isPicking ? pickingColorClass : `${colorClass} group-hover:bg-opacity-80`}
13529
- `
13530
- },
13531
- isPicking ? /* @__PURE__ */ import_react27.default.createElement(import_fi22.FiPlus, { size: 16 }) : /* @__PURE__ */ import_react27.default.createElement(Icon, { size: 14 })
13532
- ),
13533
- /* @__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" }, item.name || "Sem Nome"), badge && /* @__PURE__ */ import_react27.default.createElement("span", { className: `text-[9px] px-1 py-0.5 rounded ${isQuest ? "bg-amber-500/10 text-amber-400" : isVersion ? "bg-purple-500/10 text-purple-400" : "bg-emerald-500/10 text-emerald-400"} border border-current opacity-50` }, badge), item.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")), item.type === "ancestry" && /* @__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]" }, nodeNamesMap.get(String(item.ancestral_node)) || "Node Desconhecido")), item.description && /* @__PURE__ */ import_react27.default.createElement("p", { className: "mt-1.5 text-[11px] text-slate-400 line-clamp-2 leading-relaxed opacity-80" }, item.description)),
13534
- !isPicking && /* @__PURE__ */ import_react27.default.createElement(
13535
- "button",
13536
- {
13537
- onClick: (e) => {
13538
- e.stopPropagation();
13539
- handleSelectAncestry(item);
13540
- },
13541
- 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",
13542
- title: "Renderizar / Focar"
13543
- },
13544
- /* @__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" }))
13545
- )
13546
- );
13547
- }))
13548
- ), /* @__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(
13496
+ "Criar Primeiro Grupo"
13497
+ )) : groups.map((group, index) => /* @__PURE__ */ import_react30.default.createElement(
13549
13498
  GroupItem,
13550
13499
  {
13551
13500
  key: group.id,
13552
13501
  index,
13553
13502
  group,
13554
- siblings: groups,
13555
13503
  onUpdate: handleUpdateGroup,
13556
13504
  onDelete: handleDeleteGroup,
13557
13505
  onAddSubgroup: handleAddSubgroup,
13558
13506
  onIndent: handleIndent,
13559
13507
  onOutdent: handleOutdent,
13560
- onRemoveAncestry: handleRemoveAncestryFromGroup,
13561
- onRequestPickAncestry: handleRequestPick,
13562
- pickingGroupId,
13563
13508
  onPlayAncestry: handlePlayFromGroup,
13564
- availableIds,
13509
+ availableMentionItems,
13565
13510
  canEdit
13566
13511
  }
13567
13512
  ))))),
13568
- /* @__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"))
13513
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "px-6 py-3 border-t border-white/10 bg-slate-950/50 text-[10px] uppercase tracking-widest font-bold text-slate-600 flex justify-between items-center flex-shrink-0" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react30.default.createElement("span", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "w-1.5 h-1.5 rounded-full bg-indigo-500" }), " ", availableMentionItems.length, " RECURSOS DISPON\xCDVEIS"), /* @__PURE__ */ import_react30.default.createElement("span", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react30.default.createElement("div", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500" }), " ", groups.length, " GRUPOS PRINCIPAIS")), /* @__PURE__ */ import_react30.default.createElement("span", { className: "text-slate-700" }, "X.VIEW :: ANCESTRY BOARD ENGINE"))
13569
13514
  )
13570
13515
  );
13571
13516
  }
13572
13517
 
13573
13518
  // src/components/MilestoneManager.jsx
13574
- var import_react28 = __toESM(require("react"));
13575
- var import_fi23 = require("react-icons/fi");
13519
+ var import_react31 = __toESM(require("react"));
13520
+ var import_fi24 = require("react-icons/fi");
13576
13521
  function MilestoneManager({
13577
13522
  isOpen,
13578
13523
  onClose,
@@ -13580,7 +13525,7 @@ function MilestoneManager({
13580
13525
  onUpdateMilestones = () => {
13581
13526
  }
13582
13527
  }) {
13583
- const [newMilestoneName, setNewMilestoneName] = (0, import_react28.useState)("");
13528
+ const [newMilestoneName, setNewMilestoneName] = (0, import_react31.useState)("");
13584
13529
  const handleAddMilestone = () => {
13585
13530
  if (!newMilestoneName.trim()) return;
13586
13531
  const newMilestone = {
@@ -13605,27 +13550,27 @@ function MilestoneManager({
13605
13550
  };
13606
13551
  if (!isOpen) return null;
13607
13552
  const swallow = (e) => e.stopPropagation();
13608
- return /* @__PURE__ */ import_react28.default.createElement(
13553
+ return /* @__PURE__ */ import_react31.default.createElement(
13609
13554
  "div",
13610
13555
  {
13611
13556
  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",
13612
13557
  onClick: onClose
13613
13558
  },
13614
- /* @__PURE__ */ import_react28.default.createElement(
13559
+ /* @__PURE__ */ import_react31.default.createElement(
13615
13560
  "div",
13616
13561
  {
13617
13562
  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",
13618
13563
  onClick: swallow
13619
13564
  },
13620
- /* @__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(
13565
+ /* @__PURE__ */ import_react31.default.createElement("div", { className: "px-6 py-4 border-b border-white/10 flex items-center justify-between" }, /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react31.default.createElement("div", { className: "p-2 rounded-lg bg-indigo-500/20 text-indigo-400" }, /* @__PURE__ */ import_react31.default.createElement(import_fi24.FiTarget, { size: 20 })), /* @__PURE__ */ import_react31.default.createElement("div", null, /* @__PURE__ */ import_react31.default.createElement("h2", { className: "text-lg font-semibold text-slate-100" }, "Milestones"), /* @__PURE__ */ import_react31.default.createElement("p", { className: "text-xs text-slate-400" }, "Gerencie os marcos do seu cen\xE1rio"))), /* @__PURE__ */ import_react31.default.createElement(
13621
13566
  "button",
13622
13567
  {
13623
13568
  onClick: onClose,
13624
13569
  className: "p-2 rounded-full hover:bg-white/10 text-slate-400 hover:text-white transition-colors"
13625
13570
  },
13626
- /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiX, { size: 20 })
13571
+ /* @__PURE__ */ import_react31.default.createElement(import_fi24.FiX, { size: 20 })
13627
13572
  )),
13628
- /* @__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(
13573
+ /* @__PURE__ */ import_react31.default.createElement("div", { className: "px-6 py-5 bg-white/5 border-b border-white/5" }, /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ import_react31.default.createElement(
13629
13574
  "input",
13630
13575
  {
13631
13576
  type: "text",
@@ -13635,47 +13580,47 @@ function MilestoneManager({
13635
13580
  placeholder: "Adicionar novo milestone...",
13636
13581
  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"
13637
13582
  }
13638
- ), /* @__PURE__ */ import_react28.default.createElement(
13583
+ ), /* @__PURE__ */ import_react31.default.createElement(
13639
13584
  "button",
13640
13585
  {
13641
13586
  onClick: handleAddMilestone,
13642
13587
  disabled: !newMilestoneName.trim(),
13643
13588
  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"
13644
13589
  },
13645
- /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiPlus, { size: 18 }),
13590
+ /* @__PURE__ */ import_react31.default.createElement(import_fi24.FiPlus, { size: 18 }),
13646
13591
  "Adicionar"
13647
13592
  ))),
13648
- /* @__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(
13593
+ /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex-1 overflow-y-auto px-6 py-4 custom-scrollbar" }, milestones.length > 0 ? /* @__PURE__ */ import_react31.default.createElement("div", { className: "space-y-3" }, milestones.map((ms) => /* @__PURE__ */ import_react31.default.createElement(
13649
13594
  "div",
13650
13595
  {
13651
13596
  key: ms.id,
13652
13597
  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]"}`
13653
13598
  },
13654
- /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ import_react28.default.createElement(
13599
+ /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center gap-3 min-w-0" }, /* @__PURE__ */ import_react31.default.createElement(
13655
13600
  "div",
13656
13601
  {
13657
13602
  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"}`
13658
13603
  }
13659
- ), /* @__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"))),
13660
- /* @__PURE__ */ import_react28.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react28.default.createElement(
13604
+ ), /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react31.default.createElement("span", { className: `text-sm font-medium truncate ${ms.status === "active" ? "text-slate-100" : "text-slate-400 line-through"}` }, ms.name), /* @__PURE__ */ import_react31.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-wider" }, ms.status === "active" ? "Ativo" : "Inativo"))),
13605
+ /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react31.default.createElement(
13661
13606
  "button",
13662
13607
  {
13663
13608
  onClick: () => handleToggleMilestoneStatus(ms.id),
13664
13609
  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"}`,
13665
13610
  title: ms.status === "active" ? "Inativar" : "Ativar"
13666
13611
  },
13667
- ms.status === "active" ? /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiPauseCircle, { size: 18 }) : /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiPlayCircle, { size: 18 })
13668
- ), /* @__PURE__ */ import_react28.default.createElement(
13612
+ ms.status === "active" ? /* @__PURE__ */ import_react31.default.createElement(import_fi24.FiPauseCircle, { size: 18 }) : /* @__PURE__ */ import_react31.default.createElement(import_fi24.FiPlayCircle, { size: 18 })
13613
+ ), /* @__PURE__ */ import_react31.default.createElement(
13669
13614
  "button",
13670
13615
  {
13671
13616
  onClick: () => handleRemoveMilestone(ms.id),
13672
13617
  className: "p-2 rounded-lg hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-all",
13673
13618
  title: "Remover"
13674
13619
  },
13675
- /* @__PURE__ */ import_react28.default.createElement(import_fi23.FiTrash2, { size: 18 })
13620
+ /* @__PURE__ */ import_react31.default.createElement(import_fi24.FiTrash2, { size: 18 })
13676
13621
  ))
13677
- ))) : /* @__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."))),
13678
- /* @__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))))
13622
+ ))) : /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex flex-col items-center justify-center py-12 text-center" }, /* @__PURE__ */ import_react31.default.createElement("div", { className: "p-4 rounded-full bg-slate-800/30 text-slate-600 mb-4" }, /* @__PURE__ */ import_react31.default.createElement(import_fi24.FiTarget, { size: 40 })), /* @__PURE__ */ import_react31.default.createElement("h3", { className: "text-slate-400 font-medium" }, "Nenhum milestone definido"), /* @__PURE__ */ import_react31.default.createElement("p", { className: "text-xs text-slate-600 max-w-[200px] mt-1 italic" }, "Defina marcos importantes para orientar o progresso do projeto."))),
13623
+ /* @__PURE__ */ import_react31.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_react31.default.createElement("div", { className: "flex gap-4" }, /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react31.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Total:"), /* @__PURE__ */ import_react31.default.createElement("span", { className: "text-xs font-bold text-slate-300" }, milestones.length)), /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center gap-1.5" }, /* @__PURE__ */ import_react31.default.createElement("span", { className: "text-[10px] text-slate-500 uppercase tracking-widest" }, "Ativos:"), /* @__PURE__ */ import_react31.default.createElement("span", { className: "text-xs font-bold text-indigo-400" }, milestones.filter((m) => m.status === "active").length))))
13679
13624
  )
13680
13625
  );
13681
13626
  }
@@ -13762,12 +13707,12 @@ function XViewScene({
13762
13707
  get_view_members
13763
13708
  }) {
13764
13709
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
13765
- const { data: session, status } = (0, import_react30.useSession)();
13710
+ const { data: session, status } = (0, import_react33.useSession)();
13766
13711
  const router = (0, import_navigation.useRouter)();
13767
13712
  const searchParams = (0, import_navigation.useSearchParams)();
13768
13713
  const focusNodeId = searchParams == null ? void 0 : searchParams.get("focus");
13769
13714
  const focusAncestryId = searchParams == null ? void 0 : searchParams.get("ancestry");
13770
- const viewParams = (0, import_react29.useMemo)(() => {
13715
+ const viewParams = (0, import_react32.useMemo)(() => {
13771
13716
  if (encryptedConfig) {
13772
13717
  const data = decryptData(encryptedConfig);
13773
13718
  if (data) {
@@ -13776,7 +13721,7 @@ function XViewScene({
13776
13721
  }
13777
13722
  return null;
13778
13723
  }, [encryptedConfig, session]);
13779
- (0, import_react29.useEffect)(() => {
13724
+ (0, import_react32.useEffect)(() => {
13780
13725
  async function verifyPermission() {
13781
13726
  if (!viewParams || !session || !check_user_permission) return;
13782
13727
  const { id, type, owner_id } = viewParams;
@@ -13813,65 +13758,65 @@ function XViewScene({
13813
13758
  setIsLoading(false);
13814
13759
  }
13815
13760
  }, [viewParams, session, status, check_user_permission]);
13816
- const sceneConfigId = (0, import_react29.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
13817
- const ownerId = (0, import_react29.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
13818
- const dbSaveUrl = (0, import_react29.useMemo)(() => {
13761
+ const sceneConfigId = (0, import_react32.useMemo)(() => (viewParams == null ? void 0 : viewParams.id) || null, [viewParams]);
13762
+ const ownerId = (0, import_react32.useMemo)(() => (viewParams == null ? void 0 : viewParams.owner_id) || null, [viewParams]);
13763
+ const dbSaveUrl = (0, import_react32.useMemo)(() => {
13819
13764
  if (ownerId && sceneConfigId) {
13820
13765
  return `x_view_dbs/${ownerId}/${sceneConfigId}`;
13821
13766
  }
13822
13767
  return null;
13823
13768
  }, [ownerId, sceneConfigId]);
13824
- const sceneSaveUrl = (0, import_react29.useMemo)(() => {
13769
+ const sceneSaveUrl = (0, import_react32.useMemo)(() => {
13825
13770
  if (ownerId && sceneConfigId) {
13826
13771
  return `x_view_scenes/${ownerId}/${sceneConfigId}`;
13827
13772
  }
13828
13773
  return null;
13829
13774
  }, [ownerId, sceneConfigId]);
13830
- const ancestry_save_url = (0, import_react29.useMemo)(() => {
13775
+ const ancestry_save_url = (0, import_react32.useMemo)(() => {
13831
13776
  if (ownerId && sceneConfigId) {
13832
13777
  return `x_view_ancestry/${ownerId}/${sceneConfigId}`;
13833
13778
  }
13834
13779
  return null;
13835
13780
  }, [ownerId, sceneConfigId]);
13836
- const sceneDataRef = (0, import_react29.useRef)(null);
13837
- const parentDataRef = (0, import_react29.useRef)(null);
13838
- const ancestryDataRef = (0, import_react29.useRef)(null);
13839
- const [isLoading, setIsLoading] = (0, import_react29.useState)(true);
13840
- const [permissionStatus, setPermissionStatus] = (0, import_react29.useState)("loading");
13841
- const [userPermissionRole, setUserPermissionRole] = (0, import_react29.useState)(null);
13842
- const [viewMembers, setViewMembers] = (0, import_react29.useState)([]);
13843
- const [isInitialized, setIsInitialized] = (0, import_react29.useState)(false);
13844
- const [sceneVersion, setSceneVersion] = (0, import_react29.useState)(0);
13845
- const [contextMenu, setContextMenu] = (0, import_react29.useState)({
13781
+ const sceneDataRef = (0, import_react32.useRef)(null);
13782
+ const parentDataRef = (0, import_react32.useRef)(null);
13783
+ const ancestryDataRef = (0, import_react32.useRef)(null);
13784
+ const [isLoading, setIsLoading] = (0, import_react32.useState)(true);
13785
+ const [permissionStatus, setPermissionStatus] = (0, import_react32.useState)("loading");
13786
+ const [userPermissionRole, setUserPermissionRole] = (0, import_react32.useState)(null);
13787
+ const [viewMembers, setViewMembers] = (0, import_react32.useState)([]);
13788
+ const [isInitialized, setIsInitialized] = (0, import_react32.useState)(false);
13789
+ const [sceneVersion, setSceneVersion] = (0, import_react32.useState)(0);
13790
+ const [contextMenu, setContextMenu] = (0, import_react32.useState)({
13846
13791
  visible: false,
13847
13792
  x: 0,
13848
13793
  y: 0,
13849
13794
  nodeData: null
13850
13795
  });
13851
- const [multiContextMenu, setMultiContextMenu] = (0, import_react29.useState)({
13796
+ const [multiContextMenu, setMultiContextMenu] = (0, import_react32.useState)({
13852
13797
  visible: false,
13853
13798
  x: 0,
13854
13799
  y: 0,
13855
13800
  nodeIds: null
13856
13801
  });
13857
- const [relationshipMenu, setRelationshipMenu] = (0, import_react29.useState)({
13802
+ const [relationshipMenu, setRelationshipMenu] = (0, import_react32.useState)({
13858
13803
  visible: false,
13859
13804
  x: 0,
13860
13805
  y: 0,
13861
13806
  linkObject: null
13862
13807
  });
13863
- const [creationMode, setCreationMode] = (0, import_react29.useState)({
13808
+ const [creationMode, setCreationMode] = (0, import_react32.useState)({
13864
13809
  isActive: false,
13865
13810
  sourceNodeData: null
13866
13811
  });
13867
- const [versionMode, setVersionMode] = (0, import_react29.useState)({
13812
+ const [versionMode, setVersionMode] = (0, import_react32.useState)({
13868
13813
  isActive: false,
13869
13814
  sourceNodeData: null
13870
13815
  });
13871
- const [questMode, setQuestMode] = (0, import_react29.useState)({ isActive: false });
13872
- const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react29.useState)(false);
13873
- const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react29.useState)(false);
13874
- const [ancestryMode, setAncestryMode] = (0, import_react29.useState)({
13816
+ const [questMode, setQuestMode] = (0, import_react32.useState)({ isActive: false });
13817
+ const [hasFocusedInitial, setHasFocusedInitial] = (0, import_react32.useState)(false);
13818
+ const [hasOpenedInitialAncestry, setHasOpenedInitialAncestry] = (0, import_react32.useState)(false);
13819
+ const [ancestryMode, setAncestryMode] = (0, import_react32.useState)({
13875
13820
  isActive: false,
13876
13821
  tree: null,
13877
13822
  selectedParentId: null,
@@ -13882,42 +13827,42 @@ function XViewScene({
13882
13827
  ancestryDescriptionSections: [],
13883
13828
  isAddingNodes: false
13884
13829
  });
13885
- const [readingMode, setReadingMode] = (0, import_react29.useState)({
13830
+ const [readingMode, setReadingMode] = (0, import_react32.useState)({
13886
13831
  isActive: false,
13887
13832
  ancestry: null,
13888
13833
  branchStack: [],
13889
13834
  autoAbstraction: false
13890
13835
  });
13891
- const [formPosition, setFormPosition] = (0, import_react29.useState)({
13836
+ const [formPosition, setFormPosition] = (0, import_react32.useState)({
13892
13837
  left: 16,
13893
13838
  top: 16,
13894
13839
  opacity: 0
13895
13840
  });
13896
- const [detailsNode, setDetailsNode] = (0, import_react29.useState)(null);
13897
- const [detailsLink, setDetailsLink] = (0, import_react29.useState)(null);
13898
- const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react29.useState)(null);
13899
- const [imageViewer, setImageViewer] = (0, import_react29.useState)({
13841
+ const [detailsNode, setDetailsNode] = (0, import_react32.useState)(null);
13842
+ const [detailsLink, setDetailsLink] = (0, import_react32.useState)(null);
13843
+ const [ancestryLinkDetails, setAncestryLinkDetails] = (0, import_react32.useState)(null);
13844
+ const [imageViewer, setImageViewer] = (0, import_react32.useState)({
13900
13845
  visible: false,
13901
13846
  images: [],
13902
13847
  startIndex: 0
13903
13848
  });
13904
- const [editingAncestryRel, setEditingAncestryRel] = (0, import_react29.useState)({
13849
+ const [editingAncestryRel, setEditingAncestryRel] = (0, import_react32.useState)({
13905
13850
  visible: false,
13906
13851
  data: null,
13907
13852
  path: null
13908
13853
  });
13909
- const [isImportModalOpen, setIsImportModalOpen] = (0, import_react29.useState)(false);
13910
- const [importSuccessMessage, setImportSuccessMessage] = (0, import_react29.useState)("");
13911
- const [invalidTargetError, setInvalidTargetError] = (0, import_react29.useState)(null);
13912
- const [highlightedNodeId, setHighlightedNodeId] = (0, import_react29.useState)(null);
13913
- const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react29.useState)(false);
13914
- const [ancestryBoardData, setAncestryBoardData] = (0, import_react29.useState)([]);
13915
- const [isSidebarOpen, setIsSidebarOpen] = (0, import_react29.useState)(false);
13916
- const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = (0, import_react29.useState)(false);
13917
- const mountRef = (0, import_react29.useRef)(null);
13918
- const tooltipRef = (0, import_react29.useRef)(null);
13919
- const formRef = (0, import_react29.useRef)(null);
13920
- const stateRef = (0, import_react29.useRef)({
13854
+ const [isImportModalOpen, setIsImportModalOpen] = (0, import_react32.useState)(false);
13855
+ const [importSuccessMessage, setImportSuccessMessage] = (0, import_react32.useState)("");
13856
+ const [invalidTargetError, setInvalidTargetError] = (0, import_react32.useState)(null);
13857
+ const [highlightedNodeId, setHighlightedNodeId] = (0, import_react32.useState)(null);
13858
+ const [isAncestryBoardOpen, setIsAncestryBoardOpen] = (0, import_react32.useState)(false);
13859
+ const [ancestryBoardData, setAncestryBoardData] = (0, import_react32.useState)([]);
13860
+ const [isSidebarOpen, setIsSidebarOpen] = (0, import_react32.useState)(false);
13861
+ const [isMilestoneManagerOpen, setIsMilestoneManagerOpen] = (0, import_react32.useState)(false);
13862
+ const mountRef = (0, import_react32.useRef)(null);
13863
+ const tooltipRef = (0, import_react32.useRef)(null);
13864
+ const formRef = (0, import_react32.useRef)(null);
13865
+ const stateRef = (0, import_react32.useRef)({
13921
13866
  readMode: {
13922
13867
  currentMaxIndex: 0,
13923
13868
  progressMap: {}
@@ -13981,10 +13926,10 @@ function XViewScene({
13981
13926
  minWidth: 320,
13982
13927
  maxWidth: maxReadPanelW
13983
13928
  });
13984
- (0, import_react29.useEffect)(() => {
13929
+ (0, import_react32.useEffect)(() => {
13985
13930
  stateRef.current.ancestry = ancestryMode;
13986
13931
  }, [ancestryMode]);
13987
- (0, import_react29.useEffect)(() => {
13932
+ (0, import_react32.useEffect)(() => {
13988
13933
  var _a2;
13989
13934
  if (!isInitialized) return;
13990
13935
  const map = /* @__PURE__ */ new Map();
@@ -14007,10 +13952,10 @@ function XViewScene({
14007
13952
  }
14008
13953
  stateRef.current.nodeIdToParentFileMap = map;
14009
13954
  }, [isInitialized, sceneVersion]);
14010
- const handleNavigateBack = (0, import_react29.useCallback)(() => {
13955
+ const handleNavigateBack = (0, import_react32.useCallback)(() => {
14011
13956
  router.push("/dashboard/scenes");
14012
13957
  }, [router]);
14013
- const handleConfirmImport = (0, import_react29.useCallback)(
13958
+ const handleConfirmImport = (0, import_react32.useCallback)(
14014
13959
  async (importPayload) => {
14015
13960
  var _a2, _b2;
14016
13961
  let files = [];
@@ -14138,7 +14083,7 @@ function XViewScene({
14138
14083
  const handleOpenImageViewer = (images, startIndex) => {
14139
14084
  setImageViewer({ visible: true, images, startIndex });
14140
14085
  };
14141
- const tweenToTarget = (0, import_react29.useCallback)(
14086
+ const tweenToTarget = (0, import_react32.useCallback)(
14142
14087
  (target, zoomFactor = 1, forcedDirection = null) => {
14143
14088
  const { camera, controls, tweenGroup } = stateRef.current;
14144
14089
  if (!camera || !controls || !tweenGroup) return;
@@ -14164,7 +14109,7 @@ function XViewScene({
14164
14109
  if (!t || typeof t.closest !== "function") return false;
14165
14110
  return !!t.closest(".ui-overlay");
14166
14111
  };
14167
- const buildFullAncestryTree = (0, import_react29.useCallback)(
14112
+ const buildFullAncestryTree = (0, import_react32.useCallback)(
14168
14113
  (idTree, nodes, ancestries = []) => {
14169
14114
  if (!idTree) return null;
14170
14115
  const nodeMap = new Map(nodes.map((n) => [String(n.id), n]));
@@ -14249,7 +14194,7 @@ function XViewScene({
14249
14194
  },
14250
14195
  []
14251
14196
  );
14252
- const handleActivateTimeline = (0, import_react29.useCallback)(() => {
14197
+ const handleActivateTimeline = (0, import_react32.useCallback)(() => {
14253
14198
  const { nodeObjects, tweenGroup, timelineIntervalsGroup } = stateRef.current;
14254
14199
  if (!nodeObjects || !tweenGroup || !timelineIntervalsGroup) return;
14255
14200
  while (timelineIntervalsGroup.children.length > 0) {
@@ -14409,7 +14354,7 @@ function XViewScene({
14409
14354
  }
14410
14355
  });
14411
14356
  }, []);
14412
- const handleVersionTimeline = (0, import_react29.useCallback)((sourceMesh, versionMeshes) => {
14357
+ const handleVersionTimeline = (0, import_react32.useCallback)((sourceMesh, versionMeshes) => {
14413
14358
  const { tweenGroup, timelineIntervalsGroup } = stateRef.current;
14414
14359
  if (!tweenGroup || !timelineIntervalsGroup || versionMeshes.length === 0)
14415
14360
  return;
@@ -14546,7 +14491,7 @@ function XViewScene({
14546
14491
  }
14547
14492
  });
14548
14493
  }, []);
14549
- (0, import_react29.useEffect)(() => {
14494
+ (0, import_react32.useEffect)(() => {
14550
14495
  async function fetchAllData(configPath, ownerId2) {
14551
14496
  var _a2, _b2;
14552
14497
  if (!get_scene_view_data) {
@@ -14651,12 +14596,12 @@ function XViewScene({
14651
14596
  focusNodeId,
14652
14597
  focusAncestryId
14653
14598
  ]);
14654
- const isNodeInView = (0, import_react29.useCallback)((id) => {
14599
+ const isNodeInView = (0, import_react32.useCallback)((id) => {
14655
14600
  const key = String(id);
14656
14601
  const objs = stateRef.current.nodeObjects || {};
14657
14602
  return !!objs[key];
14658
14603
  }, []);
14659
- const addOrUpdateNodeMesh = (0, import_react29.useCallback)(
14604
+ const addOrUpdateNodeMesh = (0, import_react32.useCallback)(
14660
14605
  (nodeData, position, suppressVersionUpdate = false, forceShowQuestDate = false) => {
14661
14606
  const {
14662
14607
  graphGroup,
@@ -14697,7 +14642,7 @@ function XViewScene({
14697
14642
  },
14698
14643
  []
14699
14644
  );
14700
- const handleActivateQuestLens = (0, import_react29.useCallback)(({ assigneeId, status: status2, milestoneId }) => {
14645
+ const handleActivateQuestLens = (0, import_react32.useCallback)(({ assigneeId, status: status2, milestoneId }) => {
14701
14646
  var _a2;
14702
14647
  const { nodeObjects, tweenGroup, graphGroup } = stateRef.current;
14703
14648
  if (!nodeObjects || !tweenGroup || !graphGroup) return;
@@ -14911,7 +14856,7 @@ function XViewScene({
14911
14856
  camTween.start();
14912
14857
  }
14913
14858
  }, [addOrUpdateNodeMesh]);
14914
- (0, import_react29.useEffect)(() => {
14859
+ (0, import_react32.useEffect)(() => {
14915
14860
  if (!isInitialized || !sceneDataRef.current) return;
14916
14861
  const currentMount = mountRef.current;
14917
14862
  if (!currentMount) return;
@@ -15667,7 +15612,7 @@ function XViewScene({
15667
15612
  get_scene_view_data,
15668
15613
  save_view_data
15669
15614
  ]);
15670
- const handleGhostNodeImageChange = (0, import_react29.useCallback)((useImage, imageUrl) => {
15615
+ const handleGhostNodeImageChange = (0, import_react32.useCallback)((useImage, imageUrl) => {
15671
15616
  const {
15672
15617
  node: ghostNode,
15673
15618
  line: ghostLine,
@@ -15715,7 +15660,7 @@ function XViewScene({
15715
15660
  aura: newGhostNode.getObjectByName("aura")
15716
15661
  };
15717
15662
  }, []);
15718
- const handleGhostNodeIntensityChange = (0, import_react29.useCallback)((newIntensity) => {
15663
+ const handleGhostNodeIntensityChange = (0, import_react32.useCallback)((newIntensity) => {
15719
15664
  const { node: ghostNode, aura: ghostAura } = stateRef.current.ghostElements;
15720
15665
  if (!ghostNode) return;
15721
15666
  const adjustedIntensity = newIntensity + MIN_VISIBILITY_INTENSITY;
@@ -15736,7 +15681,7 @@ function XViewScene({
15736
15681
  ghostAura.material.opacity = Math.min(0.8, newIntensity * 0.15);
15737
15682
  }
15738
15683
  }, []);
15739
- const handleDetailNodeIntensityChange = (0, import_react29.useCallback)(
15684
+ const handleDetailNodeIntensityChange = (0, import_react32.useCallback)(
15740
15685
  (nodeId, newIntensity) => {
15741
15686
  const mesh = stateRef.current.nodeObjects[String(nodeId)];
15742
15687
  if (!mesh) return;
@@ -15892,7 +15837,7 @@ function XViewScene({
15892
15837
  mountRef.current.style.cursor = "default";
15893
15838
  }
15894
15839
  };
15895
- const handleAncestryTreeUpdate = (0, import_react29.useCallback)((newTree, extraData = null) => {
15840
+ const handleAncestryTreeUpdate = (0, import_react32.useCallback)((newTree, extraData = null) => {
15896
15841
  setAncestryMode((prev) => {
15897
15842
  const prevTreeStr = JSON.stringify(prev.tree);
15898
15843
  const newTreeStr = JSON.stringify(newTree);
@@ -15915,7 +15860,7 @@ function XViewScene({
15915
15860
  };
15916
15861
  });
15917
15862
  }, []);
15918
- const actionHandlerContext = (0, import_react29.useMemo)(
15863
+ const actionHandlerContext = (0, import_react32.useMemo)(
15919
15864
  () => {
15920
15865
  var _a2;
15921
15866
  return {
@@ -15976,7 +15921,7 @@ function XViewScene({
15976
15921
  const handleStartVersioning = (nodeData) => {
15977
15922
  userActionHandlers.handleStartVersioning(actionHandlerContext, nodeData);
15978
15923
  };
15979
- const handleStartQuestQuick = (0, import_react29.useCallback)((questNode) => {
15924
+ const handleStartQuestQuick = (0, import_react32.useCallback)((questNode) => {
15980
15925
  var _a2, _b2, _c2;
15981
15926
  if (!questNode || !actionHandlerContext) return;
15982
15927
  const allParentNodes = Object.values(parentDataRef.current).flatMap((fileData) => fileData.nodes || []);
@@ -16011,7 +15956,7 @@ function XViewScene({
16011
15956
  }
16012
15957
  setDetailsNode(updatedNode);
16013
15958
  }, [session, actionHandlerContext]);
16014
- const handleFinishQuestQuick = (0, import_react29.useCallback)((questNode) => {
15959
+ const handleFinishQuestQuick = (0, import_react32.useCallback)((questNode) => {
16015
15960
  var _a2, _b2, _c2, _d2;
16016
15961
  if (!questNode || !actionHandlerContext) return;
16017
15962
  const {
@@ -16085,7 +16030,7 @@ function XViewScene({
16085
16030
  setDetailsNode(null);
16086
16031
  }
16087
16032
  }, [session, actionHandlerContext, viewMembers, detailsNode]);
16088
- const handleCancelQuest = (0, import_react29.useCallback)(() => {
16033
+ const handleCancelQuest = (0, import_react32.useCallback)(() => {
16089
16034
  const { graphGroup, ghostElements } = stateRef.current;
16090
16035
  if (ghostElements.node && graphGroup) {
16091
16036
  if (ghostElements.node.userData.labelObject) {
@@ -16240,7 +16185,7 @@ function XViewScene({
16240
16185
  }
16241
16186
  userActionHandlers.handleCancelConnection(context);
16242
16187
  };
16243
- const handleClearAncestryVisuals = (0, import_react29.useCallback)((ancestryId) => {
16188
+ const handleClearAncestryVisuals = (0, import_react32.useCallback)((ancestryId) => {
16244
16189
  const { renderedAncestries, ancestryGroup } = stateRef.current;
16245
16190
  const renderIndex = renderedAncestries.findIndex(
16246
16191
  (a) => String(a.id) === String(ancestryId)
@@ -16258,7 +16203,7 @@ function XViewScene({
16258
16203
  );
16259
16204
  }
16260
16205
  }, []);
16261
- const handleRenderAncestry = (0, import_react29.useCallback)(
16206
+ const handleRenderAncestry = (0, import_react32.useCallback)(
16262
16207
  async (ancestryObject, allowedSectionIds = null, activeSectionIdForFocus = null, baseRotation = 0, forceReprocess = true) => {
16263
16208
  setContextMenu(
16264
16209
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -16752,7 +16697,7 @@ function XViewScene({
16752
16697
  ancestryMode.isActive
16753
16698
  ]
16754
16699
  );
16755
- const handleRenderAbstractionTree = (0, import_react29.useCallback)(
16700
+ const handleRenderAbstractionTree = (0, import_react32.useCallback)(
16756
16701
  (ancestryObject, targetNodeId = null) => {
16757
16702
  setContextMenu(
16758
16703
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -16840,7 +16785,7 @@ function XViewScene({
16840
16785
  handleClearAncestryVisuals
16841
16786
  ]
16842
16787
  );
16843
- const handleReadModeBranchNav = (0, import_react29.useCallback)(
16788
+ const handleReadModeBranchNav = (0, import_react32.useCallback)(
16844
16789
  (nodeId, action, direction = "right") => {
16845
16790
  const { ancestry, branchStack } = readingMode;
16846
16791
  if (!ancestry || !ancestry.tree) return;
@@ -17018,13 +16963,13 @@ function XViewScene({
17018
16963
  },
17019
16964
  [readingMode, handleRenderAncestry, buildFullAncestryTree, tweenToTarget]
17020
16965
  );
17021
- const handleReadModeHighlight = (0, import_react29.useCallback)((nodeId) => {
16966
+ const handleReadModeHighlight = (0, import_react32.useCallback)((nodeId) => {
17022
16967
  if (stateRef.current.highlightedNodeId !== nodeId) {
17023
16968
  stateRef.current.highlightedNodeId = nodeId;
17024
16969
  }
17025
16970
  setHighlightedNodeId(nodeId);
17026
16971
  }, []);
17027
- const activeNodeBranches = (0, import_react29.useMemo)(() => {
16972
+ const activeNodeBranches = (0, import_react32.useMemo)(() => {
17028
16973
  if (!highlightedNodeId || !readingMode.ancestry || !readingMode.ancestry.tree)
17029
16974
  return null;
17030
16975
  const fullTree = buildFullAncestryTree(
@@ -17068,7 +17013,7 @@ function XViewScene({
17068
17013
  readingMode.branchStack,
17069
17014
  ancestryDataRef.current
17070
17015
  ]);
17071
- const backNavigationInfo = (0, import_react29.useMemo)(() => {
17016
+ const backNavigationInfo = (0, import_react32.useMemo)(() => {
17072
17017
  const { branchStack } = readingMode;
17073
17018
  if (!branchStack || branchStack.length === 0) return null;
17074
17019
  const lastStep = branchStack[branchStack.length - 1];
@@ -17079,7 +17024,7 @@ function XViewScene({
17079
17024
  name: "Voltar para anterior"
17080
17025
  };
17081
17026
  }, [readingMode.branchStack]);
17082
- const getReadModeDisplayContext = (0, import_react29.useMemo)(() => {
17027
+ const getReadModeDisplayContext = (0, import_react32.useMemo)(() => {
17083
17028
  const { ancestry, branchStack } = readingMode;
17084
17029
  if (!ancestry) return null;
17085
17030
  if (branchStack.length === 0) {
@@ -17122,7 +17067,7 @@ function XViewScene({
17122
17067
  customProperties: branchProps
17123
17068
  };
17124
17069
  }, [readingMode, buildFullAncestryTree, ancestryDataRef.current]);
17125
- const readModeAbstractionTree = (0, import_react29.useMemo)(() => {
17070
+ const readModeAbstractionTree = (0, import_react32.useMemo)(() => {
17126
17071
  if (!readingMode.isActive || !readingMode.ancestry || !readingMode.ancestry.abstraction_tree) {
17127
17072
  return null;
17128
17073
  }
@@ -17141,7 +17086,7 @@ function XViewScene({
17141
17086
  buildFullAncestryTree,
17142
17087
  sceneVersion
17143
17088
  ]);
17144
- const handleStartReadingAncestry = (0, import_react29.useCallback)(
17089
+ const handleStartReadingAncestry = (0, import_react32.useCallback)(
17145
17090
  async (ancestryObject, renderMode = "full") => {
17146
17091
  setContextMenu(
17147
17092
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -17184,7 +17129,7 @@ function XViewScene({
17184
17129
  },
17185
17130
  [handleRenderAncestry, handleRenderAbstractionTree]
17186
17131
  );
17187
- const handleReadModeSectionChange = (0, import_react29.useCallback)(
17132
+ const handleReadModeSectionChange = (0, import_react32.useCallback)(
17188
17133
  (activeSectionId) => {
17189
17134
  const { ancestry, branchStack } = readingMode;
17190
17135
  if (!ancestry || !readingMode.isActive) return;
@@ -17269,10 +17214,10 @@ function XViewScene({
17269
17214
  ancestryDataRef.current
17270
17215
  ]
17271
17216
  );
17272
- const handleCloseReadMode = (0, import_react29.useCallback)(() => {
17217
+ const handleCloseReadMode = (0, import_react32.useCallback)(() => {
17273
17218
  setReadingMode({ isActive: false, ancestry: null, branchStack: [] });
17274
17219
  }, []);
17275
- const handleAncestrySectionChange = (0, import_react29.useCallback)(
17220
+ const handleAncestrySectionChange = (0, import_react32.useCallback)(
17276
17221
  (activeSectionId, ancestryOverride = null, rotation = 0) => {
17277
17222
  var _a2, _b2;
17278
17223
  const currentMode = stateRef.current.ancestry;
@@ -17334,7 +17279,7 @@ function XViewScene({
17334
17279
  },
17335
17280
  [handleRenderAncestry]
17336
17281
  );
17337
- const handleEditAncestry = (0, import_react29.useCallback)(
17282
+ const handleEditAncestry = (0, import_react32.useCallback)(
17338
17283
  async (ancestryObject) => {
17339
17284
  setContextMenu(
17340
17285
  (prev) => prev.visible ? { ...prev, visible: false } : prev
@@ -17389,7 +17334,7 @@ function XViewScene({
17389
17334
  const handleSelectAncestryParent = (nodeId) => {
17390
17335
  setAncestryMode((prev) => ({ ...prev, selectedParentId: nodeId }));
17391
17336
  };
17392
- const handleRemoveFromAncestry = (0, import_react29.useCallback)((pathToRemove) => {
17337
+ const handleRemoveFromAncestry = (0, import_react32.useCallback)((pathToRemove) => {
17393
17338
  if (!Array.isArray(pathToRemove) || pathToRemove.length === 0) {
17394
17339
  console.warn("Tentativa de remover a raiz ou caminho inv\xE1lido.");
17395
17340
  return;
@@ -17414,7 +17359,7 @@ function XViewScene({
17414
17359
  return { ...prev, tree: newTree };
17415
17360
  });
17416
17361
  }, []);
17417
- const handleSaveAncestry = (0, import_react29.useCallback)(
17362
+ const handleSaveAncestry = (0, import_react32.useCallback)(
17418
17363
  async (ancestryName, ancestryDescription, ancestrySections, keepOpen = false, treeOverride = null, ancestryCustomProps = {}) => {
17419
17364
  const treeToUse = treeOverride || ancestryMode.tree;
17420
17365
  const { isEditMode, currentAncestryId } = ancestryMode;
@@ -17650,7 +17595,7 @@ function XViewScene({
17650
17595
  });
17651
17596
  setEditingAncestryRel({ visible: false, data: null, path: null });
17652
17597
  };
17653
- const handleDeleteAncestry = (0, import_react29.useCallback)(
17598
+ const handleDeleteAncestry = (0, import_react32.useCallback)(
17654
17599
  async (ancestryIdToDelete) => {
17655
17600
  if (!ancestryIdToDelete) {
17656
17601
  alert("ID da ancestralidade n\xE3o encontrado.");
@@ -17732,10 +17677,10 @@ function XViewScene({
17732
17677
  },
17733
17678
  [save_view_data, delete_file_action]
17734
17679
  );
17735
- const handleOpenAncestryBoard = (0, import_react29.useCallback)(() => {
17680
+ const handleOpenAncestryBoard = (0, import_react32.useCallback)(() => {
17736
17681
  setIsAncestryBoardOpen(true);
17737
17682
  }, []);
17738
- const handleSelectAncestryFromBoard = (0, import_react29.useCallback)(
17683
+ const handleSelectAncestryFromBoard = (0, import_react32.useCallback)(
17739
17684
  (item) => {
17740
17685
  setIsAncestryBoardOpen(false);
17741
17686
  setIsSidebarOpen(false);
@@ -17753,7 +17698,7 @@ function XViewScene({
17753
17698
  },
17754
17699
  [handleStartReadingAncestry, tweenToTarget]
17755
17700
  );
17756
- const handleSaveAncestryBoard = (0, import_react29.useCallback)(
17701
+ const handleSaveAncestryBoard = (0, import_react32.useCallback)(
17757
17702
  async (groups) => {
17758
17703
  if (!sceneConfigId || !viewParams || !session) return;
17759
17704
  const sceneType = (viewParams.type || "").toLowerCase().includes("database") ? "database" : "view";
@@ -17767,7 +17712,7 @@ function XViewScene({
17767
17712
  },
17768
17713
  [sceneConfigId, viewParams, session, save_ancestry_board_action, ownerId]
17769
17714
  );
17770
- const existingNodeTypes = (0, import_react29.useMemo)(() => {
17715
+ const existingNodeTypes = (0, import_react32.useMemo)(() => {
17771
17716
  if (!parentDataRef.current) {
17772
17717
  return [];
17773
17718
  }
@@ -17779,7 +17724,7 @@ function XViewScene({
17779
17724
  ).filter((t) => Boolean(t) && String(t).toLowerCase() !== "quest");
17780
17725
  return [...new Set(allTypes)];
17781
17726
  }, [parentDataRef.current, sceneVersion]);
17782
- const searchableDbNodes = (0, import_react29.useMemo)(() => {
17727
+ const searchableDbNodes = (0, import_react32.useMemo)(() => {
17783
17728
  var _a2;
17784
17729
  if (!parentDataRef.current) {
17785
17730
  return [];
@@ -17800,7 +17745,7 @@ function XViewScene({
17800
17745
  return !((_a3 = node.version_node) == null ? void 0 : _a3.is_version);
17801
17746
  });
17802
17747
  }, [parentDataRef.current, (_b = sceneDataRef.current) == null ? void 0 : _b.quest_nodes, sceneVersion]);
17803
- const handleAddExistingNode = (0, import_react29.useCallback)(
17748
+ const handleAddExistingNode = (0, import_react32.useCallback)(
17804
17749
  (nodeId) => {
17805
17750
  return userActionHandlers.handleAddExistingNodeById(
17806
17751
  actionHandlerContext,
@@ -17809,7 +17754,7 @@ function XViewScene({
17809
17754
  },
17810
17755
  [actionHandlerContext]
17811
17756
  );
17812
- const handleUpdateMilestones = (0, import_react29.useCallback)(
17757
+ const handleUpdateMilestones = (0, import_react32.useCallback)(
17813
17758
  async (newMilestones) => {
17814
17759
  var _a2, _b2, _c2;
17815
17760
  if (!sceneDataRef.current) return;
@@ -17855,7 +17800,7 @@ function XViewScene({
17855
17800
  viewParams == null ? void 0 : viewParams.type
17856
17801
  ]
17857
17802
  );
17858
- const handleSaveCurrentView = (0, import_react29.useCallback)(async () => {
17803
+ const handleSaveCurrentView = (0, import_react32.useCallback)(async () => {
17859
17804
  var _a2, _b2, _c2;
17860
17805
  const { nodeObjects, allLinks } = stateRef.current;
17861
17806
  if (!nodeObjects || !allLinks || !sceneSaveUrl || !parentDataRef.current) {
@@ -17898,16 +17843,16 @@ function XViewScene({
17898
17843
  console.error("Erro na chamada de save_view_data:", error);
17899
17844
  }
17900
17845
  }, [sceneSaveUrl, save_view_data, sceneConfigId, viewParams == null ? void 0 : viewParams.type]);
17901
- const allAvailableNodes = (0, import_react29.useMemo)(() => {
17846
+ const allAvailableNodes = (0, import_react32.useMemo)(() => {
17902
17847
  if (!parentDataRef.current) return [];
17903
17848
  return Object.values(parentDataRef.current).flatMap(
17904
17849
  (fileData) => fileData.nodes || []
17905
17850
  );
17906
17851
  }, [sceneVersion, isInitialized]);
17907
- const allAvailableAncestries = (0, import_react29.useMemo)(() => {
17852
+ const allAvailableAncestries = (0, import_react32.useMemo)(() => {
17908
17853
  return ancestryDataRef.current || [];
17909
17854
  }, [sceneVersion, isInitialized]);
17910
- const handleOpenReference = (0, import_react29.useCallback)(
17855
+ const handleOpenReference = (0, import_react32.useCallback)(
17911
17856
  (referenceData) => {
17912
17857
  const { type, id } = referenceData;
17913
17858
  if (type === "node") {
@@ -17946,13 +17891,13 @@ function XViewScene({
17946
17891
  tweenToTarget
17947
17892
  ]
17948
17893
  );
17949
- const handleToggleAncestryAddMode = (0, import_react29.useCallback)(() => {
17894
+ const handleToggleAncestryAddMode = (0, import_react32.useCallback)(() => {
17950
17895
  setAncestryMode((prev) => ({
17951
17896
  ...prev,
17952
17897
  isAddingNodes: !prev.isAddingNodes
17953
17898
  }));
17954
17899
  }, []);
17955
- const handleFocusNode = (0, import_react29.useCallback)(
17900
+ const handleFocusNode = (0, import_react32.useCallback)(
17956
17901
  (nodeData) => {
17957
17902
  var _a2;
17958
17903
  if (!nodeData) return;
@@ -17968,7 +17913,7 @@ function XViewScene({
17968
17913
  },
17969
17914
  [tweenToTarget]
17970
17915
  );
17971
- const availableDatasets = (0, import_react29.useMemo)(() => {
17916
+ const availableDatasets = (0, import_react32.useMemo)(() => {
17972
17917
  if (!sceneDataRef.current || !parentDataRef.current) return [];
17973
17918
  return sceneDataRef.current.parent_dbs.map((db) => {
17974
17919
  var _a2;
@@ -17982,7 +17927,7 @@ function XViewScene({
17982
17927
  String(creationMode.sourceNodeData.id)
17983
17928
  )) == null ? void 0 : _c.parentFileId : null;
17984
17929
  const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
17985
- (0, import_react29.useEffect)(() => {
17930
+ (0, import_react32.useEffect)(() => {
17986
17931
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
17987
17932
  const nodeObjects = stateRef.current.nodeObjects || {};
17988
17933
  const targetMesh = nodeObjects[String(focusNodeId)];
@@ -18005,7 +17950,7 @@ function XViewScene({
18005
17950
  hasFocusedInitial,
18006
17951
  tweenToTarget
18007
17952
  ]);
18008
- (0, import_react29.useEffect)(() => {
17953
+ (0, import_react32.useEffect)(() => {
18009
17954
  if (isInitialized && focusAncestryId && !hasOpenedInitialAncestry) {
18010
17955
  const ancestries = ancestryDataRef.current || [];
18011
17956
  const targetAncestry = ancestries.find(
@@ -18030,7 +17975,7 @@ function XViewScene({
18030
17975
  hasOpenedInitialAncestry,
18031
17976
  handleStartReadingAncestry
18032
17977
  ]);
18033
- (0, import_react29.useEffect)(() => {
17978
+ (0, import_react32.useEffect)(() => {
18034
17979
  function handleKeyDown(event) {
18035
17980
  var _a2, _b2, _c2;
18036
17981
  const context = actionHandlerContext;
@@ -18153,10 +18098,10 @@ function XViewScene({
18153
18098
  // <-- handleCancelQuest adicionado aqui
18154
18099
  ]);
18155
18100
  if (isLoading || status === "loading" || permissionStatus === "loading") {
18156
- return /* @__PURE__ */ import_react29.default.createElement(LoadingScreen, null);
18101
+ return /* @__PURE__ */ import_react32.default.createElement(LoadingScreen, null);
18157
18102
  }
18158
18103
  if (permissionStatus === "denied") {
18159
- 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(
18104
+ return /* @__PURE__ */ import_react32.default.createElement("div", { className: "flex flex-col items-center justify-center min-h-screen w-full bg-slate-950 text-white" }, /* @__PURE__ */ import_react32.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_react32.default.createElement("div", { className: "mb-4 text-red-500" }, /* @__PURE__ */ import_react32.default.createElement(
18160
18105
  "svg",
18161
18106
  {
18162
18107
  xmlns: "http://www.w3.org/2000/svg",
@@ -18166,7 +18111,7 @@ function XViewScene({
18166
18111
  stroke: "currentColor",
18167
18112
  className: "w-16 h-16 mx-auto"
18168
18113
  },
18169
- /* @__PURE__ */ import_react29.default.createElement(
18114
+ /* @__PURE__ */ import_react32.default.createElement(
18170
18115
  "path",
18171
18116
  {
18172
18117
  strokeLinecap: "round",
@@ -18174,13 +18119,13 @@ function XViewScene({
18174
18119
  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"
18175
18120
  }
18176
18121
  )
18177
- )), /* @__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(
18122
+ )), /* @__PURE__ */ import_react32.default.createElement("h2", { className: "text-2xl font-bold mb-2" }, "Acesso Negado"), /* @__PURE__ */ import_react32.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_react32.default.createElement(
18178
18123
  "button",
18179
18124
  {
18180
18125
  onClick: () => router.push("/dashboard/scenes"),
18181
18126
  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"
18182
18127
  },
18183
- /* @__PURE__ */ import_react29.default.createElement(
18128
+ /* @__PURE__ */ import_react32.default.createElement(
18184
18129
  "svg",
18185
18130
  {
18186
18131
  xmlns: "http://www.w3.org/2000/svg",
@@ -18190,7 +18135,7 @@ function XViewScene({
18190
18135
  stroke: "currentColor",
18191
18136
  className: "w-5 h-5"
18192
18137
  },
18193
- /* @__PURE__ */ import_react29.default.createElement(
18138
+ /* @__PURE__ */ import_react32.default.createElement(
18194
18139
  "path",
18195
18140
  {
18196
18141
  strokeLinecap: "round",
@@ -18202,7 +18147,7 @@ function XViewScene({
18202
18147
  "Voltar para Scenes"
18203
18148
  )));
18204
18149
  }
18205
- return /* @__PURE__ */ import_react29.default.createElement(
18150
+ return /* @__PURE__ */ import_react32.default.createElement(
18206
18151
  "div",
18207
18152
  {
18208
18153
  ref: mountRef,
@@ -18214,7 +18159,7 @@ function XViewScene({
18214
18159
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
18215
18160
  }
18216
18161
  },
18217
- userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react29.default.createElement(
18162
+ userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react32.default.createElement(
18218
18163
  XViewSidebar,
18219
18164
  {
18220
18165
  dbNodes: searchableDbNodes,
@@ -18238,7 +18183,7 @@ function XViewScene({
18238
18183
  onOpenMilestoneManager: () => setIsMilestoneManagerOpen(true)
18239
18184
  }
18240
18185
  ),
18241
- creationMode.isActive && /* @__PURE__ */ import_react29.default.createElement(
18186
+ creationMode.isActive && /* @__PURE__ */ import_react32.default.createElement(
18242
18187
  InSceneCreationForm,
18243
18188
  {
18244
18189
  onSave: (data) => userActionHandlers.handleSaveNode(actionHandlerContext, data),
@@ -18270,7 +18215,7 @@ function XViewScene({
18270
18215
  availableAncestries: allAvailableAncestries
18271
18216
  }
18272
18217
  ),
18273
- versionMode.isActive && /* @__PURE__ */ import_react29.default.createElement(
18218
+ versionMode.isActive && /* @__PURE__ */ import_react32.default.createElement(
18274
18219
  InSceneVersionForm,
18275
18220
  {
18276
18221
  onSave: (data) => userActionHandlers.handleSaveVersionNode(actionHandlerContext, data),
@@ -18296,7 +18241,7 @@ function XViewScene({
18296
18241
  availableAncestries: allAvailableAncestries
18297
18242
  }
18298
18243
  ),
18299
- questMode.isActive && /* @__PURE__ */ import_react29.default.createElement(
18244
+ questMode.isActive && /* @__PURE__ */ import_react32.default.createElement(
18300
18245
  InSceneQuestForm,
18301
18246
  {
18302
18247
  onSave: (data) => handleSaveQuestNode(actionHandlerContext, data),
@@ -18324,7 +18269,7 @@ function XViewScene({
18324
18269
  onUpdateMilestones: handleUpdateMilestones
18325
18270
  }
18326
18271
  ),
18327
- readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react29.default.createElement(
18272
+ readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react32.default.createElement(
18328
18273
  "div",
18329
18274
  {
18330
18275
  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"}`,
@@ -18337,7 +18282,7 @@ function XViewScene({
18337
18282
  maxWidth: "92vw"
18338
18283
  }
18339
18284
  },
18340
- /* @__PURE__ */ import_react29.default.createElement(
18285
+ /* @__PURE__ */ import_react32.default.createElement(
18341
18286
  "div",
18342
18287
  {
18343
18288
  onPointerDown: (e) => {
@@ -18348,7 +18293,7 @@ function XViewScene({
18348
18293
  title: "Arraste para redimensionar"
18349
18294
  }
18350
18295
  ),
18351
- /* @__PURE__ */ import_react29.default.createElement(
18296
+ /* @__PURE__ */ import_react32.default.createElement(
18352
18297
  DescriptionReadModePanel,
18353
18298
  {
18354
18299
  key: readingMode.branchStack.length > 0 ? readingMode.branchStack[readingMode.branchStack.length - 1].branchId : readingMode.ancestry.ancestry_id,
@@ -18383,7 +18328,7 @@ function XViewScene({
18383
18328
  }
18384
18329
  )
18385
18330
  ),
18386
- ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react29.default.createElement(
18331
+ ancestryMode.isActive && ancestryMode.tree && /* @__PURE__ */ import_react32.default.createElement(
18387
18332
  CreateAncestryPanel,
18388
18333
  {
18389
18334
  ancestryMode,
@@ -18419,7 +18364,7 @@ function XViewScene({
18419
18364
  onRenderAbstractionTree: (data, targetId) => handleRenderAbstractionTree(data, targetId)
18420
18365
  }
18421
18366
  ),
18422
- editingAncestryRel.visible && /* @__PURE__ */ import_react29.default.createElement(
18367
+ editingAncestryRel.visible && /* @__PURE__ */ import_react32.default.createElement(
18423
18368
  AncestryRelationshipPanel,
18424
18369
  {
18425
18370
  data: editingAncestryRel.data,
@@ -18433,7 +18378,7 @@ function XViewScene({
18433
18378
  onUploadFile: upload_file_action
18434
18379
  }
18435
18380
  ),
18436
- detailsNode && detailsNode.is_quest && /* @__PURE__ */ import_react29.default.createElement(
18381
+ detailsNode && detailsNode.is_quest && /* @__PURE__ */ import_react32.default.createElement(
18437
18382
  QuestDetailsPanel,
18438
18383
  {
18439
18384
  node: detailsNode,
@@ -18459,7 +18404,7 @@ function XViewScene({
18459
18404
  onUpdateMilestones: handleUpdateMilestones
18460
18405
  }
18461
18406
  ),
18462
- detailsNode && !detailsNode.is_quest && /* @__PURE__ */ import_react29.default.createElement(
18407
+ detailsNode && !detailsNode.is_quest && /* @__PURE__ */ import_react32.default.createElement(
18463
18408
  NodeDetailsPanel,
18464
18409
  {
18465
18410
  node: detailsNode,
@@ -18491,7 +18436,7 @@ function XViewScene({
18491
18436
  currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
18492
18437
  }
18493
18438
  ),
18494
- detailsLink && /* @__PURE__ */ import_react29.default.createElement(
18439
+ detailsLink && /* @__PURE__ */ import_react32.default.createElement(
18495
18440
  RelationshipDetailsPanel,
18496
18441
  {
18497
18442
  link: detailsLink,
@@ -18505,7 +18450,7 @@ function XViewScene({
18505
18450
  userRole: userPermissionRole
18506
18451
  }
18507
18452
  ),
18508
- ancestryLinkDetails && /* @__PURE__ */ import_react29.default.createElement(
18453
+ ancestryLinkDetails && /* @__PURE__ */ import_react32.default.createElement(
18509
18454
  AncestryLinkDetailsPanel,
18510
18455
  {
18511
18456
  data: ancestryLinkDetails,
@@ -18516,7 +18461,7 @@ function XViewScene({
18516
18461
  onUploadFile: upload_file_action
18517
18462
  }
18518
18463
  ),
18519
- /* @__PURE__ */ import_react29.default.createElement(
18464
+ /* @__PURE__ */ import_react32.default.createElement(
18520
18465
  "div",
18521
18466
  {
18522
18467
  ref: tooltipRef,
@@ -18543,7 +18488,7 @@ function XViewScene({
18543
18488
  }
18544
18489
  }
18545
18490
  ),
18546
- /* @__PURE__ */ import_react29.default.createElement(
18491
+ /* @__PURE__ */ import_react32.default.createElement(
18547
18492
  ContextMenu,
18548
18493
  {
18549
18494
  data: contextMenu,
@@ -18576,7 +18521,7 @@ function XViewScene({
18576
18521
  onFinishQuest: handleFinishQuestQuick
18577
18522
  }
18578
18523
  ),
18579
- /* @__PURE__ */ import_react29.default.createElement(
18524
+ /* @__PURE__ */ import_react32.default.createElement(
18580
18525
  MultiNodeContextMenu,
18581
18526
  {
18582
18527
  data: multiContextMenu,
@@ -18596,7 +18541,7 @@ function XViewScene({
18596
18541
  )
18597
18542
  }
18598
18543
  ),
18599
- /* @__PURE__ */ import_react29.default.createElement(
18544
+ /* @__PURE__ */ import_react32.default.createElement(
18600
18545
  RelationshipContextMenu,
18601
18546
  {
18602
18547
  data: relationshipMenu,
@@ -18614,14 +18559,14 @@ function XViewScene({
18614
18559
  onDelete: (data) => userActionHandlers.handleDeleteLink(actionHandlerContext, data)
18615
18560
  }
18616
18561
  ),
18617
- /* @__PURE__ */ import_react29.default.createElement(
18562
+ /* @__PURE__ */ import_react32.default.createElement(
18618
18563
  ImageViewer,
18619
18564
  {
18620
18565
  data: imageViewer,
18621
18566
  onClose: () => setImageViewer({ ...imageViewer, visible: false })
18622
18567
  }
18623
18568
  ),
18624
- /* @__PURE__ */ import_react29.default.createElement(
18569
+ /* @__PURE__ */ import_react32.default.createElement(
18625
18570
  AncestryBoard,
18626
18571
  {
18627
18572
  isOpen: isAncestryBoardOpen,
@@ -18634,7 +18579,7 @@ function XViewScene({
18634
18579
  userRole: userPermissionRole
18635
18580
  }
18636
18581
  ),
18637
- /* @__PURE__ */ import_react29.default.createElement(
18582
+ /* @__PURE__ */ import_react32.default.createElement(
18638
18583
  MilestoneManager,
18639
18584
  {
18640
18585
  isOpen: isMilestoneManagerOpen,
@@ -18643,7 +18588,7 @@ function XViewScene({
18643
18588
  onUpdateMilestones: handleUpdateMilestones
18644
18589
  }
18645
18590
  ),
18646
- /* @__PURE__ */ import_react29.default.createElement(
18591
+ /* @__PURE__ */ import_react32.default.createElement(
18647
18592
  ImportParentFileModal,
18648
18593
  {
18649
18594
  isOpen: isImportModalOpen,
@@ -18656,7 +18601,7 @@ function XViewScene({
18656
18601
  currentAncestries: ancestryDataRef.current || []
18657
18602
  }
18658
18603
  ),
18659
- invalidTargetError && /* @__PURE__ */ import_react29.default.createElement(
18604
+ invalidTargetError && /* @__PURE__ */ import_react32.default.createElement(
18660
18605
  "div",
18661
18606
  {
18662
18607
  className: "ui-overlay",
@@ -18681,13 +18626,13 @@ function XViewScene({
18681
18626
  animation: "fadeInDown 0.5s cubic-bezier(0.16, 1, 0.3, 1)"
18682
18627
  }
18683
18628
  },
18684
- /* @__PURE__ */ import_react29.default.createElement("style", null, `
18629
+ /* @__PURE__ */ import_react32.default.createElement("style", null, `
18685
18630
  @keyframes fadeInDown {
18686
18631
  from { opacity: 0; transform: translate(-50%, -20px); }
18687
18632
  to { opacity: 1; transform: translate(-50%, 0); }
18688
18633
  }
18689
18634
  `),
18690
- /* @__PURE__ */ import_react29.default.createElement(
18635
+ /* @__PURE__ */ import_react32.default.createElement(
18691
18636
  "svg",
18692
18637
  {
18693
18638
  width: "20",
@@ -18699,12 +18644,12 @@ function XViewScene({
18699
18644
  strokeLinecap: "round",
18700
18645
  strokeLinejoin: "round"
18701
18646
  },
18702
- /* @__PURE__ */ import_react29.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
18703
- /* @__PURE__ */ import_react29.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
18704
- /* @__PURE__ */ import_react29.default.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
18647
+ /* @__PURE__ */ import_react32.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
18648
+ /* @__PURE__ */ import_react32.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
18649
+ /* @__PURE__ */ import_react32.default.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
18705
18650
  ),
18706
- /* @__PURE__ */ import_react29.default.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
18707
- /* @__PURE__ */ import_react29.default.createElement(
18651
+ /* @__PURE__ */ import_react32.default.createElement("span", { style: { fontSize: "14px", fontWeight: 500 } }, invalidTargetError),
18652
+ /* @__PURE__ */ import_react32.default.createElement(
18708
18653
  "button",
18709
18654
  {
18710
18655
  onClick: () => setInvalidTargetError(null),