@cyvest/cyvest-vis 4.3.0 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,54 +1,22 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- CyvestGraph: () => CyvestGraph,
34
- DEFAULT_FORCE_CONFIG: () => DEFAULT_FORCE_CONFIG,
35
- INVESTIGATION_ICON_MAP: () => INVESTIGATION_ICON_MAP,
36
- InvestigationGraph: () => InvestigationGraph,
37
- OBSERVABLE_ICON_MAP: () => OBSERVABLE_ICON_MAP,
38
- ObservablesGraph: () => ObservablesGraph,
39
- getInvestigationIcon: () => getInvestigationIcon,
40
- getObservableIcon: () => getObservableIcon
41
- });
42
- module.exports = __toCommonJS(index_exports);
43
-
44
1
  // src/components/CyvestGraph.tsx
45
- var import_react14 = require("react");
2
+ import { useState as useState2, useCallback as useCallback4, useMemo as useMemo8 } from "react";
46
3
 
47
4
  // src/components/ObservablesGraph.tsx
48
- var import_react7 = __toESM(require("react"));
49
- var import_react8 = require("@xyflow/react");
50
- var import_style = require("@xyflow/react/dist/style.css");
51
- var import_cyvest_js2 = require("@cyvest/cyvest-js");
5
+ import React3, { useMemo as useMemo4, useCallback as useCallback2, useState, useRef as useRef2 } from "react";
6
+ import {
7
+ ReactFlow,
8
+ ReactFlowProvider,
9
+ Background,
10
+ Controls,
11
+ MiniMap,
12
+ useNodesState,
13
+ useEdgesState,
14
+ ConnectionMode,
15
+ BackgroundVariant,
16
+ Panel
17
+ } from "@xyflow/react";
18
+ import "@xyflow/react/dist/style.css";
19
+ import { getObservableGraph } from "@cyvest/cyvest-js";
52
20
 
53
21
  // src/types.ts
54
22
  var DEFAULT_FORCE_CONFIG = {
@@ -60,11 +28,11 @@ var DEFAULT_FORCE_CONFIG = {
60
28
  };
61
29
 
62
30
  // src/components/ObservableNode.tsx
63
- var import_react = require("react");
64
- var import_react2 = require("@xyflow/react");
31
+ import { memo, useMemo } from "react";
32
+ import { Handle, Position } from "@xyflow/react";
65
33
 
66
34
  // src/utils/observables.ts
67
- var import_cyvest_js = require("@cyvest/cyvest-js");
35
+ import { getColorForLevel } from "@cyvest/cyvest-js";
68
36
  function truncateLabel(value, maxLength = 20, truncateMiddle = true) {
69
37
  if (value.length <= maxLength) {
70
38
  return value;
@@ -76,7 +44,7 @@ function truncateLabel(value, maxLength = 20, truncateMiddle = true) {
76
44
  return `${value.slice(0, maxLength - 1)}\u2026`;
77
45
  }
78
46
  function getLevelColor(level) {
79
- return (0, import_cyvest_js.getColorForLevel)(level);
47
+ return getColorForLevel(level);
80
48
  }
81
49
  function lightenHexColor(hex, amount) {
82
50
  const normalized = hex.startsWith("#") ? hex.slice(1) : hex;
@@ -95,14 +63,14 @@ function getLevelBackgroundColor(level) {
95
63
  }
96
64
 
97
65
  // src/components/Icons.tsx
98
- var import_jsx_runtime = require("react/jsx-runtime");
66
+ import { jsx, jsxs } from "react/jsx-runtime";
99
67
  var defaultSize = 16;
100
68
  var defaultColor = "currentColor";
101
69
  var GlobeIcon = ({
102
70
  size = defaultSize,
103
71
  color = defaultColor,
104
72
  className
105
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
73
+ }) => /* @__PURE__ */ jsxs(
106
74
  "svg",
107
75
  {
108
76
  width: size,
@@ -115,9 +83,9 @@ var GlobeIcon = ({
115
83
  strokeLinejoin: "round",
116
84
  className,
117
85
  children: [
118
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
119
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 12h20" }),
120
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })
86
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
87
+ /* @__PURE__ */ jsx("path", { d: "M2 12h20" }),
88
+ /* @__PURE__ */ jsx("path", { d: "M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })
121
89
  ]
122
90
  }
123
91
  );
@@ -125,7 +93,7 @@ var DomainIcon = ({
125
93
  size = defaultSize,
126
94
  color = defaultColor,
127
95
  className
128
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
96
+ }) => /* @__PURE__ */ jsxs(
129
97
  "svg",
130
98
  {
131
99
  width: size,
@@ -138,8 +106,8 @@ var DomainIcon = ({
138
106
  strokeLinejoin: "round",
139
107
  className,
140
108
  children: [
141
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }),
142
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "9,22 9,12 15,12 15,22" })
109
+ /* @__PURE__ */ jsx("path", { d: "M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }),
110
+ /* @__PURE__ */ jsx("polyline", { points: "9,22 9,12 15,12 15,22" })
143
111
  ]
144
112
  }
145
113
  );
@@ -147,7 +115,7 @@ var LinkIcon = ({
147
115
  size = defaultSize,
148
116
  color = defaultColor,
149
117
  className
150
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
118
+ }) => /* @__PURE__ */ jsxs(
151
119
  "svg",
152
120
  {
153
121
  width: size,
@@ -160,8 +128,8 @@ var LinkIcon = ({
160
128
  strokeLinejoin: "round",
161
129
  className,
162
130
  children: [
163
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
164
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
131
+ /* @__PURE__ */ jsx("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
132
+ /* @__PURE__ */ jsx("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
165
133
  ]
166
134
  }
167
135
  );
@@ -169,7 +137,7 @@ var MailIcon = ({
169
137
  size = defaultSize,
170
138
  color = defaultColor,
171
139
  className
172
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
140
+ }) => /* @__PURE__ */ jsxs(
173
141
  "svg",
174
142
  {
175
143
  width: size,
@@ -182,8 +150,8 @@ var MailIcon = ({
182
150
  strokeLinejoin: "round",
183
151
  className,
184
152
  children: [
185
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
186
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" })
153
+ /* @__PURE__ */ jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
154
+ /* @__PURE__ */ jsx("path", { d: "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" })
187
155
  ]
188
156
  }
189
157
  );
@@ -191,7 +159,7 @@ var EnvelopeIcon = ({
191
159
  size = defaultSize,
192
160
  color = defaultColor,
193
161
  className
194
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
162
+ }) => /* @__PURE__ */ jsxs(
195
163
  "svg",
196
164
  {
197
165
  width: size,
@@ -204,8 +172,8 @@ var EnvelopeIcon = ({
204
172
  strokeLinejoin: "round",
205
173
  className,
206
174
  children: [
207
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M22 12h-6l-2 3h-4l-2-3H2" }),
208
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" })
175
+ /* @__PURE__ */ jsx("path", { d: "M22 12h-6l-2 3h-4l-2-3H2" }),
176
+ /* @__PURE__ */ jsx("path", { d: "M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" })
209
177
  ]
210
178
  }
211
179
  );
@@ -213,7 +181,7 @@ var FileIcon = ({
213
181
  size = defaultSize,
214
182
  color = defaultColor,
215
183
  className
216
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
184
+ }) => /* @__PURE__ */ jsxs(
217
185
  "svg",
218
186
  {
219
187
  width: size,
@@ -226,8 +194,8 @@ var FileIcon = ({
226
194
  strokeLinejoin: "round",
227
195
  className,
228
196
  children: [
229
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
230
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "14,2 14,8 20,8" })
197
+ /* @__PURE__ */ jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
198
+ /* @__PURE__ */ jsx("polyline", { points: "14,2 14,8 20,8" })
231
199
  ]
232
200
  }
233
201
  );
@@ -235,7 +203,7 @@ var HashIcon = ({
235
203
  size = defaultSize,
236
204
  color = defaultColor,
237
205
  className
238
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
206
+ }) => /* @__PURE__ */ jsxs(
239
207
  "svg",
240
208
  {
241
209
  width: size,
@@ -248,10 +216,10 @@ var HashIcon = ({
248
216
  strokeLinejoin: "round",
249
217
  className,
250
218
  children: [
251
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "4", y1: "9", x2: "20", y2: "9" }),
252
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "4", y1: "15", x2: "20", y2: "15" }),
253
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "10", y1: "3", x2: "8", y2: "21" }),
254
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "16", y1: "3", x2: "14", y2: "21" })
219
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "9", x2: "20", y2: "9" }),
220
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "15", x2: "20", y2: "15" }),
221
+ /* @__PURE__ */ jsx("line", { x1: "10", y1: "3", x2: "8", y2: "21" }),
222
+ /* @__PURE__ */ jsx("line", { x1: "16", y1: "3", x2: "14", y2: "21" })
255
223
  ]
256
224
  }
257
225
  );
@@ -259,7 +227,7 @@ var UserIcon = ({
259
227
  size = defaultSize,
260
228
  color = defaultColor,
261
229
  className
262
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
230
+ }) => /* @__PURE__ */ jsxs(
263
231
  "svg",
264
232
  {
265
233
  width: size,
@@ -272,8 +240,8 @@ var UserIcon = ({
272
240
  strokeLinejoin: "round",
273
241
  className,
274
242
  children: [
275
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "8", r: "5" }),
276
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 21a8 8 0 1 0-16 0" })
243
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "8", r: "5" }),
244
+ /* @__PURE__ */ jsx("path", { d: "M20 21a8 8 0 1 0-16 0" })
277
245
  ]
278
246
  }
279
247
  );
@@ -281,7 +249,7 @@ var IdCardIcon = ({
281
249
  size = defaultSize,
282
250
  color = defaultColor,
283
251
  className
284
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
252
+ }) => /* @__PURE__ */ jsxs(
285
253
  "svg",
286
254
  {
287
255
  width: size,
@@ -294,10 +262,10 @@ var IdCardIcon = ({
294
262
  strokeLinejoin: "round",
295
263
  className,
296
264
  children: [
297
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2", y: "5", width: "20", height: "14", rx: "2" }),
298
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "8", cy: "12", r: "2" }),
299
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 10h4" }),
300
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 14h4" })
265
+ /* @__PURE__ */ jsx("rect", { x: "2", y: "5", width: "20", height: "14", rx: "2" }),
266
+ /* @__PURE__ */ jsx("circle", { cx: "8", cy: "12", r: "2" }),
267
+ /* @__PURE__ */ jsx("path", { d: "M14 10h4" }),
268
+ /* @__PURE__ */ jsx("path", { d: "M14 14h4" })
301
269
  ]
302
270
  }
303
271
  );
@@ -305,7 +273,7 @@ var GearIcon = ({
305
273
  size = defaultSize,
306
274
  color = defaultColor,
307
275
  className
308
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
276
+ }) => /* @__PURE__ */ jsxs(
309
277
  "svg",
310
278
  {
311
279
  width: size,
@@ -318,8 +286,8 @@ var GearIcon = ({
318
286
  strokeLinejoin: "round",
319
287
  className,
320
288
  children: [
321
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "3" }),
322
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" })
289
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" }),
290
+ /* @__PURE__ */ jsx("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" })
323
291
  ]
324
292
  }
325
293
  );
@@ -327,7 +295,7 @@ var AppIcon = ({
327
295
  size = defaultSize,
328
296
  color = defaultColor,
329
297
  className
330
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
298
+ }) => /* @__PURE__ */ jsxs(
331
299
  "svg",
332
300
  {
333
301
  width: size,
@@ -340,9 +308,9 @@ var AppIcon = ({
340
308
  strokeLinejoin: "round",
341
309
  className,
342
310
  children: [
343
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
344
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 3v18" }),
345
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 9h18" })
311
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
312
+ /* @__PURE__ */ jsx("path", { d: "M9 3v18" }),
313
+ /* @__PURE__ */ jsx("path", { d: "M3 9h18" })
346
314
  ]
347
315
  }
348
316
  );
@@ -350,7 +318,7 @@ var RegistryIcon = ({
350
318
  size = defaultSize,
351
319
  color = defaultColor,
352
320
  className
353
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
321
+ }) => /* @__PURE__ */ jsx(
354
322
  "svg",
355
323
  {
356
324
  width: size,
@@ -362,14 +330,14 @@ var RegistryIcon = ({
362
330
  strokeLinecap: "round",
363
331
  strokeLinejoin: "round",
364
332
  className,
365
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21 2-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0 3 3L22 7l-3-3m-3.5 3.5L19 4" })
333
+ children: /* @__PURE__ */ jsx("path", { d: "m21 2-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0 3 3L22 7l-3-3m-3.5 3.5L19 4" })
366
334
  }
367
335
  );
368
336
  var ThreatActorIcon = ({
369
337
  size = defaultSize,
370
338
  color = defaultColor,
371
339
  className
372
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
340
+ }) => /* @__PURE__ */ jsxs(
373
341
  "svg",
374
342
  {
375
343
  width: size,
@@ -382,12 +350,12 @@ var ThreatActorIcon = ({
382
350
  strokeLinejoin: "round",
383
351
  className,
384
352
  children: [
385
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "10", r: "7" }),
386
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "9", cy: "9", r: "1.5", fill: color }),
387
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "15", cy: "9", r: "1.5", fill: color }),
388
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 17v-2" }),
389
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 17v-2" }),
390
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M15 17v-2" })
353
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "10", r: "7" }),
354
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "1.5", fill: color }),
355
+ /* @__PURE__ */ jsx("circle", { cx: "15", cy: "9", r: "1.5", fill: color }),
356
+ /* @__PURE__ */ jsx("path", { d: "M9 17v-2" }),
357
+ /* @__PURE__ */ jsx("path", { d: "M12 17v-2" }),
358
+ /* @__PURE__ */ jsx("path", { d: "M15 17v-2" })
391
359
  ]
392
360
  }
393
361
  );
@@ -395,7 +363,7 @@ var BugIcon = ({
395
363
  size = defaultSize,
396
364
  color = defaultColor,
397
365
  className
398
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
366
+ }) => /* @__PURE__ */ jsxs(
399
367
  "svg",
400
368
  {
401
369
  width: size,
@@ -408,17 +376,17 @@ var BugIcon = ({
408
376
  strokeLinejoin: "round",
409
377
  className,
410
378
  children: [
411
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m8 2 1.88 1.88" }),
412
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14.12 3.88 16 2" }),
413
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 7.13v-1a3.003 3.003 0 1 1 6 0v1" }),
414
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6" }),
415
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 20v-9" }),
416
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6.53 9C4.6 8.8 3 7.1 3 5" }),
417
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 13H2" }),
418
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 21c0-2.1 1.7-3.9 3.8-4" }),
419
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20.97 5c0 2.1-1.6 3.8-3.5 4" }),
420
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M22 13h-4" }),
421
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M17.2 17c2.1.1 3.8 1.9 3.8 4" })
379
+ /* @__PURE__ */ jsx("path", { d: "m8 2 1.88 1.88" }),
380
+ /* @__PURE__ */ jsx("path", { d: "M14.12 3.88 16 2" }),
381
+ /* @__PURE__ */ jsx("path", { d: "M9 7.13v-1a3.003 3.003 0 1 1 6 0v1" }),
382
+ /* @__PURE__ */ jsx("path", { d: "M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6" }),
383
+ /* @__PURE__ */ jsx("path", { d: "M12 20v-9" }),
384
+ /* @__PURE__ */ jsx("path", { d: "M6.53 9C4.6 8.8 3 7.1 3 5" }),
385
+ /* @__PURE__ */ jsx("path", { d: "M6 13H2" }),
386
+ /* @__PURE__ */ jsx("path", { d: "M3 21c0-2.1 1.7-3.9 3.8-4" }),
387
+ /* @__PURE__ */ jsx("path", { d: "M20.97 5c0 2.1-1.6 3.8-3.5 4" }),
388
+ /* @__PURE__ */ jsx("path", { d: "M22 13h-4" }),
389
+ /* @__PURE__ */ jsx("path", { d: "M17.2 17c2.1.1 3.8 1.9 3.8 4" })
422
390
  ]
423
391
  }
424
392
  );
@@ -426,7 +394,7 @@ var SwordIcon = ({
426
394
  size = defaultSize,
427
395
  color = defaultColor,
428
396
  className
429
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
397
+ }) => /* @__PURE__ */ jsxs(
430
398
  "svg",
431
399
  {
432
400
  width: size,
@@ -439,10 +407,10 @@ var SwordIcon = ({
439
407
  strokeLinejoin: "round",
440
408
  className,
441
409
  children: [
442
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "14.5,17.5 3,6 3,3 6,3 17.5,14.5" }),
443
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "13", y1: "19", x2: "19", y2: "13" }),
444
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "16", y1: "16", x2: "20", y2: "20" }),
445
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "19", y1: "21", x2: "21", y2: "19" })
410
+ /* @__PURE__ */ jsx("polyline", { points: "14.5,17.5 3,6 3,3 6,3 17.5,14.5" }),
411
+ /* @__PURE__ */ jsx("line", { x1: "13", y1: "19", x2: "19", y2: "13" }),
412
+ /* @__PURE__ */ jsx("line", { x1: "16", y1: "16", x2: "20", y2: "20" }),
413
+ /* @__PURE__ */ jsx("line", { x1: "19", y1: "21", x2: "21", y2: "19" })
446
414
  ]
447
415
  }
448
416
  );
@@ -450,7 +418,7 @@ var TargetIcon = ({
450
418
  size = defaultSize,
451
419
  color = defaultColor,
452
420
  className
453
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
421
+ }) => /* @__PURE__ */ jsxs(
454
422
  "svg",
455
423
  {
456
424
  width: size,
@@ -463,9 +431,9 @@ var TargetIcon = ({
463
431
  strokeLinejoin: "round",
464
432
  className,
465
433
  children: [
466
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
467
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "6" }),
468
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "2" })
434
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
435
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "6" }),
436
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "2" })
469
437
  ]
470
438
  }
471
439
  );
@@ -473,7 +441,7 @@ var AlertIcon = ({
473
441
  size = defaultSize,
474
442
  color = defaultColor,
475
443
  className
476
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
444
+ }) => /* @__PURE__ */ jsxs(
477
445
  "svg",
478
446
  {
479
447
  width: size,
@@ -486,9 +454,9 @@ var AlertIcon = ({
486
454
  strokeLinejoin: "round",
487
455
  className,
488
456
  children: [
489
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
490
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
491
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
457
+ /* @__PURE__ */ jsx("path", { d: "M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
458
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
459
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
492
460
  ]
493
461
  }
494
462
  );
@@ -496,7 +464,7 @@ var FlaskIcon = ({
496
464
  size = defaultSize,
497
465
  color = defaultColor,
498
466
  className
499
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
467
+ }) => /* @__PURE__ */ jsxs(
500
468
  "svg",
501
469
  {
502
470
  width: size,
@@ -509,9 +477,9 @@ var FlaskIcon = ({
509
477
  strokeLinejoin: "round",
510
478
  className,
511
479
  children: [
512
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2" }),
513
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8.5 2h7" }),
514
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7 16h10" })
480
+ /* @__PURE__ */ jsx("path", { d: "M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2" }),
481
+ /* @__PURE__ */ jsx("path", { d: "M8.5 2h7" }),
482
+ /* @__PURE__ */ jsx("path", { d: "M7 16h10" })
515
483
  ]
516
484
  }
517
485
  );
@@ -519,7 +487,7 @@ var CertificateIcon = ({
519
487
  size = defaultSize,
520
488
  color = defaultColor,
521
489
  className
522
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
490
+ }) => /* @__PURE__ */ jsxs(
523
491
  "svg",
524
492
  {
525
493
  width: size,
@@ -532,9 +500,9 @@ var CertificateIcon = ({
532
500
  strokeLinejoin: "round",
533
501
  className,
534
502
  children: [
535
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" }),
536
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6Z" }),
537
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m9.5 15.5-3 3v3l3.5-1.5 3.5 1.5v-3l-3-3" })
503
+ /* @__PURE__ */ jsx("path", { d: "M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" }),
504
+ /* @__PURE__ */ jsx("path", { d: "M2 6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6Z" }),
505
+ /* @__PURE__ */ jsx("path", { d: "m9.5 15.5-3 3v3l3.5-1.5 3.5 1.5v-3l-3-3" })
538
506
  ]
539
507
  }
540
508
  );
@@ -542,7 +510,7 @@ var WifiIcon = ({
542
510
  size = defaultSize,
543
511
  color = defaultColor,
544
512
  className
545
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
513
+ }) => /* @__PURE__ */ jsxs(
546
514
  "svg",
547
515
  {
548
516
  width: size,
@@ -555,10 +523,10 @@ var WifiIcon = ({
555
523
  strokeLinejoin: "round",
556
524
  className,
557
525
  children: [
558
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 12.55a11 11 0 0 1 14.08 0" }),
559
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M1.42 9a16 16 0 0 1 21.16 0" }),
560
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8.53 16.11a6 6 0 0 1 6.95 0" }),
561
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "20", x2: "12.01", y2: "20" })
526
+ /* @__PURE__ */ jsx("path", { d: "M5 12.55a11 11 0 0 1 14.08 0" }),
527
+ /* @__PURE__ */ jsx("path", { d: "M1.42 9a16 16 0 0 1 21.16 0" }),
528
+ /* @__PURE__ */ jsx("path", { d: "M8.53 16.11a6 6 0 0 1 6.95 0" }),
529
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "20", x2: "12.01", y2: "20" })
562
530
  ]
563
531
  }
564
532
  );
@@ -566,7 +534,7 @@ var WorldIcon = ({
566
534
  size = defaultSize,
567
535
  color = defaultColor,
568
536
  className
569
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
537
+ }) => /* @__PURE__ */ jsxs(
570
538
  "svg",
571
539
  {
572
540
  width: size,
@@ -579,9 +547,9 @@ var WorldIcon = ({
579
547
  strokeLinejoin: "round",
580
548
  className,
581
549
  children: [
582
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
583
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }),
584
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 12h20" })
550
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
551
+ /* @__PURE__ */ jsx("path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }),
552
+ /* @__PURE__ */ jsx("path", { d: "M2 12h20" })
585
553
  ]
586
554
  }
587
555
  );
@@ -589,7 +557,7 @@ var QuestionIcon = ({
589
557
  size = defaultSize,
590
558
  color = defaultColor,
591
559
  className
592
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
560
+ }) => /* @__PURE__ */ jsxs(
593
561
  "svg",
594
562
  {
595
563
  width: size,
@@ -602,9 +570,9 @@ var QuestionIcon = ({
602
570
  strokeLinejoin: "round",
603
571
  className,
604
572
  children: [
605
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
606
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
607
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 17h.01" })
573
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
574
+ /* @__PURE__ */ jsx("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
575
+ /* @__PURE__ */ jsx("path", { d: "M12 17h.01" })
608
576
  ]
609
577
  }
610
578
  );
@@ -612,7 +580,7 @@ var CheckIcon = ({
612
580
  size = defaultSize,
613
581
  color = defaultColor,
614
582
  className
615
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
583
+ }) => /* @__PURE__ */ jsx(
616
584
  "svg",
617
585
  {
618
586
  width: size,
@@ -624,14 +592,14 @@ var CheckIcon = ({
624
592
  strokeLinecap: "round",
625
593
  strokeLinejoin: "round",
626
594
  className,
627
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 6 9 17l-5-5" })
595
+ children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" })
628
596
  }
629
597
  );
630
598
  var BoxIcon = ({
631
599
  size = defaultSize,
632
600
  color = defaultColor,
633
601
  className
634
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
602
+ }) => /* @__PURE__ */ jsxs(
635
603
  "svg",
636
604
  {
637
605
  width: size,
@@ -644,9 +612,9 @@ var BoxIcon = ({
644
612
  strokeLinejoin: "round",
645
613
  className,
646
614
  children: [
647
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" }),
648
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m3.3 7 8.7 5 8.7-5" }),
649
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 22V12" })
615
+ /* @__PURE__ */ jsx("path", { d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" }),
616
+ /* @__PURE__ */ jsx("path", { d: "m3.3 7 8.7 5 8.7-5" }),
617
+ /* @__PURE__ */ jsx("path", { d: "M12 22V12" })
650
618
  ]
651
619
  }
652
620
  );
@@ -654,7 +622,7 @@ var CrosshairIcon = ({
654
622
  size = defaultSize,
655
623
  color = defaultColor,
656
624
  className
657
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
625
+ }) => /* @__PURE__ */ jsxs(
658
626
  "svg",
659
627
  {
660
628
  width: size,
@@ -667,11 +635,11 @@ var CrosshairIcon = ({
667
635
  strokeLinejoin: "round",
668
636
  className,
669
637
  children: [
670
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
671
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "22", y1: "12", x2: "18", y2: "12" }),
672
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "6", y1: "12", x2: "2", y2: "12" }),
673
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "6", x2: "12", y2: "2" }),
674
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "22", x2: "12", y2: "18" })
638
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
639
+ /* @__PURE__ */ jsx("line", { x1: "22", y1: "12", x2: "18", y2: "12" }),
640
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "12", x2: "2", y2: "12" }),
641
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "6", x2: "12", y2: "2" }),
642
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "22", x2: "12", y2: "18" })
675
643
  ]
676
644
  }
677
645
  );
@@ -727,7 +695,7 @@ function getInvestigationIcon(nodeType) {
727
695
  }
728
696
 
729
697
  // src/components/ObservableNode.tsx
730
- var import_jsx_runtime2 = require("react/jsx-runtime");
698
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
731
699
  var NODE_SIZE = 40;
732
700
  var ROOT_NODE_WIDTH = 56;
733
701
  var ROOT_NODE_HEIGHT = 40;
@@ -778,11 +746,11 @@ function ObservableNodeComponent({ data, selected }) {
778
746
  const { label, level, isRoot, whitelisted, fullValue, observableType } = nodeData;
779
747
  const borderColor = getLevelColor(level);
780
748
  const backgroundColor = getLevelBackgroundColor(level);
781
- const IconComponent = (0, import_react.useMemo)(() => {
749
+ const IconComponent = useMemo(() => {
782
750
  if (isRoot) return CrosshairIcon;
783
751
  return getObservableIcon(observableType);
784
752
  }, [isRoot, observableType]);
785
- const shapeStyle = (0, import_react.useMemo)(() => {
753
+ const shapeStyle = useMemo(() => {
786
754
  if (isRoot) {
787
755
  return {
788
756
  width: ROOT_NODE_WIDTH,
@@ -812,34 +780,34 @@ function ObservableNodeComponent({ data, selected }) {
812
780
  transition: "box-shadow 0.15s ease-out, transform 0.1s ease-out"
813
781
  };
814
782
  }, [isRoot, backgroundColor, borderColor, selected, whitelisted]);
815
- const labelStyle = (0, import_react.useMemo)(
783
+ const labelStyle = useMemo(
816
784
  () => ({
817
785
  ...nodeStyles.label,
818
786
  color: whitelisted ? "#9ca3af" : "#374151"
819
787
  }),
820
788
  [whitelisted]
821
789
  );
822
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "observable-node", style: nodeStyles.container, children: [
823
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: nodeStyles.shapeWrapper, children: [
824
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: shapeStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
790
+ return /* @__PURE__ */ jsxs2("div", { className: "observable-node", style: nodeStyles.container, children: [
791
+ /* @__PURE__ */ jsxs2("div", { style: nodeStyles.shapeWrapper, children: [
792
+ /* @__PURE__ */ jsx2("div", { style: shapeStyle, children: /* @__PURE__ */ jsx2(
825
793
  IconComponent,
826
794
  {
827
795
  size: isRoot ? ROOT_ICON_SIZE : ICON_SIZE,
828
796
  color: borderColor
829
797
  }
830
798
  ) }),
831
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Handle, { type: "source", position: import_react2.Position.Right, style: nodeStyles.handle }),
832
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Handle, { type: "target", position: import_react2.Position.Left, style: nodeStyles.handle })
799
+ /* @__PURE__ */ jsx2(Handle, { type: "source", position: Position.Right, style: nodeStyles.handle }),
800
+ /* @__PURE__ */ jsx2(Handle, { type: "target", position: Position.Left, style: nodeStyles.handle })
833
801
  ] }),
834
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: labelStyle, title: fullValue, children: label })
802
+ /* @__PURE__ */ jsx2("div", { style: labelStyle, title: fullValue, children: label })
835
803
  ] });
836
804
  }
837
- var ObservableNode = (0, import_react.memo)(ObservableNodeComponent);
805
+ var ObservableNode = memo(ObservableNodeComponent);
838
806
 
839
807
  // src/components/FloatingEdge.tsx
840
- var import_react3 = require("react");
841
- var import_react4 = require("@xyflow/react");
842
- var import_jsx_runtime3 = require("react/jsx-runtime");
808
+ import { memo as memo2, useMemo as useMemo2 } from "react";
809
+ import { BaseEdge, getBezierPath } from "@xyflow/react";
810
+ import { jsx as jsx3 } from "react/jsx-runtime";
843
811
  function getControlOffset(sourceX, sourceY, targetX, targetY) {
844
812
  const dx = targetX - sourceX;
845
813
  const dy = targetY - sourceY;
@@ -856,18 +824,18 @@ function FloatingEdgeComponent({
856
824
  markerEnd,
857
825
  selected
858
826
  }) {
859
- const offset = (0, import_react3.useMemo)(
827
+ const offset = useMemo2(
860
828
  () => getControlOffset(sourceX, sourceY, targetX, targetY),
861
829
  [sourceX, sourceY, targetX, targetY]
862
830
  );
863
- const [edgePath] = (0, import_react4.getBezierPath)({
831
+ const [edgePath] = getBezierPath({
864
832
  sourceX,
865
833
  sourceY,
866
834
  targetX,
867
835
  targetY,
868
836
  curvature: 0.15
869
837
  });
870
- const edgeStyle = (0, import_react3.useMemo)(
838
+ const edgeStyle = useMemo2(
871
839
  () => ({
872
840
  strokeWidth: selected ? 2.5 : 1.5,
873
841
  stroke: selected ? "#3b82f6" : "#94a3b8",
@@ -876,8 +844,8 @@ function FloatingEdgeComponent({
876
844
  }),
877
845
  [selected, style]
878
846
  );
879
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
880
- import_react4.BaseEdge,
847
+ return /* @__PURE__ */ jsx3(
848
+ BaseEdge,
881
849
  {
882
850
  id,
883
851
  path: edgePath,
@@ -886,31 +854,43 @@ function FloatingEdgeComponent({
886
854
  }
887
855
  );
888
856
  }
889
- var FloatingEdge = (0, import_react3.memo)(FloatingEdgeComponent);
857
+ var FloatingEdge = memo2(FloatingEdgeComponent);
890
858
 
891
859
  // src/hooks/useForceLayout.ts
892
- var import_react5 = require("react");
893
- var import_d3_force = require("d3-force");
894
- var import_react6 = require("@xyflow/react");
860
+ import { useEffect, useRef, useCallback, useMemo as useMemo3 } from "react";
861
+ import {
862
+ forceSimulation,
863
+ forceLink,
864
+ forceManyBody,
865
+ forceCenter,
866
+ forceCollide,
867
+ forceX,
868
+ forceY
869
+ } from "d3-force";
870
+ import {
871
+ useReactFlow,
872
+ useNodesInitialized,
873
+ useStore
874
+ } from "@xyflow/react";
895
875
  var nodeIdsSelector = (state) => {
896
876
  const ids = Array.from(state.nodeLookup.keys()).sort();
897
877
  return ids.join(",");
898
878
  };
899
879
  function useForceLayout(config = {}, rootNodeId) {
900
- const { getNodes, getEdges, setNodes } = (0, import_react6.useReactFlow)();
901
- const nodesInitialized = (0, import_react6.useNodesInitialized)();
902
- const nodeIds = (0, import_react6.useStore)(nodeIdsSelector);
903
- const forceConfig = (0, import_react5.useMemo)(
880
+ const { getNodes, getEdges, setNodes } = useReactFlow();
881
+ const nodesInitialized = useNodesInitialized();
882
+ const nodeIds = useStore(nodeIdsSelector);
883
+ const forceConfig = useMemo3(
904
884
  () => ({ ...DEFAULT_FORCE_CONFIG, ...config }),
905
885
  [config]
906
886
  );
907
- const simulationRef = (0, import_react5.useRef)(null);
908
- const draggingRef = (0, import_react5.useRef)({ nodeId: null, active: false });
909
- const nodePositionsRef = (0, import_react5.useRef)(
887
+ const simulationRef = useRef(null);
888
+ const draggingRef = useRef({ nodeId: null, active: false });
889
+ const nodePositionsRef = useRef(
910
890
  /* @__PURE__ */ new Map()
911
891
  );
912
- const rafRef = (0, import_react5.useRef)(null);
913
- (0, import_react5.useEffect)(() => {
892
+ const rafRef = useRef(null);
893
+ useEffect(() => {
914
894
  if (!nodesInitialized || !nodeIds) {
915
895
  return;
916
896
  }
@@ -952,13 +932,13 @@ function useForceLayout(config = {}, rootNodeId) {
952
932
  cancelAnimationFrame(rafRef.current);
953
933
  rafRef.current = null;
954
934
  }
955
- const simulation = (0, import_d3_force.forceSimulation)(simNodes).force(
935
+ const simulation = forceSimulation(simNodes).force(
956
936
  "link",
957
- (0, import_d3_force.forceLink)(simLinks).id((d) => d.id).distance(forceConfig.linkDistance).strength(0.4)
937
+ forceLink(simLinks).id((d) => d.id).distance(forceConfig.linkDistance).strength(0.4)
958
938
  ).force(
959
939
  "charge",
960
- (0, import_d3_force.forceManyBody)().strength(forceConfig.chargeStrength)
961
- ).force("center", (0, import_d3_force.forceCenter)(0, 0).strength(forceConfig.centerStrength)).force("collision", (0, import_d3_force.forceCollide)(forceConfig.collisionRadius)).force("x", (0, import_d3_force.forceX)(0).strength(8e-3)).force("y", (0, import_d3_force.forceY)(0).strength(8e-3)).alphaDecay(0.02).velocityDecay(0.35);
940
+ forceManyBody().strength(forceConfig.chargeStrength)
941
+ ).force("center", forceCenter(0, 0).strength(forceConfig.centerStrength)).force("collision", forceCollide(forceConfig.collisionRadius)).force("x", forceX(0).strength(8e-3)).force("y", forceY(0).strength(8e-3)).alphaDecay(0.02).velocityDecay(0.35);
962
942
  const updateNodes = () => {
963
943
  if (draggingRef.current.active) {
964
944
  rafRef.current = requestAnimationFrame(updateNodes);
@@ -1010,7 +990,7 @@ function useForceLayout(config = {}, rootNodeId) {
1010
990
  forceConfig,
1011
991
  rootNodeId
1012
992
  ]);
1013
- const onNodeDragStart = (0, import_react5.useCallback)(
993
+ const onNodeDragStart = useCallback(
1014
994
  (_, node) => {
1015
995
  const simulation = simulationRef.current;
1016
996
  if (!simulation) return;
@@ -1024,7 +1004,7 @@ function useForceLayout(config = {}, rootNodeId) {
1024
1004
  },
1025
1005
  []
1026
1006
  );
1027
- const onNodeDrag = (0, import_react5.useCallback)((_, node) => {
1007
+ const onNodeDrag = useCallback((_, node) => {
1028
1008
  const simulation = simulationRef.current;
1029
1009
  if (!simulation) return;
1030
1010
  const simNode = simulation.nodes().find((n) => n.id === node.id);
@@ -1037,7 +1017,7 @@ function useForceLayout(config = {}, rootNodeId) {
1037
1017
  });
1038
1018
  }
1039
1019
  }, []);
1040
- const onNodeDragStop = (0, import_react5.useCallback)(
1020
+ const onNodeDragStop = useCallback(
1041
1021
  (_, node) => {
1042
1022
  const simulation = simulationRef.current;
1043
1023
  draggingRef.current = { nodeId: null, active: false };
@@ -1058,14 +1038,14 @@ function useForceLayout(config = {}, rootNodeId) {
1058
1038
  },
1059
1039
  [rootNodeId]
1060
1040
  );
1061
- const updateForceConfig = (0, import_react5.useCallback)(
1041
+ const updateForceConfig = useCallback(
1062
1042
  (updates) => {
1063
1043
  const simulation = simulationRef.current;
1064
1044
  if (!simulation) return;
1065
1045
  if (updates.chargeStrength !== void 0) {
1066
1046
  simulation.force(
1067
1047
  "charge",
1068
- (0, import_d3_force.forceManyBody)().strength(updates.chargeStrength)
1048
+ forceManyBody().strength(updates.chargeStrength)
1069
1049
  );
1070
1050
  }
1071
1051
  if (updates.linkDistance !== void 0) {
@@ -1077,14 +1057,14 @@ function useForceLayout(config = {}, rootNodeId) {
1077
1057
  if (updates.collisionRadius !== void 0) {
1078
1058
  simulation.force(
1079
1059
  "collision",
1080
- (0, import_d3_force.forceCollide)(updates.collisionRadius)
1060
+ forceCollide(updates.collisionRadius)
1081
1061
  );
1082
1062
  }
1083
1063
  simulation.alpha(0.3).restart();
1084
1064
  },
1085
1065
  []
1086
1066
  );
1087
- const restartSimulation = (0, import_react5.useCallback)(() => {
1067
+ const restartSimulation = useCallback(() => {
1088
1068
  const simulation = simulationRef.current;
1089
1069
  if (!simulation) return;
1090
1070
  simulation.alpha(1).restart();
@@ -1099,7 +1079,7 @@ function useForceLayout(config = {}, rootNodeId) {
1099
1079
  }
1100
1080
 
1101
1081
  // src/components/ObservablesGraph.tsx
1102
- var import_jsx_runtime4 = require("react/jsx-runtime");
1082
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1103
1083
  var nodeTypes = {
1104
1084
  observable: ObservableNode
1105
1085
  };
@@ -1111,7 +1091,7 @@ var defaultEdgeOptions = {
1111
1091
  style: { stroke: "#94a3b8", strokeWidth: 1.5 }
1112
1092
  };
1113
1093
  function createObservableNodes(investigation, rootObservableIds) {
1114
- const graph = (0, import_cyvest_js2.getObservableGraph)(investigation);
1094
+ const graph = getObservableGraph(investigation);
1115
1095
  return graph.nodes.map((graphNode, index) => {
1116
1096
  const isRoot = rootObservableIds.has(graphNode.id);
1117
1097
  const nodeData = {
@@ -1142,7 +1122,7 @@ function createObservableNodes(investigation, rootObservableIds) {
1142
1122
  });
1143
1123
  }
1144
1124
  function createObservableEdges(investigation) {
1145
- const graph = (0, import_cyvest_js2.getObservableGraph)(investigation);
1125
+ const graph = getObservableGraph(investigation);
1146
1126
  return graph.edges.map((graphEdge, index) => {
1147
1127
  const edgeData = {
1148
1128
  relationshipType: graphEdge.type,
@@ -1161,7 +1141,7 @@ function createObservableEdges(investigation) {
1161
1141
  });
1162
1142
  }
1163
1143
  var ForceControls = ({ config, onChange, onRestart }) => {
1164
- const [isExpanded, setIsExpanded] = (0, import_react7.useState)(false);
1144
+ const [isExpanded, setIsExpanded] = useState(false);
1165
1145
  const panelStyle = {
1166
1146
  background: "rgba(255, 255, 255, 0.95)",
1167
1147
  backdropFilter: "blur(8px)",
@@ -1233,18 +1213,18 @@ var ForceControls = ({ config, onChange, onRestart }) => {
1233
1213
  transition: "transform 0.1s ease, box-shadow 0.1s ease",
1234
1214
  boxShadow: "0 2px 4px rgba(59, 130, 246, 0.3)"
1235
1215
  };
1236
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: panelStyle, children: [
1237
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: headerStyle, onClick: () => setIsExpanded(!isExpanded), children: [
1238
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: titleStyle, children: "\u26A1 Force Layout" }),
1239
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { style: toggleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "6 9 12 15 18 9" }) }) })
1216
+ return /* @__PURE__ */ jsxs3("div", { style: panelStyle, children: [
1217
+ /* @__PURE__ */ jsxs3("div", { style: headerStyle, onClick: () => setIsExpanded(!isExpanded), children: [
1218
+ /* @__PURE__ */ jsx4("span", { style: titleStyle, children: "\u26A1 Force Layout" }),
1219
+ /* @__PURE__ */ jsx4("button", { style: toggleStyle, children: /* @__PURE__ */ jsx4("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx4("polyline", { points: "6 9 12 15 18 9" }) }) })
1240
1220
  ] }),
1241
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: sliderContainerStyle, children: [
1242
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { marginBottom: 10 }, children: [
1243
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: sliderLabelStyle, children: [
1244
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Repulsion" }),
1245
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: config.chargeStrength })
1221
+ /* @__PURE__ */ jsxs3("div", { style: sliderContainerStyle, children: [
1222
+ /* @__PURE__ */ jsxs3("div", { style: { marginBottom: 10 }, children: [
1223
+ /* @__PURE__ */ jsxs3("div", { style: sliderLabelStyle, children: [
1224
+ /* @__PURE__ */ jsx4("span", { children: "Repulsion" }),
1225
+ /* @__PURE__ */ jsx4("span", { children: config.chargeStrength })
1246
1226
  ] }),
1247
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1227
+ /* @__PURE__ */ jsx4(
1248
1228
  "input",
1249
1229
  {
1250
1230
  type: "range",
@@ -1256,12 +1236,12 @@ var ForceControls = ({ config, onChange, onRestart }) => {
1256
1236
  }
1257
1237
  )
1258
1238
  ] }),
1259
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { marginBottom: 10 }, children: [
1260
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: sliderLabelStyle, children: [
1261
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Link Distance" }),
1262
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: config.linkDistance })
1239
+ /* @__PURE__ */ jsxs3("div", { style: { marginBottom: 10 }, children: [
1240
+ /* @__PURE__ */ jsxs3("div", { style: sliderLabelStyle, children: [
1241
+ /* @__PURE__ */ jsx4("span", { children: "Link Distance" }),
1242
+ /* @__PURE__ */ jsx4("span", { children: config.linkDistance })
1263
1243
  ] }),
1264
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1244
+ /* @__PURE__ */ jsx4(
1265
1245
  "input",
1266
1246
  {
1267
1247
  type: "range",
@@ -1273,12 +1253,12 @@ var ForceControls = ({ config, onChange, onRestart }) => {
1273
1253
  }
1274
1254
  )
1275
1255
  ] }),
1276
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { marginBottom: 6 }, children: [
1277
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: sliderLabelStyle, children: [
1278
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Collision" }),
1279
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: config.collisionRadius })
1256
+ /* @__PURE__ */ jsxs3("div", { style: { marginBottom: 6 }, children: [
1257
+ /* @__PURE__ */ jsxs3("div", { style: sliderLabelStyle, children: [
1258
+ /* @__PURE__ */ jsx4("span", { children: "Collision" }),
1259
+ /* @__PURE__ */ jsx4("span", { children: config.collisionRadius })
1280
1260
  ] }),
1281
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1261
+ /* @__PURE__ */ jsx4(
1282
1262
  "input",
1283
1263
  {
1284
1264
  type: "range",
@@ -1290,7 +1270,7 @@ var ForceControls = ({ config, onChange, onRestart }) => {
1290
1270
  }
1291
1271
  )
1292
1272
  ] }),
1293
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1273
+ /* @__PURE__ */ jsx4(
1294
1274
  "button",
1295
1275
  {
1296
1276
  onClick: onRestart,
@@ -1321,14 +1301,14 @@ var ObservablesGraphInner = ({
1321
1301
  className,
1322
1302
  showControls = true
1323
1303
  }) => {
1324
- const [forceConfig, setForceConfig] = (0, import_react7.useState)({
1304
+ const [forceConfig, setForceConfig] = useState({
1325
1305
  ...DEFAULT_FORCE_CONFIG,
1326
1306
  ...initialForceConfig
1327
1307
  });
1328
- const initialFitDone = (0, import_react7.useRef)(false);
1329
- const [nodes, setNodes, onNodesChange] = (0, import_react8.useNodesState)(initialNodes);
1330
- const [edges, setEdges, onEdgesChange] = (0, import_react8.useEdgesState)(initialEdges);
1331
- import_react7.default.useEffect(() => {
1308
+ const initialFitDone = useRef2(false);
1309
+ const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
1310
+ const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
1311
+ React3.useEffect(() => {
1332
1312
  setNodes(initialNodes);
1333
1313
  setEdges(initialEdges);
1334
1314
  initialFitDone.current = false;
@@ -1340,30 +1320,30 @@ var ObservablesGraphInner = ({
1340
1320
  updateForceConfig,
1341
1321
  restartSimulation
1342
1322
  } = useForceLayout(forceConfig, primaryRootId);
1343
- const handleNodeClick = (0, import_react7.useCallback)(
1323
+ const handleNodeClick = useCallback2(
1344
1324
  (_, node) => {
1345
1325
  onNodeClick?.(node.id);
1346
1326
  },
1347
1327
  [onNodeClick]
1348
1328
  );
1349
- const handleNodeDoubleClick = (0, import_react7.useCallback)(
1329
+ const handleNodeDoubleClick = useCallback2(
1350
1330
  (_, node) => {
1351
1331
  onNodeDoubleClick?.(node.id);
1352
1332
  },
1353
1333
  [onNodeDoubleClick]
1354
1334
  );
1355
- const handleConfigChange = (0, import_react7.useCallback)(
1335
+ const handleConfigChange = useCallback2(
1356
1336
  (updates) => {
1357
1337
  setForceConfig((prev) => ({ ...prev, ...updates }));
1358
1338
  updateForceConfig(updates);
1359
1339
  },
1360
1340
  [updateForceConfig]
1361
1341
  );
1362
- const miniMapNodeColor = (0, import_react7.useCallback)((node) => {
1342
+ const miniMapNodeColor = useCallback2((node) => {
1363
1343
  const data = node.data;
1364
1344
  return getLevelColor(data.level);
1365
1345
  }, []);
1366
- const containerStyle = (0, import_react7.useMemo)(
1346
+ const containerStyle = useMemo4(
1367
1347
  () => ({
1368
1348
  width,
1369
1349
  height,
@@ -1372,8 +1352,8 @@ var ObservablesGraphInner = ({
1372
1352
  }),
1373
1353
  [width, height]
1374
1354
  );
1375
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className, style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1376
- import_react8.ReactFlow,
1355
+ return /* @__PURE__ */ jsx4("div", { className, style: containerStyle, children: /* @__PURE__ */ jsxs3(
1356
+ ReactFlow,
1377
1357
  {
1378
1358
  nodes,
1379
1359
  edges,
@@ -1387,7 +1367,7 @@ var ObservablesGraphInner = ({
1387
1367
  nodeTypes,
1388
1368
  edgeTypes,
1389
1369
  defaultEdgeOptions,
1390
- connectionMode: import_react8.ConnectionMode.Loose,
1370
+ connectionMode: ConnectionMode.Loose,
1391
1371
  fitView: true,
1392
1372
  fitViewOptions: { padding: 0.4, maxZoom: 1.5 },
1393
1373
  minZoom: 0.1,
@@ -1402,17 +1382,17 @@ var ObservablesGraphInner = ({
1402
1382
  zoomOnPinch: true,
1403
1383
  panOnScroll: false,
1404
1384
  children: [
1405
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1406
- import_react8.Background,
1385
+ /* @__PURE__ */ jsx4(
1386
+ Background,
1407
1387
  {
1408
- variant: import_react8.BackgroundVariant.Dots,
1388
+ variant: BackgroundVariant.Dots,
1409
1389
  gap: 24,
1410
1390
  size: 1,
1411
1391
  color: "#d1d5db"
1412
1392
  }
1413
1393
  ),
1414
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1415
- import_react8.Controls,
1394
+ /* @__PURE__ */ jsx4(
1395
+ Controls,
1416
1396
  {
1417
1397
  showInteractive: false,
1418
1398
  style: {
@@ -1422,8 +1402,8 @@ var ObservablesGraphInner = ({
1422
1402
  }
1423
1403
  }
1424
1404
  ),
1425
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1426
- import_react8.MiniMap,
1405
+ /* @__PURE__ */ jsx4(
1406
+ MiniMap,
1427
1407
  {
1428
1408
  nodeColor: miniMapNodeColor,
1429
1409
  zoomable: true,
@@ -1437,7 +1417,7 @@ var ObservablesGraphInner = ({
1437
1417
  maskColor: "rgba(0,0,0,0.08)"
1438
1418
  }
1439
1419
  ),
1440
- showControls && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react8.Panel, { position: "top-right", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1420
+ showControls && /* @__PURE__ */ jsx4(Panel, { position: "top-right", children: /* @__PURE__ */ jsx4(
1441
1421
  ForceControls,
1442
1422
  {
1443
1423
  config: forceConfig,
@@ -1451,7 +1431,7 @@ var ObservablesGraphInner = ({
1451
1431
  };
1452
1432
  var ObservablesGraph = (props) => {
1453
1433
  const { investigation } = props;
1454
- const { rootKeys, primaryRootId } = (0, import_react7.useMemo)(() => {
1434
+ const { rootKeys, primaryRootId } = useMemo4(() => {
1455
1435
  const rootType = investigation.data_extraction.root_type;
1456
1436
  if (!rootType) {
1457
1437
  return { rootKeys: /* @__PURE__ */ new Set(), primaryRootId: void 0 };
@@ -1465,12 +1445,12 @@ var ObservablesGraph = (props) => {
1465
1445
  primaryRootId: rootsByType[0]?.key
1466
1446
  };
1467
1447
  }, [investigation]);
1468
- const { initialNodes, initialEdges } = (0, import_react7.useMemo)(() => {
1448
+ const { initialNodes, initialEdges } = useMemo4(() => {
1469
1449
  const nodes = createObservableNodes(investigation, rootKeys);
1470
1450
  const edges = createObservableEdges(investigation);
1471
1451
  return { initialNodes: nodes, initialEdges: edges };
1472
1452
  }, [investigation, rootKeys]);
1473
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react8.ReactFlowProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1453
+ return /* @__PURE__ */ jsx4(ReactFlowProvider, { children: /* @__PURE__ */ jsx4(
1474
1454
  ObservablesGraphInner,
1475
1455
  {
1476
1456
  ...props,
@@ -1482,14 +1462,23 @@ var ObservablesGraph = (props) => {
1482
1462
  };
1483
1463
 
1484
1464
  // src/components/InvestigationGraph.tsx
1485
- var import_react12 = __toESM(require("react"));
1486
- var import_react13 = require("@xyflow/react");
1487
- var import_style2 = require("@xyflow/react/dist/style.css");
1465
+ import React5, { useMemo as useMemo7, useCallback as useCallback3 } from "react";
1466
+ import {
1467
+ ReactFlow as ReactFlow2,
1468
+ Background as Background2,
1469
+ Controls as Controls2,
1470
+ MiniMap as MiniMap2,
1471
+ useNodesState as useNodesState2,
1472
+ useEdgesState as useEdgesState2,
1473
+ BackgroundVariant as BackgroundVariant2,
1474
+ MarkerType
1475
+ } from "@xyflow/react";
1476
+ import "@xyflow/react/dist/style.css";
1488
1477
 
1489
1478
  // src/components/InvestigationNode.tsx
1490
- var import_react9 = require("react");
1491
- var import_react10 = require("@xyflow/react");
1492
- var import_jsx_runtime5 = require("react/jsx-runtime");
1479
+ import { memo as memo3, useMemo as useMemo5 } from "react";
1480
+ import { Handle as Handle2, Position as Position2 } from "@xyflow/react";
1481
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1493
1482
  var NODE_CONFIG = {
1494
1483
  root: {
1495
1484
  minWidth: 140,
@@ -1530,11 +1519,11 @@ function InvestigationNodeComponent({ data, selected }) {
1530
1519
  const borderColor = getLevelColor(level);
1531
1520
  const backgroundColor = getLevelBackgroundColor(level);
1532
1521
  const config = NODE_CONFIG[nodeType] || NODE_CONFIG.check;
1533
- const IconComponent = (0, import_react9.useMemo)(
1522
+ const IconComponent = useMemo5(
1534
1523
  () => getInvestigationIcon(nodeType),
1535
1524
  [nodeType]
1536
1525
  );
1537
- const nodeStyle = (0, import_react9.useMemo)(
1526
+ const nodeStyle = useMemo5(
1538
1527
  () => ({
1539
1528
  minWidth: config.minWidth,
1540
1529
  padding: config.padding,
@@ -1551,7 +1540,7 @@ function InvestigationNodeComponent({ data, selected }) {
1551
1540
  }),
1552
1541
  [config, backgroundColor, borderColor, selected]
1553
1542
  );
1554
- const headerStyle = (0, import_react9.useMemo)(
1543
+ const headerStyle = useMemo5(
1555
1544
  () => ({
1556
1545
  display: "flex",
1557
1546
  alignItems: "center",
@@ -1560,7 +1549,7 @@ function InvestigationNodeComponent({ data, selected }) {
1560
1549
  }),
1561
1550
  [config.alignCenter]
1562
1551
  );
1563
- const labelStyle = (0, import_react9.useMemo)(
1552
+ const labelStyle = useMemo5(
1564
1553
  () => ({
1565
1554
  fontSize: config.fontSize,
1566
1555
  fontWeight: config.fontWeight,
@@ -1573,7 +1562,7 @@ function InvestigationNodeComponent({ data, selected }) {
1573
1562
  }),
1574
1563
  [config]
1575
1564
  );
1576
- const descriptionStyle = (0, import_react9.useMemo)(
1565
+ const descriptionStyle = useMemo5(
1577
1566
  () => ({
1578
1567
  marginTop: 4,
1579
1568
  fontSize: 10,
@@ -1595,21 +1584,21 @@ function InvestigationNodeComponent({ data, selected }) {
1595
1584
  border: "none",
1596
1585
  opacity: 0
1597
1586
  };
1598
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "investigation-node", style: nodeStyle, children: [
1599
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: headerStyle, children: [
1600
- config.showIcon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(IconComponent, { size: config.iconSize, color: borderColor }),
1601
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: labelStyle, title: label, children: label })
1587
+ return /* @__PURE__ */ jsxs4("div", { className: "investigation-node", style: nodeStyle, children: [
1588
+ /* @__PURE__ */ jsxs4("div", { style: headerStyle, children: [
1589
+ config.showIcon && /* @__PURE__ */ jsx5(IconComponent, { size: config.iconSize, color: borderColor }),
1590
+ /* @__PURE__ */ jsx5("span", { style: labelStyle, title: label, children: label })
1602
1591
  ] }),
1603
- description && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: descriptionStyle, title: description, children: description }),
1604
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react10.Handle, { type: "target", position: import_react10.Position.Left, style: handleStyle }),
1605
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react10.Handle, { type: "source", position: import_react10.Position.Right, style: handleStyle })
1592
+ description && /* @__PURE__ */ jsx5("div", { style: descriptionStyle, title: description, children: description }),
1593
+ /* @__PURE__ */ jsx5(Handle2, { type: "target", position: Position2.Left, style: handleStyle }),
1594
+ /* @__PURE__ */ jsx5(Handle2, { type: "source", position: Position2.Right, style: handleStyle })
1606
1595
  ] });
1607
1596
  }
1608
- var InvestigationNode = (0, import_react9.memo)(InvestigationNodeComponent);
1597
+ var InvestigationNode = memo3(InvestigationNodeComponent);
1609
1598
 
1610
1599
  // src/hooks/useDagreLayout.ts
1611
- var import_react11 = require("react");
1612
- var import_dagre = __toESM(require("@dagrejs/dagre"));
1600
+ import { useMemo as useMemo6 } from "react";
1601
+ import Dagre from "@dagrejs/dagre";
1613
1602
  var DEFAULT_OPTIONS = {
1614
1603
  direction: "LR",
1615
1604
  // Horizontal layout by default
@@ -1621,7 +1610,7 @@ function computeDagreLayout(nodes, edges, options = {}) {
1621
1610
  return { nodes, edges };
1622
1611
  }
1623
1612
  const opts = { ...DEFAULT_OPTIONS, ...options };
1624
- const g = new import_dagre.default.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
1613
+ const g = new Dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
1625
1614
  g.setGraph({
1626
1615
  rankdir: opts.direction,
1627
1616
  nodesep: opts.nodeSpacing,
@@ -1637,7 +1626,7 @@ function computeDagreLayout(nodes, edges, options = {}) {
1637
1626
  for (const edge of edges) {
1638
1627
  g.setEdge(edge.source, edge.target);
1639
1628
  }
1640
- import_dagre.default.layout(g);
1629
+ Dagre.layout(g);
1641
1630
  const positionedNodes = nodes.map((node) => {
1642
1631
  const dagNode = g.node(node.id);
1643
1632
  const width = node.measured?.width ?? 150;
@@ -1654,7 +1643,7 @@ function computeDagreLayout(nodes, edges, options = {}) {
1654
1643
  }
1655
1644
 
1656
1645
  // src/components/InvestigationGraph.tsx
1657
- var import_jsx_runtime6 = require("react/jsx-runtime");
1646
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1658
1647
  var nodeTypes2 = {
1659
1648
  investigation: InvestigationNode
1660
1649
  };
@@ -1665,7 +1654,7 @@ var defaultEdgeOptions2 = {
1665
1654
  strokeWidth: 1.5
1666
1655
  },
1667
1656
  markerEnd: {
1668
- type: import_react13.MarkerType.ArrowClosed,
1657
+ type: MarkerType.ArrowClosed,
1669
1658
  width: 16,
1670
1659
  height: 16,
1671
1660
  color: "#94a3b8"
@@ -1794,35 +1783,35 @@ var InvestigationGraph = ({
1794
1783
  onNodeClick,
1795
1784
  className
1796
1785
  }) => {
1797
- const { initialNodes, initialEdges } = (0, import_react12.useMemo)(() => {
1786
+ const { initialNodes, initialEdges } = useMemo7(() => {
1798
1787
  const { nodes: nodes2, edges: edges2 } = createInvestigationGraph(investigation);
1799
1788
  return { initialNodes: nodes2, initialEdges: edges2 };
1800
1789
  }, [investigation]);
1801
- const { nodes: layoutNodes, edges: layoutEdges } = (0, import_react12.useMemo)(() => {
1790
+ const { nodes: layoutNodes, edges: layoutEdges } = useMemo7(() => {
1802
1791
  return computeDagreLayout(initialNodes, initialEdges, {
1803
1792
  direction: "LR",
1804
1793
  nodeSpacing: 40,
1805
1794
  rankSpacing: 140
1806
1795
  });
1807
1796
  }, [initialNodes, initialEdges]);
1808
- const [nodes, setNodes, onNodesChange] = (0, import_react13.useNodesState)(layoutNodes);
1809
- const [edges, setEdges, onEdgesChange] = (0, import_react13.useEdgesState)(layoutEdges);
1810
- import_react12.default.useEffect(() => {
1797
+ const [nodes, setNodes, onNodesChange] = useNodesState2(layoutNodes);
1798
+ const [edges, setEdges, onEdgesChange] = useEdgesState2(layoutEdges);
1799
+ React5.useEffect(() => {
1811
1800
  setNodes(layoutNodes);
1812
1801
  setEdges(layoutEdges);
1813
1802
  }, [layoutNodes, layoutEdges, setNodes, setEdges]);
1814
- const handleNodeClick = (0, import_react12.useCallback)(
1803
+ const handleNodeClick = useCallback3(
1815
1804
  (_, node) => {
1816
1805
  const data = node.data;
1817
1806
  onNodeClick?.(node.id, data.nodeType);
1818
1807
  },
1819
1808
  [onNodeClick]
1820
1809
  );
1821
- const miniMapNodeColor = (0, import_react12.useCallback)((node) => {
1810
+ const miniMapNodeColor = useCallback3((node) => {
1822
1811
  const data = node.data;
1823
1812
  return getLevelColor(data.level);
1824
1813
  }, []);
1825
- const containerStyle = (0, import_react12.useMemo)(
1814
+ const containerStyle = useMemo7(
1826
1815
  () => ({
1827
1816
  width,
1828
1817
  height,
@@ -1831,8 +1820,8 @@ var InvestigationGraph = ({
1831
1820
  }),
1832
1821
  [width, height]
1833
1822
  );
1834
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className, style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1835
- import_react13.ReactFlow,
1823
+ return /* @__PURE__ */ jsx6("div", { className, style: containerStyle, children: /* @__PURE__ */ jsxs5(
1824
+ ReactFlow2,
1836
1825
  {
1837
1826
  nodes,
1838
1827
  edges,
@@ -1855,17 +1844,17 @@ var InvestigationGraph = ({
1855
1844
  zoomOnPinch: true,
1856
1845
  panOnScroll: false,
1857
1846
  children: [
1858
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1859
- import_react13.Background,
1847
+ /* @__PURE__ */ jsx6(
1848
+ Background2,
1860
1849
  {
1861
- variant: import_react13.BackgroundVariant.Dots,
1850
+ variant: BackgroundVariant2.Dots,
1862
1851
  gap: 24,
1863
1852
  size: 1,
1864
1853
  color: "#d1d5db"
1865
1854
  }
1866
1855
  ),
1867
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1868
- import_react13.Controls,
1856
+ /* @__PURE__ */ jsx6(
1857
+ Controls2,
1869
1858
  {
1870
1859
  showInteractive: false,
1871
1860
  style: {
@@ -1875,8 +1864,8 @@ var InvestigationGraph = ({
1875
1864
  }
1876
1865
  }
1877
1866
  ),
1878
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1879
- import_react13.MiniMap,
1867
+ /* @__PURE__ */ jsx6(
1868
+ MiniMap2,
1880
1869
  {
1881
1870
  nodeColor: miniMapNodeColor,
1882
1871
  zoomable: true,
@@ -1896,9 +1885,9 @@ var InvestigationGraph = ({
1896
1885
  };
1897
1886
 
1898
1887
  // src/components/CyvestGraph.tsx
1899
- var import_jsx_runtime7 = require("react/jsx-runtime");
1888
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1900
1889
  var ViewToggle = ({ currentView, onChange }) => {
1901
- const containerStyle = (0, import_react14.useMemo)(
1890
+ const containerStyle = useMemo8(
1902
1891
  () => ({
1903
1892
  position: "absolute",
1904
1893
  top: 12,
@@ -1916,7 +1905,7 @@ var ViewToggle = ({ currentView, onChange }) => {
1916
1905
  }),
1917
1906
  []
1918
1907
  );
1919
- const getButtonStyle = (0, import_react14.useCallback)(
1908
+ const getButtonStyle = useCallback4(
1920
1909
  (isActive) => ({
1921
1910
  padding: "8px 14px",
1922
1911
  border: "none",
@@ -1931,8 +1920,8 @@ var ViewToggle = ({ currentView, onChange }) => {
1931
1920
  }),
1932
1921
  []
1933
1922
  );
1934
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: containerStyle, children: [
1935
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1923
+ return /* @__PURE__ */ jsxs6("div", { style: containerStyle, children: [
1924
+ /* @__PURE__ */ jsx7(
1936
1925
  "button",
1937
1926
  {
1938
1927
  onClick: () => onChange("observables"),
@@ -1949,8 +1938,8 @@ var ViewToggle = ({ currentView, onChange }) => {
1949
1938
  e.currentTarget.style.color = "#4b5563";
1950
1939
  }
1951
1940
  },
1952
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
1953
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1941
+ children: /* @__PURE__ */ jsxs6("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
1942
+ /* @__PURE__ */ jsxs6(
1954
1943
  "svg",
1955
1944
  {
1956
1945
  width: "14",
@@ -1962,12 +1951,12 @@ var ViewToggle = ({ currentView, onChange }) => {
1962
1951
  strokeLinecap: "round",
1963
1952
  strokeLinejoin: "round",
1964
1953
  children: [
1965
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12", cy: "12", r: "3" }),
1966
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
1967
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "12", y1: "2", x2: "12", y2: "4" }),
1968
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "12", y1: "20", x2: "12", y2: "22" }),
1969
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "2", y1: "12", x2: "4", y2: "12" }),
1970
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "20", y1: "12", x2: "22", y2: "12" })
1954
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "3" }),
1955
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "10" }),
1956
+ /* @__PURE__ */ jsx7("line", { x1: "12", y1: "2", x2: "12", y2: "4" }),
1957
+ /* @__PURE__ */ jsx7("line", { x1: "12", y1: "20", x2: "12", y2: "22" }),
1958
+ /* @__PURE__ */ jsx7("line", { x1: "2", y1: "12", x2: "4", y2: "12" }),
1959
+ /* @__PURE__ */ jsx7("line", { x1: "20", y1: "12", x2: "22", y2: "12" })
1971
1960
  ]
1972
1961
  }
1973
1962
  ),
@@ -1975,7 +1964,7 @@ var ViewToggle = ({ currentView, onChange }) => {
1975
1964
  ] })
1976
1965
  }
1977
1966
  ),
1978
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1967
+ /* @__PURE__ */ jsx7(
1979
1968
  "button",
1980
1969
  {
1981
1970
  onClick: () => onChange("investigation"),
@@ -1992,8 +1981,8 @@ var ViewToggle = ({ currentView, onChange }) => {
1992
1981
  e.currentTarget.style.color = "#4b5563";
1993
1982
  }
1994
1983
  },
1995
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
1996
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1984
+ children: /* @__PURE__ */ jsxs6("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
1985
+ /* @__PURE__ */ jsxs6(
1997
1986
  "svg",
1998
1987
  {
1999
1988
  width: "14",
@@ -2005,9 +1994,9 @@ var ViewToggle = ({ currentView, onChange }) => {
2005
1994
  strokeLinecap: "round",
2006
1995
  strokeLinejoin: "round",
2007
1996
  children: [
2008
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2009
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M9 3v18" }),
2010
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M3 9h18" })
1997
+ /* @__PURE__ */ jsx7("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
1998
+ /* @__PURE__ */ jsx7("path", { d: "M9 3v18" }),
1999
+ /* @__PURE__ */ jsx7("path", { d: "M3 9h18" })
2011
2000
  ]
2012
2001
  }
2013
2002
  ),
@@ -2026,16 +2015,16 @@ var CyvestGraph = ({
2026
2015
  className,
2027
2016
  showViewToggle = true
2028
2017
  }) => {
2029
- const [view, setView] = (0, import_react14.useState)(
2018
+ const [view, setView] = useState2(
2030
2019
  initialView
2031
2020
  );
2032
- const handleNodeClick = (0, import_react14.useCallback)(
2021
+ const handleNodeClick = useCallback4(
2033
2022
  (nodeId, _nodeType) => {
2034
2023
  onNodeClick?.(nodeId);
2035
2024
  },
2036
2025
  [onNodeClick]
2037
2026
  );
2038
- const containerStyle = (0, import_react14.useMemo)(
2027
+ const containerStyle = useMemo8(
2039
2028
  () => ({
2040
2029
  width,
2041
2030
  height,
@@ -2043,9 +2032,9 @@ var CyvestGraph = ({
2043
2032
  }),
2044
2033
  [width, height]
2045
2034
  );
2046
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className, style: containerStyle, children: [
2047
- showViewToggle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ViewToggle, { currentView: view, onChange: setView }),
2048
- view === "observables" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2035
+ return /* @__PURE__ */ jsxs6("div", { className, style: containerStyle, children: [
2036
+ showViewToggle && /* @__PURE__ */ jsx7(ViewToggle, { currentView: view, onChange: setView }),
2037
+ view === "observables" ? /* @__PURE__ */ jsx7(
2049
2038
  ObservablesGraph,
2050
2039
  {
2051
2040
  investigation,
@@ -2054,7 +2043,7 @@ var CyvestGraph = ({
2054
2043
  onNodeClick: handleNodeClick,
2055
2044
  showControls: true
2056
2045
  }
2057
- ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2046
+ ) : /* @__PURE__ */ jsx7(
2058
2047
  InvestigationGraph,
2059
2048
  {
2060
2049
  investigation,
@@ -2065,8 +2054,7 @@ var CyvestGraph = ({
2065
2054
  )
2066
2055
  ] });
2067
2056
  };
2068
- // Annotate the CommonJS export names for ESM import in node:
2069
- 0 && (module.exports = {
2057
+ export {
2070
2058
  CyvestGraph,
2071
2059
  DEFAULT_FORCE_CONFIG,
2072
2060
  INVESTIGATION_ICON_MAP,
@@ -2075,4 +2063,4 @@ var CyvestGraph = ({
2075
2063
  ObservablesGraph,
2076
2064
  getInvestigationIcon,
2077
2065
  getObservableIcon
2078
- });
2066
+ };