@tangle-network/sandbox-ui 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D8jQpDG7.js";
2
- import { t as VirtualList } from "./VirtualList-DLh2JE0F.js";
2
+ import { t as VirtualList } from "./VirtualList-CMynqkkh.js";
3
3
  import { t as useFollowTail } from "./use-follow-tail-Ht7fZGQQ.js";
4
4
  import { HoverCard, HoverCardContent, HoverCardTrigger } from "@tangle-network/ui/primitives";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -1,4 +1,4 @@
1
- import { a as fmt, c as modelIdentity, d as recordFlowTrace, f as roleOf, h as utcTime, i as eventSource, m as toolKey, n as Conversation, o as indexRecord, p as textOf, r as eventMatches, s as interval, t as AgentTree, u as ms } from "./AgentTree-CJRVpgPq.js";
1
+ import { a as fmt, c as modelIdentity, d as recordFlowTrace, f as roleOf, h as utcTime, i as eventSource, m as toolKey, n as Conversation, o as indexRecord, p as textOf, r as eventMatches, s as interval, t as AgentTree, u as ms } from "./AgentTree-Cju8jn51.js";
2
2
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "@tangle-network/ui/primitives";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  import { createContext, memo, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
@@ -1,23 +1,13 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Fragment as Fragment$1, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
3
3
  // src/run/record/VirtualList.tsx
4
- /**
5
- * Renders only the rows near the viewport of `scroller`. Row heights are measured as they render; unmeasured
6
- * rows use `estimate`. Spacers keep the scroll height, so the browser's scroll anchoring holds the reading place.
7
- */
8
- function VirtualList({ items, keyOf, render, scroller, estimate = 96, overscan = 900, target, origin, targetAlign = "start", virtualize = true, keepMounted }) {
4
+ /** Row heights measured as rows render through `bind`; `version` changes when a measured height changes. */
5
+ function useMeasuredHeights() {
9
6
  const heights = useRef(/* @__PURE__ */ new Map());
10
- const [version, setVersion] = useState(0);
11
- const [viewport, setViewport] = useState({
12
- top: 0,
13
- height: 900
14
- });
7
+ const rows = useRef(/* @__PURE__ */ new Map());
15
8
  const observer = useRef(null);
16
9
  const frame = useRef(0);
17
- const originTop = () => {
18
- const element = scroller.current, node = origin?.current;
19
- return element && node ? node.getBoundingClientRect().top - (element === document.scrollingElement ? 0 : element.getBoundingClientRect().top + element.clientTop) + element.scrollTop : 0;
20
- };
10
+ const [version, setVersion] = useState(0);
21
11
  const observe = (element) => {
22
12
  if (!observer.current && typeof ResizeObserver !== "undefined") observer.current = new ResizeObserver((entries) => {
23
13
  let changed = false;
@@ -45,6 +35,31 @@ function VirtualList({ items, keyOf, render, scroller, estimate = 96, overscan =
45
35
  observer.current?.disconnect();
46
36
  };
47
37
  }, []);
38
+ const bind = (key) => (element) => {
39
+ const previous = rows.current.get(key);
40
+ if (previous) observer.current?.unobserve(previous);
41
+ if (element) {
42
+ rows.current.set(key, element);
43
+ observe(element);
44
+ } else rows.current.delete(key);
45
+ };
46
+ return {
47
+ heights,
48
+ rows,
49
+ version,
50
+ bind
51
+ };
52
+ }
53
+ /** The scroller's visible window, measured from `origin` when the rows start below other content. */
54
+ function useViewport(scroller, origin) {
55
+ const [viewport, setViewport] = useState({
56
+ top: 0,
57
+ height: 900
58
+ });
59
+ const originTop = () => {
60
+ const element = scroller.current, node = origin?.current;
61
+ return element && node ? node.getBoundingClientRect().top - (element === document.scrollingElement ? 0 : element.getBoundingClientRect().top + element.clientTop) + element.scrollTop : 0;
62
+ };
48
63
  useEffect(() => {
49
64
  const element = scroller.current;
50
65
  if (!element) return;
@@ -73,59 +88,42 @@ function VirtualList({ items, keyOf, render, scroller, estimate = 96, overscan =
73
88
  resize.disconnect();
74
89
  };
75
90
  }, [scroller, origin]);
76
- const offsets = useMemo(() => {
77
- const result = new Float64Array(items.length + 1);
78
- const guess = typeof estimate === "function" ? estimate : () => estimate;
79
- for (let i = 0; i < items.length; i++) result[i + 1] = result[i] + (heights.current.get(keyOf(items[i])) ?? guess(items[i]));
80
- return result;
81
- }, [
82
- items,
83
- keyOf,
84
- estimate,
85
- version
86
- ]);
87
- const find = (y) => {
88
- let low = 0, high = items.length;
89
- while (low < high) {
90
- const mid = low + high >> 1;
91
- if (offsets[mid + 1] <= y) low = mid + 1;
92
- else high = mid;
93
- }
94
- return low;
95
- };
96
- const start = virtualize ? Math.max(0, find(viewport.top - overscan)) : 0;
97
- const end = virtualize ? Math.min(items.length, find(viewport.top + viewport.height + overscan) + 1) : items.length;
98
- const scrollTo = (key, align) => {
99
- const element = scroller.current;
100
- const index = items.findIndex((item) => keyOf(item) === key);
101
- if (!element || index < 0) return false;
102
- const origin = originTop(), top = origin + offsets[index];
103
- const bottom = origin + offsets[index + 1];
104
- if (align || top < element.scrollTop) element.scrollTop = Math.max(0, top - 8);
105
- else if (bottom > element.scrollTop + element.clientHeight) element.scrollTop = Math.max(0, bottom - element.clientHeight);
106
- return true;
91
+ return {
92
+ viewport,
93
+ originTop
107
94
  };
95
+ }
96
+ /**
97
+ * A target is settled, not jumped to once: rows above it are measured only after the first jump renders them, which
98
+ * moves it. Each measurement, viewport move and change of the rows (a record that arrived late) re-aligns it until the
99
+ * reader scrolls, or after two seconds. Home and End settle the first and last row the same way.
100
+ */
101
+ function useSettleTarget(scroller, { target, align, items, keyOf, offsets, originTop, rows, version, viewport }) {
108
102
  const pending = useRef(null);
109
- const rows = useRef(/* @__PURE__ */ new Map());
103
+ const goal = (key) => ({
104
+ key,
105
+ until: performance.now() + 2e3
106
+ });
110
107
  const settle = () => {
111
- const goal = pending.current;
112
- if (!goal) return;
113
- if (performance.now() > goal.until) {
108
+ const current = pending.current;
109
+ if (!current) return;
110
+ if (performance.now() > current.until) {
114
111
  pending.current = null;
115
112
  return;
116
113
  }
117
- if (!scrollTo(goal.key, targetAlign === "start")) return;
118
- const row = rows.current.get(goal.key);
119
- if (targetAlign === "start" && row?.isConnected) {
114
+ const element = scroller.current, index = items.findIndex((item) => keyOf(item) === current.key);
115
+ if (!element || index < 0) return;
116
+ const origin = originTop(), top = origin + offsets[index], bottom = origin + offsets[index + 1];
117
+ if (align === "start" || top < element.scrollTop) element.scrollTop = Math.max(0, top - 8);
118
+ else if (bottom > element.scrollTop + element.clientHeight) element.scrollTop = Math.max(0, bottom - element.clientHeight);
119
+ const row = rows.current.get(current.key);
120
+ if (align === "start" && row?.isConnected) {
120
121
  const box = row.getBoundingClientRect();
121
122
  if (box.top < 72 || box.top > window.innerHeight - 96) window.scrollBy({ top: box.top - 120 });
122
123
  }
123
124
  };
124
125
  useLayoutEffect(() => {
125
- pending.current = target ? {
126
- key: target,
127
- until: performance.now() + 2e3
128
- } : null;
126
+ pending.current = target ? goal(target) : null;
129
127
  settle();
130
128
  }, [target]);
131
129
  useLayoutEffect(settle, [
@@ -138,10 +136,7 @@ function VirtualList({ items, keyOf, render, scroller, estimate = 96, overscan =
138
136
  if (!element) return;
139
137
  const release = (event) => {
140
138
  const key = event instanceof KeyboardEvent && event.target === element && !event.defaultPrevented ? event.key : "";
141
- pending.current = items.length && (key === "Home" || key === "End") ? {
142
- key: keyOf(items[key === "Home" ? 0 : items.length - 1]),
143
- until: performance.now() + 2e3
144
- } : null;
139
+ pending.current = items.length && (key === "Home" || key === "End") ? goal(keyOf(items[key === "Home" ? 0 : items.length - 1])) : null;
145
140
  if (pending.current) {
146
141
  event.preventDefault();
147
142
  settle();
@@ -163,14 +158,47 @@ function VirtualList({ items, keyOf, render, scroller, estimate = 96, overscan =
163
158
  keyOf,
164
159
  offsets
165
160
  ]);
166
- const bind = (key) => (element) => {
167
- const previous = rows.current.get(key);
168
- if (previous) observer.current?.unobserve(previous);
169
- if (element) {
170
- rows.current.set(key, element);
171
- observe(element);
172
- } else rows.current.delete(key);
161
+ }
162
+ /**
163
+ * Renders only the rows near the viewport of `scroller`. Row heights are measured as they render; unmeasured
164
+ * rows use `estimate`. Spacers keep the scroll height, so the browser's scroll anchoring holds the reading place.
165
+ */
166
+ function VirtualList({ items, keyOf, render, scroller, estimate = 96, overscan = 900, target, origin, targetAlign = "start", virtualize = true, keepMounted }) {
167
+ const { heights, rows, version, bind } = useMeasuredHeights();
168
+ const { viewport, originTop } = useViewport(scroller, origin);
169
+ const offsets = useMemo(() => {
170
+ const result = new Float64Array(items.length + 1);
171
+ const guess = typeof estimate === "function" ? estimate : () => estimate;
172
+ for (let i = 0; i < items.length; i++) result[i + 1] = result[i] + (heights.current.get(keyOf(items[i])) ?? guess(items[i]));
173
+ return result;
174
+ }, [
175
+ items,
176
+ keyOf,
177
+ estimate,
178
+ version
179
+ ]);
180
+ useSettleTarget(scroller, {
181
+ target,
182
+ align: targetAlign,
183
+ items,
184
+ keyOf,
185
+ offsets,
186
+ originTop,
187
+ rows,
188
+ version,
189
+ viewport
190
+ });
191
+ const find = (y) => {
192
+ let low = 0, high = items.length;
193
+ while (low < high) {
194
+ const mid = low + high >> 1;
195
+ if (offsets[mid + 1] <= y) low = mid + 1;
196
+ else high = mid;
197
+ }
198
+ return low;
173
199
  };
200
+ const start = virtualize ? Math.max(0, find(viewport.top - overscan)) : 0;
201
+ const end = virtualize ? Math.min(items.length, find(viewport.top + viewport.height + overscan) + 1) : items.length;
174
202
  const indices = Array.from({ length: end - start }, (_, i) => start + i);
175
203
  const kept = keepMounted ? items.findIndex((item) => keyOf(item) === keepMounted) : -1;
176
204
  if (kept >= 0 && kept < start) indices.unshift(kept);
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { $ as ContextMenuShortcut, $n as TabsContent, $t as Popover, A as Card, An as SheetHeader, Ar as seriesAreaPath, At as DropdownMenuSubTrigger, B as CollapsibleContent, Bn as StatCard, Br as TangleKnot, Bt as HoverCardHeader, C as BreadcrumbLink, Cn as SettingsRow, Cr as fieldMessageId, Ct as DropdownMenuPortal, D as Button, Dn as SheetContent, Dr as normalizeSeries, Dt as DropdownMenuShortcut, E as BreadcrumbSeparator, En as SheetClose, Er as localToday, Et as DropdownMenuSeparator, F as CardTitle, Fn as SidebarDropZone, Fr as toneFor, Ft as Heading, G as ContextMenuContent, Gn as TableBody, Gt as Input, H as ComplianceBadge, Hn as Switch, Ht as HoverCardTrigger, I as Checkbox, In as Skeleton, Ir as useTheme, It as HelpText, J as ContextMenuLabel, Jn as TableFooter, Jt as MetricChart, K as ContextMenuGroup, Kn as TableCaption, Kt as Label, L as Chip, Ln as SkeletonCard, Lr as useToast, Lt as HoverCard, M as CardDescription, Mn as SheetPortal, Mr as seriesLinePath, Mt as EmptyState, N as CardFooter, Nn as SheetTitle, Nr as seriesMean, Nt as Field, O as CATEGORY_TONES, On as SheetDescription, Or as parseCalendarDate, Ot as DropdownMenuSub, P as CardHeader, Pn as SheetTrigger, Pr as seriesScale, Pt as FilterField, Q as ContextMenuSeparator, Qn as Tabs, Qt as Pagination, R as CodeBlock, Rn as SkeletonTable, Rr as SectionTitle, Rt as HoverCardContent, S as BreadcrumbItem, Sn as SettingsNote, Sr as buttonVariants, St as DropdownMenuLabel, T as BreadcrumbPage, Tn as Sheet, Tr as initialsOf, Tt as DropdownMenuRadioItem, U as ContextMenu, Un as TONE_CLASSES, Ut as IconTile, V as CollapsibleTrigger, Vn as StatusPill, Vt as HoverCardTitle, W as ContextMenuCheckboxItem, Wn as Table, Wt as InlineCode, X as ContextMenuRadioGroup, Xn as TableHeader, Xt as PageHeader, Y as ContextMenuPortal, Yn as TableHead, Yt as MetricStrip, Z as ContextMenuRadioItem, Zn as TableRow, Zt as PageShell, _ as AvatarFallback, _n as SelectValue, _r as TooltipTrigger, _t as DropdownMenu, a as AlertDialogCancel, an as RadioGroup, ar as TerminalInput, at as DatePicker, b as Breadcrumb, bn as SettingsList, br as WizardStep, bt as DropdownMenuGroup, c as AlertDialogFooter, cn as Select, cr as Textarea, ct as DialogContent, d as AlertDialogPortal, dn as SelectItem, dr as ToastContainer, dt as DialogHeader, en as PopoverAnchor, er as TabsList, et as ContextMenuSub, f as AlertDialogTitle, fn as SelectLabel, fr as ToastProvider, ft as DialogOverlay, g as Avatar, gn as SelectTrigger, gr as TooltipProvider, gt as DropZone, h as ArtifactPane, hn as SelectSeparator, hr as TooltipContent, ht as DialogTrigger, i as AlertDialogAction, in as Progress, ir as TerminalDisplay, it as CopyButton, j as CardContent, jn as SheetOverlay, jr as seriesExtent, jt as DropdownMenuTrigger, k as Calendar, kn as SheetFooter, kr as periodDelta, kt as DropdownMenuSubContent, l as AlertDialogHeader, ln as SelectContent, lr as ThemeToggle, lt as DialogDescription, m as AlertTitle, mn as SelectScrollUpButton, mr as Tooltip, mt as DialogTitle, n as AlertDescription, nn as PopoverContent, nr as Tag, nt as ContextMenuSubTrigger, o as AlertDialogContent, on as RadioGroupItem, or as TerminalLine, ot as Dialog, p as AlertDialogTrigger, pn as SelectScrollDownButton, pr as Toolbar, pt as DialogPortal, q as ContextMenuItem, qn as TableCell, qt as Metric, r as AlertDialog, rn as PopoverTrigger, rr as TerminalCursor, rt as ContextMenuTrigger, s as AlertDialogDescription, sn as SegmentedControl, sr as TextShimmer, st as DialogClose, t as Alert, tn as PopoverClose, tr as TabsTrigger, tt as ContextMenuSubContent, u as AlertDialogOverlay, un as SelectGroup, ur as TimeSelect, ut as DialogFooter, v as AvatarImage, vn as Separator, vr as UploadProgress, vt as DropdownMenuCheckboxItem, w as BreadcrumbList, wn as SettingsSection, wr as formatCalendarDate, wt as DropdownMenuRadioGroup, x as BreadcrumbEllipsis, xn as SettingsListItem, xr as badgeVariants, xt as DropdownMenuItem, y as Badge, yn as SeriesSparkline, yr as Wizard, yt as DropdownMenuContent, z as Collapsible, zn as Slider, zr as Logo, zt as HoverCardDescription } from "./primitives-znfPK9NP.js";
2
2
  import { i as WorkspacePaneHeader, n as SHELL_INSET_GUTTER, r as ShellHeader, t as SHELL_HEADER_HEIGHT } from "./shell-header-CwqDzC4I.js";
3
- import { S as WorkspaceSurfaceTitle, _ as StatusBanner, a as SandboxWorkbench, b as WorkspaceSurface, c as shellShouldRevalidate, d as dispatchSessionCreated, f as useOptimisticSessionItems, g as StatusBar, h as TerminalPanel, i as TaskBoard, l as SessionSidebar, m as RuntimePane, n as ApprovalQueue, o as WorkspaceArtifactView, p as formatRelativeAge, r as CalendarView, s as createShellShouldRevalidate, u as SESSION_CREATED_EVENT, v as DirectoryPane, x as WorkspaceSurfaceFrame, y as WorkspaceLayout } from "./workspace-CAdAoNmW.js";
4
- import { t as VirtualList } from "./VirtualList-DLh2JE0F.js";
5
- import { i as VaultTree, n as filterFileNodes, r as VAULT_TREE_CHILD_PAGE, t as fileTreeFromPaths } from "./tree-data-B_IXAIgg.js";
6
- import { t as WorkspaceFilesPane } from "./workspace-files-pane-C0PeY6rY.js";
3
+ import { S as WorkspaceSurfaceTitle, _ as StatusBanner, a as SandboxWorkbench, b as WorkspaceSurface, c as shellShouldRevalidate, d as dispatchSessionCreated, f as useOptimisticSessionItems, g as StatusBar, h as TerminalPanel, i as TaskBoard, l as SessionSidebar, m as RuntimePane, n as ApprovalQueue, o as WorkspaceArtifactView, p as formatRelativeAge, r as CalendarView, s as createShellShouldRevalidate, u as SESSION_CREATED_EVENT, v as DirectoryPane, x as WorkspaceSurfaceFrame, y as WorkspaceLayout } from "./workspace-BrS_rHWN.js";
4
+ import { t as VirtualList } from "./VirtualList-CMynqkkh.js";
5
+ import { i as VaultTree, n as filterFileNodes, r as VAULT_TREE_CHILD_PAGE, t as fileTreeFromPaths } from "./tree-data-9D309DqD.js";
6
+ import { t as WorkspaceFilesPane } from "./workspace-files-pane-Di_rn4FL.js";
7
7
  import { $ as useSidebar, A as parseInsufficientBalance, B as SidebarPanel, C as SandboxStatusPill, D as ResourceMeter, E as ResourceSnapshot, F as RailHeader, G as SidebarRailNav, H as SidebarPanelHeader, I as RailModeButton, J as SIDEBAR_PANEL_WIDTH, K as RailTooltip, L as RailSeparator, M as RailButton, N as RailExpandable, O as INSUFFICIENT_BALANCE_CODE, P as RailFlyout, Q as SidebarProvider, R as Sidebar, S as SANDBOX_STATUS, T as ActivityFeed, U as SidebarRail, V as SidebarPanelContent, W as SidebarRailFooter, X as SIDEBAR_RAIL_WIDTH, Y as SIDEBAR_RAIL_LABELED_WIDTH, Z as SIDEBAR_TOTAL_WIDTH, _ as BackendSelector, a as PortsList, b as SandboxCard, c as SystemLogsViewer, d as DashboardLayout, f as HARNESS_OPTIONS, g as HarnessLogo, h as HARNESS_BRAND, i as TemplateCard, j as ProfileAvatar, k as OutOfCreditsModal, l as MetricAreaChart, m as chatCapableHarnesses, n as SnapshotList, o as GitPanel, p as HarnessPicker, q as SIDEBAR_MOBILE_WIDTH, r as ProcessList, s as UsageSummary, t as PromoBanner, u as SidebarLayout, v as SandboxTable, w as sandboxStatus, x as canAdminSandbox, y as NewSandboxCard, z as SidebarContent } from "./dashboard-exTS8tta.js";
8
8
  import { i as modelBrandFor, n as ProviderMark, r as canonicalModelId, t as ModelBrandStack } from "./model-brand-BQlarCIo.js";
9
9
  import { a as formatPrice, i as PricingPage, n as SandboxPageShell, o as BillingDashboard, r as UsageChart, t as DashboardPageHeader } from "./page-layout-CuOpvZys.js";
@@ -16,8 +16,8 @@ import { n as PreviewView, t as EmbeddedAppView } from "./embedded-app-view-DXso
16
16
  import { OPENUI_NODE_JSON_SCHEMA, OPENUI_NODE_TYPES, OpenUIArtifactRenderer, findUnsupportedOpenUINode, validateOpenUIJsonArtifact, validateOpenUIJsonNode } from "./openui.js";
17
17
  import { S as ReasoningLevelPicker, _ as modelProvider, a as ChatMessage, b as DEFAULT_REASONING_LEVEL_OPTIONS, c as SpeakerHeader, d as UserMessage, f as agentTimelineStepKind, g as ArtifactAgentDock, h as partitionBySpeaker, i as ChatContainer, l as TRANSCRIPT_TEXT, m as isViewerMessage, n as AgentTimelineColumn, o as MessageAuthor, p as foldSummary, r as AgentTimelineStep, s as MessageList, t as AgentTimeline, u as ThinkingIndicator, v as snapHarnessToModel, x as HARNESS_REASONING_OPTIONS, y as AgentProfilePicker } from "./chat-BrlLa4rg.js";
18
18
  import { a as useEventStream, i as useAgentStream, n as LatestEvents, o as TraceWaterfall, r as foldAgentRows, s as traceSpanMark, t as TraceWorkspace } from "./trace-workspace-BiJbv9WQ.js";
19
- import { d as recordFlowTrace, l as model_exports, n as Conversation, o as indexRecord, t as AgentTree } from "./AgentTree-CJRVpgPq.js";
20
- import { t as withPrompts } from "./record-Ct_MZeZC.js";
19
+ import { d as recordFlowTrace, l as model_exports, n as Conversation, o as indexRecord, t as AgentTree } from "./AgentTree-Cju8jn51.js";
20
+ import { t as withPrompts } from "./record-B_4XWfUz.js";
21
21
  import { ApprovalCard, ApprovalDiffSummary, ExpandedToolDetail, InlineThinkingItem, InlineToolItem, LiveDuration, RunGroup, RunPhaseList, RunRowShell, RunRowStatusDot, RunStatusIcon, TaskList, ToolCallFeed, isOpen, parseToolEvent, runStatus, showsTaskPriority, statusMeta, taskProgress, taskStatus } from "./run.js";
22
22
  import "./vault-tree.js";
23
23
  import { a as TangleLoginButton, i as UserMenu, n as GitHubLoginButton, r as LoginLayout, t as AuthHeader } from "./auth-BDpoZ_2f.js";
@@ -1 +1 @@
1
- export { t as ResearchReport } from "../ResearchReport-CSNpZ-pj.js";
1
+ export { t as ResearchReport } from "../ResearchReport-vqefUbVp.js";
@@ -1,5 +1,5 @@
1
- import "./VirtualList-DLh2JE0F.js";
2
- import "./AgentTree-CJRVpgPq.js";
1
+ import "./VirtualList-CMynqkkh.js";
2
+ import "./AgentTree-Cju8jn51.js";
3
3
  // src/run/record/prompts.ts
4
4
  /** The conversation needs an opening prompt even when the provider did not retain its first user turn. */
5
5
  function withPrompts(record) {
package/dist/record.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as AgentRecord, t as ResearchReport } from "./ResearchReport-CSNpZ-pj.js";
1
+ import { n as AgentRecord, t as ResearchReport } from "./ResearchReport-vqefUbVp.js";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useMemo, useRef, useState } from "react";
4
4
  import { useColorMode } from "@tangle-network/charts/react/agent-graph/presentation";