@cyvest/cyvest-vis 4.4.0 → 5.0.0

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
- var BoxIcon = ({
598
+ var TagIcon = ({
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
  );
@@ -716,7 +684,7 @@ var OBSERVABLE_ICON_MAP = {
716
684
  var INVESTIGATION_ICON_MAP = {
717
685
  root: CrosshairIcon,
718
686
  check: CheckIcon,
719
- container: BoxIcon
687
+ tag: TagIcon
720
688
  };
721
689
  function getObservableIcon(observableType) {
722
690
  const normalized = observableType.toLowerCase().trim();
@@ -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,24 @@ 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";
1477
+ import { getTagAncestors } from "@cyvest/cyvest-js";
1488
1478
 
1489
1479
  // 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");
1480
+ import { memo as memo3, useMemo as useMemo5 } from "react";
1481
+ import { Handle as Handle2, Position as Position2 } from "@xyflow/react";
1482
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1493
1483
  var NODE_CONFIG = {
1494
1484
  root: {
1495
1485
  minWidth: 140,
@@ -1513,7 +1503,7 @@ var NODE_CONFIG = {
1513
1503
  alignCenter: false
1514
1504
  // Left-aligned
1515
1505
  },
1516
- container: {
1506
+ tag: {
1517
1507
  minWidth: 120,
1518
1508
  padding: "8px 14px",
1519
1509
  borderRadius: 16,
@@ -1530,11 +1520,11 @@ function InvestigationNodeComponent({ data, selected }) {
1530
1520
  const borderColor = getLevelColor(level);
1531
1521
  const backgroundColor = getLevelBackgroundColor(level);
1532
1522
  const config = NODE_CONFIG[nodeType] || NODE_CONFIG.check;
1533
- const IconComponent = (0, import_react9.useMemo)(
1523
+ const IconComponent = useMemo5(
1534
1524
  () => getInvestigationIcon(nodeType),
1535
1525
  [nodeType]
1536
1526
  );
1537
- const nodeStyle = (0, import_react9.useMemo)(
1527
+ const nodeStyle = useMemo5(
1538
1528
  () => ({
1539
1529
  minWidth: config.minWidth,
1540
1530
  padding: config.padding,
@@ -1551,7 +1541,7 @@ function InvestigationNodeComponent({ data, selected }) {
1551
1541
  }),
1552
1542
  [config, backgroundColor, borderColor, selected]
1553
1543
  );
1554
- const headerStyle = (0, import_react9.useMemo)(
1544
+ const headerStyle = useMemo5(
1555
1545
  () => ({
1556
1546
  display: "flex",
1557
1547
  alignItems: "center",
@@ -1560,7 +1550,7 @@ function InvestigationNodeComponent({ data, selected }) {
1560
1550
  }),
1561
1551
  [config.alignCenter]
1562
1552
  );
1563
- const labelStyle = (0, import_react9.useMemo)(
1553
+ const labelStyle = useMemo5(
1564
1554
  () => ({
1565
1555
  fontSize: config.fontSize,
1566
1556
  fontWeight: config.fontWeight,
@@ -1573,7 +1563,7 @@ function InvestigationNodeComponent({ data, selected }) {
1573
1563
  }),
1574
1564
  [config]
1575
1565
  );
1576
- const descriptionStyle = (0, import_react9.useMemo)(
1566
+ const descriptionStyle = useMemo5(
1577
1567
  () => ({
1578
1568
  marginTop: 4,
1579
1569
  fontSize: 10,
@@ -1595,21 +1585,21 @@ function InvestigationNodeComponent({ data, selected }) {
1595
1585
  border: "none",
1596
1586
  opacity: 0
1597
1587
  };
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 })
1588
+ return /* @__PURE__ */ jsxs4("div", { className: "investigation-node", style: nodeStyle, children: [
1589
+ /* @__PURE__ */ jsxs4("div", { style: headerStyle, children: [
1590
+ config.showIcon && /* @__PURE__ */ jsx5(IconComponent, { size: config.iconSize, color: borderColor }),
1591
+ /* @__PURE__ */ jsx5("span", { style: labelStyle, title: label, children: label })
1602
1592
  ] }),
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 })
1593
+ description && /* @__PURE__ */ jsx5("div", { style: descriptionStyle, title: description, children: description }),
1594
+ /* @__PURE__ */ jsx5(Handle2, { type: "target", position: Position2.Left, style: handleStyle }),
1595
+ /* @__PURE__ */ jsx5(Handle2, { type: "source", position: Position2.Right, style: handleStyle })
1606
1596
  ] });
1607
1597
  }
1608
- var InvestigationNode = (0, import_react9.memo)(InvestigationNodeComponent);
1598
+ var InvestigationNode = memo3(InvestigationNodeComponent);
1609
1599
 
1610
1600
  // src/hooks/useDagreLayout.ts
1611
- var import_react11 = require("react");
1612
- var import_dagre = __toESM(require("@dagrejs/dagre"));
1601
+ import { useMemo as useMemo6 } from "react";
1602
+ import Dagre from "@dagrejs/dagre";
1613
1603
  var DEFAULT_OPTIONS = {
1614
1604
  direction: "LR",
1615
1605
  // Horizontal layout by default
@@ -1621,7 +1611,7 @@ function computeDagreLayout(nodes, edges, options = {}) {
1621
1611
  return { nodes, edges };
1622
1612
  }
1623
1613
  const opts = { ...DEFAULT_OPTIONS, ...options };
1624
- const g = new import_dagre.default.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
1614
+ const g = new Dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
1625
1615
  g.setGraph({
1626
1616
  rankdir: opts.direction,
1627
1617
  nodesep: opts.nodeSpacing,
@@ -1637,7 +1627,7 @@ function computeDagreLayout(nodes, edges, options = {}) {
1637
1627
  for (const edge of edges) {
1638
1628
  g.setEdge(edge.source, edge.target);
1639
1629
  }
1640
- import_dagre.default.layout(g);
1630
+ Dagre.layout(g);
1641
1631
  const positionedNodes = nodes.map((node) => {
1642
1632
  const dagNode = g.node(node.id);
1643
1633
  const width = node.measured?.width ?? 150;
@@ -1654,7 +1644,7 @@ function computeDagreLayout(nodes, edges, options = {}) {
1654
1644
  }
1655
1645
 
1656
1646
  // src/components/InvestigationGraph.tsx
1657
- var import_jsx_runtime6 = require("react/jsx-runtime");
1647
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1658
1648
  var nodeTypes2 = {
1659
1649
  investigation: InvestigationNode
1660
1650
  };
@@ -1665,21 +1655,14 @@ var defaultEdgeOptions2 = {
1665
1655
  strokeWidth: 1.5
1666
1656
  },
1667
1657
  markerEnd: {
1668
- type: import_react13.MarkerType.ArrowClosed,
1658
+ type: MarkerType.ArrowClosed,
1669
1659
  width: 16,
1670
1660
  height: 16,
1671
1661
  color: "#94a3b8"
1672
1662
  }
1673
1663
  };
1674
- function flattenContainers(containers) {
1675
- const result = [];
1676
- for (const container of Object.values(containers)) {
1677
- result.push(container);
1678
- if (container.sub_containers) {
1679
- result.push(...flattenContainers(container.sub_containers));
1680
- }
1681
- }
1682
- return result;
1664
+ function getAllTags(tags) {
1665
+ return Object.values(tags);
1683
1666
  }
1684
1667
  function createInvestigationGraph(investigation) {
1685
1668
  const nodes = [];
@@ -1707,23 +1690,20 @@ function createInvestigationGraph(investigation) {
1707
1690
  selectable: true,
1708
1691
  draggable: true
1709
1692
  });
1710
- const allContainers = flattenContainers(investigation.containers);
1711
- const checksInContainers = /* @__PURE__ */ new Set();
1712
- for (const container of allContainers) {
1713
- for (const checkKey of container.checks) {
1714
- checksInContainers.add(checkKey);
1693
+ const allTags = getAllTags(investigation.tags);
1694
+ const checksInTags = /* @__PURE__ */ new Set();
1695
+ for (const tag of allTags) {
1696
+ for (const checkKey of tag.checks) {
1697
+ checksInTags.add(checkKey);
1715
1698
  }
1716
1699
  }
1717
- const allChecks = [];
1718
- for (const checksForKey of Object.values(investigation.checks)) {
1719
- allChecks.push(...checksForKey);
1720
- }
1700
+ const allChecks = Object.values(investigation.checks);
1721
1701
  const seenCheckIds = /* @__PURE__ */ new Set();
1722
1702
  for (const check of allChecks) {
1723
1703
  if (seenCheckIds.has(check.key)) continue;
1724
1704
  seenCheckIds.add(check.key);
1725
1705
  const checkNodeData = {
1726
- label: truncateLabel(check.check_id, 20),
1706
+ label: truncateLabel(check.check_name, 20),
1727
1707
  nodeType: "check",
1728
1708
  level: check.level,
1729
1709
  score: check.score,
@@ -1737,7 +1717,7 @@ function createInvestigationGraph(investigation) {
1737
1717
  selectable: true,
1738
1718
  draggable: true
1739
1719
  });
1740
- if (!checksInContainers.has(check.key)) {
1720
+ if (!checksInTags.has(check.key)) {
1741
1721
  edges.push({
1742
1722
  id: `edge-root-${check.key}`,
1743
1723
  source: rootKey,
@@ -1747,37 +1727,63 @@ function createInvestigationGraph(investigation) {
1747
1727
  });
1748
1728
  }
1749
1729
  }
1750
- for (const container of allContainers) {
1751
- const containerNodeData = {
1752
- label: truncateLabel(
1753
- container.path.split("/").pop() ?? container.path,
1754
- 20
1755
- ),
1756
- nodeType: "container",
1757
- level: container.aggregated_level,
1758
- score: container.aggregated_score,
1759
- path: container.path
1730
+ const tagByName = /* @__PURE__ */ new Map();
1731
+ for (const tag of allTags) {
1732
+ tagByName.set(tag.name, tag);
1733
+ }
1734
+ const allTagNames = /* @__PURE__ */ new Set();
1735
+ for (const tag of allTags) {
1736
+ allTagNames.add(tag.name);
1737
+ for (const ancestor of getTagAncestors(tag.name)) {
1738
+ allTagNames.add(ancestor);
1739
+ }
1740
+ }
1741
+ for (const tagName of allTagNames) {
1742
+ const realTag = tagByName.get(tagName);
1743
+ const tagNodeData = {
1744
+ label: truncateLabel(tagName.split(":").pop() ?? tagName, 20),
1745
+ nodeType: "tag",
1746
+ level: realTag?.direct_level ?? "INFO",
1747
+ score: realTag?.direct_score ?? 0,
1748
+ name: tagName
1760
1749
  };
1761
1750
  nodes.push({
1762
- id: `container-${container.key}`,
1751
+ id: `tag-${tagName}`,
1763
1752
  type: "investigation",
1764
1753
  position: { x: 0, y: 0 },
1765
- data: containerNodeData,
1754
+ data: tagNodeData,
1766
1755
  selectable: true,
1767
1756
  draggable: true
1768
1757
  });
1769
- edges.push({
1770
- id: `edge-root-container-${container.key}`,
1771
- source: rootKey,
1772
- target: `container-${container.key}`,
1773
- type: "smoothstep",
1774
- animated: false
1775
- });
1776
- for (const checkKey of container.checks) {
1758
+ }
1759
+ for (const tagName of allTagNames) {
1760
+ const nodeId = `tag-${tagName}`;
1761
+ const parts = tagName.split(":");
1762
+ if (parts.length === 1) {
1763
+ edges.push({
1764
+ id: `edge-root-tag-${tagName}`,
1765
+ source: rootKey,
1766
+ target: nodeId,
1767
+ type: "smoothstep",
1768
+ animated: false
1769
+ });
1770
+ } else {
1771
+ const parentName = parts.slice(0, -1).join(":");
1772
+ edges.push({
1773
+ id: `edge-tag-${parentName}-${tagName}`,
1774
+ source: `tag-${parentName}`,
1775
+ target: nodeId,
1776
+ type: "smoothstep",
1777
+ animated: false
1778
+ });
1779
+ }
1780
+ }
1781
+ for (const tag of allTags) {
1782
+ for (const checkKey of tag.checks) {
1777
1783
  if (seenCheckIds.has(checkKey)) {
1778
1784
  edges.push({
1779
- id: `edge-container-check-${container.key}-${checkKey}`,
1780
- source: `container-${container.key}`,
1785
+ id: `edge-tag-check-${tag.name}-${checkKey}`,
1786
+ source: `tag-${tag.name}`,
1781
1787
  target: `check-${checkKey}`,
1782
1788
  type: "smoothstep",
1783
1789
  animated: false
@@ -1794,35 +1800,35 @@ var InvestigationGraph = ({
1794
1800
  onNodeClick,
1795
1801
  className
1796
1802
  }) => {
1797
- const { initialNodes, initialEdges } = (0, import_react12.useMemo)(() => {
1803
+ const { initialNodes, initialEdges } = useMemo7(() => {
1798
1804
  const { nodes: nodes2, edges: edges2 } = createInvestigationGraph(investigation);
1799
1805
  return { initialNodes: nodes2, initialEdges: edges2 };
1800
1806
  }, [investigation]);
1801
- const { nodes: layoutNodes, edges: layoutEdges } = (0, import_react12.useMemo)(() => {
1807
+ const { nodes: layoutNodes, edges: layoutEdges } = useMemo7(() => {
1802
1808
  return computeDagreLayout(initialNodes, initialEdges, {
1803
1809
  direction: "LR",
1804
1810
  nodeSpacing: 40,
1805
1811
  rankSpacing: 140
1806
1812
  });
1807
1813
  }, [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(() => {
1814
+ const [nodes, setNodes, onNodesChange] = useNodesState2(layoutNodes);
1815
+ const [edges, setEdges, onEdgesChange] = useEdgesState2(layoutEdges);
1816
+ React5.useEffect(() => {
1811
1817
  setNodes(layoutNodes);
1812
1818
  setEdges(layoutEdges);
1813
1819
  }, [layoutNodes, layoutEdges, setNodes, setEdges]);
1814
- const handleNodeClick = (0, import_react12.useCallback)(
1820
+ const handleNodeClick = useCallback3(
1815
1821
  (_, node) => {
1816
1822
  const data = node.data;
1817
1823
  onNodeClick?.(node.id, data.nodeType);
1818
1824
  },
1819
1825
  [onNodeClick]
1820
1826
  );
1821
- const miniMapNodeColor = (0, import_react12.useCallback)((node) => {
1827
+ const miniMapNodeColor = useCallback3((node) => {
1822
1828
  const data = node.data;
1823
1829
  return getLevelColor(data.level);
1824
1830
  }, []);
1825
- const containerStyle = (0, import_react12.useMemo)(
1831
+ const containerStyle = useMemo7(
1826
1832
  () => ({
1827
1833
  width,
1828
1834
  height,
@@ -1831,8 +1837,8 @@ var InvestigationGraph = ({
1831
1837
  }),
1832
1838
  [width, height]
1833
1839
  );
1834
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className, style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1835
- import_react13.ReactFlow,
1840
+ return /* @__PURE__ */ jsx6("div", { className, style: containerStyle, children: /* @__PURE__ */ jsxs5(
1841
+ ReactFlow2,
1836
1842
  {
1837
1843
  nodes,
1838
1844
  edges,
@@ -1855,17 +1861,17 @@ var InvestigationGraph = ({
1855
1861
  zoomOnPinch: true,
1856
1862
  panOnScroll: false,
1857
1863
  children: [
1858
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1859
- import_react13.Background,
1864
+ /* @__PURE__ */ jsx6(
1865
+ Background2,
1860
1866
  {
1861
- variant: import_react13.BackgroundVariant.Dots,
1867
+ variant: BackgroundVariant2.Dots,
1862
1868
  gap: 24,
1863
1869
  size: 1,
1864
1870
  color: "#d1d5db"
1865
1871
  }
1866
1872
  ),
1867
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1868
- import_react13.Controls,
1873
+ /* @__PURE__ */ jsx6(
1874
+ Controls2,
1869
1875
  {
1870
1876
  showInteractive: false,
1871
1877
  style: {
@@ -1875,8 +1881,8 @@ var InvestigationGraph = ({
1875
1881
  }
1876
1882
  }
1877
1883
  ),
1878
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1879
- import_react13.MiniMap,
1884
+ /* @__PURE__ */ jsx6(
1885
+ MiniMap2,
1880
1886
  {
1881
1887
  nodeColor: miniMapNodeColor,
1882
1888
  zoomable: true,
@@ -1896,9 +1902,9 @@ var InvestigationGraph = ({
1896
1902
  };
1897
1903
 
1898
1904
  // src/components/CyvestGraph.tsx
1899
- var import_jsx_runtime7 = require("react/jsx-runtime");
1905
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1900
1906
  var ViewToggle = ({ currentView, onChange }) => {
1901
- const containerStyle = (0, import_react14.useMemo)(
1907
+ const containerStyle = useMemo8(
1902
1908
  () => ({
1903
1909
  position: "absolute",
1904
1910
  top: 12,
@@ -1916,7 +1922,7 @@ var ViewToggle = ({ currentView, onChange }) => {
1916
1922
  }),
1917
1923
  []
1918
1924
  );
1919
- const getButtonStyle = (0, import_react14.useCallback)(
1925
+ const getButtonStyle = useCallback4(
1920
1926
  (isActive) => ({
1921
1927
  padding: "8px 14px",
1922
1928
  border: "none",
@@ -1931,8 +1937,8 @@ var ViewToggle = ({ currentView, onChange }) => {
1931
1937
  }),
1932
1938
  []
1933
1939
  );
1934
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: containerStyle, children: [
1935
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1940
+ return /* @__PURE__ */ jsxs6("div", { style: containerStyle, children: [
1941
+ /* @__PURE__ */ jsx7(
1936
1942
  "button",
1937
1943
  {
1938
1944
  onClick: () => onChange("observables"),
@@ -1949,8 +1955,8 @@ var ViewToggle = ({ currentView, onChange }) => {
1949
1955
  e.currentTarget.style.color = "#4b5563";
1950
1956
  }
1951
1957
  },
1952
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
1953
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1958
+ children: /* @__PURE__ */ jsxs6("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
1959
+ /* @__PURE__ */ jsxs6(
1954
1960
  "svg",
1955
1961
  {
1956
1962
  width: "14",
@@ -1962,12 +1968,12 @@ var ViewToggle = ({ currentView, onChange }) => {
1962
1968
  strokeLinecap: "round",
1963
1969
  strokeLinejoin: "round",
1964
1970
  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" })
1971
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "3" }),
1972
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "10" }),
1973
+ /* @__PURE__ */ jsx7("line", { x1: "12", y1: "2", x2: "12", y2: "4" }),
1974
+ /* @__PURE__ */ jsx7("line", { x1: "12", y1: "20", x2: "12", y2: "22" }),
1975
+ /* @__PURE__ */ jsx7("line", { x1: "2", y1: "12", x2: "4", y2: "12" }),
1976
+ /* @__PURE__ */ jsx7("line", { x1: "20", y1: "12", x2: "22", y2: "12" })
1971
1977
  ]
1972
1978
  }
1973
1979
  ),
@@ -1975,7 +1981,7 @@ var ViewToggle = ({ currentView, onChange }) => {
1975
1981
  ] })
1976
1982
  }
1977
1983
  ),
1978
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1984
+ /* @__PURE__ */ jsx7(
1979
1985
  "button",
1980
1986
  {
1981
1987
  onClick: () => onChange("investigation"),
@@ -1992,8 +1998,8 @@ var ViewToggle = ({ currentView, onChange }) => {
1992
1998
  e.currentTarget.style.color = "#4b5563";
1993
1999
  }
1994
2000
  },
1995
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
1996
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2001
+ children: /* @__PURE__ */ jsxs6("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
2002
+ /* @__PURE__ */ jsxs6(
1997
2003
  "svg",
1998
2004
  {
1999
2005
  width: "14",
@@ -2005,9 +2011,9 @@ var ViewToggle = ({ currentView, onChange }) => {
2005
2011
  strokeLinecap: "round",
2006
2012
  strokeLinejoin: "round",
2007
2013
  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" })
2014
+ /* @__PURE__ */ jsx7("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2015
+ /* @__PURE__ */ jsx7("path", { d: "M9 3v18" }),
2016
+ /* @__PURE__ */ jsx7("path", { d: "M3 9h18" })
2011
2017
  ]
2012
2018
  }
2013
2019
  ),
@@ -2026,16 +2032,16 @@ var CyvestGraph = ({
2026
2032
  className,
2027
2033
  showViewToggle = true
2028
2034
  }) => {
2029
- const [view, setView] = (0, import_react14.useState)(
2035
+ const [view, setView] = useState2(
2030
2036
  initialView
2031
2037
  );
2032
- const handleNodeClick = (0, import_react14.useCallback)(
2038
+ const handleNodeClick = useCallback4(
2033
2039
  (nodeId, _nodeType) => {
2034
2040
  onNodeClick?.(nodeId);
2035
2041
  },
2036
2042
  [onNodeClick]
2037
2043
  );
2038
- const containerStyle = (0, import_react14.useMemo)(
2044
+ const containerStyle = useMemo8(
2039
2045
  () => ({
2040
2046
  width,
2041
2047
  height,
@@ -2043,9 +2049,9 @@ var CyvestGraph = ({
2043
2049
  }),
2044
2050
  [width, height]
2045
2051
  );
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)(
2052
+ return /* @__PURE__ */ jsxs6("div", { className, style: containerStyle, children: [
2053
+ showViewToggle && /* @__PURE__ */ jsx7(ViewToggle, { currentView: view, onChange: setView }),
2054
+ view === "observables" ? /* @__PURE__ */ jsx7(
2049
2055
  ObservablesGraph,
2050
2056
  {
2051
2057
  investigation,
@@ -2054,7 +2060,7 @@ var CyvestGraph = ({
2054
2060
  onNodeClick: handleNodeClick,
2055
2061
  showControls: true
2056
2062
  }
2057
- ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2063
+ ) : /* @__PURE__ */ jsx7(
2058
2064
  InvestigationGraph,
2059
2065
  {
2060
2066
  investigation,
@@ -2065,8 +2071,7 @@ var CyvestGraph = ({
2065
2071
  )
2066
2072
  ] });
2067
2073
  };
2068
- // Annotate the CommonJS export names for ESM import in node:
2069
- 0 && (module.exports = {
2074
+ export {
2070
2075
  CyvestGraph,
2071
2076
  DEFAULT_FORCE_CONFIG,
2072
2077
  INVESTIGATION_ICON_MAP,
@@ -2075,4 +2080,4 @@ var CyvestGraph = ({
2075
2080
  ObservablesGraph,
2076
2081
  getInvestigationIcon,
2077
2082
  getObservableIcon
2078
- });
2083
+ };