@anlyx/ui 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/components/AnalysisEvidenceList.d.ts +5 -0
  2. package/dist/components/AnalysisEvidenceList.js +61 -0
  3. package/dist/components/AnlyxAppShell.d.ts +1 -1
  4. package/dist/components/AnlyxAppShell.js +159 -15
  5. package/dist/components/ApiCallList.d.ts +3 -3
  6. package/dist/components/ApiCallList.js +12 -3
  7. package/dist/components/CanvasPlaceholder.d.ts +0 -1
  8. package/dist/components/CanvasPlaceholder.js +0 -1
  9. package/dist/components/CaptureStatusEmptyState.d.ts +0 -1
  10. package/dist/components/CaptureStatusEmptyState.js +5 -4
  11. package/dist/components/EndpointList.d.ts +0 -1
  12. package/dist/components/EndpointList.js +1 -2
  13. package/dist/components/EndpointMapCanvas.d.ts +5 -2
  14. package/dist/components/EndpointMapCanvas.js +93 -13
  15. package/dist/components/FlowLegend.d.ts +4 -2
  16. package/dist/components/FlowLegend.js +4 -2
  17. package/dist/components/FlowNodeCard.d.ts +1 -2
  18. package/dist/components/FlowNodeCard.js +25 -3
  19. package/dist/components/FlowStoryView.d.ts +22 -0
  20. package/dist/components/FlowStoryView.js +117 -0
  21. package/dist/components/InspectorPanel.d.ts +8 -3
  22. package/dist/components/InspectorPanel.js +36 -3
  23. package/dist/components/PageList.d.ts +0 -1
  24. package/dist/components/PageList.js +1 -2
  25. package/dist/components/PageStoryboardCard.d.ts +0 -1
  26. package/dist/components/PageStoryboardCard.js +4 -2
  27. package/dist/components/PageStoryboardView.d.ts +4 -3
  28. package/dist/components/PageStoryboardView.js +13 -3
  29. package/dist/components/ProcessFlowView.d.ts +21 -0
  30. package/dist/components/ProcessFlowView.js +16 -0
  31. package/dist/components/ProcessTimeline.d.ts +9 -0
  32. package/dist/components/ProcessTimeline.js +46 -0
  33. package/dist/components/ReplayControls.d.ts +6 -2
  34. package/dist/components/ReplayControls.js +31 -3
  35. package/dist/components/ScreenshotSegmentCard.d.ts +0 -1
  36. package/dist/components/ScreenshotSegmentCard.js +0 -1
  37. package/dist/components/Sidebar.d.ts +5 -4
  38. package/dist/components/Sidebar.js +19 -4
  39. package/dist/components/StatusBadge.d.ts +0 -1
  40. package/dist/components/StatusBadge.js +0 -1
  41. package/dist/flow/build-react-flow-model.d.ts +6 -2
  42. package/dist/flow/build-react-flow-model.js +15 -18
  43. package/dist/flow/layout/elk-layout.d.ts +7 -0
  44. package/dist/flow/layout/elk-layout.js +74 -0
  45. package/dist/index.d.ts +0 -1
  46. package/dist/index.js +0 -1
  47. package/dist/mock-data.d.ts +0 -1
  48. package/dist/mock-data.js +50 -5
  49. package/dist/overlay/AnlyxFlowEdge.d.ts +2 -0
  50. package/dist/overlay/AnlyxFlowEdge.js +15 -0
  51. package/dist/overlay/AnlyxFlowNode.d.ts +13 -0
  52. package/dist/overlay/AnlyxFlowNode.js +28 -0
  53. package/dist/overlay/FlowDrawer.d.ts +2 -0
  54. package/dist/overlay/FlowDrawer.js +59 -0
  55. package/dist/overlay/MainFlowCanvas.d.ts +20 -0
  56. package/dist/overlay/MainFlowCanvas.js +285 -0
  57. package/dist/overlay/RecentApiEventsTable.d.ts +5 -0
  58. package/dist/overlay/RecentApiEventsTable.js +19 -0
  59. package/dist/overlay/overlay-entry.d.ts +8 -0
  60. package/dist/overlay/overlay-entry.js +14 -0
  61. package/dist/overlay/overlay-ui.css +2 -0
  62. package/dist/overlay/overlay-ui.js +14 -0
  63. package/dist/overlay/types.d.ts +38 -0
  64. package/dist/overlay/types.js +1 -0
  65. package/dist/overlay/ui.d.ts +18 -0
  66. package/dist/overlay/ui.js +13 -0
  67. package/dist/readme-demo/ReadmeDemoApp.d.ts +4 -0
  68. package/dist/readme-demo/ReadmeDemoApp.js +126 -0
  69. package/dist/readme-demo/readme-demo-entry.d.ts +1 -0
  70. package/dist/readme-demo/readme-demo-entry.js +8 -0
  71. package/dist/replay/build-replay-steps.d.ts +0 -1
  72. package/dist/replay/build-replay-steps.js +0 -1
  73. package/dist/replay/use-replay-lite.d.ts +2 -2
  74. package/dist/replay/use-replay-lite.js +1 -1
  75. package/dist/styles.css +2018 -178
  76. package/dist/viewer/ViewerApp.d.ts +0 -1
  77. package/dist/viewer/ViewerApp.js +13 -7
  78. package/dist/viewer/viewer-entry.d.ts +1 -1
  79. package/dist/viewer/viewer-entry.js +1 -1
  80. package/package.json +7 -3
  81. package/dist/components/AnlyxAppShell.d.ts.map +0 -1
  82. package/dist/components/AnlyxAppShell.js.map +0 -1
  83. package/dist/components/ApiCallList.d.ts.map +0 -1
  84. package/dist/components/ApiCallList.js.map +0 -1
  85. package/dist/components/CanvasPlaceholder.d.ts.map +0 -1
  86. package/dist/components/CanvasPlaceholder.js.map +0 -1
  87. package/dist/components/CaptureStatusEmptyState.d.ts.map +0 -1
  88. package/dist/components/CaptureStatusEmptyState.js.map +0 -1
  89. package/dist/components/EndpointList.d.ts.map +0 -1
  90. package/dist/components/EndpointList.js.map +0 -1
  91. package/dist/components/EndpointMapCanvas.d.ts.map +0 -1
  92. package/dist/components/EndpointMapCanvas.js.map +0 -1
  93. package/dist/components/FlowLegend.d.ts.map +0 -1
  94. package/dist/components/FlowLegend.js.map +0 -1
  95. package/dist/components/FlowNodeCard.d.ts.map +0 -1
  96. package/dist/components/FlowNodeCard.js.map +0 -1
  97. package/dist/components/InspectorPanel.d.ts.map +0 -1
  98. package/dist/components/InspectorPanel.js.map +0 -1
  99. package/dist/components/PageList.d.ts.map +0 -1
  100. package/dist/components/PageList.js.map +0 -1
  101. package/dist/components/PageStoryboardCard.d.ts.map +0 -1
  102. package/dist/components/PageStoryboardCard.js.map +0 -1
  103. package/dist/components/PageStoryboardView.d.ts.map +0 -1
  104. package/dist/components/PageStoryboardView.js.map +0 -1
  105. package/dist/components/ReplayControls.d.ts.map +0 -1
  106. package/dist/components/ReplayControls.js.map +0 -1
  107. package/dist/components/ScreenshotSegmentCard.d.ts.map +0 -1
  108. package/dist/components/ScreenshotSegmentCard.js.map +0 -1
  109. package/dist/components/Sidebar.d.ts.map +0 -1
  110. package/dist/components/Sidebar.js.map +0 -1
  111. package/dist/components/StatusBadge.d.ts.map +0 -1
  112. package/dist/components/StatusBadge.js.map +0 -1
  113. package/dist/flow/build-react-flow-model.d.ts.map +0 -1
  114. package/dist/flow/build-react-flow-model.js.map +0 -1
  115. package/dist/index.d.ts.map +0 -1
  116. package/dist/index.js.map +0 -1
  117. package/dist/mock-data.d.ts.map +0 -1
  118. package/dist/mock-data.js.map +0 -1
  119. package/dist/replay/build-replay-steps.d.ts.map +0 -1
  120. package/dist/replay/build-replay-steps.js.map +0 -1
  121. package/dist/replay/use-replay-lite.d.ts.map +0 -1
  122. package/dist/replay/use-replay-lite.js.map +0 -1
  123. package/dist/viewer/ViewerApp.d.ts.map +0 -1
  124. package/dist/viewer/ViewerApp.js.map +0 -1
  125. package/dist/viewer/viewer-entry.d.ts.map +0 -1
  126. package/dist/viewer/viewer-entry.js.map +0 -1
@@ -0,0 +1,285 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Background, BackgroundVariant, MarkerType, Panel, ReactFlow, useReactFlow } from "@xyflow/react";
3
+ import { useCallback, useMemo } from "react";
4
+ import { AnlyxFlowEdge } from "./AnlyxFlowEdge.js";
5
+ import { AnlyxFlowNode } from "./AnlyxFlowNode.js";
6
+ import { Badge } from "./ui.js";
7
+ const nodeTypes = {
8
+ anlyxFlowNode: AnlyxFlowNode
9
+ };
10
+ const edgeTypes = {
11
+ anlyxFlowEdge: AnlyxFlowEdge
12
+ };
13
+ const NODE_X_GAP = 224;
14
+ const MAIN_Y = 76;
15
+ const AUTH_Y = 54;
16
+ const SUPPORT_Y = 196;
17
+ export function MainFlowCanvas({ flow, method, path, status, endpointConfidence }) {
18
+ const model = useMemo(() => buildDrawerFlowModel({ flow, method, path, status }), [flow, method, path, status]);
19
+ if (model.nodes.length === 0) {
20
+ return (_jsxs("section", { className: "anlyx-flow-rf-section", children: [_jsx("div", { className: "anlyx-flow-rf-head", children: _jsx("h3", { children: "Matched backend flow" }) }), _jsx("div", { className: "anlyx-flow-rf-empty", children: "No scanned main flow was inferred yet." })] }));
21
+ }
22
+ return (_jsxs("section", { className: "anlyx-flow-rf-section", children: [_jsxs("div", { className: "anlyx-flow-rf-head", children: [_jsxs("div", { children: [_jsx("h3", { children: "Matched backend flow" }), _jsx("p", { children: "Live path first, scanned downstream stays muted." })] }), _jsxs("div", { className: "anlyx-flow-rf-head__badges", children: [_jsx(Badge, { tone: "blue", children: method }), _jsxs(Badge, { tone: "green", children: ["confidence ", endpointConfidence ?? "unknown"] })] })] }), _jsx("div", { className: "anlyx-flow-rf-canvas", "data-testid": "anlyx-react-flow-main", children: _jsxs(ReactFlow, { edgeTypes: edgeTypes, edges: model.edges, elementsSelectable: false, fitView: true, fitViewOptions: { padding: 0.16 }, maxZoom: 1.35, minZoom: 0.58, nodes: model.nodes, nodesConnectable: false, nodesDraggable: false, nodeTypes: nodeTypes, panOnDrag: true, proOptions: { hideAttribution: true }, zoomOnDoubleClick: false, zoomOnPinch: true, zoomOnScroll: true, children: [_jsx(ViewportControls, {}), _jsx(Background, { color: "rgba(148, 163, 184, .42)", gap: 18, size: 1, variant: BackgroundVariant.Dots })] }) }), _jsx("p", { className: "anlyx-flow-rf-note", children: "Anlyx mapped this browser-visible request to the scanned backend flow. Muted nodes are known code paths; framework server-side fetches, such as Next.js server component data loading, require the scanned path until a server runtime bridge is enabled." })] }));
23
+ }
24
+ function ViewportControls() {
25
+ const { fitView, setViewport } = useReactFlow();
26
+ const fit = useCallback(() => {
27
+ void fitView({ padding: 0.18, duration: 160 });
28
+ }, [fitView]);
29
+ const reset = useCallback(() => {
30
+ void setViewport({ x: 20, y: 22, zoom: 0.82 }, { duration: 160 });
31
+ }, [setViewport]);
32
+ return (_jsxs(Panel, { className: "anlyx-flow-rf-controls", position: "top-right", children: [_jsx("button", { type: "button", onClick: fit, title: "Fit the full flow into view", children: "Fit view" }), _jsx("button", { type: "button", onClick: reset, title: "Reset to the default canvas position", children: "Reset view" })] }));
33
+ }
34
+ export function buildDrawerFlowModel({ flow, method, path, status }) {
35
+ const isAuthBlocked = Number(status) === 401 || Number(status) === 403;
36
+ const mainNodes = getMainNodes(flow);
37
+ const controller = mainNodes.find((node) => node.type === "controller");
38
+ const supportNodes = mainNodes.filter((item) => item.type !== "endpoint" && item.type !== "controller");
39
+ const nodes = [];
40
+ const edges = [];
41
+ nodes.push(createFlowNode("api", 0, MAIN_Y, {
42
+ kind: "api",
43
+ label: "API",
44
+ value: `${method} ${path}`,
45
+ badge: "high",
46
+ accent: "blue",
47
+ fullValue: `${method} ${path}`,
48
+ step: "01",
49
+ state: "taken"
50
+ }));
51
+ if (controller) {
52
+ nodes.push(createFlowNode("controller", NODE_X_GAP, MAIN_Y, {
53
+ kind: "controller",
54
+ label: "Controller",
55
+ value: compactHandlerName(controller.label),
56
+ sub: compactHandlerClassName(controller.label),
57
+ badge: controller.confidence ?? "unknown",
58
+ accent: "blue",
59
+ fullValue: controller.label,
60
+ step: "02",
61
+ state: "taken"
62
+ }));
63
+ }
64
+ if (isAuthBlocked) {
65
+ const authX = controller ? NODE_X_GAP * 2 : NODE_X_GAP;
66
+ const resultX = controller ? NODE_X_GAP * 3 : NODE_X_GAP * 2;
67
+ nodes.push(createFlowNode("auth", authX, AUTH_Y, {
68
+ kind: "auth",
69
+ label: "Auth / Session",
70
+ value: "Auth gate inferred",
71
+ sub: Number(status) === 403 ? "Likely permission gate" : "Likely login gate",
72
+ badge: `inferred ${status}`,
73
+ accent: "violet",
74
+ fullValue: "Inferred from the browser 401/403 result, not a runtime server trace.",
75
+ step: controller ? "03" : "02",
76
+ state: "taken"
77
+ }));
78
+ nodes.push(createFlowNode("result", resultX, AUTH_Y, getResultNodeData(status, { step: controller ? "04" : "03" })));
79
+ supportNodes.forEach((node, index) => {
80
+ nodes.push(createFlowNode(`support-${index}`, authX + index * NODE_X_GAP, SUPPORT_Y, toNodeData(node, true)));
81
+ });
82
+ edges.push(createFlowEdge("api-controller", "api", controller ? "controller" : "auth", "blue", true));
83
+ if (controller) {
84
+ edges.push(createFlowEdge("controller-auth", "controller", "auth", "violet", true));
85
+ }
86
+ edges.push(createFlowEdge("auth-result", "auth", "result", "amber", true));
87
+ supportNodes.forEach((_, index) => {
88
+ edges.push(createFlowEdge(`support-${index}`, index === 0 ? (controller ? "controller" : "api") : `support-${index - 1}`, `support-${index}`, "gray", false));
89
+ });
90
+ return { nodes, edges };
91
+ }
92
+ supportNodes.forEach((node, index) => {
93
+ nodes.push(createFlowNode(`support-${index}`, (index + (controller ? 2 : 1)) * NODE_X_GAP, MAIN_Y, toNodeData(node)));
94
+ });
95
+ nodes.push(createFlowNode("result", (supportNodes.length + (controller ? 2 : 1)) * NODE_X_GAP, MAIN_Y, getResultNodeData(status, {
96
+ step: String(supportNodes.length + (controller ? 3 : 2)).padStart(2, "0")
97
+ })));
98
+ nodes.slice(0, -1).forEach((node, index) => {
99
+ const target = nodes[index + 1];
100
+ edges.push(createFlowEdge(`main-${index}`, node.id, target.id, getEdgeTone(index, target.data.kind), true));
101
+ });
102
+ return { nodes, edges };
103
+ }
104
+ function createFlowNode(id, x, y, data) {
105
+ return {
106
+ id,
107
+ type: "anlyxFlowNode",
108
+ position: { x, y },
109
+ data
110
+ };
111
+ }
112
+ function createFlowEdge(id, source, target, tone, animated) {
113
+ return {
114
+ id: `drawer-edge-${id}`,
115
+ source,
116
+ target,
117
+ type: "anlyxFlowEdge",
118
+ animated,
119
+ markerEnd: {
120
+ type: MarkerType.ArrowClosed,
121
+ width: 10,
122
+ height: 10,
123
+ color: getEdgeColor(tone)
124
+ },
125
+ data: { tone }
126
+ };
127
+ }
128
+ function getResultNodeData(status, options = {}) {
129
+ return {
130
+ kind: "result",
131
+ label: "Result",
132
+ value: `${status} ${getStatusShortLabel(status)}`,
133
+ sub: Number(status) >= 400 ? "Request blocked" : "Request completed",
134
+ badge: Number(status) >= 400 ? "blocked" : "observed",
135
+ accent: Number(status) >= 400 ? "amber" : "green",
136
+ fullValue: getStatusLabel(status),
137
+ ...(options.step ? { step: options.step } : {}),
138
+ state: Number(status) >= 400 ? "blocked" : "taken"
139
+ };
140
+ }
141
+ function getMainNodes(flow) {
142
+ if (!flow || !Array.isArray(flow.mainPath)) {
143
+ return [];
144
+ }
145
+ const byId = new Map(flow.nodes.map((node) => [node.id, node]));
146
+ return flow.mainPath.map((id) => byId.get(id)).filter((node) => Boolean(node));
147
+ }
148
+ function toNodeData(node, blockedByAuth = false) {
149
+ const kind = getKind(node.type);
150
+ const sub = blockedByAuth
151
+ ? `Scanned ${getNodeSub(kind)?.toLowerCase() ?? "step"}`
152
+ : getNodeSub(kind);
153
+ return {
154
+ kind,
155
+ label: getNodeLabel(kind),
156
+ value: compactHandlerName(node.label),
157
+ badge: blockedByAuth ? "scanned" : (node.confidence ?? "unknown"),
158
+ accent: blockedByAuth ? "gray" : getNodeAccent(kind),
159
+ fullValue: node.label,
160
+ state: blockedByAuth ? "scanned" : "taken",
161
+ ...(sub ? { sub } : {})
162
+ };
163
+ }
164
+ function getKind(type) {
165
+ if (type === "service") {
166
+ return "service";
167
+ }
168
+ if (type === "repository") {
169
+ return "repository";
170
+ }
171
+ if (type === "database") {
172
+ return "database";
173
+ }
174
+ return "service";
175
+ }
176
+ function getNodeLabel(kind) {
177
+ if (kind === "repository") {
178
+ return "Repository";
179
+ }
180
+ if (kind === "database") {
181
+ return "Database";
182
+ }
183
+ return "Service";
184
+ }
185
+ function getNodeSub(kind) {
186
+ if (kind === "repository") {
187
+ return "Data access";
188
+ }
189
+ if (kind === "database") {
190
+ return "Persistence";
191
+ }
192
+ return "Business logic";
193
+ }
194
+ function getNodeAccent(kind) {
195
+ if (kind === "database") {
196
+ return "green";
197
+ }
198
+ if (kind === "repository") {
199
+ return "amber";
200
+ }
201
+ return "violet";
202
+ }
203
+ function getEdgeTone(index, targetKind) {
204
+ if (targetKind === "auth") {
205
+ return "violet";
206
+ }
207
+ if (targetKind === "result") {
208
+ return "amber";
209
+ }
210
+ return index === 0 ? "blue" : "violet";
211
+ }
212
+ function getEdgeColor(tone) {
213
+ if (tone === "amber") {
214
+ return "#f59e0b";
215
+ }
216
+ if (tone === "violet") {
217
+ return "#7c3aed";
218
+ }
219
+ if (tone === "gray") {
220
+ return "#94a3b8";
221
+ }
222
+ return "#2563eb";
223
+ }
224
+ function compactHandlerName(label) {
225
+ if (!label) {
226
+ return "Unknown";
227
+ }
228
+ if (label.includes("#")) {
229
+ const [className, methodName] = label.split("#");
230
+ return `${compactClassName(className ?? "")}#${methodName ?? ""}`;
231
+ }
232
+ return compactClassName(label);
233
+ }
234
+ function compactHandlerClassName(label) {
235
+ if (!label) {
236
+ return "Unknown";
237
+ }
238
+ if (label.includes("#")) {
239
+ const [className] = label.split("#");
240
+ return compactClassName(className ?? "");
241
+ }
242
+ return compactClassName(label);
243
+ }
244
+ function compactClassName(label) {
245
+ const parts = String(label).split(".");
246
+ return parts[parts.length - 1] || label;
247
+ }
248
+ function getStatusShortLabel(status) {
249
+ const numeric = Number(status);
250
+ if (numeric === 401) {
251
+ return "Auth required";
252
+ }
253
+ if (numeric === 403) {
254
+ return "Permission denied";
255
+ }
256
+ if (numeric >= 500) {
257
+ return "Server error";
258
+ }
259
+ if (numeric >= 400) {
260
+ return "Client error";
261
+ }
262
+ if (numeric >= 200 && numeric < 300) {
263
+ return "OK";
264
+ }
265
+ return "Observed";
266
+ }
267
+ function getStatusLabel(status) {
268
+ const numeric = Number(status);
269
+ if (numeric === 401) {
270
+ return "login required · 401";
271
+ }
272
+ if (numeric === 403) {
273
+ return "permission denied · 403";
274
+ }
275
+ if (numeric >= 500) {
276
+ return `server error · ${status}`;
277
+ }
278
+ if (numeric >= 400) {
279
+ return `client error · ${status}`;
280
+ }
281
+ if (numeric >= 200 && numeric < 300) {
282
+ return `success · ${status}`;
283
+ }
284
+ return `status ${status}`;
285
+ }
@@ -0,0 +1,5 @@
1
+ import type { OverlayApiEvent } from "./types.js";
2
+ export declare function RecentApiEventsTable({ events, selectedEventId }: {
3
+ events: OverlayApiEvent[];
4
+ selectedEventId?: string | null;
5
+ }): JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useState } from "react";
3
+ import { Badge, Table } from "./ui.js";
4
+ export function RecentApiEventsTable({ events, selectedEventId }) {
5
+ const [filter, setFilter] = useState("action");
6
+ const actionEvents = useMemo(() => events.filter((event) => Boolean(event.triggeredBy)), [events]);
7
+ const backgroundEvents = useMemo(() => events.filter((event) => !event.triggeredBy), [events]);
8
+ const visibleEvents = filter === "action" ? actionEvents : filter === "background" ? backgroundEvents : events;
9
+ const emptyText = filter === "action"
10
+ ? "No user-action API requests yet."
11
+ : filter === "background"
12
+ ? "No background API requests observed."
13
+ : "No API events observed yet.";
14
+ return (_jsxs("section", { className: "anlyx-events-table-section", children: [_jsxs("div", { className: "anlyx-events-table-head", children: [_jsxs("div", { children: [_jsx("h3", { children: "Recent API events" }), _jsx("p", { children: "Action requests are primary. Background traffic stays quiet until selected." })] }), _jsxs("div", { className: "anlyx-events-filter", role: "tablist", "aria-label": "Filter API events", children: [_jsxs("button", { "aria-selected": filter === "action", type: "button", onClick: () => setFilter("action"), children: ["Actions ", _jsx("span", { children: actionEvents.length })] }), _jsxs("button", { "aria-selected": filter === "background", type: "button", onClick: () => setFilter("background"), children: ["Background ", _jsx("span", { children: backgroundEvents.length })] }), _jsxs("button", { "aria-selected": filter === "all", type: "button", onClick: () => setFilter("all"), children: ["All ", _jsx("span", { children: events.length })] })] })] }), visibleEvents.length === 0 ? (_jsx("div", { className: "anlyx-ov-empty", children: emptyText })) : (_jsxs(Table, { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Method" }), _jsx("th", { children: "Path" }), _jsx("th", { children: "Status" }), _jsx("th", { children: "Match" }), _jsx("th", { children: "Source" }), _jsx("th", { children: "Duration" })] }) }), _jsx("tbody", { children: visibleEvents.slice(0, 6).map((event) => (_jsxs("tr", { className: event.id === selectedEventId ? "anlyx-events-table-row--selected" : "", "data-event-id": event.id, tabIndex: 0, title: "Inspect this API event", children: [_jsx("td", { children: _jsx(Badge, { tone: "blue", children: event.method }) }), _jsx("td", { className: "anlyx-events-table-path", children: event.path }), _jsx("td", { children: _jsx(Badge, { tone: Number(event.status) >= 400 ? "amber" : "green", children: event.status }) }), _jsx("td", { children: _jsx(Badge, { tone: event.matchedEndpoint ? "green" : "amber", children: event.matchedEndpoint ? "matched" : "unmatched" }) }), _jsx("td", { children: _jsx(Badge, { tone: event.triggeredBy ? "blue" : "gray", children: event.triggeredBy
15
+ ? "action"
16
+ : event.source === "health"
17
+ ? "health"
18
+ : "background" }) }), _jsxs("td", { children: [event.durationMs, "ms"] })] }, event.id))) })] }))] }));
19
+ }
@@ -0,0 +1,8 @@
1
+ import "@xyflow/react/dist/style.css";
2
+ import "./overlay.css";
3
+ import type { FlowDrawerProps } from "./types.js";
4
+ declare global {
5
+ interface Window {
6
+ __ANLYX_RENDER_FLOW_DRAWER__?: (container: Element, props: FlowDrawerProps) => void;
7
+ }
8
+ }
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createRoot } from "react-dom/client";
3
+ import "@xyflow/react/dist/style.css";
4
+ import "./overlay.css";
5
+ import { FlowDrawer } from "./FlowDrawer.js";
6
+ const roots = new WeakMap();
7
+ window.__ANLYX_RENDER_FLOW_DRAWER__ = (container, props) => {
8
+ const existingRoot = roots.get(container);
9
+ const root = existingRoot ?? createRoot(container);
10
+ if (!existingRoot) {
11
+ roots.set(container, root);
12
+ }
13
+ root.render(_jsx(FlowDrawer, { ...props }));
14
+ };
@@ -0,0 +1,2 @@
1
+ .react-flow{--xy-edge-stroke-default:#b1b1b7;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#555;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#ffffff80;--xy-minimap-background-color-default:#fff;--xy-minimap-mask-background-color-default:#f0f0f099;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#e2e2e2;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:transparent;--xy-background-pattern-dots-color-default:#91919a;--xy-background-pattern-lines-color-default:#eee;--xy-background-pattern-cross-color-default:#e2e2e2;background-color:var(--xy-background-color,var(--xy-background-color-default));--xy-node-color-default:inherit;--xy-node-border-default:1px solid #1a192b;--xy-node-background-color-default:#fff;--xy-node-group-background-color-default:#f0f0f040;--xy-node-boxshadow-hover-default:0 1px 4px 1px #00000014;--xy-node-boxshadow-selected-default:0 0 0 .5px #1a192b;--xy-node-border-radius-default:3px;--xy-handle-background-color-default:#1a192b;--xy-handle-border-color-default:#fff;--xy-selection-background-color-default:#0059dc14;--xy-selection-border-default:1px dotted #0059dccc;--xy-controls-button-background-color-default:#fefefe;--xy-controls-button-background-color-hover-default:#f4f4f4;--xy-controls-button-color-default:inherit;--xy-controls-button-color-hover-default:inherit;--xy-controls-button-border-color-default:#eee;--xy-controls-box-shadow-default:0 0 2px 1px #00000014;--xy-edge-label-background-color-default:#fff;--xy-edge-label-color-default:inherit;--xy-resize-background-color-default:#3367d9;direction:ltr}.react-flow.dark{--xy-edge-stroke-default:#3e3e3e;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#727272;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#96969640;--xy-minimap-background-color-default:#141414;--xy-minimap-mask-background-color-default:#3c3c3c99;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#2b2b2b;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:#141414;--xy-background-pattern-dots-color-default:#777;--xy-background-pattern-lines-color-default:#777;--xy-background-pattern-cross-color-default:#777;--xy-node-color-default:#f8f8f8;--xy-node-border-default:1px solid #3c3c3c;--xy-node-background-color-default:#1e1e1e;--xy-node-group-background-color-default:#f0f0f040;--xy-node-boxshadow-hover-default:0 1px 4px 1px #ffffff14;--xy-node-boxshadow-selected-default:0 0 0 .5px #999;--xy-handle-background-color-default:#bebebe;--xy-handle-border-color-default:#1e1e1e;--xy-selection-background-color-default:#c8c8dc14;--xy-selection-border-default:1px dotted #c8c8dccc;--xy-controls-button-background-color-default:#2b2b2b;--xy-controls-button-background-color-hover-default:#3e3e3e;--xy-controls-button-color-default:#f8f8f8;--xy-controls-button-color-hover-default:#fff;--xy-controls-button-border-color-default:#5b5b5b;--xy-controls-box-shadow-default:0 0 2px 1px #00000014;--xy-edge-label-background-color-default:#141414;--xy-edge-label-color-default:#f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props,var(--xy-background-color,var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__pane{z-index:1;touch-action:none}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width,var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke,var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width,var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{pointer-events:none;position:absolute;overflow:visible}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:.5s linear infinite dashdraw}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected,var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:.5s linear infinite dashdraw}svg.react-flow__connectionline{z-index:1001;position:absolute;overflow:visible}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{-webkit-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default;position:absolute}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:0 0;pointer-events:none}.react-flow__nodesselection-rect{pointer-events:all;cursor:grab;position:absolute}.react-flow__handle{pointer-events:none;background-color:var(--xy-handle-background-color,var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color,var(--xy-handle-border-color-default));border-radius:100%;width:6px;min-width:5px;height:6px;min-height:5px;position:absolute}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;bottom:0;left:50%;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{z-index:5;margin:15px;position:absolute}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px)translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px)translateY(-50%)}.react-flow__attribution{background:var(--xy-attribution-background-color,var(--xy-attribution-background-color-default));margin:0;padding:2px 3px;font-size:10px}.react-flow__attribution a{color:#999;text-decoration:none}@keyframes dashdraw{0%{stroke-dashoffset:10px}}.react-flow__edgelabel-renderer{pointer-events:none;-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__viewport-portal{-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__minimap{background:var(--xy-minimap-background-color-props,var(--xy-minimap-background-color,var(--xy-minimap-background-color-default)))}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var(--xy-minimap-mask-background-color-props,var(--xy-minimap-mask-background-color,var(--xy-minimap-mask-background-color-default)));stroke:var(--xy-minimap-mask-stroke-color-props,var(--xy-minimap-mask-stroke-color,var(--xy-minimap-mask-stroke-color-default)));stroke-width:var(--xy-minimap-mask-stroke-width-props,var(--xy-minimap-mask-stroke-width,var(--xy-minimap-mask-stroke-width-default)))}.react-flow__minimap-node{fill:var(--xy-minimap-node-background-color-props,var(--xy-minimap-node-background-color,var(--xy-minimap-node-background-color-default)));stroke:var(--xy-minimap-node-stroke-color-props,var(--xy-minimap-node-stroke-color,var(--xy-minimap-node-stroke-color-default)));stroke-width:var(--xy-minimap-node-stroke-width-props,var(--xy-minimap-node-stroke-width,var(--xy-minimap-node-stroke-width-default)))}.react-flow__background-pattern.dots{fill:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-dots-color-default)))}.react-flow__background-pattern.lines{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-lines-color-default)))}.react-flow__background-pattern.cross{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-cross-color-default)))}.react-flow__controls{box-shadow:var(--xy-controls-box-shadow,var(--xy-controls-box-shadow-default));flex-direction:column;display:flex}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{background:var(--xy-controls-button-background-color,var(--xy-controls-button-background-color-default));border:none;border-bottom:1px solid var(--xy-controls-button-border-color-props,var(--xy-controls-button-border-color,var(--xy-controls-button-border-color-default)));width:26px;height:26px;color:var(--xy-controls-button-color-props,var(--xy-controls-button-color,var(--xy-controls-button-color-default)));cursor:pointer;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;padding:4px;display:flex}.react-flow__controls-button svg{fill:currentColor;width:100%;max-width:12px;max-height:12px}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{border-radius:var(--xy-node-border-radius,var(--xy-node-border-radius-default));width:150px;color:var(--xy-node-color,var(--xy-node-color-default));text-align:center;border:var(--xy-node-border,var(--xy-node-border-default));background-color:var(--xy-node-background-color,var(--xy-node-background-color-default));padding:10px;font-size:12px}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover,var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected,var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color,var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color,var(--xy-selection-background-color-default));border:var(--xy-selection-border,var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var(--xy-controls-button-background-color-hover-props,var(--xy-controls-button-background-color-hover,var(--xy-controls-button-background-color-hover-default)));color:var(--xy-controls-button-color-hover-props,var(--xy-controls-button-color-hover,var(--xy-controls-button-color-hover-default)))}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var(--xy-controls-button-border-color-props,var(--xy-controls-button-border-color,var(--xy-controls-button-border-color-default)))}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{background-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border:1px solid #fff;border-radius:1px;width:5px;height:5px;translate:-50% -50%}.react-flow__resize-control.handle.left{top:50%;left:0}.react-flow__resize-control.handle.right{top:50%;left:100%}.react-flow__resize-control.handle.top{top:0;left:50%}.react-flow__resize-control.handle.bottom{top:100%;left:50%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border-style:solid;border-width:0}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;height:100%;top:0;transform:translate(-50%)}.react-flow__resize-control.line.left{border-left-width:1px;left:0}.react-flow__resize-control.line.right{border-right-width:1px;left:100%}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{width:100%;height:1px;left:0;transform:translateY(-50%)}.react-flow__resize-control.line.top{border-top-width:1px;top:0}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color,var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color,var(--xy-edge-label-color-default))}*{box-sizing:border-box}.anlyx-flow-drawer-body{color:#0f172a;gap:9px;padding:11px;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;display:grid}.anlyx-ov-card{background:#fffffff7;border:1px solid #0f172a14;border-radius:12px;overflow:hidden;box-shadow:0 1px 2px #0f172a0a}.anlyx-ov-section-title{color:#64748b;letter-spacing:.08em;text-transform:uppercase;border-bottom:1px solid #eef2f7;margin:0;padding:10px 12px;font-size:10px;font-weight:900}.anlyx-ov-empty{color:#667085;padding:18px 12px;font-size:13px;line-height:1.5}.anlyx-ov-badge{color:#475569;white-space:nowrap;background:#fff;border:1px solid #e2e8f0;border-radius:999px;justify-content:center;align-items:center;width:fit-content;padding:3px 7px;font-size:9px;font-weight:850;line-height:1;display:inline-flex}.anlyx-ov-badge--blue{color:#1d4ed8;background:#eff6ff;border-color:#bfdbfe}.anlyx-ov-badge--green{color:#087443;background:#ecfdf3;border-color:#bbf7d0}.anlyx-ov-badge--amber{color:#b45309;background:#fffbeb;border-color:#fed7aa}.anlyx-ov-badge--violet{color:#6d28d9;background:#f5f3ff;border-color:#ddd6fe}.anlyx-ov-badge--gray,.anlyx-ov-badge--neutral{color:#475569;background:#f8fafc;border-color:#e2e8f0}.anlyx-no-primary-card{background:linear-gradient(#fffbeb8a,#fffffffa),#fff;gap:10px;padding:12px;display:grid}.anlyx-no-primary-card h3{color:#101828;letter-spacing:0;margin:8px 0 3px;font-size:15px;font-weight:900}.anlyx-no-primary-card p{color:#667085;text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:12px;font-weight:700;overflow:hidden}.anlyx-no-primary-card__note{color:#7c2d12;background:#fff7ed9e;border:1px dashed #fed7aa;border-radius:10px;padding:9px 10px;font-size:12px;font-weight:750;line-height:1.45}.anlyx-scanned-hints{padding:11px 12px}.anlyx-scanned-hints__head{grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:10px;margin-bottom:10px;display:grid}.anlyx-scanned-hints__head h3{color:#101828;letter-spacing:0;margin:0 0 3px;font-size:13px;font-weight:900}.anlyx-scanned-hints__head p{color:#667085;margin:0;font-size:11px;font-weight:750;line-height:1.35}.anlyx-scanned-hints__list{gap:7px;display:grid}.anlyx-scanned-hint{background:#fbfdff;border:1px solid #e4e9f2;border-radius:10px;gap:5px;padding:8px 9px;display:grid}.anlyx-scanned-hint>div{align-items:center;gap:7px;min-width:0;display:flex}.anlyx-scanned-hint strong{color:#101828;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:900;overflow:hidden}.anlyx-scanned-hint p{color:#667085;text-overflow:ellipsis;white-space:nowrap;margin:0;font-size:11px;font-weight:700;overflow:hidden}.anlyx-captured-request__top{grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:10px;padding:10px 12px 8px;display:grid}.anlyx-captured-request h3{color:#64748b;letter-spacing:.05em;text-transform:uppercase;margin:0 0 5px;font-size:10px;font-weight:900}.anlyx-captured-request__path{align-items:center;gap:8px;min-width:0;display:flex}.anlyx-captured-request__path strong{color:#101828;text-overflow:ellipsis;white-space:nowrap;font-size:15px;font-weight:900;line-height:1.35;overflow:hidden}.anlyx-captured-request__summary{color:#64748b;background:linear-gradient(#f8fafcdb,#fffffff0);border:1px solid #e5edf8;border-radius:10px;flex-wrap:wrap;align-items:center;gap:6px;margin:0 12px 8px;padding:7px 9px;font-size:9px;font-weight:850;line-height:1.3;display:flex}.anlyx-captured-request__summary span{align-items:center;gap:3px;min-width:0;display:inline-flex}.anlyx-captured-request__summary span:not(:last-child):after{content:"";background:#cbd5e1;border-radius:999px;width:3px;height:3px;margin-left:3px}.anlyx-captured-request__summary b{color:#334155;text-overflow:ellipsis;white-space:nowrap;font-weight:950;overflow:hidden}.anlyx-captured-request__steps{grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;padding:7px 11px 10px;display:grid}.anlyx-captured-step{background:linear-gradient(#fff,#fbfdff);border:1px solid #e2e8f0e6;border-radius:10px;grid-template-columns:22px minmax(0,1fr);align-items:start;gap:8px;min-width:0;padding:7px;display:grid}.anlyx-captured-step__dot{background:#eff6ff;border-radius:8px;width:22px;height:22px;box-shadow:inset 0 0 0 7px #2563eb}.anlyx-captured-step--green .anlyx-captured-step__dot{background:#dcfae6;box-shadow:inset 0 0 0 7px #16a34a}.anlyx-captured-step--amber .anlyx-captured-step__dot{background:#fff7ed;box-shadow:inset 0 0 0 7px #f59e0b}.anlyx-captured-step p,.anlyx-captured-step strong,.anlyx-captured-step span{text-overflow:ellipsis;white-space:nowrap;margin:0;display:block;overflow:hidden}.anlyx-captured-step p{color:#667085;letter-spacing:.08em;text-transform:uppercase;font-size:9px;font-weight:900}.anlyx-captured-step strong{color:#101828;margin-top:2px;font-size:11px;font-weight:900}.anlyx-captured-step span{color:#667085;margin-top:2px;font-size:10px;font-weight:700}.anlyx-flow-rf-section,.anlyx-events-table-section{background:#fff;border:1px solid #0f172a14;border-radius:12px;overflow:hidden;box-shadow:0 1px 2px #0f172a0a}.anlyx-flow-rf-head,.anlyx-events-table-head{justify-content:space-between;align-items:center;gap:10px;padding:10px 12px;display:flex}.anlyx-flow-rf-head h3,.anlyx-events-table-head h3{color:#344054;margin:0;font-size:12px;font-weight:900}.anlyx-flow-rf-head p{color:#8390a4;margin:3px 0 0;font-size:9px;font-weight:750;line-height:1.35}.anlyx-flow-rf-head__badges{flex-wrap:wrap;flex-shrink:0;justify-content:flex-end;gap:5px;display:inline-flex}.anlyx-events-table-head p{color:#8390a4;margin:3px 0 0;font-size:9px;font-weight:750;line-height:1.35}.anlyx-events-filter{background:#f8fafc;border:1px solid #e2e8f0;border-radius:999px;flex-shrink:0;gap:2px;padding:2px;display:inline-flex}.anlyx-events-filter button{color:#64748b;cursor:pointer;white-space:nowrap;background:0 0;border:0;border-radius:999px;height:24px;padding:0 7px;font-size:9px;font-weight:850}.anlyx-events-filter button[aria-selected=true]{color:#1d4ed8;background:#fff;box-shadow:0 1px 2px #0f172a14}.anlyx-events-filter span{color:#94a3b8;margin-left:3px}.anlyx-flow-rf-canvas{cursor:grab;background:radial-gradient(circle at 50% 30%,#2563eb0d,#0000 34%),#fbfdff;border:1px solid #cbd5e1bd;border-radius:12px;height:318px;margin:0 12px;overflow:hidden}.anlyx-flow-rf-canvas:active{cursor:grabbing}.anlyx-flow-rf-canvas .react-flow__background{opacity:.46}.anlyx-flow-rf-canvas .react-flow__viewport{transition:transform .18s}.anlyx-flow-rf-controls{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:#ffffffe0;border:1px solid #cbd5e1cc;border-radius:9px;gap:4px;padding:3px;display:inline-flex;box-shadow:0 8px 18px #0f172a14}.anlyx-flow-rf-controls button{color:#475467;cursor:pointer;white-space:nowrap;background:0 0;border:0;border-radius:7px;height:24px;padding:0 8px;font-size:10px;font-weight:850}.anlyx-flow-rf-controls button:hover{color:#1d4ed8;background:#eff6ff}.anlyx-flow-rf-controls button:focus-visible{outline-offset:1px;outline:2px solid #2563eb61}.anlyx-flow-rf-node{background:linear-gradient(#fffffffc,#f8fafcf5);border-color:#93c5fdf2 #93c5fdf2 #93c5fdf2 #2563eb;border-left-style:solid;border-left-width:2px;grid-template-rows:auto minmax(0,1fr) auto;gap:6px;width:168px;height:116px;padding:10px 11px;display:grid;position:relative;box-shadow:0 1px #0f172a05,0 14px 30px #0f172a0f}.anlyx-flow-rf-node--violet{border-color:#ddd6fe #ddd6fe #ddd6fe #7c3aed}.anlyx-flow-rf-node--amber{background:linear-gradient(#fff,#fffaf0);border-color:#fed7aa #fed7aa #fed7aa #f59e0b}.anlyx-flow-rf-node--green{border-color:#bbf7d0 #bbf7d0 #bbf7d0 #0f766e}.anlyx-flow-rf-node--gray{border-color:#e2e8f0 #e2e8f0 #e2e8f0 #94a3b8}.anlyx-flow-rf-node--blocked{box-shadow:0 0 0 1px #f59e0b1a,0 14px 30px #f59e0b14}.anlyx-flow-rf-node--scanned{box-shadow:none;opacity:.82;background:linear-gradient(#ffffffe6,#f8fafcc7);border-style:dashed}.anlyx-flow-rf-node--scanned .anlyx-flow-rf-node__value,.anlyx-flow-rf-node--scanned .anlyx-flow-rf-node__sub{color:#64748b}.anlyx-flow-rf-node__top{align-items:center;gap:7px;min-width:0;display:flex}.anlyx-flow-rf-node__icon{color:#2563eb;background:#eff6ff;border-radius:8px;flex:none;place-items:center;width:22px;height:22px;display:inline-grid}.anlyx-flow-rf-node--violet .anlyx-flow-rf-node__icon{color:#7c3aed;background:#f5f3ff}.anlyx-flow-rf-node--amber .anlyx-flow-rf-node__icon{color:#d97706;background:#fff7ed}.anlyx-flow-rf-node--green .anlyx-flow-rf-node__icon{color:#0f766e;background:#ecfdf3}.anlyx-flow-rf-node__label{color:#475467;letter-spacing:.04em;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap;font-size:9px;font-weight:950;overflow:hidden}.anlyx-flow-rf-node__step{color:#98a2b3;text-align:right;min-width:18px;margin-left:auto;font-size:10px;font-weight:950}.anlyx-flow-rf-node__value{color:#101828;-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:0;font-size:11px;font-weight:900;line-height:1.28;display:-webkit-box;overflow:hidden}.anlyx-flow-rf-node__sub{color:#667085;text-overflow:ellipsis;white-space:nowrap;margin:-3px 0 0;font-size:9px;font-weight:700;overflow:hidden}.anlyx-flow-rf-handle{background:#93c5fd;border:2px solid #fff;width:8px;height:8px;box-shadow:0 0 0 1px #2563eb47}.anlyx-flow-rf-edge{stroke-width:2px;fill:none}.anlyx-flow-rf-edge--blue{stroke:#2563eb}.anlyx-flow-rf-edge--violet{stroke:#7c3aed}.anlyx-flow-rf-edge--amber{stroke:#f59e0b}.anlyx-flow-rf-edge--gray{stroke:#94a3b8;stroke-width:1.5px;stroke-dasharray:5 5}.react-flow__edge.animated .anlyx-flow-rf-edge{stroke-dasharray:7 7;animation:.9s linear infinite anlyx-edge-dash}@keyframes anlyx-edge-dash{to{stroke-dashoffset:-14px}}.anlyx-flow-rf-note{color:#738196;background:#f8fafc61;border-top:1px solid #e2e8f08c;margin:0;padding:8px 12px;font-size:10px;font-weight:700;line-height:1.4}.anlyx-flow-rf-empty{color:#667085;padding:18px 12px;font-size:13px}.anlyx-ov-table{border-collapse:collapse;width:100%;font-size:9px}.anlyx-ov-table th{color:#667085;letter-spacing:.07em;text-align:left;text-transform:uppercase;padding:0 10px 6px;font-size:9px;font-weight:900}.anlyx-ov-table td{color:#64748b;border-top:1px solid #f1f5f9;height:28px;padding:4px 10px;font-weight:700}.anlyx-ov-table tbody tr[data-event-id]{cursor:pointer}.anlyx-ov-table tbody tr[data-event-id]:hover{background:#2563eb09}.anlyx-ov-table tbody tr.anlyx-events-table-row--selected{background:#2563eb0f;box-shadow:inset 2px 0 #2563eb}.anlyx-ov-table tbody tr[data-event-id]:focus-visible{outline-offset:-2px;outline:2px solid #2563eb57}.anlyx-events-table-path{color:#1f2937;text-overflow:ellipsis;white-space:nowrap;max-width:340px;overflow:hidden}.anlyx-unmatched-card{background:#fffaf5;border-color:#fed7aa;padding:14px}.anlyx-unmatched-card h3{color:#9a3412;margin:0;font-size:13px;font-weight:900}.anlyx-unmatched-card p{color:#667085;margin:5px 0 0;font-size:12px;font-weight:700;line-height:1.45}@media (width<=760px){.anlyx-flow-rf-head{flex-direction:column;align-items:flex-start}.anlyx-flow-rf-head__badges{justify-content:flex-start}.anlyx-events-table-head{flex-direction:column;align-items:flex-start}.anlyx-events-filter{max-width:100%;overflow-x:auto}.anlyx-captured-request__steps{grid-template-columns:1fr}.anlyx-flow-rf-canvas{height:320px}}
2
+ /*$vite$:1*/