From dfd7785cc1e0e338e9a0a90729363ae814017f91 Mon Sep 17 00:00:00 2001 From: Zohaib Hassnain <109234410+ZohaibHassan16@users.noreply.github.com> Date: Sat, 11 Apr 2026 03:19:28 +0500 Subject: [PATCH] feat: overhaul graph explorer visuals and loading flow --- semantica-explorer/package-lock.json | 112 ++ semantica-explorer/package.json | 8 +- .../src/store/edgePairKeys.d.ts | 2 + semantica-explorer/src/store/edgePairKeys.js | 7 + semantica-explorer/src/store/graphStore.ts | 77 +- .../workspaces/GraphWorkspace/GraphCanvas.tsx | 1251 ++++++----------- .../GraphWorkspace/GraphInspectorPanel.tsx | 1 + .../GraphWorkspace/GraphLoadingOverlay.tsx | 315 +++++ .../GraphWorkspace/GraphRuntimeStage.tsx | 79 +- .../GraphWorkspace/GraphWorkspace.tsx | 385 +++-- .../GraphWorkspace/GraphWorkspaceShell.tsx | 123 +- .../GraphWorkspace/SigmaSceneAdapter.tsx | 53 + .../behaviors/clickSelectionBehavior.ts | 6 + .../GraphWorkspace/behaviors/types.ts | 2 + .../GraphWorkspace/graphAnalytics.ts | 834 ++++++++--- .../workspaces/GraphWorkspace/graphLoading.ts | 84 ++ .../GraphWorkspace/graphSceneLayers.ts | 775 ++++++++++ .../GraphWorkspace/graphSceneState.ts | 977 +++++++++++++ .../workspaces/GraphWorkspace/graphTheme.ts | 315 ++++- .../explorationEffectsPluginPhaseC.tsx | 527 +++++++ .../GraphWorkspace/plugins/index.ts | 3 +- .../plugins/neighborhoodPanelPlugin.tsx | 21 +- .../GraphWorkspace/plugins/types.ts | 22 +- .../src/workspaces/GraphWorkspace/scene.ts | 65 + .../GraphWorkspace/sigmaNativeRendering.ts | 336 +++++ .../src/workspaces/GraphWorkspace/types.ts | 138 +- .../workspaces/GraphWorkspace/useGraphData.ts | 68 +- .../workspaces/GraphWorkspace/useLoadGraph.ts | 321 +++-- .../tests/graphStore.multi-edge.test.mjs | 111 ++ semantica/context/context_graph.py | 160 ++- semantica/explorer/routes/export_import.py | 43 +- semantica/explorer/routes/graph.py | 2 + semantica/explorer/schemas.py | 3 + semantica/explorer/session.py | 63 +- ...nUOYv.js => DecisionWorkspace-CkoD0QKe.js} | 2 +- ...4yP2.js => DiffMergeWorkspace-DDK7n-jO.js} | 2 +- ...jNw.js => GraphInspectorPanel-MLghMyni.js} | 2 +- .../static/assets/GraphWorkspace-Bqx0S-ru.js | 698 +++++++++ .../static/assets/GraphWorkspace-DGFkh5CZ.js | 288 ---- ...z.js => ImportExportWorkspace-BU8nK4nT.js} | 2 +- ...DQTOL97h.js => LineageDiagram-BcIhRlOg.js} | 2 +- ...-YrOmsTlw.js => TimelinePanel-DZ8Z1JsZ.js} | 2 +- ...SJd.js => VocabularyWorkspace-BonIpRiP.js} | 2 +- .../assets/{es-BveUcJeu.js => es-CS4MDIhr.js} | 2 +- .../explorationEffectsPlugin-BUgXLTPa.js | 1 - .../explorationEffectsPlugin-BhFwJ4hP.js | 1 - ...explorationEffectsPluginPhaseC-D23Zx1hX.js | 1 + ...explorationEffectsPluginPhaseC-D5jYu8XU.js | 1 + ...r-DFSl_YWi.js => graph-vendor-pbzH-eyf.js} | 2 +- .../static/assets/graphTheme-CLhhQXPS.js | 1 - .../static/assets/graphTheme-aSRma4TX.js | 1 + .../{index-BVBOQ8an.js => index-DDOaKEbH.js} | 4 +- .../neighborhoodPanelPlugin-CJEfjLxQ.js | 1 - .../neighborhoodPanelPlugin-Dra5vWrD.js | 1 - .../neighborhoodPanelPlugin-DtCzBl4D.js | 1 + .../neighborhoodPanelPlugin-qsLfEPn1.js | 1 + semantica/static/index.html | 2 +- tests/explorer/test_explorer_api.py | 134 +- 58 files changed, 6635 insertions(+), 1808 deletions(-) create mode 100644 semantica-explorer/src/store/edgePairKeys.d.ts create mode 100644 semantica-explorer/src/store/edgePairKeys.js create mode 100644 semantica-explorer/src/workspaces/GraphWorkspace/GraphLoadingOverlay.tsx create mode 100644 semantica-explorer/src/workspaces/GraphWorkspace/SigmaSceneAdapter.tsx create mode 100644 semantica-explorer/src/workspaces/GraphWorkspace/graphLoading.ts create mode 100644 semantica-explorer/src/workspaces/GraphWorkspace/graphSceneLayers.ts create mode 100644 semantica-explorer/src/workspaces/GraphWorkspace/graphSceneState.ts create mode 100644 semantica-explorer/src/workspaces/GraphWorkspace/plugins/explorationEffectsPluginPhaseC.tsx create mode 100644 semantica-explorer/src/workspaces/GraphWorkspace/scene.ts create mode 100644 semantica-explorer/src/workspaces/GraphWorkspace/sigmaNativeRendering.ts create mode 100644 semantica-explorer/tests/graphStore.multi-edge.test.mjs rename semantica/static/assets/{DecisionWorkspace-DOZnUOYv.js => DecisionWorkspace-CkoD0QKe.js} (97%) rename semantica/static/assets/{DiffMergeWorkspace-BP5v4yP2.js => DiffMergeWorkspace-DDK7n-jO.js} (97%) rename semantica/static/assets/{GraphInspectorPanel-CbpkpjNw.js => GraphInspectorPanel-MLghMyni.js} (98%) create mode 100644 semantica/static/assets/GraphWorkspace-Bqx0S-ru.js delete mode 100644 semantica/static/assets/GraphWorkspace-DGFkh5CZ.js rename semantica/static/assets/{ImportExportWorkspace-CYQpATgz.js => ImportExportWorkspace-BU8nK4nT.js} (98%) rename semantica/static/assets/{LineageDiagram-DQTOL97h.js => LineageDiagram-BcIhRlOg.js} (99%) rename semantica/static/assets/{TimelinePanel-YrOmsTlw.js => TimelinePanel-DZ8Z1JsZ.js} (98%) rename semantica/static/assets/{VocabularyWorkspace-Xth7XSJd.js => VocabularyWorkspace-BonIpRiP.js} (99%) rename semantica/static/assets/{es-BveUcJeu.js => es-CS4MDIhr.js} (99%) delete mode 100644 semantica/static/assets/explorationEffectsPlugin-BUgXLTPa.js delete mode 100644 semantica/static/assets/explorationEffectsPlugin-BhFwJ4hP.js create mode 100644 semantica/static/assets/explorationEffectsPluginPhaseC-D23Zx1hX.js create mode 100644 semantica/static/assets/explorationEffectsPluginPhaseC-D5jYu8XU.js rename semantica/static/assets/{graph-vendor-DFSl_YWi.js => graph-vendor-pbzH-eyf.js} (99%) delete mode 100644 semantica/static/assets/graphTheme-CLhhQXPS.js create mode 100644 semantica/static/assets/graphTheme-aSRma4TX.js rename semantica/static/assets/{index-BVBOQ8an.js => index-DDOaKEbH.js} (99%) delete mode 100644 semantica/static/assets/neighborhoodPanelPlugin-CJEfjLxQ.js delete mode 100644 semantica/static/assets/neighborhoodPanelPlugin-Dra5vWrD.js create mode 100644 semantica/static/assets/neighborhoodPanelPlugin-DtCzBl4D.js create mode 100644 semantica/static/assets/neighborhoodPanelPlugin-qsLfEPn1.js diff --git a/semantica-explorer/package-lock.json b/semantica-explorer/package-lock.json index 78d4d658..48e61227 100644 --- a/semantica-explorer/package-lock.json +++ b/semantica-explorer/package-lock.json @@ -9,10 +9,15 @@ "version": "0.0.0", "dependencies": { "@monaco-editor/react": "^4.7.0", + "@sigma/edge-curve": "^3.1.0", + "@sigma/node-border": "^3.0.0", "@tanstack/react-query": "^5.95.2", "@xyflow/react": "^12.10.2", "graphology": "^0.26.0", + "graphology-communities-louvain": "^2.0.2", "graphology-layout-forceatlas2": "^0.10.1", + "graphology-metrics": "^2.4.0", + "graphology-shortest-path": "^2.1.0", "lucide-react": "^1.7.0", "react": "^19.2.4", "react-arborist": "^3.4.3", @@ -962,6 +967,24 @@ "dev": true, "license": "MIT" }, + "node_modules/@sigma/edge-curve": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigma/edge-curve/-/edge-curve-3.1.0.tgz", + "integrity": "sha512-OFWkfAXEsm+X8l1K4K49cC0psB0gQ+gqxKA08HG5piNPdzrDZ5gG9Gza6htZ5AirOVwd/4/uq/gPpD5En+H+3Q==", + "license": "MIT", + "peerDependencies": { + "sigma": ">=3.0.0-beta.10" + } + }, + "node_modules/@sigma/node-border": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sigma/node-border/-/node-border-3.0.0.tgz", + "integrity": "sha512-mE3zUfjvJVuAMhSjiP/zdlkqe0OVTETxd04XHUwof01YqdzTk0OB4ACJIhWrwgsBXl7tTd9lPuKoroafLh8MtQ==", + "license": "MIT", + "peerDependencies": { + "sigma": ">=3.0.0-beta.17" + } + }, "node_modules/@tanstack/query-core": { "version": "5.95.2", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.95.2.tgz", @@ -1505,6 +1528,12 @@ "d3-zoom": "^3.0.0" } }, + "node_modules/@yomguithereal/helpers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@yomguithereal/helpers/-/helpers-1.1.1.tgz", + "integrity": "sha512-UYvAq/XCA7xoh1juWDYsq3W0WywOB+pz8cgVnE1b45ZfdMhBvHDrgmSFG3jXeZSr2tMTYLGHFHON+ekG05Jebg==", + "license": "MIT" + }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -2343,6 +2372,34 @@ "graphology-types": ">=0.24.0" } }, + "node_modules/graphology-communities-louvain": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/graphology-communities-louvain/-/graphology-communities-louvain-2.0.2.tgz", + "integrity": "sha512-zt+2hHVPYxjEquyecxWXoUoIuN/UvYzsvI7boDdMNz0rRvpESQ7+e+Ejv6wK7AThycbZXuQ6DkG8NPMCq6XwoA==", + "license": "MIT", + "dependencies": { + "graphology-indices": "^0.17.0", + "graphology-utils": "^2.4.4", + "mnemonist": "^0.39.0", + "pandemonium": "^2.4.1" + }, + "peerDependencies": { + "graphology-types": ">=0.19.0" + } + }, + "node_modules/graphology-indices": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/graphology-indices/-/graphology-indices-0.17.0.tgz", + "integrity": "sha512-A7RXuKQvdqSWOpn7ZVQo4S33O0vCfPBnUSf7FwE0zNCasqwZVUaCXePuWo5HBpWw68KJcwObZDHpFk6HKH6MYQ==", + "license": "MIT", + "dependencies": { + "graphology-utils": "^2.4.2", + "mnemonist": "^0.39.0" + }, + "peerDependencies": { + "graphology-types": ">=0.20.0" + } + }, "node_modules/graphology-layout-forceatlas2": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/graphology-layout-forceatlas2/-/graphology-layout-forceatlas2-0.10.1.tgz", @@ -2355,6 +2412,37 @@ "graphology-types": ">=0.19.0" } }, + "node_modules/graphology-metrics": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/graphology-metrics/-/graphology-metrics-2.4.0.tgz", + "integrity": "sha512-7WOfOP+mFLCaTJx55Qg4eY+211vr1/b3D/R3biz3SXGhAaCVcWYkfabnmO4O4WBNWANEHtVnFrGgJ0kj6MM6xw==", + "license": "MIT", + "dependencies": { + "graphology-indices": "^0.17.0", + "graphology-shortest-path": "^2.0.0", + "graphology-utils": "^2.4.4", + "mnemonist": "^0.39.0", + "pandemonium": "2.4.1" + }, + "peerDependencies": { + "graphology-types": ">=0.20.0" + } + }, + "node_modules/graphology-shortest-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/graphology-shortest-path/-/graphology-shortest-path-2.1.0.tgz", + "integrity": "sha512-KbT9CTkP/u72vGEJzyRr24xFC7usI9Es3LMmCPHGwQ1KTsoZjxwA9lMKxfU0syvT/w+7fZUdB/Hu2wWYcJBm6Q==", + "license": "MIT", + "dependencies": { + "@yomguithereal/helpers": "^1.1.1", + "graphology-indices": "^0.17.0", + "graphology-utils": "^2.4.3", + "mnemonist": "^0.39.0" + }, + "peerDependencies": { + "graphology-types": ">=0.20.0" + } + }, "node_modules/graphology-types": { "version": "0.24.8", "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.8.tgz", @@ -2918,6 +3006,15 @@ "node": "*" } }, + "node_modules/mnemonist": { + "version": "0.39.8", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz", + "integrity": "sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==", + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.1" + } + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -2988,6 +3085,12 @@ "node": ">=0.10.0" } }, + "node_modules/obliterator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", + "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", + "license": "MIT" + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -3038,6 +3141,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pandemonium": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/pandemonium/-/pandemonium-2.4.1.tgz", + "integrity": "sha512-wRqjisUyiUfXowgm7MFH2rwJzKIr20rca5FsHXCMNm1W5YPP1hCtrZfgmQ62kP7OZ7Xt+cR858aB28lu5NX55g==", + "license": "MIT", + "dependencies": { + "mnemonist": "^0.39.2" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", diff --git a/semantica-explorer/package.json b/semantica-explorer/package.json index 62e54204..61e69892 100644 --- a/semantica-explorer/package.json +++ b/semantica-explorer/package.json @@ -7,14 +7,20 @@ "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "test:graph-store": "node --test tests/graphStore.multi-edge.test.mjs" }, "dependencies": { "@monaco-editor/react": "^4.7.0", + "@sigma/edge-curve": "^3.1.0", + "@sigma/node-border": "^3.0.0", "@tanstack/react-query": "^5.95.2", "@xyflow/react": "^12.10.2", "graphology": "^0.26.0", + "graphology-communities-louvain": "^2.0.2", "graphology-layout-forceatlas2": "^0.10.1", + "graphology-metrics": "^2.4.0", + "graphology-shortest-path": "^2.1.0", "lucide-react": "^1.7.0", "react": "^19.2.4", "react-arborist": "^3.4.3", diff --git a/semantica-explorer/src/store/edgePairKeys.d.ts b/semantica-explorer/src/store/edgePairKeys.d.ts new file mode 100644 index 00000000..286588cd --- /dev/null +++ b/semantica-explorer/src/store/edgePairKeys.d.ts @@ -0,0 +1,2 @@ +export function pairRegistryKey(source: string, target: string): string; +export function curveGroupForPair(source: string, target: string): string; diff --git a/semantica-explorer/src/store/edgePairKeys.js b/semantica-explorer/src/store/edgePairKeys.js new file mode 100644 index 00000000..65e5f778 --- /dev/null +++ b/semantica-explorer/src/store/edgePairKeys.js @@ -0,0 +1,7 @@ +export function pairRegistryKey(source, target) { + return JSON.stringify([source, target]); +} + +export function curveGroupForPair(source, target) { + return JSON.stringify([source, target]); +} diff --git a/semantica-explorer/src/store/graphStore.ts b/semantica-explorer/src/store/graphStore.ts index 1d74c163..7ce63ba0 100644 --- a/semantica-explorer/src/store/graphStore.ts +++ b/semantica-explorer/src/store/graphStore.ts @@ -6,11 +6,12 @@ import type { GraphLabelVisibilityPolicy, GraphNodeShapeVariant, } from "../workspaces/GraphWorkspace/graphTheme"; +import { curveGroupForPair, pairRegistryKey } from "./edgePairKeys.js"; export const graph = new Graph({ type: "directed", - multi: false, + multi: true, allowSelfLoops: false }); @@ -50,6 +51,10 @@ export interface NodeAttributes { } export interface EdgeAttributes { + edgeId?: string; + familyId?: string; + sourceId?: string; + targetId?: string; size?: number; baseSize?: number; @@ -57,6 +62,7 @@ export interface EdgeAttributes { baseColor?: string; mutedColor?: string; type?: string; + curvature?: number; visualPriority?: number; edgeFamily?: "line" | "parallel" | "bidirectional" | "path"; isBidirectional?: boolean; @@ -67,6 +73,7 @@ export interface EdgeAttributes { isParallelPair?: boolean; parallelIndex?: number; parallelCount?: number; + familySize?: number; edgeType: string; @@ -74,6 +81,51 @@ export interface EdgeAttributes { properties: Record; } +function normalizeParallelMetadataForPair(source: string, target: string): void { + const edgeIds: string[] = []; + graph.forEachDirectedEdge(source, target, (edgeId) => { + edgeIds.push(String(edgeId)); + }); + + const pairCount = edgeIds.length; + const familyCounts = new Map(); + edgeIds.forEach((edgeId) => { + const attrs = graph.getEdgeAttributes(edgeId) as EdgeAttributes; + const familyId = String(attrs.familyId || edgeId); + familyCounts.set(familyId, (familyCounts.get(familyId) ?? 0) + 1); + }); + + edgeIds + .sort((left, right) => { + const leftAttrs = graph.getEdgeAttributes(left) as EdgeAttributes; + const rightAttrs = graph.getEdgeAttributes(right) as EdgeAttributes; + const priorityDelta = Number(rightAttrs.visualPriority ?? 0) - Number(leftAttrs.visualPriority ?? 0); + if (priorityDelta !== 0) { + return priorityDelta; + } + const weightDelta = Number(rightAttrs.weight ?? 0) - Number(leftAttrs.weight ?? 0); + if (weightDelta !== 0) { + return weightDelta; + } + return left.localeCompare(right); + }) + .forEach((edgeId, index) => { + const attrs = graph.getEdgeAttributes(edgeId) as EdgeAttributes; + const familyId = String(attrs.familyId || edgeId); + graph.mergeEdgeAttributes(edgeId, { + edgeId, + familyId, + sourceId: source, + targetId: target, + isParallelPair: pairCount > 1, + parallelIndex: index, + parallelCount: pairCount, + familySize: familyCounts.get(familyId) ?? 1, + curveGroup: curveGroupForPair(source, target), + }); + }); +} + export function batchMergeNodes( nodes: { id: string; attributes: NodeAttributes }[] @@ -85,14 +137,29 @@ export function batchMergeNodes( export function batchMergeEdges( - edges: { source: string; target: string; attributes: EdgeAttributes }[] + edges: { id: string; familyId?: string; source: string; target: string; attributes: EdgeAttributes }[] ): void { - for (const { source, target, attributes } of edges) { - + const touchedPairs = new Map(); + + for (const { id, familyId, source, target, attributes } of edges) { + const edgeId = String(attributes.edgeId || id); + const resolvedFamilyId = String(attributes.familyId || familyId || edgeId); + if (graph.hasNode(source) && graph.hasNode(target)) { - graph.mergeDirectedEdge(source, target, attributes); + graph.mergeDirectedEdgeWithKey(edgeId, source, target, { + ...attributes, + edgeId, + familyId: resolvedFamilyId, + sourceId: source, + targetId: target, + }); + touchedPairs.set(pairRegistryKey(source, target), { source, target }); } } + + touchedPairs.forEach(({ source, target }) => { + normalizeParallelMetadataForPair(source, target); + }); } export function clearGraph(): void { diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/GraphCanvas.tsx b/semantica-explorer/src/workspaces/GraphWorkspace/GraphCanvas.tsx index 4c818c5a..ecb3b951 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/GraphCanvas.tsx +++ b/semantica-explorer/src/workspaces/GraphWorkspace/GraphCanvas.tsx @@ -1,5 +1,5 @@ import { useEffect, useMemo, useRef, useCallback, forwardRef, useImperativeHandle, useState, type ReactNode } from "react"; -import Graph from "graphology"; +import type Graph from "graphology"; import Sigma from "sigma"; import FA2Layout from "graphology-layout-forceatlas2/worker"; import { graph, type EdgeAttributes, type NodeAttributes } from "../../store/graphStore"; @@ -14,41 +14,71 @@ import { createViewModeSwitchBehavior } from "./behaviors/viewModeSwitchBehavior import { GRAPH_THEME, getZoomTier, - type GraphArrowVisibilityPolicy, type GraphBadgeKind, - type GraphEdgeVariant, - type GraphEdgeVisualState, - type GraphLabelVisibilityPolicy, - type GraphNodeShapeVariant, - type GraphNodeVisualState, - type GraphTheme, type GraphZoomTier, withAlpha, zoomTierAtLeast, } from "./graphTheme"; +import { + buildFocusSet, + buildEdgeEndpointSet, + buildPathEdgeSet, + collectInteractionRefreshTargets, + createInteractionState, + isEdgeInteractable, + resolveDisplayGraph, + resolveEdgeElementStyle, + resolveEdgeVisualState, + resolveNodeElementStyle, + resolveNodeVisualState, +} from "./graphSceneState"; +import { buildGraphAnalyticsSnapshot, computeGraphAnalyticsBase } from "./graphAnalytics"; +import { + collectVisibleNodeSamples, + drawContourLayer, + drawLensLayer, + drawPathEffectsLayer, + drawSemanticRegionsLayer, + drawTemporalEmphasisLayer, + type PathSegmentOverlay, + type ViewportPoint, +} from "./graphSceneLayers"; +import { + SEMANTICA_EDGE_PROGRAM_CLASSES, + SEMANTICA_NODE_PROGRAM_CLASSES, + drawSemanticaNodeHover, + drawSemanticaNodeLabel, +} from "./sigmaNativeRendering"; import type { + GraphAnalyticsSnapshot, GraphCameraState, GraphDiagnosticsSnapshot, GraphEffectsState, GraphInteractionState, GraphLayoutStatus, + GraphTemporalState, GraphViewMode, } from "./types"; -import type { GraphPluginRuntime } from "./plugins"; +import type { GraphSceneRuntime } from "./scene"; export type { GraphViewMode } from "./types"; export interface GraphCanvasHandle { - getSigma: () => Sigma | null; fitView: () => void; focusNode: (nodeId: string) => void; + requestRender: () => void; + getCameraState: () => GraphCameraState | null; } export interface GraphCanvasProps { onNodeClick: (nodeId: string) => void; + onEdgeClick?: (edgeId: string) => void; selectedNodeId: string; + selectedEdgeId: string; activePath?: string[]; + activePathEdgeIds?: string[]; effectsState: GraphEffectsState; + temporalState?: GraphTemporalState | null; isLayoutRunning: boolean; onLayoutRunningChange?: (running: boolean) => void; layoutSource?: string; @@ -57,9 +87,11 @@ export interface GraphCanvasProps { className?: string; showFitViewButton?: boolean; pluginOverlays?: ReactNode[]; - onPluginRuntimeChange?: (runtime: GraphPluginRuntime | null) => void; + onSceneRuntimeChange?: (runtime: GraphSceneRuntime | null) => void; onInteractionStateChange?: (interactionState: GraphInteractionState) => void; + onCameraStateChange?: (cameraState: GraphCameraState) => void; onDiagnosticsChange?: (effectAvailability: GraphDiagnosticsSnapshot["effectAvailability"]) => void; + onAnalyticsChange?: (analytics: GraphAnalyticsSnapshot | null) => void; } const FA2_SETTINGS = { @@ -68,76 +100,34 @@ const FA2_SETTINGS = { barnesHutOptimize: true, barnesHutTheta: 0.5, adjustSizes: false, - gravity: 1, - slowDown: 10, + gravity: 0.16, + scalingRatio: 7.5, + edgeWeightInfluence: 0.3, + linLogMode: true, + strongGravityMode: false, + slowDown: 18, }, }; const SIGMA_SETTINGS = { allowInvalidContainer: true, - labelRenderedSizeThreshold: 3, + labelRenderedSizeThreshold: 4, defaultNodeType: "circle", defaultEdgeType: "line", + hideLabelsOnMove: true, hideEdgesOnMove: true, + enableEdgeEvents: true, + renderEdgeLabels: false, + labelDensity: 0.86, + labelGridCellSize: 100, + zIndex: true, webGLTarget: "webgl2" as const, + nodeProgramClasses: SEMANTICA_NODE_PROGRAM_CLASSES, + edgeProgramClasses: SEMANTICA_EDGE_PROGRAM_CLASSES, + defaultDrawNodeLabel: drawSemanticaNodeLabel, + defaultDrawNodeHover: drawSemanticaNodeHover, }; -const MAX_FOCUS_NEIGHBORS = GRAPH_THEME.focus.maxNeighbors; -const FOCUS_RING_CAPACITY = GRAPH_THEME.focus.ringCapacity; -const FOCUS_RING_GAP = GRAPH_THEME.focus.ringGap; -const FOCUS_PRIMARY_LABELS = GRAPH_THEME.focus.primaryLabels; - -type ResolvedNodeStyle = { - color: string; - size: number; - forceLabel: boolean; - label: string; - zIndex: number; - hidden: boolean; - borderColor: string; - borderSize: number; - nodeVariant: GraphNodeShapeVariant; - badgeKind?: GraphBadgeKind; - badgeCount?: number; - showBadge: boolean; - showRing: boolean; - ringColor?: string; - showHalo: boolean; - haloColor: string; -}; - -type ResolvedEdgeStyle = { - hidden: boolean; - type?: "line" | "arrow"; - color?: string; - size?: number; - zIndex: number; - edgeVariant: GraphEdgeVariant; - arrowVisibilityPolicy: GraphArrowVisibilityPolicy; - curveStrength: number; - drawCurvedOverlay: boolean; -}; - -type ViewportPoint = { x: number; y: number }; -type PathSegmentOverlay = { - sourceId: string; - targetId: string; - source: ViewportPoint; - target: ViewportPoint; - color: string; - size: number; - curveStrength: number; -}; - -function buildPathEdgeSet(path: string[]): Set { - const edgeIds = new Set(); - for (let index = 0; index < path.length - 1; index += 1) { - edgeIds.add(`${path[index]}::${path[index + 1]}`); - edgeIds.add(`${path[index + 1]}::${path[index]}`); - } - return edgeIds; -} - function isPointNearViewport(point: ViewportPoint, width: number, height: number, padding = 96) { return point.x >= -padding && point.y >= -padding @@ -148,6 +138,7 @@ function isPointNearViewport(point: ViewportPoint, width: number, height: number function collectPathSegments( sigma: Sigma, path: string[], + pathEdgeIds: string[], zoomTier: GraphZoomTier, viewportWidth: number, viewportHeight: number, @@ -169,15 +160,15 @@ function collectPathSegments( continue; } - const attrs = graph.hasDirectedEdge(sourceId, targetId) - ? (graph.getDirectedEdgeAttributes(sourceId, targetId) as EdgeAttributes) + const attrs = pathEdgeIds[index] && graph.hasEdge(pathEdgeIds[index]) + ? (graph.getEdgeAttributes(pathEdgeIds[index]) as EdgeAttributes) : ({ baseColor: GRAPH_THEME.palette.accent.path, baseSize: 1.2, edgeVariant: "pathSignal", arrowVisibilityPolicy: "always", } as EdgeAttributes); - const pathStyle = resolveEdgeElementStyle(GRAPH_THEME, zoomTier, "path", attrs); + const pathStyle = resolveEdgeElementStyle(GRAPH_THEME, zoomTier, "path", attrs, sourceId, targetId); if (!pathStyle.color || !pathStyle.size) { continue; } @@ -189,7 +180,6 @@ function collectPathSegments( target, color: pathStyle.color, size: pathStyle.size, - curveStrength: pathStyle.curveStrength || GRAPH_THEME.edges.variants.pathSignal.curveStrength, }); } @@ -199,17 +189,29 @@ function collectPathSegments( function buildEffectAvailability( interactionState: GraphInteractionState, effectsState: GraphEffectsState, + temporalState: GraphTemporalState | null | undefined, + analytics: GraphAnalyticsSnapshot | null, sigma: Sigma | null, viewportWidth: number, viewportHeight: number, ): GraphDiagnosticsSnapshot["effectAvailability"] { const visiblePathSegments = sigma - ? collectPathSegments(sigma, interactionState.activePath, interactionState.zoomTier, viewportWidth, viewportHeight).length + ? collectPathSegments( + sigma, + interactionState.activePath, + interactionState.activePathEdgeIds, + interactionState.zoomTier, + viewportWidth, + viewportHeight, + ).length : 0; const hasActivePath = interactionState.activePath.length > 1; const pulseTierReady = zoomTierAtLeast(interactionState.zoomTier, GRAPH_THEME.effects.pathPulse.minZoomTier); const flowTierReady = zoomTierAtLeast(interactionState.zoomTier, GRAPH_THEME.effects.pathFlow.minZoomTier); const lensTierReady = zoomTierAtLeast(interactionState.zoomTier, GRAPH_THEME.effects.lens.minZoomTier); + const temporalTierReady = zoomTierAtLeast(interactionState.zoomTier, GRAPH_THEME.effects.temporalEmphasis.minZoomTier); + const regionsTierReady = zoomTierAtLeast(interactionState.zoomTier, GRAPH_THEME.effects.semanticRegions.minZoomTier); + const contoursTierReady = zoomTierAtLeast(interactionState.zoomTier, GRAPH_THEME.effects.contours.minZoomTier); const hasPrimaryNode = Boolean(interactionState.hoveredNodeId || interactionState.selectedNodeId); const pathPulse = !effectsState.pathPulseEnabled @@ -285,6 +287,95 @@ function buildEffectAvailability( } : { enabled: true, available: true, reason: "Ready" }; + const temporalEmphasis = !effectsState.temporalEmphasisEnabled + ? { enabled: false, available: false, reason: "Disabled by toggle" } + : !temporalState?.currentTime + ? { enabled: true, available: false, reason: "No temporal focus time" } + : !temporalTierReady + ? { + enabled: true, + available: false, + reason: "Disabled by zoom tier", + detail: `Requires ${GRAPH_THEME.effects.temporalEmphasis.minZoomTier}`, + } + : { enabled: true, available: true, reason: "Ready" }; + + const semanticRegions = !effectsState.semanticRegionsEnabled + ? { enabled: false, available: false, reason: "Disabled by toggle" } + : !regionsTierReady + ? { + enabled: true, + available: false, + reason: "Disabled by zoom tier", + detail: `Requires ${GRAPH_THEME.effects.semanticRegions.minZoomTier}`, + } + : !analytics?.semanticRegions.ready + ? { + enabled: true, + available: false, + reason: analytics?.semanticRegions.reason ?? "Waiting for semantic region summaries", + } + : { enabled: true, available: true, reason: analytics.semanticRegions.reason }; + + const contours = !effectsState.contoursEnabled + ? { enabled: false, available: false, reason: "Disabled by toggle" } + : !contoursTierReady + ? { + enabled: true, + available: false, + reason: "Disabled by zoom tier", + detail: `Requires ${GRAPH_THEME.effects.contours.minZoomTier}`, + } + : !analytics?.centrality.ready + ? { + enabled: true, + available: false, + reason: analytics?.centrality.reason ?? "Waiting for centrality ranking", + } + : { enabled: true, available: true, reason: analytics.centrality.reason }; + + const pathfinding = !effectsState.pathfindingEnabled + ? { enabled: false, available: false, reason: "Disabled by toggle" } + : !analytics?.directedPath.ready + ? { + enabled: true, + available: false, + reason: analytics?.directedPath.reason ?? "Waiting for a traced path", + } + : { + enabled: true, + available: true, + reason: analytics.directedPath.verifiedAgainstActivePath + ? "Ready · local path matches traced path" + : "Ready · local directed path differs from traced path", + }; + + const communities = !effectsState.communitiesEnabled + ? { enabled: false, available: false, reason: "Disabled by toggle" } + : !analytics?.communities.ready + ? { + enabled: true, + available: false, + reason: analytics?.communities.reason ?? "Waiting for community summaries", + } + : { + enabled: true, + available: true, + reason: analytics.communities.modularity !== null + ? `Ready · modularity ${analytics.communities.modularity.toFixed(3)}` + : analytics.communities.reason, + }; + + const centrality = !effectsState.centralityEnabled + ? { enabled: false, available: false, reason: "Disabled by toggle" } + : !analytics?.centrality.ready + ? { + enabled: true, + available: false, + reason: analytics?.centrality.reason ?? "Waiting for centrality ranking", + } + : { enabled: true, available: true, reason: analytics.centrality.reason }; + const legend = effectsState.legendEnabled ? { enabled: true, available: true, reason: "Panel enabled" } : { enabled: false, available: false, reason: "Disabled by toggle" }; @@ -295,453 +386,21 @@ function buildEffectAvailability( ? { enabled: true, available: true, reason: "Ready" } : { enabled: false, available: false, reason: "Disabled by toggle" }; - return { pathPulse, pathFlow, lens, legend, diagnostics }; -} - -function getEdgeWeightBetween(source: string, target: string): number { - let weight = 0; - - if (graph.hasDirectedEdge(source, target)) { - const attrs = graph.getDirectedEdgeAttributes(source, target) as { weight?: number }; - weight = Math.max(weight, Number(attrs?.weight ?? 0)); - } - - if (graph.hasDirectedEdge(target, source)) { - const attrs = graph.getDirectedEdgeAttributes(target, source) as { weight?: number }; - weight = Math.max(weight, Number(attrs?.weight ?? 0)); - } - - return weight; -} - -function rankNeighbors(nodeId: string): string[] { - return graph - .neighbors(nodeId) - .map((neighborId) => ({ - id: neighborId, - weight: getEdgeWeightBetween(nodeId, neighborId), - degree: graph.degree(neighborId), - })) - .sort((left, right) => { - if (right.weight !== left.weight) { - return right.weight - left.weight; - } - if (right.degree !== left.degree) { - return right.degree - left.degree; - } - return left.id.localeCompare(right.id); - }) - .map((item) => item.id); -} - -function buildFocusSet(nodeId: string): Set { - const ranked = rankNeighbors(nodeId).slice(0, MAX_FOCUS_NEIGHBORS); - return new Set([nodeId, ...ranked]); -} - -function resolveNodeColor(theme: GraphTheme, state: GraphNodeVisualState, attrs: NodeAttributes, fallbackColor?: string) { - const baseColor = String(attrs.baseColor || fallbackColor || theme.palette.semantic[0]); - - switch (theme.nodes.states[state].color) { - case "selected": - return theme.palette.accent.selected; - case "hovered": - return theme.palette.accent.hovered; - case "path": - return theme.palette.accent.path; - case "muted": - return String(attrs.mutedColor || withAlpha(baseColor, theme.nodes.mutedAlpha)); - case "base": - default: - return baseColor; - } -} - -function resolveEdgeColor(theme: GraphTheme, state: GraphEdgeVisualState, attrs: EdgeAttributes, fallbackColor?: string) { - const baseColor = String(attrs.baseColor || fallbackColor || theme.palette.muted.edgeInspection); - - switch (theme.edges.states[state].color) { - case "hover": - return theme.palette.accent.hovered; - case "path": - return theme.palette.accent.path; - case "focus": - return theme.palette.muted.edgeFocus; - case "overview": - return theme.palette.muted.edgeOverview; - case "structure": - return theme.palette.muted.edgeStructure; - case "inspection": - return theme.palette.muted.edgeInspection; - case "muted": - return String(attrs.mutedColor || theme.palette.muted.edgeOverview); - default: - return baseColor; - } -} - -function resolveNodeVisualState( - nodeId: string, - hoveredNodeId: string | null, - selectedNodeId: string, - focusIds: Set, - pathNodeIds: Set, -): GraphNodeVisualState { - if (hoveredNodeId && nodeId === hoveredNodeId) { - return "hovered"; - } - if (selectedNodeId && nodeId === selectedNodeId) { - return "selected"; - } - if (pathNodeIds.has(nodeId)) { - return "path"; - } - if (focusIds.has(nodeId)) { - return "neighbor"; - } - if (hoveredNodeId || selectedNodeId || pathNodeIds.size > 0) { - return "muted"; - } - return "default"; -} - -function resolveEdgeVisualState( - source: string, - target: string, - hoveredNodeId: string | null, - selectedNodeId: string, - focusIds: Set, - pathEdgeIds: Set, -): GraphEdgeVisualState { - const edgeKey = `${source}::${target}`; - const primaryNodeId = hoveredNodeId || selectedNodeId; - - if (pathEdgeIds.has(edgeKey)) { - return "path"; - } - - if (primaryNodeId && (source === primaryNodeId || target === primaryNodeId)) { - return hoveredNodeId ? "hovered" : "selected"; - } - - if (focusIds.has(source) && focusIds.has(target)) { - return "neighbor"; - } - - if (hoveredNodeId || selectedNodeId || pathEdgeIds.size > 0) { - return "muted"; - } - - return "default"; -} - -function resolveNodeVariant(state: GraphNodeVisualState, attrs: NodeAttributes): GraphNodeShapeVariant { - if (state === "selected") { - return "selected"; - } - - return attrs.nodeShapeVariant || attrs.nodeVariant || "default"; -} - -function resolveEdgeVariant(state: GraphEdgeVisualState, attrs: EdgeAttributes): GraphEdgeVariant { - if (state === "path") { - return "pathSignal"; - } - - if (attrs.edgeVariant) { - return attrs.edgeVariant; - } - - if (attrs.isBidirectional) { - return "bidirectionalCurve"; - } - - if (attrs.arrowVisibilityPolicy === "contextual") { - return "directional"; - } - - return "line"; -} - -function shouldForceNodeLabel( - theme: GraphTheme, - zoomTier: GraphZoomTier, - state: GraphNodeVisualState, - attrs: NodeAttributes, - labelPriority: number, -): boolean { - const tierConfig = theme.zoomTiers[zoomTier]; - const forceVisibleState = theme.labels.forceVisibleStates.includes(state); - const policy = attrs.labelVisibilityPolicy || "priority"; - - if (forceVisibleState || theme.nodes.states[state].forceLabel) { - return true; - } - - switch (policy as GraphLabelVisibilityPolicy) { - case "always": - return true; - case "local": - return zoomTier !== "overview" && state !== "default" && state !== "muted" && state !== "inactive"; - case "priority": - return labelPriority >= tierConfig.labelThreshold; - case "none": - default: - return false; - } -} - -function resolveNodeBorderColor( - theme: GraphTheme, - state: GraphNodeVisualState, - variant: GraphNodeShapeVariant, - attrs: NodeAttributes, - baseColor: string, -) { - if (state === "selected" || variant === "selected") { - return attrs.ringColor || theme.nodes.selectedRing.color; - } - if (state === "hovered") { - return theme.palette.accent.hovered; - } - if (state === "path") { - return theme.palette.accent.path; - } - if (state === "muted" || state === "inactive") { - return withAlpha(attrs.strokeColor || attrs.borderColor || theme.palette.background.nodeBorder, 0.7); - } - - if (variant === "temporal") { - return theme.palette.accent.temporal; - } - if (variant === "provenance") { - return theme.palette.accent.provenance; - } - if (variant === "inferred") { - return theme.palette.accent.inferred; - } - - return attrs.strokeColor || attrs.borderColor || theme.palette.background.nodeBorder || baseColor; -} - -function resolveNodeElementStyle( - theme: GraphTheme, - zoomTier: GraphZoomTier, - state: GraphNodeVisualState, - attrs: NodeAttributes, - label: string, -): ResolvedNodeStyle { - const tierConfig = theme.zoomTiers[zoomTier]; - const stateConfig = theme.nodes.states[state]; - const nodeVariant = resolveNodeVariant(state, attrs); - const variantConfig = theme.nodes.variants[nodeVariant]; - const baseSize = Number(attrs.baseSize || attrs.size || 4); - const labelPriority = Number(attrs.labelPriority ?? 0); - const color = resolveNodeColor(theme, state, attrs, attrs.color); - const sizeMultiplier = (state === "default" ? tierConfig.nodeScale : stateConfig.sizeMultiplier) * variantConfig.sizeMultiplier; - const forceLabel = shouldForceNodeLabel(theme, zoomTier, state, attrs, labelPriority); - const badgeKind = attrs.badgeKind || variantConfig.badgeKind; - const forceVisibleState = theme.labels.forceVisibleStates.includes(state); - const showBadge = Boolean( - badgeKind - && (forceVisibleState || (tierConfig.showBadges && zoomTierAtLeast(zoomTier, variantConfig.badgeVisibleFrom))) - && state !== "muted" - && state !== "inactive", - ); - const showRing = state === "selected" && zoomTierAtLeast(zoomTier, theme.nodes.selectedRing.visibleFrom); - const showHalo = state === "hovered" || state === "selected" || state === "path"; - const strokeBase = state === "muted" || state === "inactive" - ? theme.nodes.strokeHierarchy[zoomTier].muted - : forceVisibleState - ? theme.nodes.strokeHierarchy[zoomTier].emphasis - : theme.nodes.strokeHierarchy[zoomTier].base; - return { - color, - size: Math.max(baseSize * sizeMultiplier, stateConfig.minSize), - forceLabel, - label: forceLabel ? label : "", - zIndex: forceLabel && stateConfig.zIndex === 0 ? 1 : stateConfig.zIndex, - hidden: false, - borderColor: resolveNodeBorderColor(theme, state, nodeVariant, attrs, color), - borderSize: Math.max( - 0.4, - Number(attrs.borderSize ?? 0.85) + strokeBase + stateConfig.borderBoost + variantConfig.borderBoost - 0.8, - ), - nodeVariant, - badgeKind, - badgeCount: attrs.badgeCount, - showBadge, - showRing, - ringColor: attrs.ringColor || theme.nodes.selectedRing.color, - showHalo, - haloColor: attrs.haloColor || attrs.glowColor || withAlpha(color, theme.overlays.hoverGlowAlpha + variantConfig.haloBoost), + pathPulse, + pathFlow, + lens, + temporalEmphasis, + semanticRegions, + contours, + pathfinding, + communities, + centrality, + legend, + diagnostics, }; } -function resolveEdgeType( - theme: GraphTheme, - zoomTier: GraphZoomTier, - state: GraphEdgeVisualState, - variant: GraphEdgeVariant, - attrs: EdgeAttributes, -): "line" | "arrow" { - const variantConfig = theme.edges.variants[variant]; - - if (theme.edges.states[state].forceArrow || variantConfig.arrowPolicy === "always") { - return "arrow"; - } - - if (variantConfig.arrowPolicy === "contextual" && theme.zoomTiers[zoomTier].showContextualArrows) { - return "arrow"; - } - - if (state !== "default") { - return (attrs.type as "line" | "arrow" | undefined) || variantConfig.baseType; - } - - return Number(attrs.visualPriority ?? 0) >= theme.zoomTiers[zoomTier].arrowPriorityThreshold && theme.zoomTiers[zoomTier].showContextualArrows - ? "arrow" - : "line"; -} - -function resolveEdgeElementStyle( - theme: GraphTheme, - zoomTier: GraphZoomTier, - state: GraphEdgeVisualState, - attrs: EdgeAttributes, -): ResolvedEdgeStyle { - const tierConfig = theme.zoomTiers[zoomTier]; - const stateConfig = theme.edges.states[state]; - const edgeVariant = resolveEdgeVariant(state, attrs); - const variantConfig = theme.edges.variants[edgeVariant]; - const baseSize = Number(attrs.baseSize || attrs.size || 0.9); - const visualPriority = Number(attrs.visualPriority ?? 0); - const belowPriorityThreshold = state === "default" - && visualPriority < tierConfig.edgePriorityThreshold - && edgeVariant === "line"; - - if (stateConfig.hide || belowPriorityThreshold) { - return { - hidden: true, - zIndex: 0, - edgeVariant, - arrowVisibilityPolicy: variantConfig.arrowPolicy, - curveStrength: variantConfig.curveStrength, - drawCurvedOverlay: false, - }; - } - - const sizeMultiplier = (state === "default" ? tierConfig.edgeSizeScale : stateConfig.sizeMultiplier) * variantConfig.sizeMultiplier; - const drawCurvedOverlay = tierConfig.showCurves - && (edgeVariant === "bidirectionalCurve" || edgeVariant === "parallelCurve" || edgeVariant === "pathSignal") - && zoomTier !== "overview"; - - return { - hidden: false, - type: resolveEdgeType(theme, zoomTier, state, edgeVariant, attrs), - color: resolveEdgeColor(theme, state, attrs, attrs.color), - size: Math.max(baseSize * sizeMultiplier, stateConfig.minSize), - zIndex: stateConfig.zIndex, - edgeVariant, - arrowVisibilityPolicy: variantConfig.arrowPolicy, - curveStrength: variantConfig.curveStrength, - drawCurvedOverlay, - }; -} - -function createFocusedGraph(nodeId: string, activePath: string[]): Graph { - const focused = new Graph({ - type: "directed", - multi: false, - allowSelfLoops: false, - }); - - const rankedNeighbors = rankNeighbors(nodeId).slice(0, MAX_FOCUS_NEIGHBORS); - const focusIds = new Set([nodeId, ...rankedNeighbors]); - const labelledNeighborIds = new Set(rankedNeighbors.slice(0, FOCUS_PRIMARY_LABELS)); - const pathNodeIds = new Set(activePath); - const pathEdgeIds = buildPathEdgeSet(activePath); - - const addNode = (id: string, attrs: NodeAttributes) => { - if (!focused.hasNode(id)) { - focused.addNode(id, attrs); - } - }; - - const selectedAttrs = graph.getNodeAttributes(nodeId) as NodeAttributes; - const selectedState = resolveNodeElementStyle(GRAPH_THEME, "inspection", "selected", selectedAttrs, selectedAttrs.label); - addNode(nodeId, { - ...selectedAttrs, - x: 0, - y: 0, - color: selectedState.color, - size: Math.max(selectedState.size, 22), - label: selectedState.label, - }); - - rankedNeighbors.forEach((neighborId, index) => { - const baseAttrs = graph.getNodeAttributes(neighborId) as NodeAttributes; - const ring = Math.floor(index / FOCUS_RING_CAPACITY); - const ringIndex = index % FOCUS_RING_CAPACITY; - const itemsInRing = Math.min( - FOCUS_RING_CAPACITY, - rankedNeighbors.length - ring * FOCUS_RING_CAPACITY, - ); - const radius = FOCUS_RING_GAP * (ring + 1); - const angle = (Math.PI * 2 * ringIndex) / itemsInRing - Math.PI / 2; - const visualState: GraphNodeVisualState = pathNodeIds.has(neighborId) - ? "path" - : labelledNeighborIds.has(neighborId) - ? "neighbor" - : "default"; - const style = resolveNodeElementStyle( - GRAPH_THEME, - "inspection", - visualState, - { - ...baseAttrs, - labelPriority: labelledNeighborIds.has(neighborId) || pathNodeIds.has(neighborId) - ? Math.max(Number(baseAttrs.labelPriority ?? 0), 1) - : 0, - }, - baseAttrs.label, - ); - - addNode(neighborId, { - ...baseAttrs, - x: Math.cos(angle) * radius, - y: Math.sin(angle) * radius, - color: style.color, - size: Math.max(style.size, 8.5), - label: style.label, - }); - }); - - for (const source of focusIds) { - for (const target of focusIds) { - if (source === target || !graph.hasDirectedEdge(source, target)) { - continue; - } - const attrs = graph.getDirectedEdgeAttributes(source, target) as EdgeAttributes; - const state: GraphEdgeVisualState = pathEdgeIds.has(`${source}::${target}`) - ? "path" - : source === nodeId || target === nodeId - ? "selected" - : "neighbor"; - const style = resolveEdgeElementStyle(GRAPH_THEME, "inspection", state, attrs); - focused.mergeDirectedEdge(source, target, { - ...attrs, - type: style.type, - size: style.size, - color: style.color, - }); - } - } - - return focused; -} - function drawGlowHalo( context: CanvasRenderingContext2D, x: number, @@ -758,28 +417,6 @@ function drawGlowHalo( context.fill(); } -function drawNodeRing( - context: CanvasRenderingContext2D, - x: number, - y: number, - radius: number, - color: string, - width: number, - glowAlpha: number, -) { - context.strokeStyle = withAlpha(color, glowAlpha); - context.lineWidth = width * 2.4; - context.beginPath(); - context.arc(x, y, radius + width * 1.9, 0, Math.PI * 2); - context.stroke(); - - context.strokeStyle = color; - context.lineWidth = width; - context.beginPath(); - context.arc(x, y, radius + width * 1.45, 0, Math.PI * 2); - context.stroke(); -} - function drawNodeBadge( context: CanvasRenderingContext2D, x: number, @@ -823,192 +460,73 @@ function drawNodeBadge( context.fillText(label, badgeX, badgeY + 0.5); } -function drawCurvedEdge( - context: CanvasRenderingContext2D, - source: { x: number; y: number }, - target: { x: number; y: number }, - color: string, - width: number, - curvature: number, - glowAlpha: number, -) { - const dx = target.x - source.x; - const dy = target.y - source.y; - const length = Math.max(Math.hypot(dx, dy), 1); - const nx = -dy / length; - const ny = dx / length; - const curveOffset = length * curvature; - const controlX = (source.x + target.x) / 2 + nx * curveOffset; - const controlY = (source.y + target.y) / 2 + ny * curveOffset; - - context.strokeStyle = withAlpha(color, glowAlpha); - context.lineWidth = width + GRAPH_THEME.overlays.curveGlowWidth; - context.beginPath(); - context.moveTo(source.x, source.y); - context.quadraticCurveTo(controlX, controlY, target.x, target.y); - context.stroke(); - - context.strokeStyle = color; - context.lineWidth = width; - context.beginPath(); - context.moveTo(source.x, source.y); - context.quadraticCurveTo(controlX, controlY, target.x, target.y); - context.stroke(); -} - -function drawPathPulseOverlay( - context: CanvasRenderingContext2D, - segments: PathSegmentOverlay[], - now: number, -) { - segments.forEach((segment, index) => { - const t = ((now * GRAPH_THEME.effects.pathPulse.speed) + index * 0.17) % 1; - const x = segment.source.x + (segment.target.x - segment.source.x) * t; - const y = segment.source.y + (segment.target.y - segment.source.y) * t; - const glow = context.createRadialGradient(x, y, 0, x, y, GRAPH_THEME.effects.pathPulse.radius); - glow.addColorStop(0, withAlpha(GRAPH_THEME.palette.accent.path, GRAPH_THEME.effects.pathPulse.glowAlpha)); - glow.addColorStop(1, "rgba(0,0,0,0)"); - context.fillStyle = glow; - context.beginPath(); - context.arc(x, y, GRAPH_THEME.effects.pathPulse.radius, 0, Math.PI * 2); - context.fill(); - }); -} - -function drawPathFlowAccentOverlay( - context: CanvasRenderingContext2D, - segments: PathSegmentOverlay[], - now: number, -) { - segments.forEach((segment, index) => { - const t = ((now * GRAPH_THEME.effects.pathFlow.speed) + index * GRAPH_THEME.effects.pathFlow.spacing) % 1; - const headX = segment.source.x + (segment.target.x - segment.source.x) * t; - const headY = segment.source.y + (segment.target.y - segment.source.y) * t; - const tailT = Math.max(0, t - 0.08); - const tailX = segment.source.x + (segment.target.x - segment.source.x) * tailT; - const tailY = segment.source.y + (segment.target.y - segment.source.y) * tailT; - - context.strokeStyle = withAlpha(segment.color, 0.28); - context.lineWidth = Math.max(segment.size + 3.6, 4.6); - context.lineCap = "round"; - context.beginPath(); - context.moveTo(tailX, tailY); - context.lineTo(headX, headY); - context.stroke(); - - context.strokeStyle = withAlpha(GRAPH_THEME.palette.accent.selected, GRAPH_THEME.effects.pathFlow.opacity); - context.lineWidth = Math.max(segment.size + 1.3, 2.4); - context.beginPath(); - context.moveTo(tailX, tailY); - context.lineTo(headX, headY); - context.stroke(); - - drawGlowHalo( - context, - headX, - headY, - GRAPH_THEME.effects.pathFlow.radius, - withAlpha(GRAPH_THEME.palette.accent.selected, 0.32), - ); - }); -} - -function drawNeighborhoodLensOverlay( - context: CanvasRenderingContext2D, - sigma: Sigma, - primaryNodeId: string, - focusIds: Set, -) { - const primaryData = sigma.getNodeDisplayData(primaryNodeId); - if (!primaryData) { - return; - } - - const center = sigma.graphToViewport({ x: primaryData.x, y: primaryData.y }); - drawGlowHalo( - context, - center.x, - center.y, - GRAPH_THEME.effects.lens.radius, - withAlpha(GRAPH_THEME.palette.accent.hovered, GRAPH_THEME.effects.lens.glowAlpha), - ); - - focusIds.forEach((neighborId) => { - if (neighborId === primaryNodeId || !graph.hasNode(neighborId)) { - return; - } - - if ( - !graph.hasDirectedEdge(primaryNodeId, neighborId) - && !graph.hasDirectedEdge(neighborId, primaryNodeId) - ) { - return; - } - - const neighborData = sigma.getNodeDisplayData(neighborId); - if (!neighborData) { - return; - } - - const neighborPoint = sigma.graphToViewport({ x: neighborData.x, y: neighborData.y }); - context.strokeStyle = withAlpha(GRAPH_THEME.palette.accent.hovered, GRAPH_THEME.effects.lens.edgeAlpha * 0.38); - context.lineWidth = GRAPH_THEME.effects.lens.edgeLineWidth + 3.2; - context.lineCap = "round"; - context.beginPath(); - context.moveTo(center.x, center.y); - context.lineTo(neighborPoint.x, neighborPoint.y); - context.stroke(); - - context.strokeStyle = withAlpha(GRAPH_THEME.palette.accent.hovered, GRAPH_THEME.effects.lens.edgeAlpha); - context.lineWidth = GRAPH_THEME.effects.lens.edgeLineWidth; - context.beginPath(); - context.moveTo(center.x, center.y); - context.lineTo(neighborPoint.x, neighborPoint.y); - context.stroke(); - - drawGlowHalo( - context, - neighborPoint.x, - neighborPoint.y, - GRAPH_THEME.effects.lens.feather * 0.18, - withAlpha(GRAPH_THEME.palette.accent.hovered, 0.12), - ); - }); -} - function applySceneState( sigma: Sigma, + displayGraph: typeof graph | Graph, interactionState: GraphInteractionState, + analyticsSnapshot: GraphAnalyticsSnapshot | null, + refreshTargets?: { + nodes?: string[]; + edges?: string[]; + }, ) { - const { zoomTier, hoveredNodeId, selectedNodeId, activePath } = interactionState; + const { zoomTier, hoveredNodeId, selectedNodeId, selectedEdgeId, activePath } = interactionState; const primaryNodeId = hoveredNodeId || selectedNodeId; const focusIds = primaryNodeId && graph.hasNode(primaryNodeId) ? buildFocusSet(primaryNodeId) : new Set(); + const edgeEndpointIds = buildEdgeEndpointSet(displayGraph, selectedEdgeId); const pathNodeIds = new Set(activePath); - const pathEdgeIds = buildPathEdgeSet(activePath); + const pathEdgeIds = buildPathEdgeSet(displayGraph, activePath, interactionState.activePathEdgeIds); + const overviewBackboneEdgeIds = new Set(analyticsSnapshot?.overviewBackbone.edgeIds ?? []); + const cameraRatio = sigma.getCamera().getState().ratio; sigma.setSetting("nodeReducer", (node, data) => { const attrs = data as NodeAttributes; - const state = resolveNodeVisualState(node, hoveredNodeId, selectedNodeId, focusIds, pathNodeIds); - const style = resolveNodeElementStyle(GRAPH_THEME, zoomTier, state, attrs, data.label); + const state = resolveNodeVisualState( + node, + zoomTier, + hoveredNodeId, + selectedNodeId, + selectedEdgeId, + focusIds, + edgeEndpointIds, + pathNodeIds, + ); + const style = resolveNodeElementStyle(GRAPH_THEME, zoomTier, state, attrs, data.label, cameraRatio); - return { - ...data, - color: style.color, - size: style.size, - forceLabel: style.forceLabel, - label: style.label, - zIndex: style.zIndex, - hidden: style.hidden, - borderColor: style.borderColor, - borderSize: style.borderSize, - }; - }); + return { + ...data, + color: style.color, + shellColor: style.shellColor, + coreScale: style.coreScale, + size: style.size, + forceLabel: style.forceLabel, + label: style.label, + zIndex: style.zIndex, + hidden: style.hidden, + borderColor: style.borderColor, + borderSize: style.borderSize, + ringColor: style.showRing ? style.ringColor : style.borderColor, + ringSize: style.ringSize, + }; + }); sigma.setSetting("edgeReducer", (edge, data) => { const attrs = data as EdgeAttributes; - const [source, target] = graph.extremities(edge); - const state = resolveEdgeVisualState(source, target, hoveredNodeId, selectedNodeId, focusIds, pathEdgeIds); - const style = resolveEdgeElementStyle(GRAPH_THEME, zoomTier, state, attrs); + const [source, target] = displayGraph.extremities(edge); + const stableEdgeId = String(edge); + const state = resolveEdgeVisualState( + stableEdgeId, + source, + target, + zoomTier, + hoveredNodeId, + selectedNodeId, + selectedEdgeId, + focusIds, + pathEdgeIds, + overviewBackboneEdgeIds, + ); + const style = resolveEdgeElementStyle(GRAPH_THEME, zoomTier, state, attrs, source, target); return { ...data, @@ -1017,29 +535,21 @@ function applySceneState( color: style.color, size: style.size, zIndex: style.zIndex, + curvature: style.curvature, }; }); - sigma.refresh(); -} + if ((refreshTargets?.nodes?.length ?? 0) > 0 || (refreshTargets?.edges?.length ?? 0) > 0) { + sigma.scheduleRefresh({ + partialGraph: { + nodes: refreshTargets?.nodes, + edges: refreshTargets?.edges, + }, + }); + return; + } -function createInteractionState( - hoveredNodeId: string | null, - selectedNodeId: string, - activePath: string[], - viewMode: GraphViewMode, - zoomTier: GraphZoomTier, - isLayoutRunning: boolean, -): GraphInteractionState { - return { - hoveredNodeId, - selectedNodeId, - focusedNodeId: selectedNodeId, - activePath, - viewMode, - zoomTier, - isLayoutRunning, - }; + sigma.scheduleRefresh(); } function dispatchBehaviorAction( @@ -1058,17 +568,23 @@ export const GraphCanvas = forwardRef( function GraphCanvas( { onNodeClick, + onEdgeClick, selectedNodeId, + selectedEdgeId, activePath = [], + activePathEdgeIds = [], effectsState, + temporalState, isLayoutRunning, viewMode, className, showFitViewButton = true, pluginOverlays = [], - onPluginRuntimeChange, + onSceneRuntimeChange, onInteractionStateChange, + onCameraStateChange, onDiagnosticsChange, + onAnalyticsChange, }, ref, ) { @@ -1079,6 +595,7 @@ export const GraphCanvas = forwardRef( const behaviorContextRef = useRef(null); const [hoveredNodeId, setHoveredNodeId] = useState(null); const [zoomTier, setZoomTier] = useState("overview"); + const [analyticsSnapshot, setAnalyticsSnapshot] = useState(null); const behaviors = useMemo( () => [ @@ -1094,19 +611,36 @@ export const GraphCanvas = forwardRef( ); const isFocusedView = viewMode === "focused" && Boolean(selectedNodeId) && graph.hasNode(selectedNodeId); - const displayGraph = useMemo(() => { - if (isFocusedView && selectedNodeId) { - return createFocusedGraph(selectedNodeId, activePath); - } - return graph; - }, [activePath, isFocusedView, selectedNodeId]); + const displayGraph = useMemo( + () => resolveDisplayGraph(selectedNodeId, activePath, activePathEdgeIds, viewMode), + [activePath, activePathEdgeIds, selectedNodeId, viewMode], + ); const interactionState = useMemo( - () => createInteractionState(hoveredNodeId, selectedNodeId, activePath, viewMode, zoomTier, isLayoutRunning), - [activePath, hoveredNodeId, isLayoutRunning, selectedNodeId, viewMode, zoomTier], + () => createInteractionState( + hoveredNodeId, + selectedNodeId, + selectedEdgeId, + activePath, + activePathEdgeIds, + viewMode, + zoomTier, + isLayoutRunning, + ), + [activePath, activePathEdgeIds, hoveredNodeId, isLayoutRunning, selectedEdgeId, selectedNodeId, viewMode, zoomTier], ); const interactionStateRef = useRef(interactionState); interactionStateRef.current = interactionState; + const previousInteractionStateRef = useRef(null); + const shouldComputeCommunities = effectsState.communitiesEnabled || effectsState.semanticRegionsEnabled; + const shouldComputeCentrality = effectsState.centralityEnabled || effectsState.semanticRegionsEnabled || effectsState.contoursEnabled; + const analyticsBase = useMemo( + () => computeGraphAnalyticsBase(displayGraph, { + computeCommunities: shouldComputeCommunities, + computeCentrality: shouldComputeCentrality, + }), + [displayGraph, shouldComputeCentrality, shouldComputeCommunities], + ); const focusNodeInView = useCallback((nodeId: string) => { const sigma = sigmaRef.current; @@ -1168,16 +702,17 @@ export const GraphCanvas = forwardRef( getInteractionState: () => interactionStateRef.current, setHoveredNodeId, onNodeSelectionChange: onNodeClick, + onEdgeSelectionChange: onEdgeClick ?? (() => {}), focusNodeInView, fitCurrentView, dispatchAction, }; behaviorContextRef.current = context; return context; - }, [displayGraph, dispatchAction, fitCurrentView, focusNodeInView, onNodeClick]); + }, [displayGraph, dispatchAction, fitCurrentView, focusNodeInView, onEdgeClick, onNodeClick]); const dispatchToBehaviors = useCallback(( - hook: "onNodeEnter" | "onNodeLeave" | "onNodeClick" | "onStageClick" | "onCameraChange", + hook: "onNodeEnter" | "onNodeLeave" | "onNodeClick" | "onEdgeClick" | "onStageClick" | "onCameraChange", ...args: unknown[] ) => { const context = getBehaviorContext(); @@ -1194,9 +729,17 @@ export const GraphCanvas = forwardRef( }, [behaviors, getBehaviorContext]); useImperativeHandle(ref, () => ({ - getSigma: () => sigmaRef.current, fitView: () => dispatchAction({ type: "fitView" }), focusNode: (nodeId: string) => dispatchAction({ type: "focusNode", nodeId }), + requestRender: () => sigmaRef.current?.scheduleRefresh(), + getCameraState: () => { + const sigma = sigmaRef.current; + if (!sigma) { + return null; + } + const state = sigma.getCamera().getState(); + return { x: state.x, y: state.y, ratio: state.ratio }; + }, }), [dispatchAction]); useEffect(() => { @@ -1204,12 +747,19 @@ export const GraphCanvas = forwardRef( const sigma = new Sigma(displayGraph, containerRef.current, SIGMA_SETTINGS); sigmaRef.current = sigma; - onPluginRuntimeChange?.({ - sigma, + const camera = sigma.getCamera(); + const runtime: GraphSceneRuntime = { + renderer: "sigma", + scene: sigma, graph, displayGraph, - }); - const camera = sigma.getCamera(); + requestRender: () => sigma.scheduleRefresh(), + getCameraState: () => { + const state = camera.getState(); + return { x: state.x, y: state.y, ratio: state.ratio }; + }, + }; + onSceneRuntimeChange?.(runtime); const context = getBehaviorContext(sigma); if (context) { @@ -1226,21 +776,49 @@ export const GraphCanvas = forwardRef( }; const nextTier = getZoomTier(cameraState.ratio); setZoomTier((current) => (current === nextTier ? current : nextTier)); + onCameraStateChange?.(cameraState); dispatchToBehaviors("onCameraChange", cameraState); }; const resizeObserver = new ResizeObserver(() => { if (containerRef.current && containerRef.current.offsetWidth > 0) { - sigma.refresh(); + sigma.scheduleRefresh(); } }); resizeObserver.observe(containerRef.current); camera.on("updated", syncTier); sigma.on("clickNode", ({ node }) => dispatchToBehaviors("onNodeClick", node)); + sigma.on("clickEdge", ({ edge }) => { + const [source, target] = displayGraph.extremities(edge); + const stableEdgeId = String(edge); + const attrs = displayGraph.getEdgeAttributes(edge) as EdgeAttributes; + + if (isEdgeInteractable(displayGraph, interactionStateRef.current, stableEdgeId, source, target, attrs)) { + dispatchToBehaviors("onEdgeClick", stableEdgeId); + } + }); sigma.on("clickStage", () => dispatchToBehaviors("onStageClick")); sigma.on("enterNode", ({ node }) => dispatchToBehaviors("onNodeEnter", node)); sigma.on("leaveNode", ({ node }) => dispatchToBehaviors("onNodeLeave", node)); + sigma.on("enterEdge", ({ edge }) => { + const container = containerRef.current; + if (!container) { + return; + } + + const [source, target] = displayGraph.extremities(edge); + const stableEdgeId = String(edge); + const attrs = displayGraph.getEdgeAttributes(edge) as EdgeAttributes; + container.style.cursor = isEdgeInteractable(displayGraph, interactionStateRef.current, stableEdgeId, source, target, attrs) + ? "pointer" + : ""; + }); + sigma.on("leaveEdge", () => { + if (containerRef.current) { + containerRef.current.style.cursor = ""; + } + }); requestAnimationFrame(() => { syncTier(); @@ -1255,12 +833,15 @@ export const GraphCanvas = forwardRef( } camera.off("updated", syncTier); resizeObserver.disconnect(); + if (containerRef.current) { + containerRef.current.style.cursor = ""; + } sigma.kill(); behaviorContextRef.current = null; sigmaRef.current = null; - onPluginRuntimeChange?.(null); + onSceneRuntimeChange?.(null); }; - }, [behaviors, dispatchAction, dispatchToBehaviors, displayGraph, getBehaviorContext, onPluginRuntimeChange]); + }, [behaviors, dispatchAction, dispatchToBehaviors, displayGraph, getBehaviorContext, onCameraStateChange, onSceneRuntimeChange]); useEffect(() => { const context = getBehaviorContext(); @@ -1278,6 +859,32 @@ export const GraphCanvas = forwardRef( onInteractionStateChange?.(interactionState); }, [behaviors, getBehaviorContext, interactionState, onInteractionStateChange]); + useEffect(() => { + const sigma = sigmaRef.current; + const container = containerRef.current; + if (!sigma || !container) { + setAnalyticsSnapshot(null); + onAnalyticsChange?.(null); + return; + } + + const visibleNodes = collectVisibleNodeSamples( + sigma, + displayGraph, + container.clientWidth, + container.clientHeight, + ).map((sample) => sample.nodeId); + + const analytics = buildGraphAnalyticsSnapshot({ + graphRef: displayGraph, + interactionState, + base: analyticsBase, + visibleNodeIds: visibleNodes, + }); + setAnalyticsSnapshot(analytics); + onAnalyticsChange?.(analytics); + }, [analyticsBase, displayGraph, interactionState, onAnalyticsChange]); + useEffect(() => { if (!onDiagnosticsChange) { return; @@ -1288,20 +895,33 @@ export const GraphCanvas = forwardRef( const availability = buildEffectAvailability( interactionState, effectsState, + temporalState, + analyticsSnapshot, sigma, container?.clientWidth ?? 0, container?.clientHeight ?? 0, ); onDiagnosticsChange(availability); - }, [effectsState, interactionState, onDiagnosticsChange]); + }, [analyticsSnapshot, effectsState, interactionState, onDiagnosticsChange, temporalState]); + + useEffect(() => { + previousInteractionStateRef.current = null; + }, [displayGraph]); useEffect(() => { const sigma = sigmaRef.current; - if (!sigma || displayGraph !== graph) { + if (!sigma) { return; } - applySceneState(sigma, interactionState); - }, [displayGraph, interactionState]); + + const previousInteractionState = previousInteractionStateRef.current; + const refreshTargets = previousInteractionState + ? collectInteractionRefreshTargets(displayGraph, previousInteractionState, interactionState) + : undefined; + + applySceneState(sigma, displayGraph, interactionState, analyticsSnapshot, refreshTargets); + previousInteractionStateRef.current = interactionState; + }, [analyticsSnapshot, displayGraph, interactionState]); useEffect(() => { const sigma = sigmaRef.current; @@ -1334,28 +954,61 @@ export const GraphCanvas = forwardRef( const primaryNodeId = interactionState.hoveredNodeId || interactionState.selectedNodeId; const focusIds = primaryNodeId && graph.hasNode(primaryNodeId) ? buildFocusSet(primaryNodeId) : new Set(); + const edgeEndpointIds = buildEdgeEndpointSet(displayGraph, interactionState.selectedEdgeId); const pathNodeIds = new Set(interactionState.activePath); - const pathSegments = collectPathSegments(sigma, interactionState.activePath, interactionState.zoomTier, rect.width, rect.height); + const pathSegments = collectPathSegments( + sigma, + interactionState.activePath, + interactionState.activePathEdgeIds, + interactionState.zoomTier, + rect.width, + rect.height, + ); + const visibleNodeSamples = collectVisibleNodeSamples(sigma, displayGraph, rect.width, rect.height); const effectAvailability = buildEffectAvailability( interactionState, effectsState, + temporalState, + analyticsSnapshot, sigma, rect.width, rect.height, ); + const cameraRatio = sigma.getCamera().getState().ratio; const nodesToDecorate = new Set([ ...focusIds, + ...edgeEndpointIds, ...pathNodeIds, ...(primaryNodeId ? [primaryNodeId] : []), ]); const now = performance.now() / 1000; + drawContourLayer(context, analyticsSnapshot, visibleNodeSamples, interactionState, effectsState); + drawSemanticRegionsLayer(context, analyticsSnapshot, visibleNodeSamples, interactionState, effectsState); + drawTemporalEmphasisLayer(context, visibleNodeSamples, temporalState, interactionState, effectsState); + nodesToDecorate.forEach((nodeId) => { const displayData = sigma.getNodeDisplayData(nodeId); if (!displayData) return; const attrs = graph.getNodeAttributes(nodeId) as NodeAttributes; - const state = resolveNodeVisualState(nodeId, interactionState.hoveredNodeId, interactionState.selectedNodeId, focusIds, pathNodeIds); - const style = resolveNodeElementStyle(GRAPH_THEME, interactionState.zoomTier, state, attrs, attrs.label); + const state = resolveNodeVisualState( + nodeId, + interactionState.zoomTier, + interactionState.hoveredNodeId, + interactionState.selectedNodeId, + interactionState.selectedEdgeId, + focusIds, + edgeEndpointIds, + pathNodeIds, + ); + const style = resolveNodeElementStyle( + GRAPH_THEME, + interactionState.zoomTier, + state, + attrs, + attrs.label, + cameraRatio, + ); const point = sigma.graphToViewport({ x: displayData.x, y: displayData.y }); if (style.showHalo) { const radius = Math.max( @@ -1374,94 +1027,16 @@ export const GraphCanvas = forwardRef( ); } - if (style.showRing) { - drawNodeRing( - context, - point.x, - point.y, - displayData.size, - style.ringColor || GRAPH_THEME.nodes.selectedRing.color, - GRAPH_THEME.nodes.selectedRing.width, - GRAPH_THEME.nodes.selectedRing.glowAlpha, - ); - } - if (style.showBadge && style.badgeKind) { drawNodeBadge(context, point.x, point.y, displayData.size, style.badgeKind, style.badgeCount); } }); if (primaryNodeId && effectAvailability.lens.available) { - drawNeighborhoodLensOverlay(context, sigma, primaryNodeId, focusIds); + drawLensLayer(context, sigma, primaryNodeId, focusIds); } - if (GRAPH_THEME.zoomTiers[interactionState.zoomTier].showCurves && primaryNodeId) { - const drawnPairs = new Set(); - focusIds.forEach((sourceId) => { - focusIds.forEach((targetId) => { - if (sourceId >= targetId) { - return; - } - if (!graph.hasDirectedEdge(sourceId, targetId) || !graph.hasDirectedEdge(targetId, sourceId)) { - return; - } - - const pairKey = [sourceId, targetId].sort().join("::"); - if (drawnPairs.has(pairKey)) { - return; - } - drawnPairs.add(pairKey); - - const sourceData = sigma.getNodeDisplayData(sourceId); - const targetData = sigma.getNodeDisplayData(targetId); - if (!sourceData || !targetData) { - return; - } - - const attrs = graph.getDirectedEdgeAttributes(sourceId, targetId) as EdgeAttributes; - const state: GraphEdgeVisualState = - sourceId === primaryNodeId || targetId === primaryNodeId - ? interactionState.hoveredNodeId ? "hovered" : "selected" - : "neighbor"; - const style = resolveEdgeElementStyle(GRAPH_THEME, interactionState.zoomTier, state, attrs); - if (!style.drawCurvedOverlay || !style.color || !style.size) { - return; - } - - drawCurvedEdge( - context, - sigma.graphToViewport({ x: sourceData.x, y: sourceData.y }), - sigma.graphToViewport({ x: targetData.x, y: targetData.y }), - style.color, - Math.max(style.size, GRAPH_THEME.overlays.curveLineWidth), - style.curveStrength, - GRAPH_THEME.edges.variants.bidirectionalCurve.glowAlpha, - ); - }); - }); - } - - if (pathSegments.length > 0) { - pathSegments.forEach((segment) => { - drawCurvedEdge( - context, - segment.source, - segment.target, - segment.color, - Math.max(segment.size, GRAPH_THEME.overlays.curveLineWidth + 0.4), - segment.curveStrength, - GRAPH_THEME.edges.variants.pathSignal.glowAlpha, - ); - }); - } - - if (effectAvailability.pathFlow.available) { - drawPathFlowAccentOverlay(context, pathSegments, now); - } - - if (effectAvailability.pathPulse.available) { - drawPathPulseOverlay(context, pathSegments, now); - } + drawPathEffectsLayer(context, pathSegments, effectsState, effectAvailability, now); frame = window.requestAnimationFrame(draw); }; @@ -1470,7 +1045,7 @@ export const GraphCanvas = forwardRef( return () => { window.cancelAnimationFrame(frame); }; - }, [effectsState, interactionState]); + }, [analyticsSnapshot, displayGraph, effectsState, interactionState, temporalState]); useEffect(() => { if (selectedNodeId || isFocusedView) { diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/GraphInspectorPanel.tsx b/semantica-explorer/src/workspaces/GraphWorkspace/GraphInspectorPanel.tsx index 74feac41..c7150ac4 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/GraphInspectorPanel.tsx +++ b/semantica-explorer/src/workspaces/GraphWorkspace/GraphInspectorPanel.tsx @@ -12,6 +12,7 @@ export type LinkPrediction = { export type PathResponse = { path: string[]; + edge_ids?: string[]; total_weight: number; }; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/GraphLoadingOverlay.tsx b/semantica-explorer/src/workspaces/GraphWorkspace/GraphLoadingOverlay.tsx new file mode 100644 index 00000000..77a94130 --- /dev/null +++ b/semantica-explorer/src/workspaces/GraphWorkspace/GraphLoadingOverlay.tsx @@ -0,0 +1,315 @@ +import { useEffect, useRef, useState, type CSSProperties } from "react"; + +import { GRAPH_THEME, withAlpha } from "./graphTheme"; +import { GRAPH_LOAD_STAGE_SEQUENCE, createGraphLoadProgress, getGraphLoadStageLabel } from "./graphLoading"; +import type { GraphLoadProgress } from "./types"; + +const LOADING_OVERLAY_CSS = ` + .graph-stage-loader { + position: absolute; + inset: 0; + z-index: 9; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; + opacity: 1; + transition: opacity 220ms ease, transform 220ms ease; + } + .graph-stage-loader[data-exiting="true"] { + opacity: 0; + transform: scale(0.985); + } + .graph-stage-loader-card { + width: min(540px, calc(100% - 48px)); + border-radius: 24px; + padding: 20px 20px 18px; + border: 1px solid rgba(127, 208, 255, 0.18); + background: + radial-gradient(circle at top right, rgba(242, 182, 109, 0.12), transparent 28%), + radial-gradient(circle at top left, rgba(127, 208, 255, 0.14), transparent 30%), + linear-gradient(145deg, rgba(7, 17, 31, 0.94), rgba(12, 25, 43, 0.82)); + box-shadow: 0 26px 90px rgba(0, 0, 0, 0.34), inset 0 1px 0 rgba(255,255,255,0.05); + backdrop-filter: blur(18px) saturate(1.08); + -webkit-backdrop-filter: blur(18px) saturate(1.08); + } + .graph-stage-loader-card[data-live="true"] { + width: min(500px, calc(100% - 56px)); + background: + radial-gradient(circle at top right, rgba(242, 182, 109, 0.08), transparent 26%), + radial-gradient(circle at top left, rgba(127, 208, 255, 0.12), transparent 28%), + linear-gradient(145deg, rgba(7, 17, 31, 0.84), rgba(11, 24, 40, 0.72)); + box-shadow: 0 18px 54px rgba(0, 0, 0, 0.26), inset 0 1px 0 rgba(255,255,255,0.04); + } + .graph-stage-loader-beacon { + position: relative; + width: 12px; + height: 12px; + border-radius: 999px; + background: linear-gradient(135deg, rgba(127, 208, 255, 0.98), rgba(242, 182, 109, 0.94)); + box-shadow: 0 0 18px rgba(127, 208, 255, 0.4); + } + .graph-stage-loader-beacon::after { + content: ""; + position: absolute; + inset: -7px; + border-radius: inherit; + border: 1px solid rgba(127, 208, 255, 0.18); + animation: graph-loader-beacon 1.9s ease-out infinite; + } + .graph-stage-loader-track { + display: grid; + grid-template-columns: repeat(6, minmax(0, 1fr)); + gap: 8px; + } + .graph-stage-loader-step { + border-radius: 999px; + padding: 7px 0; + text-align: center; + font-size: 10px; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + border: 1px solid rgba(127, 208, 255, 0.08); + color: rgba(143, 168, 198, 0.72); + background: rgba(255, 255, 255, 0.02); + } + .graph-stage-loader-step[data-state="done"] { + color: rgba(214, 232, 250, 0.92); + border-color: rgba(127, 208, 255, 0.18); + background: rgba(89, 155, 220, 0.14); + } + .graph-stage-loader-step[data-state="active"] { + color: #eff7ff; + border-color: rgba(242, 182, 109, 0.24); + background: linear-gradient(135deg, rgba(49, 108, 172, 0.28), rgba(242, 182, 109, 0.16)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06); + } + .graph-stage-loader-bar { + position: relative; + width: 100%; + height: 12px; + overflow: hidden; + border-radius: 999px; + border: 1px solid rgba(127, 208, 255, 0.1); + background: rgba(255, 255, 255, 0.05); + } + .graph-stage-loader-bar-fill { + display: block; + height: 100%; + border-radius: inherit; + background: linear-gradient(90deg, rgba(74, 163, 255, 0.9), rgba(127, 208, 255, 0.96), rgba(242, 182, 109, 0.92)); + box-shadow: 0 0 30px rgba(74, 163, 255, 0.28); + transition: width 220ms ease; + } + .graph-stage-loader-bar-indeterminate::before { + content: ""; + position: absolute; + top: 1px; + bottom: 1px; + width: 34%; + border-radius: 999px; + background: linear-gradient(90deg, rgba(74, 163, 255, 0), rgba(127, 208, 255, 0.94), rgba(242, 182, 109, 0.82), rgba(74, 163, 255, 0)); + box-shadow: 0 0 26px rgba(127, 208, 255, 0.18); + animation: graph-loader-sweep 1.5s cubic-bezier(0.22, 1, 0.36, 1) infinite; + } + @keyframes graph-loader-beacon { + 0% { transform: scale(0.72); opacity: 0.6; } + 100% { transform: scale(1.44); opacity: 0; } + } + @keyframes graph-loader-sweep { + 0% { transform: translateX(-120%); } + 100% { transform: translateX(360%); } + } +`; + +function formatLayoutSource(source: GraphLoadProgress["layoutSource"]) { + switch (source) { + case "provided": + return "Persisted layout"; + case "carried": + return "Preserved layout"; + case "runtime": + return "Runtime layout"; + default: + return null; + } +} + +function formatLayoutState(state: GraphLoadProgress["layoutState"]) { + switch (state) { + case "bootstrapping": + return "Bootstrapping"; + case "running": + return "Settling"; + case "interactive": + return "Interactive"; + case "stabilized": + return "Stable"; + case "failed": + return "Fallback"; + default: + return null; + } +} + +const loadingMetricStyle = { + display: "inline-flex", + alignItems: "center", + gap: 6, + padding: "7px 10px", + borderRadius: 999, + border: "1px solid rgba(127, 208, 255, 0.12)", + background: "rgba(255, 255, 255, 0.03)", + color: "#b8cade", + fontSize: 11, + fontWeight: 600, +} satisfies CSSProperties; + +export function GraphLoadingOverlay({ + progress, + visible, + showGraphBehind, +}: { + progress: GraphLoadProgress | null; + visible: boolean; + showGraphBehind: boolean; +}) { + const [renderVisible, setRenderVisible] = useState(visible); + const [exiting, setExiting] = useState(false); + const [displayProgress, setDisplayProgress] = useState( + progress ?? createGraphLoadProgress({ + phase: "bootstrapping", + message: "Preparing graph session", + progressKind: "indeterminate", + }), + ); + const exitTimerRef = useRef(null); + + useEffect(() => { + if (progress) { + setDisplayProgress(progress); + } + }, [progress]); + + useEffect(() => { + if (visible) { + if (exitTimerRef.current !== null) { + window.clearTimeout(exitTimerRef.current); + exitTimerRef.current = null; + } + setRenderVisible(true); + setExiting(false); + return; + } + + if (!renderVisible) { + return; + } + + setExiting(true); + exitTimerRef.current = window.setTimeout(() => { + setRenderVisible(false); + setExiting(false); + exitTimerRef.current = null; + }, 220); + + return () => { + if (exitTimerRef.current !== null) { + window.clearTimeout(exitTimerRef.current); + exitTimerRef.current = null; + } + }; + }, [renderVisible, visible]); + + if (!renderVisible) { + return null; + } + + const activeProgress = progress ?? displayProgress; + const isLiveStage = activeProgress.phase === "stabilizing_layout" || activeProgress.showGraphBehind || showGraphBehind; + const overlayBackground = isLiveStage + ? "linear-gradient(180deg, rgba(1,4,9,0.04), rgba(1,4,9,0.18))" + : "linear-gradient(180deg, rgba(1,4,9,0.22), rgba(1,4,9,0.5))"; + const determinateRatio = activeProgress.progressKind === "determinate" && activeProgress.total + ? Math.max(0.05, Math.min(activeProgress.loaded ?? 0, activeProgress.total) / Math.max(activeProgress.total, 1)) + : null; + const layoutSource = formatLayoutSource(activeProgress.layoutSource); + const layoutState = formatLayoutState(activeProgress.layoutState); + + return ( +
+ +
+
+
+
+ {activeProgress.title} +
+
+ {activeProgress.message} +
+
+
+ +
+ +
+ {GRAPH_LOAD_STAGE_SEQUENCE.map((phase, index) => { + const current = activeProgress.stageIndex ?? 1; + const state = index + 1 < current ? "done" : index + 1 === current ? "active" : "upcoming"; + return ( +
+ {getGraphLoadStageLabel(phase)} +
+ ); + })} +
+ +
+
+ {activeProgress.progressKind === "determinate" && activeProgress.total + ? `${(activeProgress.loaded ?? 0).toLocaleString()} / ${activeProgress.total.toLocaleString()} in current stage` + : "Working through this stage"} +
+
+ {activeProgress.progressKind === "determinate" && determinateRatio !== null + ? `${Math.round(determinateRatio * 100)}%` + : "Live"} +
+
+ +
+ {activeProgress.progressKind === "determinate" && determinateRatio !== null ? ( + + ) : null} +
+ +
+ + {activeProgress.nodesLoaded.toLocaleString()} + {activeProgress.nodesTotal ? ` / ${activeProgress.nodesTotal.toLocaleString()}` : ""} nodes + + + {activeProgress.edgesLoaded.toLocaleString()} + {activeProgress.edgesTotal ? ` / ${activeProgress.edgesTotal.toLocaleString()}` : ""} relationships + + {layoutSource ? ( + + {layoutSource} + {layoutState ? ` · ${layoutState}` : ""} + + ) : null} +
+
+
+ ); +} diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/GraphRuntimeStage.tsx b/semantica-explorer/src/workspaces/GraphWorkspace/GraphRuntimeStage.tsx index 7cad3167..f1dac367 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/GraphRuntimeStage.tsx +++ b/semantica-explorer/src/workspaces/GraphWorkspace/GraphRuntimeStage.tsx @@ -1,8 +1,8 @@ import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react"; import { batchMergeEdges, batchMergeNodes, clearGraph, graph, type EdgeAttributes, type NodeAttributes } from "../../store/graphStore"; -import { GraphCanvas } from "./GraphCanvas"; -import type { GraphCanvasHandle } from "./GraphCanvas"; +import { SigmaSceneAdapter } from "./SigmaSceneAdapter"; +import { createGraphLoadProgress } from "./graphLoading"; import { chooseColorAccessor, colorForNodeKey, @@ -13,6 +13,7 @@ import { deterministicPosition, } from "./graphAnalytics"; import { GRAPH_THEME } from "./graphConfig"; +import type { GraphSceneHandle } from "./scene"; import type { GraphDataSnapshot, GraphEffectsState, @@ -29,6 +30,12 @@ const STAGE_EFFECTS_STATE: GraphEffectsState = { pathPulseEnabled: false, pathFlowEnabled: false, lensEnabled: false, + temporalEmphasisEnabled: false, + semanticRegionsEnabled: false, + contoursEnabled: false, + pathfindingEnabled: false, + communitiesEnabled: false, + centralityEnabled: false, legendEnabled: false, diagnosticsEnabled: false, lensMode: "neighborhood", @@ -102,7 +109,7 @@ export const GraphRuntimeStage = forwardRef(null); + const sceneRef = useRef(null); const prevActiveIdsRef = useRef>(new Set()); const [graphVersion, setGraphVersion] = useState(0); const [runtimeLayoutSource, setRuntimeLayoutSource] = useState(snapshot?.summary.layoutSource ?? "runtime"); @@ -110,8 +117,8 @@ export const GraphRuntimeStage = forwardRef (snapshot ? `${snapshot.fetchedAt}:${snapshot.summary.nodeCount}:${snapshot.summary.edgeCount}` : null), [snapshot]); useImperativeHandle(ref, () => ({ - fitView: () => canvasRef.current?.fitView(), - focusNode: (nodeId: string) => canvasRef.current?.focusNode(nodeId), + fitView: () => sceneRef.current?.fitView(), + focusNode: (nodeId: string) => sceneRef.current?.focusNode(nodeId), }), []); useEffect(() => { @@ -122,15 +129,16 @@ export const GraphRuntimeStage = forwardRef { const colorKey = colorAccessor(id, attributes); @@ -223,9 +232,15 @@ export const GraphRuntimeStage = forwardRef ({ + id: edge.id, + familyId: edge.familyId, source: edge.source, target: edge.target, attributes: { + edgeId: edge.id, + familyId: edge.familyId, + sourceId: edge.source, + targetId: edge.target, weight: edge.weight, edgeType: edge.type, properties: edge.properties, @@ -258,23 +273,26 @@ export const GraphRuntimeStage = forwardRef current + 1); if (layoutSource !== "runtime") { onProgressChange(null); } else { - onProgressChange({ - phase: "rendering", + onProgressChange(createGraphLoadProgress({ + phase: "stabilizing_layout", + progressKind: "indeterminate", nodesLoaded: snapshot.summary.nodeCount, nodesTotal: snapshot.summary.nodeCount, edgesLoaded: snapshot.summary.edgeCount, edgesTotal: snapshot.summary.edgeCount, - message: "Stabilizing full-graph layout", - progress: 0.98, - }); + message: "Settling runtime layout", + showGraphBehind: true, + layoutSource, + layoutState: "bootstrapping", + })); } onRuntimeReady(); } @@ -333,7 +351,7 @@ export const GraphRuntimeStage = forwardRef current + 1); } catch (error) { console.error("[GraphRuntimeStage] websocket update failed", error); @@ -420,9 +444,10 @@ export const GraphRuntimeStage = forwardRef import("./TimelinePanel").then((module) => ({ default: module.TimelinePanel }))); const LazyGraphInspectorPanel = lazy(() => import("./GraphInspectorPanel").then((module) => ({ default: module.GraphInspectorPanel }))); -const loadExplorationEffectsPlugin = () => import("./plugins/explorationEffectsPlugin").then((module) => module.explorationEffectsPlugin); +const loadExplorationEffectsPlugin = () => import("./plugins/explorationEffectsPluginPhaseC").then((module) => module.explorationEffectsPluginPhaseC); const loadNeighborhoodPanelPlugin = () => import("./plugins/neighborhoodPanelPlugin").then((module) => module.neighborhoodPanelPlugin); const loadTemporalOverlayPlugin = () => import("./plugins/temporalOverlayPlugin").then((module) => module.temporalOverlayPlugin); @@ -391,83 +402,6 @@ const HUD_CSS = ` } `; -function phaseLabel(phase: GraphLoadProgress["phase"]) { - switch (phase) { - case "nodes": - return "Loading nodes"; - case "edges": - return "Loading edges"; - case "styling": - return "Computing layout and styling"; - case "rendering": - return "Rendering graph"; - default: - return "Loading graph"; - } -} - -function LoadingOverlay({ - progress, - showGraphBehind, -}: { - progress: GraphLoadProgress | null; - showGraphBehind: boolean; -}) { - const safeProgress = progress ?? { - phase: "nodes" as const, - nodesLoaded: 0, - nodesTotal: null, - edgesLoaded: 0, - edgesTotal: null, - message: "Preparing graph load", - progress: 0.06, - }; - - return ( -
-
-
-
-
Loading Graph
-
{phaseLabel(safeProgress.phase)}
-
- -
- -
- {safeProgress.message} -
- -
- -
- -
- - {safeProgress.nodesLoaded.toLocaleString()} - {safeProgress.nodesTotal ? ` / ${safeProgress.nodesTotal.toLocaleString()}` : ""} nodes - - - {safeProgress.edgesLoaded.toLocaleString()} - {safeProgress.edgesTotal ? ` / ${safeProgress.edgesTotal.toLocaleString()}` : ""} edges - -
-
-
- ); -} - function getProvenanceCount(properties: Record) { return PROVENANCE_KEYS.reduce( (count, key) => (properties[key] !== undefined && properties[key] !== null ? count + 1 : count), @@ -518,6 +452,8 @@ function buildRealtimeNodeAttributes(payload: { } function buildRealtimeEdgeAttributes(payload: { + id: string; + familyId?: string; source_id: string; target_id: string; type?: string; @@ -530,6 +466,10 @@ function buildRealtimeEdgeAttributes(payload: { const baseColor = isInferred ? GRAPH_THEME.palette.accent.path : GRAPH_THEME.palette.muted.edgeStructure; return { + edgeId: payload.id, + familyId: payload.familyId || payload.id, + sourceId: payload.source_id, + targetId: payload.target_id, weight: Number(payload.weight ?? 1), edgeType: payload.type || "related_to", properties, @@ -541,7 +481,7 @@ function buildRealtimeEdgeAttributes(payload: { visualPriority: isInferred ? 0.95 : 0.5, isBidirectional, edgeFamily: isInferred ? "path" : isBidirectional ? "bidirectional" : "line", - curveGroup: isBidirectional ? [payload.source_id, payload.target_id].sort().join("::") : null, + curveGroup: isBidirectional ? curveGroupForPair(payload.source_id, payload.target_id) : null, type: "line", edgeVariant: isInferred ? "pathSignal" : isBidirectional ? "bidirectionalCurve" : "directional", arrowVisibilityPolicy: isInferred ? "always" : "contextual", @@ -549,6 +489,7 @@ function buildRealtimeEdgeAttributes(payload: { isParallelPair: false, parallelIndex: 0, parallelCount: 1, + familySize: 1, }; } @@ -580,6 +521,51 @@ function buildSelectedNodeState(nodeId: string): GraphSelectedNodeState | null { }; } +function buildSelectedEdgeState(edgeId: string): GraphSelectedEdgeState | null { + if (!edgeId || !graph.hasEdge(edgeId)) { + return null; + } + + const [sourceId, targetId] = graph.extremities(edgeId); + const attributes = graph.getEdgeAttributes(edgeId) as { + edgeType?: string; + weight?: number; + properties?: Record; + familyId?: string; + }; + const sourceAttributes = graph.getNodeAttributes(sourceId) as { label?: string; content?: string }; + const targetAttributes = graph.getNodeAttributes(targetId) as { label?: string; content?: string }; + const properties = attributes.properties ?? {}; + const familyId = String(attributes.familyId || edgeId); + let familySize = 0; + let siblingCount = 0; + graph.forEachEdge((candidateEdgeId, candidateAttrs) => { + const edgeAttrs = candidateAttrs as { familyId?: string }; + const [candidateSource, candidateTarget] = graph.extremities(candidateEdgeId); + if (String(edgeAttrs.familyId || candidateEdgeId) === familyId) { + familySize += 1; + } + if (candidateSource === sourceId && candidateTarget === targetId) { + siblingCount += 1; + } + }); + + return { + id: edgeId, + familyId, + sourceId, + sourceLabel: String(sourceAttributes.label ?? sourceAttributes.content ?? sourceId), + targetId, + targetLabel: String(targetAttributes.label ?? targetAttributes.content ?? targetId), + edgeType: String(attributes.edgeType ?? "related_to"), + weight: Number(attributes.weight ?? 1), + properties, + provenanceCount: getProvenanceCount(properties), + familySize, + siblingCount, + }; +} + function collectPluginPanels( plugins: GraphPlugin[], context: GraphPluginContext, @@ -637,6 +623,7 @@ function collectPluginOverlays( export function GraphWorkspace() { const [selectedNodeId, setSelectedNodeId] = useState(""); + const [selectedEdgeId, setSelectedEdgeId] = useState(""); const [isLayoutRunning, setIsLayoutRunning] = useState(false); const [viewMode, setViewMode] = useState("focused"); const [searchQuery, setSearchQuery] = useState(""); @@ -659,17 +646,21 @@ export function GraphWorkspace() { const [pluginRuntimeVersion, setPluginRuntimeVersion] = useState(0); const [effectsState, setEffectsState] = useState(DEFAULT_EFFECTS_STATE); const [graphDiagnosticsState, setGraphDiagnosticsState] = useState(null); + const [graphAnalyticsState, setGraphAnalyticsState] = useState(null); const [loadedPlugins, setLoadedPlugins] = useState>({}); const debouncedTime = useDebounce(scrubberTime, 150); const prevActiveIdsRef = useRef>(new Set()); - const canvasRef = useRef(null); - const pluginRuntimeRef = useRef(null); + const sceneRef = useRef(null); + const pluginRuntimeRef = useRef(null); + const settlingOverlayTimeoutRef = useRef(null); const pluginInteractionStateRef = useRef({ hoveredNodeId: null, selectedNodeId: "", + selectedEdgeId: "", focusedNodeId: "", activePath: [], + activePathEdgeIds: [], viewMode: "focused", zoomTier: "overview", isLayoutRunning: false, @@ -678,13 +669,46 @@ export function GraphWorkspace() { const { data: summary, isLoading, isFetching } = useLoadGraph({ enabled: true, - onGraphReady: () => { - setIsLayoutRunning(true); - setLoadingProgress(null); + onGraphReady: (graphSummary) => { + setIsLayoutRunning(!graphSummary.layoutReady); + if (settlingOverlayTimeoutRef.current !== null) { + window.clearTimeout(settlingOverlayTimeoutRef.current); + settlingOverlayTimeoutRef.current = null; + } + + if (graphSummary.layoutReady) { + setLoadingProgress(null); + return; + } + + setLoadingProgress(createGraphLoadProgress({ + phase: "stabilizing_layout", + progressKind: "indeterminate", + nodesLoaded: graphSummary.nodeCount, + nodesTotal: graphSummary.nodeCount, + edgesLoaded: graphSummary.edgeCount, + edgesTotal: graphSummary.edgeCount, + message: "Settling runtime layout", + showGraphBehind: true, + layoutSource: graphSummary.layoutSource, + layoutState: "bootstrapping", + })); + settlingOverlayTimeoutRef.current = window.setTimeout(() => { + setLoadingProgress((current) => (current?.phase === "stabilizing_layout" ? null : current)); + settlingOverlayTimeoutRef.current = null; + }, 900); }, onProgress: setLoadingProgress, }); + useEffect(() => { + return () => { + if (settlingOverlayTimeoutRef.current !== null) { + window.clearTimeout(settlingOverlayTimeoutRef.current); + } + }; + }, []); + useEffect(() => { let cancelled = false; const loadBounds = async () => { @@ -736,7 +760,7 @@ export function GraphWorkspace() { }); prevActiveIdsRef.current = nextActiveIds; setActiveNodeCount(data.active_node_count); - canvasRef.current?.getSigma()?.refresh(); + sceneRef.current?.getRuntime()?.requestRender(); }); } catch (fetchError) { if (!cancelled) { @@ -753,6 +777,7 @@ export function GraphWorkspace() { const focusNode = useCallback((nodeId: string) => { setSelectedNodeId(nodeId); + setSelectedEdgeId(""); setPathResult(null); setSearchResults([]); setSearchError(""); @@ -761,6 +786,10 @@ export function GraphWorkspace() { } }, []); + const handleEdgeSelect = useCallback((edgeId: string) => { + setSelectedEdgeId(edgeId); + }, []); + const handleSearch = useCallback(async () => { if (!searchQuery.trim()) { setSearchResults([]); @@ -821,7 +850,7 @@ export function GraphWorkspace() { if (data.path?.length) { const lastStep = data.path[data.path.length - 1]; if (graph.hasNode(lastStep)) { - canvasRef.current?.focusNode(lastStep); + sceneRef.current?.focusNode(lastStep); } } } catch (pathError) { @@ -870,17 +899,19 @@ export function GraphWorkspace() { attributes: buildRealtimeNodeAttributes(payload), }, ]); - canvasRef.current?.getSigma()?.refresh(); + sceneRef.current?.getRuntime()?.requestRender(); } if (eventType === "ADD_EDGE") { batchMergeEdges([ { + id: String(payload.id), + familyId: payload.familyId ? String(payload.familyId) : String(payload.id), source: payload.source_id, target: payload.target_id, attributes: buildRealtimeEdgeAttributes(payload), }, ]); - canvasRef.current?.getSigma()?.refresh(); + sceneRef.current?.getRuntime()?.requestRender(); } } catch (socketError) { console.error("[GraphWorkspace] websocket update failed", socketError); @@ -906,14 +937,19 @@ export function GraphWorkspace() { return `${localNeighborCount} direct neighbors highlighted`; }, [selectedNodeId, viewMode]); - const showLoadingOverlay = isLoading || isFetching; + const showLoadingOverlay = isLoading || isFetching || loadingProgress?.phase === "stabilizing_layout"; const hasGraphContent = Boolean(summary?.nodeCount); const activePath = pathResult?.path ?? []; + const activePathEdgeIds = pathResult?.edge_ids ?? []; const graphSummary = summary as GraphLoadSummary | null; const selectedNodeState = useMemo( () => buildSelectedNodeState(selectedNodeId), [selectedNodeId, summary?.nodeCount, summary?.edgeCount], ); + const selectedEdgeState = useMemo( + () => buildSelectedEdgeState(selectedEdgeId), + [selectedEdgeId, summary?.nodeCount, summary?.edgeCount], + ); const temporalState = useMemo( () => ({ currentTime: scrubberTime, @@ -1009,10 +1045,10 @@ export function GraphWorkspace() { const handlePluginAction = useCallback((action: GraphPluginActionRequest) => { switch (action.type) { case "fitView": - canvasRef.current?.fitView(); + sceneRef.current?.fitView(); return; case "focusNode": - canvasRef.current?.focusNode(action.nodeId); + sceneRef.current?.focusNode(action.nodeId); return; case "selectNode": focusNode(action.nodeId); @@ -1075,8 +1111,8 @@ export function GraphWorkspace() { }, [activePlugins, effectsState, graphDiagnosticsState, pluginPanelState]); const pluginContext = useMemo(() => ({ - get sigma() { - return pluginRuntimeRef.current?.sigma ?? null; + get scene() { + return pluginRuntimeRef.current; }, get graph() { return graph; @@ -1095,9 +1131,11 @@ export function GraphWorkspace() { getTemporalState: () => temporalState, getEffectsState: () => effectsState, getDiagnosticsSnapshot: () => diagnosticsSnapshot, + getAnalyticsSnapshot: () => graphAnalyticsState, isPanelOpen: (panelId: string) => Boolean(pluginPanelState[panelId]), dispatchAction: handlePluginAction, }), [ + graphAnalyticsState, diagnosticsSnapshot, effectsState, graphSummary, @@ -1108,8 +1146,11 @@ export function GraphWorkspace() { temporalState, ]); - const handlePluginRuntimeChange = useCallback((runtime: GraphPluginRuntime | null) => { + const handleSceneRuntimeChange = useCallback((runtime: GraphSceneRuntime | null) => { pluginRuntimeRef.current = runtime; + if (!runtime) { + setGraphAnalyticsState(null); + } setPluginRuntimeVersion((version) => version + 1); }, []); @@ -1131,6 +1172,10 @@ export function GraphWorkspace() { setGraphDiagnosticsState(effectAvailability); }, []); + const handleAnalyticsChange = useCallback((analytics: GraphAnalyticsSnapshot | null) => { + setGraphAnalyticsState(analytics); + }, []); + useEffect(() => { if (!pluginRuntimeRef.current) { return; @@ -1252,7 +1297,7 @@ export function GraphWorkspace() { id: "fit-view", label: "Fit View", title: "Reset the camera to the current view", - onClick: () => canvasRef.current?.fitView(), + onClick: () => sceneRef.current?.fitView(), }, { id: "layout-toggle", @@ -1288,6 +1333,25 @@ export function GraphWorkspace() { return groups; }, [isLayoutRunning, pluginToolbarItems, reload, searchQuery, selectedNodeId, showLoadingOverlay, viewMode]); + const sceneAdapterProps = { + onNodeSelect: focusNode, + onEdgeSelect: handleEdgeSelect, + selectedNodeId, + selectedEdgeId, + activePath, + activePathEdgeIds, + effectsState, + temporalState, + isLayoutRunning, + viewMode, + showFitViewButton: false, + pluginOverlays: pluginOverlays.map((overlay) => overlay.element), + onRuntimeChange: handleSceneRuntimeChange, + onInteractionStateChange: handleInteractionStateChange, + onDiagnosticsChange: handleDiagnosticsChange, + onAnalyticsChange: handleAnalyticsChange, + } as const; + return (
@@ -1301,7 +1365,7 @@ export function GraphWorkspace() {
{showLoadingOverlay && loadingProgress ? ( - {phaseLabel(loadingProgress.phase)} + {getGraphLoadTitle(loadingProgress.phase)} ) : null} {summary ? ( {summary.nodeCount.toLocaleString()} nodes · {summary.edgeCount.toLocaleString()} edges @@ -1377,6 +1441,61 @@ export function GraphWorkspace() { ))}
) : null} + + {selectedEdgeState ? ( +
+
+
+
+ Relationship +
+
+ {selectedEdgeState.edgeType} +
+
+ +
+ +
+ + + +
+ +
+ weight {selectedEdgeState.weight.toFixed(2)} + {selectedEdgeState.siblingCount} parallel lane{selectedEdgeState.siblingCount === 1 ? "" : "s"} + {selectedEdgeState.familySize} family member{selectedEdgeState.familySize === 1 ? "" : "s"} + {selectedEdgeState.provenanceCount > 0 ? ( + {selectedEdgeState.provenanceCount} provenance fields + ) : null} +
+ + {Object.keys(selectedEdgeState.properties).length ? ( +
+ {Object.entries(selectedEdgeState.properties).slice(0, 4).map(([key, value]) => ( +
+
+ {key} +
+
+ {typeof value === "object" ? JSON.stringify(value) : String(value)} +
+
+ ))} +
+ ) : null} +
+ ) : null}
@@ -1393,23 +1512,15 @@ export function GraphWorkspace() {
- overlay.element)} - onPluginRuntimeChange={handlePluginRuntimeChange} - onInteractionStateChange={handleInteractionStateChange} - onDiagnosticsChange={handleDiagnosticsChange} + + - {showLoadingOverlay ? ( - - ) : null}
@@ -1530,6 +1641,37 @@ const predictionCardStyle: React.CSSProperties = { cursor: "pointer", }; +const selectedEdgeCardStyle: React.CSSProperties = { + display: "flex", + flexDirection: "column", + gap: 12, + padding: 14, + background: "linear-gradient(135deg, rgba(88, 166, 255, 0.1), rgba(88, 166, 255, 0.04))", + border: "1px solid rgba(127, 208, 255, 0.16)", + borderRadius: 14, + boxShadow: "inset 0 1px 0 rgba(255,255,255,0.03)", +}; + +const selectedEdgeNodeChipStyle: React.CSSProperties = { + ...secondaryActionButtonStyle, + minHeight: 32, + padding: "7px 12px", + whiteSpace: "nowrap", +}; + +const selectedEdgePropertyGridStyle: React.CSSProperties = { + display: "grid", + gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", + gap: 8, +}; + +const selectedEdgePropertyCardStyle: React.CSSProperties = { + borderRadius: 10, + padding: 10, + background: "rgba(255, 255, 255, 0.03)", + border: "1px solid rgba(255, 255, 255, 0.06)", +}; + const pluginDockContentStyle: React.CSSProperties = { borderRadius: 16, border: "1px solid rgba(255, 255, 255, 0.06)", @@ -1567,12 +1709,3 @@ const timelineFallbackStyle: React.CSSProperties = { borderTop: "1px solid rgba(88, 166, 255, 0.2)", background: "rgba(1, 4, 9, 0.88)", }; - -const loadingMetricStyle: React.CSSProperties = { - background: "rgba(255, 255, 255, 0.04)", - color: "#cfe3ff", - padding: "6px 10px", - borderRadius: 999, - fontSize: 12, - border: "1px solid rgba(127, 208, 255, 0.12)", -}; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/GraphWorkspaceShell.tsx b/semantica-explorer/src/workspaces/GraphWorkspace/GraphWorkspaceShell.tsx index ddf757ff..7e32fcca 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/GraphWorkspaceShell.tsx +++ b/semantica-explorer/src/workspaces/GraphWorkspace/GraphWorkspaceShell.tsx @@ -1,5 +1,7 @@ import { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState, type CSSProperties } from "react"; +import { GraphLoadingOverlay } from "./GraphLoadingOverlay"; +import { getGraphLoadTitle } from "./graphLoading"; import { useGraphData, useReloadGraphData } from "./useGraphData"; import type { ApiNode, @@ -117,21 +119,6 @@ function useDebounce(value: T, delay: number): T { return debouncedValue; } -function phaseLabel(phase: GraphLoadProgress["phase"]) { - switch (phase) { - case "nodes": - return "Loading nodes"; - case "edges": - return "Loading edges"; - case "styling": - return "Computing layout and styling"; - case "rendering": - return "Rendering graph"; - default: - return "Loading graph"; - } -} - function sourceAttribution(properties: Record) { const keys = ["source", "source_url", "pmid", "pmids", "evidence", "provenance", "confidence"]; return keys @@ -153,86 +140,6 @@ function toSelectedNodeState(node: ApiNode, neighborCount: number, fallbackColor }; } -function LoadingOverlay({ progress }: { progress: GraphLoadProgress | null }) { - const safeProgress = progress ?? { - phase: "nodes" as const, - nodesLoaded: 0, - nodesTotal: null, - edgesLoaded: 0, - edgesTotal: null, - message: "Preparing graph load", - progress: 0.06, - }; - - return ( -
-
-
-
-
Loading Graph
-
{phaseLabel(safeProgress.phase)}
-
- -
- -
- {safeProgress.message} -
- -
- -
- -
- - {safeProgress.nodesLoaded.toLocaleString()} - {safeProgress.nodesTotal ? ` / ${safeProgress.nodesTotal.toLocaleString()}` : ""} nodes - - - {safeProgress.edgesLoaded.toLocaleString()} - {safeProgress.edgesTotal ? ` / ${safeProgress.edgesTotal.toLocaleString()}` : ""} edges - -
-
-
- ); -} - function TimelineFallback({ min, max }: TemporalBounds) { return (
- {showLoadingOverlay ? : null} +
}> @@ -703,7 +614,7 @@ export function GraphWorkspaceShell() {
Graph Studio
{visibleSelectedNode ? visibleSelectedNode.label : "Knowledge Explorer"}
- {showLoadingOverlay && loadingProgress ? {phaseLabel(loadingProgress.phase)} : null} + {showLoadingOverlay && loadingProgress ? {getGraphLoadTitle(loadingProgress.phase)} : null} {layoutStatusLabel ? {layoutStatusLabel} : null} {snapshot ? {snapshot.summary.nodeCount.toLocaleString()} nodes · {snapshot.summary.edgeCount.toLocaleString()} edges : null} {activeNodeCount !== null ? {activeNodeCount.toLocaleString()} active : null} @@ -891,24 +802,6 @@ const subtleChipStyle: CSSProperties = { border: "1px solid rgba(255, 255, 255, 0.06)", }; -const loadingMetricStyle: CSSProperties = { - background: "rgba(255, 255, 255, 0.04)", - color: "#cfe3ff", - padding: "6px 10px", - borderRadius: 999, - fontSize: 12, - border: "1px solid rgba(127, 208, 255, 0.12)", -}; - -const loadingDotStyle: CSSProperties = { - width: 10, - height: 10, - borderRadius: 999, - background: "linear-gradient(135deg, rgba(127, 208, 255, 0.96), rgba(242, 182, 109, 0.96))", - boxShadow: "0 0 18px rgba(127, 208, 255, 0.35)", - animation: "sem-loader-pulse 1.2s ease-in-out infinite", -}; - const collapseStyle: CSSProperties = { border: "1px solid rgba(255, 255, 255, 0.05)", borderRadius: 14, diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/SigmaSceneAdapter.tsx b/semantica-explorer/src/workspaces/GraphWorkspace/SigmaSceneAdapter.tsx new file mode 100644 index 00000000..8eb9c5de --- /dev/null +++ b/semantica-explorer/src/workspaces/GraphWorkspace/SigmaSceneAdapter.tsx @@ -0,0 +1,53 @@ +import { forwardRef, useImperativeHandle, useRef } from "react"; + +import { GraphCanvas, type GraphCanvasHandle } from "./GraphCanvas"; +import type { GraphSceneAdapter, GraphSceneHandle, GraphSceneProps, GraphSceneRuntime } from "./scene"; + +export const SigmaSceneAdapter = forwardRef( + function SigmaSceneAdapter( + { + onNodeSelect, + onEdgeSelect, + onInteractionStateChange, + onCameraStateChange, + onDiagnosticsChange, + onAnalyticsChange, + onRuntimeChange, + onLayoutRunningChange, + ...sceneProps + }, + ref, + ) { + const canvasRef = useRef(null); + const runtimeRef = useRef(null); + + useImperativeHandle(ref, () => ({ + fitView: () => canvasRef.current?.fitView(), + focusNode: (nodeId: string) => canvasRef.current?.focusNode(nodeId), + getRuntime: () => runtimeRef.current, + setLayoutRunning: onLayoutRunningChange + ? (running: boolean) => { + onLayoutRunningChange(running); + } + : undefined, + }), [onLayoutRunningChange]); + + return ( + {})} + onEdgeClick={onEdgeSelect} + onInteractionStateChange={onInteractionStateChange} + onCameraStateChange={onCameraStateChange} + onDiagnosticsChange={onDiagnosticsChange} + onAnalyticsChange={onAnalyticsChange} + onSceneRuntimeChange={(runtime) => { + runtimeRef.current = runtime; + onRuntimeChange?.(runtime); + }} + onLayoutRunningChange={onLayoutRunningChange} + {...sceneProps} + /> + ); + }, +) as GraphSceneAdapter; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/behaviors/clickSelectionBehavior.ts b/semantica-explorer/src/workspaces/GraphWorkspace/behaviors/clickSelectionBehavior.ts index d439baf8..16342480 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/behaviors/clickSelectionBehavior.ts +++ b/semantica-explorer/src/workspaces/GraphWorkspace/behaviors/clickSelectionBehavior.ts @@ -6,10 +6,16 @@ export const clickSelectionBehavior: GraphBehavior = { detach: () => {}, onNodeClick: (context, nodeId) => { context.setHoveredNodeId(nodeId); + context.onEdgeSelectionChange(""); context.onNodeSelectionChange(nodeId); }, + onEdgeClick: (context, edgeId) => { + context.setHoveredNodeId(null); + context.onEdgeSelectionChange(edgeId); + }, onStageClick: (context) => { context.setHoveredNodeId(null); + context.onEdgeSelectionChange(""); context.onNodeSelectionChange(""); }, }; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/behaviors/types.ts b/semantica-explorer/src/workspaces/GraphWorkspace/behaviors/types.ts index 232f80c4..cbeebc06 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/behaviors/types.ts +++ b/semantica-explorer/src/workspaces/GraphWorkspace/behaviors/types.ts @@ -15,6 +15,7 @@ export interface GraphBehaviorContext { getInteractionState: () => GraphInteractionState; setHoveredNodeId: (nodeId: string | null) => void; onNodeSelectionChange: (nodeId: string) => void; + onEdgeSelectionChange: (edgeId: string) => void; focusNodeInView: (nodeId: string) => void; fitCurrentView: () => void; dispatchAction: (action: GraphBehaviorActionRequest) => void; @@ -27,6 +28,7 @@ export interface GraphBehavior { onNodeEnter?: (context: GraphBehaviorContext, nodeId: string) => void; onNodeLeave?: (context: GraphBehaviorContext, nodeId: string) => void; onNodeClick?: (context: GraphBehaviorContext, nodeId: string) => void; + onEdgeClick?: (context: GraphBehaviorContext, edgeId: string) => void; onStageClick?: (context: GraphBehaviorContext) => void; onCameraChange?: (context: GraphBehaviorContext, cameraState: GraphCameraState) => void; onStateChange?: (context: GraphBehaviorContext, interactionState: GraphInteractionState) => void; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/graphAnalytics.ts b/semantica-explorer/src/workspaces/GraphWorkspace/graphAnalytics.ts index 3fbf0e1b..72a6f9de 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/graphAnalytics.ts +++ b/semantica-explorer/src/workspaces/GraphWorkspace/graphAnalytics.ts @@ -1,193 +1,683 @@ -import type { ApiEdge, ApiNode } from "./types"; -import type { NodeAttributes } from "../../store/graphStore"; -import { GRAPH_THEME, clamp, hashString } from "./graphConfig"; +import type Graph from "graphology"; +import louvain from "graphology-communities-louvain"; +import { dijkstra } from "graphology-shortest-path"; +import betweennessCentrality from "graphology-metrics/centrality/betweenness"; +import { + degreeCentrality, + inDegreeCentrality, + outDegreeCentrality, +} from "graphology-metrics/centrality/degree"; -const SEMANTIC_COLOR_FIELDS = [ - "community", - "cluster", - "module", - "group", - "category", - "domain", - "layer", - "source", - "nodeType", -] as const; +import { graph, type EdgeAttributes, type NodeAttributes } from "../../store/graphStore"; +import { GRAPH_THEME, hashString } from "./graphTheme"; +import type { + GraphAnalyticsSnapshot, + GraphDataSnapshot, + GraphCentralityNodeSummary, + GraphCommunitySummary, + GraphInteractionState, + GraphSemanticRegionSummary, +} from "./types"; -type SemanticField = (typeof SEMANTIC_COLOR_FIELDS)[number]; +type GraphRef = typeof graph | Graph; -function normalizedEntropy(counts: number[], total: number): number { - if (counts.length <= 1 || total <= 0) { - return 0; - } +type GraphCentralityRecord = { + degree: number; + inDegree: number; + outDegree: number; + betweenness: number; + score: number; +}; - let entropy = 0; - for (const count of counts) { - const probability = count / total; - entropy -= probability * Math.log(probability); - } +type GraphAnalyticsBase = { + communitiesByNode: Map; + communityCount: number; + modularity: number | null; + centralityByNode: Map; + topNodeIds: string[]; + betweennessReady: boolean; +}; - return entropy / Math.log(counts.length); +const MAX_BETWEENNESS_NODES = 1400; +const MAX_COMMUNITY_SUMMARIES = 6; +const MAX_REGION_SUMMARIES = 6; +const MAX_CENTRALITY_SUMMARIES = 6; +const CENTRALITY_ITERATIONS = 24; +const MAX_BACKBONE_ANCHORS = 4; +const MAX_BACKBONE_CENTRAL_LINKS = 2; +const MAX_BACKBONE_BRIDGES = 4; + +function getNodeLabel(graphRef: GraphRef, nodeId: string): string { + const attrs = graphRef.getNodeAttributes(nodeId) as NodeAttributes; + return String(attrs.label || attrs.content || nodeId); } -function getSemanticFieldValue(attributes: Pick, field: SemanticField): string | null { - if (field === "nodeType") { - return typeof attributes.nodeType === "string" && attributes.nodeType.trim() ? attributes.nodeType : null; +function getNodeColor(graphRef: GraphRef, nodeId: string): string { + const attrs = graphRef.getNodeAttributes(nodeId) as NodeAttributes; + return String(attrs.baseColor || attrs.color || "#63E6FF"); +} + +function getNodeSemanticGroup(graphRef: GraphRef, nodeId: string): string { + const attrs = graphRef.getNodeAttributes(nodeId) as NodeAttributes; + return String(attrs.semanticGroup || attrs.nodeType || "entity"); +} + +function toVisibleNodeSet(graphRef: GraphRef, visibleNodeIds?: Iterable): Set { + if (!visibleNodeIds) { + return new Set(graphRef.nodes()); } - const value = attributes.properties?.[field]; - return typeof value === "string" && value.trim() ? value : null; + const visible = new Set(); + for (const nodeId of visibleNodeIds) { + if (graphRef.hasNode(nodeId)) { + visible.add(nodeId); + } + } + + return visible.size ? visible : new Set(graphRef.nodes()); } -function structuralColorKey(nodeId: string, attributes: Pick): string { - const shard = hashString(nodeId) % GRAPH_THEME.nodes.palette.length; - return `${attributes.nodeType || "entity"}:${shard}`; -} +function buildCentralityRecords( + graphRef: GraphRef, + includeBetweenness: boolean, +): Pick { + const degree = degreeCentrality(graphRef); + const inDegree = inDegreeCentrality(graphRef); + const outDegree = outDegreeCentrality(graphRef); + const betweenness = includeBetweenness + ? betweennessCentrality(graphRef, { normalized: true, getEdgeWeight: "weight" }) + : {}; -export function chooseColorAccessor( - nodes: Array<{ id: string; attributes: Pick }>, -): (nodeId: string, attributes: Pick) => string { - let bestField: SemanticField | null = null; - let bestScore = 0; + const centralityByNode = new Map(); + graphRef.forEachNode((nodeId) => { + const degreeScore = Number(degree[nodeId] ?? 0); + const betweennessScore = Number((betweenness as Record)[nodeId] ?? 0); + const inDegreeScore = Number(inDegree[nodeId] ?? 0); + const outDegreeScore = Number(outDegree[nodeId] ?? 0); + centralityByNode.set(nodeId, { + degree: degreeScore, + inDegree: inDegreeScore, + outDegree: outDegreeScore, + betweenness: betweennessScore, + score: degreeScore * 0.7 + betweennessScore * 0.3, + }); + }); - for (const field of SEMANTIC_COLOR_FIELDS) { - const counts = new Map(); - let covered = 0; - - for (const node of nodes) { - const value = getSemanticFieldValue(node.attributes, field); - if (!value) { - continue; + const topNodeIds = graphRef + .nodes() + .sort((left, right) => { + const leftScore = centralityByNode.get(left)?.score ?? 0; + const rightScore = centralityByNode.get(right)?.score ?? 0; + if (rightScore !== leftScore) { + return rightScore - leftScore; } - covered += 1; - counts.set(value, (counts.get(value) ?? 0) + 1); - } + return left.localeCompare(right); + }); - const uniqueCount = counts.size; - if (covered === 0 || uniqueCount <= 1) { - continue; - } - - const countValues = [...counts.values()]; - const coverage = covered / nodes.length; - const dominantRatio = Math.max(...countValues) / covered; - const entropy = normalizedEntropy(countValues, covered); - const diversity = Math.min(uniqueCount, GRAPH_THEME.nodes.palette.length) / GRAPH_THEME.nodes.palette.length; - const score = entropy * 0.6 + diversity * 0.25 + coverage * 0.15; - const informativeEnough = coverage >= 0.4 && entropy >= 0.42 && dominantRatio <= 0.8; - - if (!informativeEnough) { - continue; - } - - if (score > bestScore) { - bestField = field; - bestScore = score; - } - } - - if (bestField) { - return (nodeId, attributes) => getSemanticFieldValue(attributes, bestField) ?? structuralColorKey(nodeId, attributes); - } - - return (nodeId, attributes) => structuralColorKey(nodeId, attributes); -} - -export function computeDegreeMap(nodes: ApiNode[], edges: ApiEdge[]): Map { - const degreeByNode = new Map(); - for (const node of nodes) { - degreeByNode.set(node.id, 0); - } - - for (const edge of edges) { - degreeByNode.set(edge.source, (degreeByNode.get(edge.source) ?? 0) + 1); - degreeByNode.set(edge.target, (degreeByNode.get(edge.target) ?? 0) + 1); - } - - return degreeByNode; -} - -export function computePageRank(nodes: ApiNode[], edges: ApiEdge[], iterations = 18, damping = 0.85): Map { - const nodeIds = nodes.map((node) => node.id); - const nodeCount = nodeIds.length; - const score = new Map(); - const inbound = new Map(); - const outbound = new Map(); - - for (const nodeId of nodeIds) { - score.set(nodeId, 1 / Math.max(nodeCount, 1)); - inbound.set(nodeId, []); - outbound.set(nodeId, 0); - } - - for (const edge of edges) { - inbound.get(edge.target)?.push(edge.source); - outbound.set(edge.source, (outbound.get(edge.source) ?? 0) + 1); - } - - for (let iteration = 0; iteration < iterations; iteration += 1) { - const next = new Map(); - let danglingMass = 0; - - for (const nodeId of nodeIds) { - if ((outbound.get(nodeId) ?? 0) === 0) { - danglingMass += score.get(nodeId) ?? 0; - } - } - - for (const nodeId of nodeIds) { - let incoming = 0; - for (const sourceId of inbound.get(nodeId) ?? []) { - const outDegree = outbound.get(sourceId) ?? 1; - incoming += (score.get(sourceId) ?? 0) / Math.max(outDegree, 1); - } - - const distributedDangling = danglingMass / Math.max(nodeCount, 1); - const nextScore = (1 - damping) / Math.max(nodeCount, 1) + damping * (incoming + distributedDangling); - next.set(nodeId, nextScore); - } - - next.forEach((value, key) => score.set(key, value)); - } - - const maxScore = Math.max(...score.values(), 1); - score.forEach((value, key) => score.set(key, value / maxScore)); - return score; -} - -export function computeNodeSize(nodeId: string, degreeByNode: Map, pageRank: Map): number { - const degree = degreeByNode.get(nodeId) ?? 0; - const maxDegree = Math.max(...degreeByNode.values(), 1); - const normalizedLogDegree = Math.log(degree + 1) / Math.log(maxDegree + 1); - const normalizedPageRank = pageRank.get(nodeId) ?? normalizedLogDegree; - return clamp(2.5, 2.5 + 12 * normalizedLogDegree + 7 * normalizedPageRank, 22); -} - -export function computeEdgeSize(weight: number | undefined): number { - const safeWeight = Number.isFinite(weight) ? Math.max(Number(weight), 0) : 0; - return clamp(0.5, 0.6 + Math.sqrt(safeWeight || 0.04), 2.4); -} - -export function deterministicPosition(nodeId: string, index: number, total: number): { x: number; y: number } { - const seed = hashString(`${nodeId}:${index}:${total}`) ^ 0x9e3779b9; - let state = seed || 0x12345678; - const next = () => { - state += 0x6d2b79f5; - let value = state; - value = Math.imul(value ^ (value >>> 15), value | 1); - value ^= value + Math.imul(value ^ (value >>> 7), value | 61); - return ((value ^ (value >>> 14)) >>> 0) / 4294967296; - }; - - const angle = next() * Math.PI * 2; - const radius = Math.sqrt(next()) * Math.min(90 + Math.sqrt(total) * 0.55, 170); - const spread = 0.82 + Math.min(index / Math.max(total, 1), 0.18); return { - x: Math.cos(angle) * radius * spread, - y: Math.sin(angle) * radius * spread, + centralityByNode, + topNodeIds, + betweennessReady: includeBetweenness, + }; +} + +export function computeGraphAnalyticsBase( + graphRef: GraphRef, + options?: { + computeCommunities?: boolean; + computeCentrality?: boolean; + }, +): GraphAnalyticsBase { + const shouldComputeCommunities = options?.computeCommunities ?? true; + const shouldComputeCentrality = options?.computeCentrality ?? true; + const communitiesByNode = new Map(); + let communityCount = 0; + let modularity: number | null = null; + + if (shouldComputeCommunities && graphRef.order > 1 && graphRef.size > 0) { + try { + const result = louvain.detailed(graphRef, { getEdgeWeight: "weight" }); + modularity = Number(result.modularity ?? 0); + communityCount = Number(result.count ?? 0); + Object.entries(result.communities).forEach(([nodeId, communityId]) => { + communitiesByNode.set(nodeId, Number(communityId)); + }); + } catch (error) { + console.error("[GraphAnalytics] community detection failed", error); + } + } + + if (!shouldComputeCentrality || graphRef.order === 0) { + return { + communitiesByNode, + communityCount, + modularity, + centralityByNode: new Map(), + topNodeIds: [], + betweennessReady: false, + }; + } + + const includeBetweenness = graphRef.order <= MAX_BETWEENNESS_NODES; + const centrality = buildCentralityRecords(graphRef, includeBetweenness); + + return { + communitiesByNode, + communityCount, + modularity, + ...centrality, + }; +} + +function buildCommunitySummaries( + graphRef: GraphRef, + visibleNodeIds: Set, + base: GraphAnalyticsBase, +): GraphCommunitySummary[] { + const grouped = new Map; + anchorNodeId: string | null; + prominence: number; + color: string; + }>(); + + graphRef.forEachNode((nodeId) => { + const communityId = base.communitiesByNode.get(nodeId); + if (communityId === undefined) { + return; + } + + const entry = grouped.get(communityId) ?? { + nodeCount: 0, + visibleNodeCount: 0, + semanticCounts: new Map(), + anchorNodeId: null, + prominence: 0, + color: getNodeColor(graphRef, nodeId), + }; + + entry.nodeCount += 1; + if (visibleNodeIds.has(nodeId)) { + entry.visibleNodeCount += 1; + } + + const semanticGroup = getNodeSemanticGroup(graphRef, nodeId); + entry.semanticCounts.set(semanticGroup, (entry.semanticCounts.get(semanticGroup) ?? 0) + 1); + + const nodeScore = base.centralityByNode.get(nodeId)?.score ?? 0; + if (!entry.anchorNodeId || nodeScore > (base.centralityByNode.get(entry.anchorNodeId)?.score ?? -1)) { + entry.anchorNodeId = nodeId; + entry.color = getNodeColor(graphRef, nodeId); + } + entry.prominence += visibleNodeIds.has(nodeId) ? 1 + nodeScore : nodeScore * 0.15; + + grouped.set(communityId, entry); + }); + + return [...grouped.entries()] + .map(([communityId, data]) => { + const dominantSemanticGroup = [...data.semanticCounts.entries()] + .sort((left, right) => right[1] - left[1])[0]?.[0] ?? "entity"; + return { + communityId: String(communityId), + nodeCount: data.nodeCount, + visibleNodeCount: data.visibleNodeCount, + dominantSemanticGroup, + color: data.color, + anchorNodeId: data.anchorNodeId, + anchorLabel: data.anchorNodeId ? getNodeLabel(graphRef, data.anchorNodeId) : "Community anchor", + prominence: data.prominence, + }; + }) + .filter((summary) => summary.visibleNodeCount > 0) + .sort((left, right) => right.prominence - left.prominence) + .slice(0, MAX_COMMUNITY_SUMMARIES); +} + +function buildSemanticRegionSummaries( + graphRef: GraphRef, + visibleNodeIds: Set, + base: GraphAnalyticsBase, +): GraphSemanticRegionSummary[] { + const grouped = new Map; + anchorNodeId: string | null; + prominence: number; + color: string; + }>(); + + graphRef.forEachNode((nodeId) => { + const semanticGroup = getNodeSemanticGroup(graphRef, nodeId); + const entry = grouped.get(semanticGroup) ?? { + nodeCount: 0, + visibleNodeCount: 0, + communityCounts: new Map(), + anchorNodeId: null, + prominence: 0, + color: getNodeColor(graphRef, nodeId), + }; + + entry.nodeCount += 1; + if (visibleNodeIds.has(nodeId)) { + entry.visibleNodeCount += 1; + } + + const communityId = base.communitiesByNode.get(nodeId); + if (communityId !== undefined) { + const communityKey = String(communityId); + entry.communityCounts.set(communityKey, (entry.communityCounts.get(communityKey) ?? 0) + 1); + } + + const nodeScore = base.centralityByNode.get(nodeId)?.score ?? 0; + if (!entry.anchorNodeId || nodeScore > (base.centralityByNode.get(entry.anchorNodeId)?.score ?? -1)) { + entry.anchorNodeId = nodeId; + entry.color = getNodeColor(graphRef, nodeId); + } + entry.prominence += visibleNodeIds.has(nodeId) ? 1 + nodeScore : nodeScore * 0.1; + + grouped.set(semanticGroup, entry); + }); + + return [...grouped.entries()] + .map(([semanticGroup, data]) => ({ + semanticGroup, + nodeCount: data.nodeCount, + visibleNodeCount: data.visibleNodeCount, + color: data.color, + anchorNodeId: data.anchorNodeId, + anchorLabel: data.anchorNodeId ? getNodeLabel(graphRef, data.anchorNodeId) : semanticGroup, + dominantCommunityId: [...data.communityCounts.entries()].sort((left, right) => right[1] - left[1])[0]?.[0] ?? null, + prominence: data.prominence, + })) + .filter((summary) => summary.visibleNodeCount > 0) + .sort((left, right) => right.prominence - left.prominence) + .slice(0, MAX_REGION_SUMMARIES); +} + +function buildCentralitySummaries( + graphRef: GraphRef, + visibleNodeIds: Set, + base: GraphAnalyticsBase, +): GraphCentralityNodeSummary[] { + const candidateIds = base.topNodeIds.filter((nodeId) => visibleNodeIds.has(nodeId)); + const rankedIds = (candidateIds.length ? candidateIds : base.topNodeIds).slice(0, MAX_CENTRALITY_SUMMARIES); + + return rankedIds.map((nodeId) => { + const record = base.centralityByNode.get(nodeId) ?? { + degree: 0, + betweenness: 0, + score: 0, + }; + return { + id: nodeId, + label: getNodeLabel(graphRef, nodeId), + semanticGroup: getNodeSemanticGroup(graphRef, nodeId), + color: getNodeColor(graphRef, nodeId), + degree: Number(record.degree ?? 0), + betweenness: Number(record.betweenness ?? 0), + score: Number(record.score ?? 0), + }; + }); +} + +function collectNodeIncidentEdges( + graphRef: GraphRef, + nodeId: string, + visibleNodeIds: Set, +): Array<{ edgeId: string; source: string; target: string; attrs: EdgeAttributes }> { + const edges: Array<{ edgeId: string; source: string; target: string; attrs: EdgeAttributes }> = []; + + graphRef.forEachOutEdge(nodeId, (edgeId, attrs, source, target) => { + if (!visibleNodeIds.has(target)) { + return; + } + edges.push({ edgeId: String(edgeId), source, target, attrs: attrs as EdgeAttributes }); + }); + + graphRef.forEachInEdge(nodeId, (edgeId, attrs, source, target) => { + if (!visibleNodeIds.has(source)) { + return; + } + edges.push({ edgeId: String(edgeId), source, target, attrs: attrs as EdgeAttributes }); + }); + + return edges; +} + +function scoreBackboneEdge( + attrs: EdgeAttributes, + sourceId: string, + targetId: string, + base: GraphAnalyticsBase, +) { + const sourceScore = base.centralityByNode.get(sourceId)?.score ?? 0; + const targetScore = base.centralityByNode.get(targetId)?.score ?? 0; + const weight = Number(attrs.weight ?? 0); + const priority = Number(attrs.visualPriority ?? 0); + const parallelBoost = Number(attrs.parallelCount ?? 1) > 1 ? 0.14 : 0; + const bidirectionalBoost = attrs.isBidirectional ? 0.18 : 0; + + return weight * 1.4 + (sourceScore + targetScore) * 2.4 + priority * 0.6 + parallelBoost + bidirectionalBoost; +} + +function buildOverviewBackboneSnapshot( + graphRef: GraphRef, + visibleNodeIds: Set, + base: GraphAnalyticsBase, + semanticRegionSummaries: GraphSemanticRegionSummary[], + centralitySummaries: GraphCentralityNodeSummary[], +): GraphAnalyticsSnapshot["overviewBackbone"] { + if (visibleNodeIds.size === 0) { + return { + ready: false, + reason: "No visible nodes are available for overview backbone selection.", + edgeIds: [], + }; + } + + const selectedEdgeIds = new Set(); + const regionByNode = new Map(); + visibleNodeIds.forEach((nodeId) => { + regionByNode.set(nodeId, getNodeSemanticGroup(graphRef, nodeId)); + }); + const topRegionIds = new Set(semanticRegionSummaries.slice(0, 3).map((summary) => summary.semanticGroup)); + const backboneCoreNodeIds = new Set( + centralitySummaries + .slice(0, MAX_BACKBONE_ANCHORS * 2) + .map((summary) => summary.id) + .filter((nodeId) => visibleNodeIds.has(nodeId)), + ); + + const anchorIds = centralitySummaries + .slice(0, MAX_BACKBONE_ANCHORS) + .map((summary) => summary.id) + .filter((nodeId) => visibleNodeIds.has(nodeId)); + + const coreLinkCandidates = new Map(); + anchorIds.forEach((anchorId) => { + collectNodeIncidentEdges(graphRef, anchorId, visibleNodeIds) + .filter((entry) => { + const otherNodeId = entry.source === anchorId ? entry.target : entry.source; + if (!backboneCoreNodeIds.has(otherNodeId)) { + return false; + } + const sourceRegion = regionByNode.get(entry.source); + const targetRegion = regionByNode.get(entry.target); + return Boolean(sourceRegion && targetRegion && (topRegionIds.has(sourceRegion) || topRegionIds.has(targetRegion))); + }) + .forEach((entry) => { + const pairKey = [entry.source, entry.target].sort().join("::"); + const sourceRegion = regionByNode.get(entry.source); + const targetRegion = regionByNode.get(entry.target); + const bridgeBoost = sourceRegion && targetRegion && sourceRegion !== targetRegion ? 0.28 : 0; + const score = scoreBackboneEdge(entry.attrs, entry.source, entry.target, base) + bridgeBoost; + const current = coreLinkCandidates.get(pairKey); + if (!current || score > current.score || (score === current.score && entry.edgeId.localeCompare(current.edgeId) < 0)) { + coreLinkCandidates.set(pairKey, { edgeId: entry.edgeId, score }); + } + }); + }); + + const bridgeByPair = new Map(); + graphRef.forEachEdge((edgeId, attrs, source, target) => { + if (!visibleNodeIds.has(source) || !visibleNodeIds.has(target)) { + return; + } + + const sourceRegion = regionByNode.get(source); + const targetRegion = regionByNode.get(target); + if (!sourceRegion || !targetRegion || sourceRegion === targetRegion) { + return; + } + + if (!topRegionIds.has(sourceRegion) && !topRegionIds.has(targetRegion)) { + return; + } + + const pairKey = [sourceRegion, targetRegion].sort().join("::"); + const score = scoreBackboneEdge(attrs as EdgeAttributes, source, target, base) + 0.36; + const current = bridgeByPair.get(pairKey); + if (!current || score > current.score || (score === current.score && String(edgeId).localeCompare(current.edgeId) < 0)) { + bridgeByPair.set(pairKey, { edgeId: String(edgeId), score }); + } + }); + + [...bridgeByPair.values()] + .sort((left, right) => { + if (right.score !== left.score) { + return right.score - left.score; + } + return left.edgeId.localeCompare(right.edgeId); + }) + .slice(0, MAX_BACKBONE_BRIDGES) + .forEach((entry) => selectedEdgeIds.add(entry.edgeId)); + + [...coreLinkCandidates.values()] + .sort((left, right) => { + if (right.score !== left.score) { + return right.score - left.score; + } + return left.edgeId.localeCompare(right.edgeId); + }) + .slice(0, MAX_BACKBONE_CENTRAL_LINKS) + .forEach((entry) => selectedEdgeIds.add(entry.edgeId)); + + const edgeIds = [...selectedEdgeIds] + .filter((edgeId) => graphRef.hasEdge(edgeId)) + .sort((left, right) => left.localeCompare(right)); + + return { + ready: edgeIds.length > 0, + reason: edgeIds.length > 0 + ? "Ready" + : "No overview backbone edges met the current visibility thresholds.", + edgeIds, + }; +} + +function buildDirectedPathSnapshot( + graphRef: GraphRef, + interactionState: GraphInteractionState, +): GraphAnalyticsSnapshot["directedPath"] { + if (interactionState.activePath.length < 2) { + return { + ready: false, + reason: "Trace a path to compare it against local strict directed shortest pathfinding.", + sourceId: interactionState.selectedNodeId || null, + targetId: null, + path: [], + length: null, + verifiedAgainstActivePath: false, + }; + } + + const sourceId = interactionState.activePath[0] ?? null; + const targetId = interactionState.activePath[interactionState.activePath.length - 1] ?? null; + if (!sourceId || !targetId || !graphRef.hasNode(sourceId) || !graphRef.hasNode(targetId)) { + return { + ready: false, + reason: "Active path endpoints are not available in the current graph view.", + sourceId, + targetId, + path: [], + length: null, + verifiedAgainstActivePath: false, + }; + } + + try { + const path = dijkstra.bidirectional(graphRef, sourceId, targetId, "weight") ?? []; + return { + ready: path.length > 1, + reason: path.length > 1 + ? "Ready" + : "No strict directed shortest path found in the current graph view.", + sourceId, + targetId, + path, + length: path.length > 1 ? path.length - 1 : null, + verifiedAgainstActivePath: path.join("::") === interactionState.activePath.join("::"), + }; + } catch (error) { + console.error("[GraphAnalytics] directed pathfinding failed", error); + return { + ready: false, + reason: "Directed pathfinding failed for the current graph snapshot.", + sourceId, + targetId, + path: [], + length: null, + verifiedAgainstActivePath: false, + }; + } +} + +export function buildGraphAnalyticsSnapshot(params: { + graphRef: GraphRef; + interactionState: GraphInteractionState; + base: GraphAnalyticsBase; + visibleNodeIds?: Iterable; +}): GraphAnalyticsSnapshot { + const { graphRef, interactionState, base } = params; + const visibleNodeIds = toVisibleNodeSet(graphRef, params.visibleNodeIds); + const directedPath = buildDirectedPathSnapshot(graphRef, interactionState); + const communitySummaries = base.communitiesByNode.size + ? buildCommunitySummaries(graphRef, visibleNodeIds, base) + : []; + const semanticRegionSummaries = buildSemanticRegionSummaries(graphRef, visibleNodeIds, base); + const centralitySummaries = buildCentralitySummaries(graphRef, visibleNodeIds, base); + const overviewBackbone = buildOverviewBackboneSnapshot( + graphRef, + visibleNodeIds, + base, + semanticRegionSummaries, + centralitySummaries, + ); + + return { + generatedAt: Date.now(), + directedPath, + communities: { + ready: communitySummaries.length > 0, + reason: communitySummaries.length > 0 + ? "Ready" + : base.communitiesByNode.size > 0 + ? "No visible communities in the current graph context." + : "Community detection has not produced summaries yet.", + count: base.communityCount, + modularity: base.modularity, + summaries: communitySummaries, + }, + centrality: { + ready: centralitySummaries.length > 0, + reason: centralitySummaries.length > 0 + ? base.betweennessReady + ? "Ready" + : "Ready (degree-biased while betweenness is bounded for large graphs)." + : "Centrality ranking is waiting for graph data.", + topNodes: centralitySummaries, + }, + semanticRegions: { + ready: semanticRegionSummaries.length > 0, + reason: semanticRegionSummaries.length > 0 + ? "Ready" + : "No semantic regions are visible in the current graph context.", + summaries: semanticRegionSummaries, + }, + overviewBackbone, }; } export function colorForNodeKey(key: string): string { - return GRAPH_THEME.nodes.palette[hashString(key) % GRAPH_THEME.nodes.palette.length]; + const palette = GRAPH_THEME.palette.semantic; + return palette[hashString(key) % palette.length]; +} + +export function chooseColorAccessor( + nodes: Array<{ id: string; attributes: Pick }>, +) { + return (id: string, attributes: Pick) => { + const semanticKey = String(attributes.nodeType || attributes.content || id); + const node = nodes.find((entry) => entry.id === id); + const fallbackKey = String(node?.attributes.nodeType || node?.attributes.content || semanticKey); + return `${fallbackKey}:${id}`; + }; +} + +export function deterministicPosition(nodeId: string, index: number, totalNodes: number) { + const angle = (hashString(nodeId) % 360) * (Math.PI / 180); + const ring = Math.floor(index / Math.max(12, Math.ceil(Math.sqrt(Math.max(totalNodes, 1))))); + const radius = 120 + ring * 90 + (hashString(`${nodeId}:radius`) % 46); + return { + x: Math.cos(angle) * radius, + y: Math.sin(angle) * radius, + }; +} + +export function computeDegreeMap( + nodes: GraphDataSnapshot["nodes"], + edges: GraphDataSnapshot["edges"], +) { + const degreeByNode = new Map(); + nodes.forEach((node) => degreeByNode.set(node.id, 0)); + edges.forEach((edge) => { + degreeByNode.set(edge.source, (degreeByNode.get(edge.source) ?? 0) + 1); + degreeByNode.set(edge.target, (degreeByNode.get(edge.target) ?? 0) + 1); + }); + return degreeByNode; +} + +export function computePageRank( + nodes: GraphDataSnapshot["nodes"], + edges: GraphDataSnapshot["edges"], +) { + const pageRank = new Map(); + const outbound = new Map(); + const inbound = new Map(); + const nodeCount = Math.max(nodes.length, 1); + + nodes.forEach((node) => { + pageRank.set(node.id, 1 / nodeCount); + outbound.set(node.id, []); + inbound.set(node.id, []); + }); + + edges.forEach((edge) => { + outbound.set(edge.source, [...(outbound.get(edge.source) ?? []), edge.target]); + inbound.set(edge.target, [...(inbound.get(edge.target) ?? []), edge.source]); + }); + + for (let iteration = 0; iteration < CENTRALITY_ITERATIONS; iteration += 1) { + const next = new Map(); + nodes.forEach((node) => { + const incoming = inbound.get(node.id) ?? []; + let sum = 0; + incoming.forEach((sourceId) => { + const outDegree = (outbound.get(sourceId) ?? []).length || nodeCount; + sum += (pageRank.get(sourceId) ?? 0) / outDegree; + }); + next.set(node.id, 0.15 / nodeCount + 0.85 * sum); + }); + next.forEach((value, nodeId) => pageRank.set(nodeId, value)); + } + + return pageRank; +} + +export function computeNodeSize( + nodeId: string, + degreeByNode: Map, + pageRankByNode: Map, +) { + const degree = degreeByNode.get(nodeId) ?? 0; + const pageRank = pageRankByNode.get(nodeId) ?? 0; + return 5.5 + Math.min(16, degree * 0.18 + pageRank * 160); +} + +export function computeEdgeSize(weight: number) { + return Math.max(0.8, Math.min(3.2, 0.9 + Math.log2(Math.max(weight, 1) + 1) * 0.36)); } diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/graphLoading.ts b/semantica-explorer/src/workspaces/GraphWorkspace/graphLoading.ts new file mode 100644 index 00000000..6a07b447 --- /dev/null +++ b/semantica-explorer/src/workspaces/GraphWorkspace/graphLoading.ts @@ -0,0 +1,84 @@ +import type { GraphLoadPhase, GraphLoadProgress, GraphLoadProgressKind, GraphLayoutSource, GraphLayoutState } from "./types"; + +export const GRAPH_LOAD_STAGE_SEQUENCE: Exclude[] = [ + "bootstrapping", + "fetching_nodes", + "fetching_edges", + "computing_styling", + "hydrating_scene", + "stabilizing_layout", +]; + +export function getGraphLoadTitle(phase: GraphLoadPhase): string { + switch (phase) { + case "bootstrapping": + return "Preparing graph session"; + case "fetching_nodes": + return "Loading nodes"; + case "fetching_edges": + return "Loading relationships"; + case "computing_styling": + return "Computing node styling"; + case "hydrating_scene": + return "Hydrating graph scene"; + case "stabilizing_layout": + return "Stabilizing layout"; + case "ready": + default: + return "Graph ready"; + } +} + +export function getGraphLoadStageLabel(phase: Exclude): string { + switch (phase) { + case "bootstrapping": + return "Prepare"; + case "fetching_nodes": + return "Nodes"; + case "fetching_edges": + return "Relations"; + case "computing_styling": + return "Styling"; + case "hydrating_scene": + return "Scene"; + case "stabilizing_layout": + return "Layout"; + default: + return "Stage"; + } +} + +export function createGraphLoadProgress(input: { + phase: GraphLoadPhase; + message: string; + progressKind: GraphLoadProgressKind; + loaded?: number | null; + total?: number | null; + nodesLoaded?: number; + nodesTotal?: number | null; + edgesLoaded?: number; + edgesTotal?: number | null; + showGraphBehind?: boolean; + layoutSource?: GraphLayoutSource; + layoutState?: GraphLayoutState; +}): GraphLoadProgress { + const phaseIndex = GRAPH_LOAD_STAGE_SEQUENCE.indexOf(input.phase as Exclude); + + return { + phase: input.phase, + title: getGraphLoadTitle(input.phase), + message: input.message, + progressKind: input.progressKind, + loaded: input.loaded ?? null, + total: input.total ?? null, + nodesLoaded: input.nodesLoaded ?? 0, + nodesTotal: input.nodesTotal ?? null, + edgesLoaded: input.edgesLoaded ?? 0, + edgesTotal: input.edgesTotal ?? null, + showGraphBehind: input.showGraphBehind ?? false, + stageIndex: phaseIndex >= 0 ? phaseIndex + 1 : GRAPH_LOAD_STAGE_SEQUENCE.length, + stageCount: GRAPH_LOAD_STAGE_SEQUENCE.length, + layoutSource: input.layoutSource, + layoutState: input.layoutState, + }; +} diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/graphSceneLayers.ts b/semantica-explorer/src/workspaces/GraphWorkspace/graphSceneLayers.ts new file mode 100644 index 00000000..91a8b257 --- /dev/null +++ b/semantica-explorer/src/workspaces/GraphWorkspace/graphSceneLayers.ts @@ -0,0 +1,775 @@ +import type Graph from "graphology"; +import Sigma from "sigma"; + +import { graph, type EdgeAttributes, type NodeAttributes } from "../../store/graphStore"; +import { blendHex, GRAPH_THEME, withAlpha, zoomTierAtLeast } from "./graphTheme"; +import type { + GraphAnalyticsSnapshot, + GraphEffectsState, + GraphInteractionState, + GraphTemporalState, +} from "./types"; + +type GraphRef = typeof graph | Graph; + +export type ViewportPoint = { x: number; y: number }; + +export type PathSegmentOverlay = { + sourceId: string; + targetId: string; + source: ViewportPoint; + target: ViewportPoint; + color: string; + size: number; +}; + +export type VisibleNodeSample = { + nodeId: string; + point: ViewportPoint; + size: number; + attrs: NodeAttributes; +}; + +function isPointNearViewport(point: ViewportPoint, width: number, height: number, padding = 96) { + return point.x >= -padding + && point.y >= -padding + && point.x <= width + padding + && point.y <= height + padding; +} + +function drawGlowHalo( + context: CanvasRenderingContext2D, + x: number, + y: number, + radius: number, + color: string, +) { + const gradient = context.createRadialGradient(x, y, 0, x, y, radius); + gradient.addColorStop(0, color); + gradient.addColorStop(1, "rgba(0,0,0,0)"); + context.fillStyle = gradient; + context.beginPath(); + context.arc(x, y, radius, 0, Math.PI * 2); + context.fill(); +} + +function createScratchCanvas(width: number, height: number) { + const canvas = document.createElement("canvas"); + canvas.width = width; + canvas.height = height; + return canvas; +} + +function parseCssColor(color: string) { + if (color.startsWith("#")) { + const hex = color.slice(1); + const normalized = hex.length === 3 + ? hex.split("").map((char) => `${char}${char}`).join("") + : hex; + if (normalized.length === 6) { + return { + r: Number.parseInt(normalized.slice(0, 2), 16), + g: Number.parseInt(normalized.slice(2, 4), 16), + b: Number.parseInt(normalized.slice(4, 6), 16), + }; + } + } + + const match = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/i); + if (match) { + return { + r: Number.parseInt(match[1], 10), + g: Number.parseInt(match[2], 10), + b: Number.parseInt(match[3], 10), + }; + } + + return { r: 130, g: 145, b: 165 }; +} + +function createThresholdMask( + alphaValues: Uint8ClampedArray, + width: number, + height: number, + threshold: number, +) { + const mask = new Uint8Array(width * height); + let count = 0; + let sumX = 0; + let sumY = 0; + let sumWeight = 0; + + for (let y = 0; y < height; y += 1) { + for (let x = 0; x < width; x += 1) { + const index = y * width + x; + const alpha = alphaValues[index]; + if (alpha < threshold) { + continue; + } + + mask[index] = 1; + count += 1; + sumX += x * alpha; + sumY += y * alpha; + sumWeight += alpha; + } + } + + const centroid = sumWeight > 0 + ? { x: sumX / sumWeight, y: sumY / sumWeight } + : { x: width / 2, y: height / 2 }; + + return { mask, count, centroid }; +} + +function blurAlphaValues( + alphaValues: Uint8ClampedArray, + width: number, + height: number, + passes: number, +) { + if (passes <= 0) { + return alphaValues; + } + + let source = alphaValues; + for (let pass = 0; pass < passes; pass += 1) { + const next = new Uint8ClampedArray(width * height); + for (let y = 0; y < height; y += 1) { + for (let x = 0; x < width; x += 1) { + let sum = 0; + let samples = 0; + for (let oy = -1; oy <= 1; oy += 1) { + const sampleY = y + oy; + if (sampleY < 0 || sampleY >= height) { + continue; + } + for (let ox = -1; ox <= 1; ox += 1) { + const sampleX = x + ox; + if (sampleX < 0 || sampleX >= width) { + continue; + } + sum += source[sampleY * width + sampleX]; + samples += 1; + } + } + next[y * width + x] = Math.round(sum / Math.max(samples, 1)); + } + } + source = next; + } + + return source; +} + +function isolateDominantMask( + mask: Uint8Array, + width: number, + height: number, + alphaValues: Uint8ClampedArray, +) { + const visited = new Uint8Array(mask.length); + const queue = new Int32Array(mask.length); + let bestPixels: number[] = []; + let totalCount = 0; + + for (let index = 0; index < mask.length; index += 1) { + if (!mask[index] || visited[index]) { + continue; + } + + let head = 0; + let tail = 0; + const component: number[] = []; + visited[index] = 1; + queue[tail++] = index; + + while (head < tail) { + const current = queue[head++]; + component.push(current); + + const x = current % width; + const y = Math.floor(current / width); + const neighbors = [ + current - 1, + current + 1, + current - width, + current + width, + ]; + + for (let n = 0; n < neighbors.length; n += 1) { + const neighbor = neighbors[n]; + if (neighbor < 0 || neighbor >= mask.length || visited[neighbor] || !mask[neighbor]) { + continue; + } + if ((n === 0 && x === 0) || (n === 1 && x === width - 1) || (n === 2 && y === 0) || (n === 3 && y === height - 1)) { + continue; + } + visited[neighbor] = 1; + queue[tail++] = neighbor; + } + } + + totalCount += component.length; + if (component.length > bestPixels.length) { + bestPixels = component; + } + } + + const dominantMask = new Uint8Array(mask.length); + let sumX = 0; + let sumY = 0; + let sumWeight = 0; + bestPixels.forEach((index) => { + dominantMask[index] = 1; + const alpha = alphaValues[index]; + const x = index % width; + const y = Math.floor(index / width); + sumX += x * alpha; + sumY += y * alpha; + sumWeight += alpha; + }); + + return { + mask: dominantMask, + count: bestPixels.length, + centroid: sumWeight > 0 + ? { x: sumX / sumWeight, y: sumY / sumWeight } + : { x: width / 2, y: height / 2 }, + occupancyRatio: bestPixels.length / Math.max(width * height, 1), + dominantMassRatio: bestPixels.length / Math.max(totalCount, 1), + }; +} + +function renderDensityField( + samples: VisibleNodeSample[], + width: number, + height: number, +) { + const scale = GRAPH_THEME.effects.semanticRegions.fogResolutionScale; + const gridWidth = Math.max(72, Math.round(width * scale)); + const gridHeight = Math.max(72, Math.round(height * scale)); + const canvas = createScratchCanvas(gridWidth, gridHeight); + const context = canvas.getContext("2d"); + if (!context) { + return null; + } + + context.clearRect(0, 0, gridWidth, gridHeight); + context.globalCompositeOperation = "source-over"; + + samples.forEach((sample) => { + const x = sample.point.x * scale; + const y = sample.point.y * scale; + const radius = Math.max( + 2.5, + (GRAPH_THEME.effects.semanticRegions.splatRadius + sample.size * 0.9) * scale, + ); + const gradient = context.createRadialGradient(x, y, 0, x, y, radius); + gradient.addColorStop(0, "rgba(255,255,255,0.22)"); + gradient.addColorStop(0.58, "rgba(255,255,255,0.08)"); + gradient.addColorStop(1, "rgba(255,255,255,0)"); + context.fillStyle = gradient; + context.beginPath(); + context.arc(x, y, radius, 0, Math.PI * 2); + context.fill(); + }); + + const imageData = context.getImageData(0, 0, gridWidth, gridHeight); + const alphaValues = new Uint8ClampedArray(gridWidth * gridHeight); + let maxAlpha = 0; + for (let index = 0; index < alphaValues.length; index += 1) { + const alpha = imageData.data[index * 4 + 3]; + alphaValues[index] = alpha; + if (alpha > maxAlpha) { + maxAlpha = alpha; + } + } + + if (maxAlpha <= 0) { + return null; + } + + const blurredAlphaValues = blurAlphaValues( + alphaValues, + gridWidth, + gridHeight, + GRAPH_THEME.effects.semanticRegions.blurPasses, + ); + const blurredMaxAlpha = blurredAlphaValues.reduce((value, alpha) => Math.max(value, alpha), 0); + if (blurredMaxAlpha <= 0) { + return null; + } + + return { canvas, gridWidth, gridHeight, alphaValues: blurredAlphaValues, maxAlpha: blurredMaxAlpha, scale }; +} + +function drawDensityFog( + context: CanvasRenderingContext2D, + densityField: ReturnType, + color: string, + alpha: number, +) { + if (!densityField) { + return; + } + + const { gridWidth, gridHeight, alphaValues } = densityField; + const fogCanvas = createScratchCanvas(gridWidth, gridHeight); + const fogContext = fogCanvas.getContext("2d"); + if (!fogContext) { + return; + } + + const imageData = fogContext.createImageData(gridWidth, gridHeight); + const rgb = parseCssColor(color); + for (let index = 0; index < alphaValues.length; index += 1) { + const sourceAlpha = alphaValues[index] / 255; + if (sourceAlpha <= 0) { + continue; + } + + const pixelIndex = index * 4; + imageData.data[pixelIndex] = rgb.r; + imageData.data[pixelIndex + 1] = rgb.g; + imageData.data[pixelIndex + 2] = rgb.b; + imageData.data[pixelIndex + 3] = Math.round(255 * Math.pow(sourceAlpha, 1.7) * alpha); + } + + fogContext.putImageData(imageData, 0, 0); + context.save(); + context.imageSmoothingEnabled = true; + context.globalCompositeOperation = "lighter"; + context.drawImage(fogCanvas, 0, 0, context.canvas.width, context.canvas.height); + context.restore(); +} + +function drawMaskContour( + context: CanvasRenderingContext2D, + mask: Uint8Array, + gridWidth: number, + gridHeight: number, + color: string, + alpha: number, +) { + const contourCanvas = createScratchCanvas(gridWidth, gridHeight); + const contourContext = contourCanvas.getContext("2d"); + if (!contourContext) { + return; + } + + const imageData = contourContext.createImageData(gridWidth, gridHeight); + const rgb = parseCssColor(color); + + for (let y = 1; y < gridHeight - 1; y += 1) { + for (let x = 1; x < gridWidth - 1; x += 1) { + const index = y * gridWidth + x; + if (!mask[index]) { + continue; + } + + const isEdge = !mask[index - 1] + || !mask[index + 1] + || !mask[index - gridWidth] + || !mask[index + gridWidth]; + if (!isEdge) { + continue; + } + + const pixelIndex = index * 4; + imageData.data[pixelIndex] = rgb.r; + imageData.data[pixelIndex + 1] = rgb.g; + imageData.data[pixelIndex + 2] = rgb.b; + imageData.data[pixelIndex + 3] = Math.round(255 * alpha); + } + } + + contourContext.putImageData(imageData, 0, 0); + context.save(); + context.imageSmoothingEnabled = true; + context.drawImage(contourCanvas, 0, 0, context.canvas.width, context.canvas.height); + context.restore(); +} + +function buildRegionRenderColors(color: string) { + return { + fogColor: blendHex("#0E1927", color, 0.46), + innerContourColor: blendHex("#1C2C3F", color, 0.78), + outerContourColor: blendHex("#132131", color, 0.6), + labelBorderColor: blendHex("#2B3F57", color, 0.78), + }; +} + +export function collectVisibleNodeSamples( + sigma: Sigma, + graphRef: GraphRef, + viewportWidth: number, + viewportHeight: number, +): VisibleNodeSample[] { + const samples: VisibleNodeSample[] = []; + + graphRef.forEachNode((nodeId, attrs) => { + const displayData = sigma.getNodeDisplayData(nodeId); + if (!displayData) { + return; + } + + const point = sigma.graphToViewport({ x: displayData.x, y: displayData.y }); + if (!isPointNearViewport(point, viewportWidth, viewportHeight, 84)) { + return; + } + + samples.push({ + nodeId, + point, + size: displayData.size, + attrs: attrs as NodeAttributes, + }); + }); + + return samples; +} + +function drawRegionLabel( + context: CanvasRenderingContext2D, + x: number, + y: number, + text: string, + color: string, +) { + const label = text.length > 22 ? `${text.slice(0, 21)}…` : text; + context.save(); + context.font = `600 11px "IBM Plex Sans", Inter, system-ui, sans-serif`; + context.textBaseline = "middle"; + const width = context.measureText(label).width + 14; + const height = 22; + const left = x - width / 2; + const top = y - height / 2; + + context.fillStyle = "rgba(8, 14, 24, 0.84)"; + context.strokeStyle = withAlpha(color, 0.24); + context.lineWidth = 1; + context.beginPath(); + context.roundRect(left, top, width, height, 999); + context.fill(); + context.stroke(); + + context.fillStyle = "rgba(235, 244, 255, 0.88)"; + context.fillText(label, left + 7, y); + context.restore(); +} + +export function drawSemanticRegionsLayer( + context: CanvasRenderingContext2D, + analytics: GraphAnalyticsSnapshot | null, + visibleNodes: VisibleNodeSample[], + interactionState: GraphInteractionState, + effectsState: GraphEffectsState, +) { + if (!effectsState.semanticRegionsEnabled || !analytics?.semanticRegions.ready) { + return; + } + + if (!zoomTierAtLeast(interactionState.zoomTier, GRAPH_THEME.effects.semanticRegions.minZoomTier)) { + return; + } + + const visibleByGroup = new Map(); + visibleNodes.forEach((sample) => { + const group = String(sample.attrs.semanticGroup || sample.attrs.nodeType || "entity"); + const entry = visibleByGroup.get(group); + if (entry) { + entry.push(sample); + } else { + visibleByGroup.set(group, [sample]); + } + }); + + const summaries = analytics.semanticRegions.summaries + .slice(0, GRAPH_THEME.effects.semanticRegions.maxRegions); + const maxProminence = summaries.reduce((value, summary) => Math.max(value, summary.prominence), 1); + const semanticConfig = GRAPH_THEME.effects.semanticRegions; + + summaries.forEach((summary) => { + const samples = visibleByGroup.get(summary.semanticGroup); + if (!samples || samples.length < semanticConfig.minVisibleSamples) { + return; + } + + const densityField = renderDensityField(samples, context.canvas.width, context.canvas.height); + if (!densityField) { + return; + } + + const prominenceRatio = 0.52 + (summary.prominence / maxProminence) * 0.48; + const densityThreshold = Math.max(18, densityField.maxAlpha * semanticConfig.densityThreshold); + const contourThreshold = Math.max(28, densityField.maxAlpha * semanticConfig.contourThreshold); + const outerContourThreshold = Math.max(18, contourThreshold * 0.72); + + const densityMask = createThresholdMask( + densityField.alphaValues, + densityField.gridWidth, + densityField.gridHeight, + densityThreshold, + ); + const dominantDensityMask = isolateDominantMask( + densityMask.mask, + densityField.gridWidth, + densityField.gridHeight, + densityField.alphaValues, + ); + if ( + dominantDensityMask.count < semanticConfig.minMaskPixels + || dominantDensityMask.occupancyRatio < semanticConfig.minOccupancyRatio + || dominantDensityMask.dominantMassRatio < semanticConfig.dominantMassRatio + ) { + return; + } + + const contourMask = createThresholdMask( + densityField.alphaValues, + densityField.gridWidth, + densityField.gridHeight, + contourThreshold, + ); + const outerContourMask = createThresholdMask( + densityField.alphaValues, + densityField.gridWidth, + densityField.gridHeight, + outerContourThreshold, + ); + const dominantContourMask = isolateDominantMask( + contourMask.mask, + densityField.gridWidth, + densityField.gridHeight, + densityField.alphaValues, + ); + const dominantOuterContourMask = isolateDominantMask( + outerContourMask.mask, + densityField.gridWidth, + densityField.gridHeight, + densityField.alphaValues, + ); + + const colors = buildRegionRenderColors(summary.color); + drawDensityFog( + context, + densityField, + colors.fogColor, + semanticConfig.fogAlpha * prominenceRatio, + ); + if ( + dominantOuterContourMask.count >= semanticConfig.outerContourMinMaskPixels + && dominantOuterContourMask.dominantMassRatio >= semanticConfig.dominantMassRatio + ) { + drawMaskContour( + context, + dominantOuterContourMask.mask, + densityField.gridWidth, + densityField.gridHeight, + colors.outerContourColor, + semanticConfig.outerContourAlpha * prominenceRatio, + ); + } + drawMaskContour( + context, + dominantContourMask.mask, + densityField.gridWidth, + densityField.gridHeight, + colors.innerContourColor, + semanticConfig.innerContourAlpha * prominenceRatio, + ); + + if (summary.visibleNodeCount >= 18) { + const labelX = dominantDensityMask.centroid.x / densityField.scale; + const labelY = dominantDensityMask.centroid.y / densityField.scale - 18; + drawRegionLabel( + context, + labelX, + labelY, + summary.semanticGroup, + colors.labelBorderColor, + ); + } + }); +} + +export function drawContourLayer( + context: CanvasRenderingContext2D, + analytics: GraphAnalyticsSnapshot | null, + visibleNodes: VisibleNodeSample[], + interactionState: GraphInteractionState, + effectsState: GraphEffectsState, +) { + if (!effectsState.contoursEnabled || !analytics?.centrality.ready) { + return; + } + + if (!zoomTierAtLeast(interactionState.zoomTier, GRAPH_THEME.effects.contours.minZoomTier)) { + return; + } + + const visibleById = new Map(visibleNodes.map((sample) => [sample.nodeId, sample] as const)); + + analytics.centrality.topNodes.slice(0, GRAPH_THEME.effects.contours.maxContours).forEach((node) => { + const sample = visibleById.get(node.id); + if (!sample) { + return; + } + + drawGlowHalo( + context, + sample.point.x, + sample.point.y, + GRAPH_THEME.effects.contours.baseRadius + sample.size * 3.2, + withAlpha(node.color, GRAPH_THEME.effects.contours.glowAlpha), + ); + }); +} + +function isTemporalNodeActive(attrs: NodeAttributes, currentTime: Date | null) { + if (!currentTime || (!attrs.valid_from && !attrs.valid_until)) { + return false; + } + + const time = currentTime.getTime(); + const from = attrs.valid_from ? new Date(attrs.valid_from).getTime() : Number.NEGATIVE_INFINITY; + const until = attrs.valid_until ? new Date(attrs.valid_until).getTime() : Number.POSITIVE_INFINITY; + return time >= from && time <= until; +} + +export function drawTemporalEmphasisLayer( + context: CanvasRenderingContext2D, + visibleNodes: VisibleNodeSample[], + temporalState: GraphTemporalState | null | undefined, + interactionState: GraphInteractionState, + effectsState: GraphEffectsState, +) { + if (!effectsState.temporalEmphasisEnabled || !temporalState?.currentTime) { + return; + } + + if (!zoomTierAtLeast(interactionState.zoomTier, GRAPH_THEME.effects.temporalEmphasis.minZoomTier)) { + return; + } + + visibleNodes + .filter((sample) => isTemporalNodeActive(sample.attrs, temporalState.currentTime)) + .slice(0, GRAPH_THEME.effects.temporalEmphasis.maxHighlights) + .forEach((sample) => { + drawGlowHalo( + context, + sample.point.x, + sample.point.y, + Math.max(sample.size * GRAPH_THEME.effects.temporalEmphasis.radiusMultiplier, 14), + withAlpha(GRAPH_THEME.palette.accent.temporal, GRAPH_THEME.effects.temporalEmphasis.glowAlpha), + ); + }); +} + +export function drawLensLayer( + context: CanvasRenderingContext2D, + sigma: Sigma, + primaryNodeId: string, + focusIds: Set, +) { + const primaryData = sigma.getNodeDisplayData(primaryNodeId); + if (!primaryData) { + return; + } + + const center = sigma.graphToViewport({ x: primaryData.x, y: primaryData.y }); + drawGlowHalo( + context, + center.x, + center.y, + GRAPH_THEME.effects.lens.radius, + withAlpha(GRAPH_THEME.palette.accent.hovered, GRAPH_THEME.effects.lens.glowAlpha), + ); + + focusIds.forEach((neighborId) => { + if (neighborId === primaryNodeId || !graph.hasNode(neighborId)) { + return; + } + + if ( + !graph.hasDirectedEdge(primaryNodeId, neighborId) + && !graph.hasDirectedEdge(neighborId, primaryNodeId) + ) { + return; + } + + const neighborData = sigma.getNodeDisplayData(neighborId); + if (!neighborData) { + return; + } + + const neighborPoint = sigma.graphToViewport({ x: neighborData.x, y: neighborData.y }); + context.strokeStyle = withAlpha(GRAPH_THEME.palette.accent.hovered, GRAPH_THEME.effects.lens.edgeAlpha * 0.38); + context.lineWidth = GRAPH_THEME.effects.lens.edgeLineWidth + 3.2; + context.lineCap = "round"; + context.beginPath(); + context.moveTo(center.x, center.y); + context.lineTo(neighborPoint.x, neighborPoint.y); + context.stroke(); + + context.strokeStyle = withAlpha(GRAPH_THEME.palette.accent.hovered, GRAPH_THEME.effects.lens.edgeAlpha); + context.lineWidth = GRAPH_THEME.effects.lens.edgeLineWidth; + context.beginPath(); + context.moveTo(center.x, center.y); + context.lineTo(neighborPoint.x, neighborPoint.y); + context.stroke(); + }); +} + +export function drawPathEffectsLayer( + context: CanvasRenderingContext2D, + segments: PathSegmentOverlay[], + effectsState: GraphEffectsState, + effectAvailability: { + pathPulse: { available: boolean }; + pathFlow: { available: boolean }; + }, + now: number, +) { + if (effectsState.pathFlowEnabled && effectAvailability.pathFlow.available) { + segments.forEach((segment, index) => { + const t = ((now * GRAPH_THEME.effects.pathFlow.speed) + index * GRAPH_THEME.effects.pathFlow.spacing) % 1; + const headX = segment.source.x + (segment.target.x - segment.source.x) * t; + const headY = segment.source.y + (segment.target.y - segment.source.y) * t; + const tailT = Math.max(0, t - 0.08); + const tailX = segment.source.x + (segment.target.x - segment.source.x) * tailT; + const tailY = segment.source.y + (segment.target.y - segment.source.y) * tailT; + + context.strokeStyle = withAlpha(segment.color, 0.28); + context.lineWidth = Math.max(segment.size + 3.6, 4.6); + context.lineCap = "round"; + context.beginPath(); + context.moveTo(tailX, tailY); + context.lineTo(headX, headY); + context.stroke(); + + context.strokeStyle = withAlpha(GRAPH_THEME.palette.accent.selected, GRAPH_THEME.effects.pathFlow.opacity); + context.lineWidth = Math.max(segment.size + 1.3, 2.4); + context.beginPath(); + context.moveTo(tailX, tailY); + context.lineTo(headX, headY); + context.stroke(); + }); + } + + if (effectsState.pathPulseEnabled && effectAvailability.pathPulse.available) { + segments.forEach((segment, index) => { + const t = ((now * GRAPH_THEME.effects.pathPulse.speed) + index * 0.17) % 1; + const x = segment.source.x + (segment.target.x - segment.source.x) * t; + const y = segment.source.y + (segment.target.y - segment.source.y) * t; + const glow = context.createRadialGradient(x, y, 0, x, y, GRAPH_THEME.effects.pathPulse.radius); + glow.addColorStop(0, withAlpha(GRAPH_THEME.palette.accent.path, GRAPH_THEME.effects.pathPulse.glowAlpha)); + glow.addColorStop(1, "rgba(0,0,0,0)"); + context.fillStyle = glow; + context.beginPath(); + context.arc(x, y, GRAPH_THEME.effects.pathPulse.radius, 0, Math.PI * 2); + context.fill(); + }); + } +} diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/graphSceneState.ts b/semantica-explorer/src/workspaces/GraphWorkspace/graphSceneState.ts new file mode 100644 index 00000000..a4d066a0 --- /dev/null +++ b/semantica-explorer/src/workspaces/GraphWorkspace/graphSceneState.ts @@ -0,0 +1,977 @@ +import Graph from "graphology"; + +import { graph, type EdgeAttributes, type NodeAttributes } from "../../store/graphStore"; +import { + clamp, + blendHex, + GRAPH_THEME, + type GraphArrowVisibilityPolicy, + type GraphBadgeKind, + type GraphEdgeVariant, + type GraphEdgeVisualState, + type GraphLabelVisibilityPolicy, + type GraphNodeShapeVariant, + type GraphNodeVisualState, + type GraphTheme, + type GraphZoomTier, + withAlpha, + zoomTierAtLeast, +} from "./graphTheme"; +import type { GraphInteractionState, GraphViewMode } from "./types"; + +const MAX_FOCUS_NEIGHBORS = GRAPH_THEME.focus.maxNeighbors; +const FOCUS_RING_CAPACITY = GRAPH_THEME.focus.ringCapacity; +const FOCUS_RING_GAP = GRAPH_THEME.focus.ringGap; +const FOCUS_PRIMARY_LABELS = GRAPH_THEME.focus.primaryLabels; + +function getOverviewPresenceBoost(cameraRatio: number) { + return clamp(0, Math.log2(Math.max(cameraRatio, 1)) / 1.85, 1); +} + +export type GraphSigmaEdgeType = "line" | "arrow" | "curve" | "curvedArrow"; + +export type ResolvedNodeStyle = { + color: string; + shellColor: string; + coreScale: number; + size: number; + forceLabel: boolean; + label: string; + zIndex: number; + hidden: boolean; + borderColor: string; + borderSize: number; + nodeVariant: GraphNodeShapeVariant; + badgeKind?: GraphBadgeKind; + badgeCount?: number; + showBadge: boolean; + showRing: boolean; + ringColor?: string; + ringSize: number; + showHalo: boolean; + haloColor: string; +}; + +export type ResolvedEdgeStyle = { + hidden: boolean; + type?: GraphSigmaEdgeType; + color?: string; + size?: number; + zIndex: number; + edgeVariant: GraphEdgeVariant; + arrowVisibilityPolicy: GraphArrowVisibilityPolicy; + curveStrength: number; + curvature: number; +}; + +function forEachDirectedEdgeBetween( + graphRef: typeof graph | Graph, + source: string, + target: string, + callback: (edgeId: string, attrs: EdgeAttributes) => void, +) { + graphRef.forEachDirectedEdge(source, target, (edgeId, attrs) => { + callback(String(edgeId), attrs as EdgeAttributes); + }); +} + +function collectDirectedEdgeIdsBetween( + graphRef: typeof graph | Graph, + source: string, + target: string, +): string[] { + const edgeIds: string[] = []; + forEachDirectedEdgeBetween(graphRef, source, target, (edgeId) => { + edgeIds.push(edgeId); + }); + return edgeIds; +} + +export function buildPathEdgeSet( + graphRef: typeof graph | Graph, + path: string[], + pathEdgeIds: string[] = [], +): Set { + if (pathEdgeIds.length > 0) { + return new Set(pathEdgeIds.filter((edgeId) => graphRef.hasEdge(edgeId))); + } + + const edgeIds = new Set(); + for (let index = 0; index < path.length - 1; index += 1) { + collectDirectedEdgeIdsBetween(graphRef, path[index], path[index + 1]).forEach((edgeId) => edgeIds.add(edgeId)); + } + return edgeIds; +} + +export function buildEdgeEndpointSet( + graphRef: typeof graph | Graph, + ...edgeIds: Array +): Set { + const nodeIds = new Set(); + + edgeIds.forEach((edgeId) => { + if (!edgeId || !graphRef.hasEdge(edgeId)) { + return; + } + + const [source, target] = graphRef.extremities(edgeId); + nodeIds.add(source); + nodeIds.add(target); + }); + + return nodeIds; +} + +function collectFocusEdgeIds( + graphRef: typeof graph | Graph, + nodeIds: Set, +): Set { + const edgeIds = new Set(); + const ids = Array.from(nodeIds); + + for (let sourceIndex = 0; sourceIndex < ids.length; sourceIndex += 1) { + const source = ids[sourceIndex]; + + for (let targetIndex = 0; targetIndex < ids.length; targetIndex += 1) { + const target = ids[targetIndex]; + if (source === target) { + continue; + } + + collectDirectedEdgeIdsBetween(graphRef, source, target).forEach((edgeId) => edgeIds.add(edgeId)); + } + } + + return edgeIds; +} + +function collectImpactedNodeIds( + graphRef: typeof graph | Graph, + interactionState: GraphInteractionState | null, +): Set { + if (!interactionState) { + return new Set(); + } + + const impacted = new Set(interactionState.activePath); + const primaryNodeId = interactionState.hoveredNodeId || interactionState.selectedNodeId; + if (primaryNodeId && graphRef.hasNode(primaryNodeId)) { + buildFocusSet(primaryNodeId).forEach((nodeId) => impacted.add(nodeId)); + } + + buildEdgeEndpointSet(graphRef, interactionState.selectedEdgeId) + .forEach((nodeId) => impacted.add(nodeId)); + + return impacted; +} + +function collectImpactedEdgeKeys( + graphRef: typeof graph | Graph, + interactionState: GraphInteractionState | null, +): Set { + if (!interactionState) { + return new Set(); + } + + const impacted = new Set(buildPathEdgeSet(graphRef, interactionState.activePath, interactionState.activePathEdgeIds)); + const primaryNodeId = interactionState.hoveredNodeId || interactionState.selectedNodeId; + if (primaryNodeId && graphRef.hasNode(primaryNodeId)) { + collectFocusEdgeIds(graphRef, buildFocusSet(primaryNodeId)).forEach((edgeId) => impacted.add(edgeId)); + } + + if (interactionState.selectedEdgeId) { + impacted.add(interactionState.selectedEdgeId); + } + + return impacted; +} + +function resolveDisplayEdgeIds( + graphRef: typeof graph | Graph, + stableEdgeIds: Set, +): string[] { + return Array.from(stableEdgeIds).filter((edgeId) => graphRef.hasEdge(edgeId)); +} + +export function collectInteractionRefreshTargets( + graphRef: typeof graph | Graph, + previousState: GraphInteractionState | null, + nextState: GraphInteractionState, +): { nodes: string[]; edges: string[] } { + const nodeIds = new Set(); + const edgeKeys = new Set(); + + collectImpactedNodeIds(graphRef, previousState).forEach((nodeId) => nodeIds.add(nodeId)); + collectImpactedNodeIds(graphRef, nextState).forEach((nodeId) => nodeIds.add(nodeId)); + collectImpactedEdgeKeys(graphRef, previousState).forEach((edgeId) => edgeKeys.add(edgeId)); + collectImpactedEdgeKeys(graphRef, nextState).forEach((edgeId) => edgeKeys.add(edgeId)); + + return { + nodes: Array.from(nodeIds).filter((nodeId) => graphRef.hasNode(nodeId)), + edges: resolveDisplayEdgeIds(graphRef, edgeKeys), + }; +} + +export function getEdgeWeightBetween(source: string, target: string): number { + let weight = 0; + + forEachDirectedEdgeBetween(graph, source, target, (_edgeId, attrs) => { + weight = Math.max(weight, Number(attrs?.weight ?? 0)); + }); + + forEachDirectedEdgeBetween(graph, target, source, (_edgeId, attrs) => { + weight = Math.max(weight, Number(attrs?.weight ?? 0)); + }); + + return weight; +} + +export function rankNeighbors(nodeId: string): string[] { + return graph + .neighbors(nodeId) + .map((neighborId) => ({ + id: neighborId, + weight: getEdgeWeightBetween(nodeId, neighborId), + degree: graph.degree(neighborId), + })) + .sort((left, right) => { + if (right.weight !== left.weight) { + return right.weight - left.weight; + } + if (right.degree !== left.degree) { + return right.degree - left.degree; + } + return left.id.localeCompare(right.id); + }) + .map((item) => item.id); +} + +export function buildFocusSet(nodeId: string): Set { + const ranked = rankNeighbors(nodeId).slice(0, MAX_FOCUS_NEIGHBORS); + return new Set([nodeId, ...ranked]); +} + +export function isEdgeInteractable( + graphRef: typeof graph | Graph, + interactionState: GraphInteractionState, + edgeId: string, + source: string, + target: string, + attrs: EdgeAttributes, +): boolean { + const pathEdgeIds = buildPathEdgeSet(graphRef, interactionState.activePath, interactionState.activePathEdgeIds); + if (pathEdgeIds.has(edgeId) || interactionState.selectedEdgeId === edgeId) { + return true; + } + + const primaryNodeId = interactionState.selectedNodeId; + if (primaryNodeId && graphRef.hasNode(primaryNodeId)) { + if (source === primaryNodeId || target === primaryNodeId) { + return true; + } + + const focusIds = buildFocusSet(primaryNodeId); + return focusIds.has(source) && focusIds.has(target); + } + + if (interactionState.zoomTier !== "inspection") { + return false; + } + + return Number(attrs.visualPriority ?? 0) >= GRAPH_THEME.zoomTiers[interactionState.zoomTier].edgePriorityThreshold; +} + +function resolveNodeColor( + theme: GraphTheme, + zoomTier: GraphZoomTier, + state: GraphNodeVisualState, + attrs: NodeAttributes, + cameraRatio: number, + fallbackColor?: string, +) { + const semanticColor = String(attrs.baseColor || fallbackColor || theme.palette.semantic[0]); + const overviewTint = state === "neighbor" + ? theme.palette.overview.nodeTintMix + 0.09 + : theme.palette.overview.nodeTintMix; + const overviewCore = blendHex( + theme.palette.overview.nodeCore, + semanticColor, + Math.min(0.74, theme.palette.overview.nodeCoreMix + overviewTint), + ); + + switch (theme.nodes.states[state].color) { + case "selected": + return theme.palette.accent.selected; + case "hovered": + return theme.palette.accent.hovered; + case "path": + return theme.palette.accent.path; + case "muted": + return zoomTier === "overview" + ? withAlpha(theme.palette.overview.nodeMuted, 0.42) + : String(attrs.mutedColor || withAlpha(semanticColor, theme.nodes.mutedAlpha)); + case "base": + default: + if (zoomTier === "overview") { + const presenceBoost = getOverviewPresenceBoost(cameraRatio); + const boostedCore = blendHex(overviewCore, semanticColor, 0.3 + 0.26 * presenceBoost); + return withAlpha(boostedCore, Math.min(0.98, theme.palette.overview.nodeCoreAlpha + presenceBoost * 0.18)); + } + return semanticColor; + } +} + +function resolveNodeShellColor( + theme: GraphTheme, + zoomTier: GraphZoomTier, + state: GraphNodeVisualState, + attrs: NodeAttributes, + cameraRatio: number, + fallbackColor?: string, +) { + const semanticColor = String(attrs.baseColor || fallbackColor || theme.palette.semantic[0]); + const presenceBoost = getOverviewPresenceBoost(cameraRatio); + const overviewShell = blendHex( + theme.palette.overview.nodeBase, + semanticColor, + (state === "neighbor" ? 0.02 : 0.012) + presenceBoost * 0.024, + ); + + if (zoomTier !== "overview") { + return withAlpha(blendHex(theme.palette.overview.nodeBase, semanticColor, 0.26), 0.95); + } + + if (state === "selected") { + return withAlpha(blendHex(theme.palette.overview.nodeBase, theme.palette.accent.selected, 0.05), 0.98); + } + + if (state === "hovered") { + return withAlpha(blendHex(theme.palette.overview.nodeBase, theme.palette.accent.hovered, 0.06), 0.98); + } + + if (state === "path") { + return withAlpha(blendHex(theme.palette.overview.nodeBase, theme.palette.accent.path, 0.06), 0.97); + } + + if (state === "muted" || state === "inactive") { + return withAlpha(theme.palette.overview.nodeMuted, 0.22); + } + + return withAlpha(overviewShell, theme.palette.overview.nodeShellAlpha); +} + +function resolveNodeCoreScale( + zoomTier: GraphZoomTier, + state: GraphNodeVisualState, + cameraRatio: number, +) { + const presenceBoost = getOverviewPresenceBoost(cameraRatio); + if (zoomTier === "overview") { + switch (state) { + case "selected": + return 0.34 + presenceBoost * 0.08; + case "hovered": + return 0.32 + presenceBoost * 0.08; + case "path": + return 0.28 + presenceBoost * 0.07; + case "neighbor": + return 0.2 + presenceBoost * 0.06; + case "muted": + case "inactive": + return 0.08 + presenceBoost * 0.03; + case "default": + default: + return 0.16 + presenceBoost * 0.08; + } + } + + switch (state) { + case "selected": + return 0.52; + case "hovered": + return 0.48; + case "path": + return 0.44; + case "neighbor": + return 0.3; + case "muted": + case "inactive": + return 0.1; + case "default": + default: + return zoomTier === "structure" ? 0.22 : 0.28; + } +} + +function resolveEdgeColor( + theme: GraphTheme, + zoomTier: GraphZoomTier, + state: GraphEdgeVisualState, + attrs: EdgeAttributes, + fallbackColor?: string, +) { + const defaultInspectionColor = zoomTier === "overview" + ? theme.palette.overview.edgeInspection + : theme.palette.muted.edgeInspection; + const baseColor = String(attrs.baseColor || fallbackColor || defaultInspectionColor); + + switch (theme.edges.states[state].color) { + case "hover": + return theme.palette.accent.hovered; + case "path": + return theme.palette.accent.path; + case "backbone": + return zoomTier === "overview" + ? theme.palette.overview.edgeBackbone + : theme.palette.muted.edgeFocus; + case "focus": + return theme.palette.muted.edgeFocus; + case "overview": + return theme.palette.muted.edgeOverview; + case "structure": + return zoomTier === "overview" + ? theme.palette.overview.edgeStructure + : theme.palette.muted.edgeStructure; + case "inspection": + return zoomTier === "overview" + ? theme.palette.overview.edgeInspection + : theme.palette.muted.edgeInspection; + case "muted": + return zoomTier === "overview" + ? theme.palette.overview.edgeStructure + : String(attrs.mutedColor || theme.palette.muted.edgeOverview); + default: + return baseColor; + } +} + +function resolveNodeRingColor( + theme: GraphTheme, + state: GraphNodeVisualState, + attrs: NodeAttributes, +) { + if (state === "selected") { + return attrs.ringColor || theme.nodes.selectedRing.color; + } + if (state === "hovered") { + return theme.palette.accent.hovered; + } + if (state === "path") { + return theme.palette.accent.path; + } + + return undefined; +} + +function resolveNodeRingSize( + theme: GraphTheme, + state: GraphNodeVisualState, + zoomTier: GraphZoomTier, +) { + if (state === "selected" && zoomTierAtLeast(zoomTier, theme.nodes.selectedRing.visibleFrom)) { + return theme.nodes.selectedRing.nativeSize; + } + if (state === "hovered") { + return Math.max(1.45, theme.nodes.selectedRing.nativeSize - 0.35); + } + if (state === "path") { + return Math.max(1.2, theme.nodes.selectedRing.nativeSize - 0.55); + } + + return 0; +} + +export function resolveNodeVisualState( + nodeId: string, + zoomTier: GraphZoomTier, + hoveredNodeId: string | null, + selectedNodeId: string, + selectedEdgeId: string, + focusIds: Set, + edgeEndpointIds: Set, + pathNodeIds: Set, +): GraphNodeVisualState { + if (hoveredNodeId && nodeId === hoveredNodeId) { + return "hovered"; + } + if (selectedNodeId && nodeId === selectedNodeId) { + return "selected"; + } + if (pathNodeIds.has(nodeId)) { + return "path"; + } + if (focusIds.has(nodeId)) { + return "neighbor"; + } + if (edgeEndpointIds.has(nodeId)) { + return "neighbor"; + } + if (hoveredNodeId || selectedNodeId || selectedEdgeId || pathNodeIds.size > 0) { + if (zoomTier === "overview") { + return "default"; + } + return "muted"; + } + return "default"; +} + +export function resolveEdgeVisualState( + edgeId: string, + source: string, + target: string, + zoomTier: GraphZoomTier, + hoveredNodeId: string | null, + selectedNodeId: string, + selectedEdgeId: string, + focusIds: Set, + pathEdgeIds: Set, + overviewBackboneEdgeIds: Set, +): GraphEdgeVisualState { + const primaryNodeId = hoveredNodeId || selectedNodeId; + + if (pathEdgeIds.has(edgeId)) { + return "path"; + } + + if (selectedEdgeId && edgeId === selectedEdgeId) { + return "selected"; + } + + if (primaryNodeId && (source === primaryNodeId || target === primaryNodeId)) { + return hoveredNodeId ? "hovered" : "selected"; + } + + if (zoomTier !== "overview" && focusIds.has(source) && focusIds.has(target)) { + return "neighbor"; + } + + if (zoomTier === "overview" && overviewBackboneEdgeIds.has(edgeId)) { + return "backbone"; + } + + if (hoveredNodeId || selectedNodeId || selectedEdgeId || pathEdgeIds.size > 0) { + return "muted"; + } + + if (zoomTier === "overview") { + return "inactive"; + } + + return "default"; +} + +export function resolveNodeVariant(state: GraphNodeVisualState, attrs: NodeAttributes): GraphNodeShapeVariant { + if (state === "selected") { + return "selected"; + } + + return attrs.nodeShapeVariant || attrs.nodeVariant || "default"; +} + +export function resolveEdgeVariant(state: GraphEdgeVisualState, attrs: EdgeAttributes): GraphEdgeVariant { + if (state === "path") { + return "pathSignal"; + } + + if ((attrs.parallelCount ?? 1) > 1) { + return "parallelCurve"; + } + + if (attrs.edgeVariant) { + return attrs.edgeVariant; + } + + if (attrs.isBidirectional) { + return "bidirectionalCurve"; + } + + if (attrs.arrowVisibilityPolicy === "contextual") { + return "directional"; + } + + return "line"; +} + +export function shouldForceNodeLabel( + theme: GraphTheme, + zoomTier: GraphZoomTier, + state: GraphNodeVisualState, + attrs: NodeAttributes, + labelPriority: number, +): boolean { + const tierConfig = theme.zoomTiers[zoomTier]; + const forceVisibleState = theme.labels.forceVisibleStates.includes(state); + const policy = attrs.labelVisibilityPolicy || "priority"; + + if (forceVisibleState || theme.nodes.states[state].forceLabel) { + return true; + } + + switch (policy as GraphLabelVisibilityPolicy) { + case "always": + return true; + case "local": + return zoomTier !== "overview" && state !== "default" && state !== "muted" && state !== "inactive"; + case "priority": + return labelPriority >= tierConfig.labelThreshold; + case "none": + default: + return false; + } +} + +function resolveNodeBorderColor( + theme: GraphTheme, + zoomTier: GraphZoomTier, + state: GraphNodeVisualState, + variant: GraphNodeShapeVariant, + attrs: NodeAttributes, + baseColor: string, +) { + if (state === "selected" || variant === "selected") { + return attrs.ringColor || theme.nodes.selectedRing.color; + } + if (state === "hovered") { + return theme.palette.accent.hovered; + } + if (state === "path") { + return theme.palette.accent.path; + } + if (state === "muted" || state === "inactive") { + return withAlpha( + attrs.strokeColor || attrs.borderColor || theme.palette.overview.nodeBorder || theme.palette.background.nodeBorder, + zoomTier === "overview" ? 0.26 : 0.7, + ); + } + + if (variant === "temporal") { + return theme.palette.accent.temporal; + } + if (variant === "provenance") { + return theme.palette.accent.provenance; + } + if (variant === "inferred") { + return theme.palette.accent.inferred; + } + + if (zoomTier === "overview") { + return withAlpha( + blendHex(theme.palette.overview.nodeBorder, baseColor, state === "neighbor" ? 0.08 : 0.03), + state === "neighbor" ? 0.24 : 0.06, + ); + } + + return attrs.strokeColor || attrs.borderColor || theme.palette.background.nodeBorder || baseColor; +} + +export function resolveNodeElementStyle( + theme: GraphTheme, + zoomTier: GraphZoomTier, + state: GraphNodeVisualState, + attrs: NodeAttributes, + label: string, + cameraRatio = 1, +): ResolvedNodeStyle { + const tierConfig = theme.zoomTiers[zoomTier]; + const stateConfig = theme.nodes.states[state]; + const nodeVariant = resolveNodeVariant(state, attrs); + const variantConfig = theme.nodes.variants[nodeVariant]; + const baseSize = Number(attrs.baseSize || attrs.size || 4); + const labelPriority = Number(attrs.labelPriority ?? 0); + const color = resolveNodeColor(theme, zoomTier, state, attrs, cameraRatio, attrs.color); + const shellColor = resolveNodeShellColor(theme, zoomTier, state, attrs, cameraRatio, attrs.color); + const sizeMultiplier = (state === "default" ? tierConfig.nodeScale : stateConfig.sizeMultiplier) * variantConfig.sizeMultiplier; + const overviewPresence = zoomTier === "overview" ? 1 + getOverviewPresenceBoost(cameraRatio) * 1.2 : 1; + const forceLabel = shouldForceNodeLabel(theme, zoomTier, state, attrs, labelPriority); + const badgeKind = attrs.badgeKind || variantConfig.badgeKind; + const forceVisibleState = theme.labels.forceVisibleStates.includes(state); + const showBadge = Boolean( + badgeKind + && (forceVisibleState || (tierConfig.showBadges && zoomTierAtLeast(zoomTier, variantConfig.badgeVisibleFrom))) + && state !== "muted" + && state !== "inactive", + ); + const ringSize = resolveNodeRingSize(theme, state, zoomTier); + const ringColor = resolveNodeRingColor(theme, state, attrs); + const showRing = ringSize > 0; + const showHalo = state === "hovered" || state === "selected" || state === "path"; + const strokeBase = state === "muted" || state === "inactive" + ? theme.nodes.strokeHierarchy[zoomTier].muted + : forceVisibleState + ? theme.nodes.strokeHierarchy[zoomTier].emphasis + : theme.nodes.strokeHierarchy[zoomTier].base; + + return { + color, + shellColor, + coreScale: resolveNodeCoreScale(zoomTier, state, cameraRatio), + size: Math.max(baseSize * sizeMultiplier * overviewPresence, stateConfig.minSize), + forceLabel, + label: forceLabel ? label : "", + zIndex: forceLabel && stateConfig.zIndex === 0 ? 1 : stateConfig.zIndex, + hidden: false, + borderColor: resolveNodeBorderColor(theme, zoomTier, state, nodeVariant, attrs, color), + borderSize: Math.max( + 0.4, + Number(attrs.borderSize ?? 0.85) + strokeBase + stateConfig.borderBoost + variantConfig.borderBoost - 0.8, + ), + nodeVariant, + badgeKind, + badgeCount: attrs.badgeCount, + showBadge, + showRing, + ringColor, + ringSize, + showHalo, + haloColor: attrs.haloColor || attrs.glowColor || withAlpha(color, theme.overlays.hoverGlowAlpha + variantConfig.haloBoost), + }; +} + +function resolveStraightEdgeType( + theme: GraphTheme, + zoomTier: GraphZoomTier, + state: GraphEdgeVisualState, + variant: GraphEdgeVariant, + attrs: EdgeAttributes, +): "line" | "arrow" { + const variantConfig = theme.edges.variants[variant]; + + if (theme.edges.states[state].forceArrow || variantConfig.arrowPolicy === "always") { + return "arrow"; + } + + if (variantConfig.arrowPolicy === "contextual" && theme.zoomTiers[zoomTier].showContextualArrows) { + return "arrow"; + } + + if (state !== "default") { + return (attrs.type as "line" | "arrow" | undefined) || variantConfig.baseType; + } + + return Number(attrs.visualPriority ?? 0) >= theme.zoomTiers[zoomTier].arrowPriorityThreshold && theme.zoomTiers[zoomTier].showContextualArrows + ? "arrow" + : "line"; +} + +function resolveEdgeCurvature( + theme: GraphTheme, + state: GraphEdgeVisualState, + edgeVariant: GraphEdgeVariant, + attrs: EdgeAttributes, + sourceId: string | undefined, + targetId: string | undefined, +) { + const variantConfig = theme.edges.variants[edgeVariant]; + const baseCurvature = edgeVariant === "line" && state === "selected" + ? Math.max(variantConfig.curveStrength, 0.14) + : variantConfig.curveStrength; + + if (baseCurvature === 0) { + return 0; + } + + if (typeof attrs.parallelCount === "number" && attrs.parallelCount > 1 && typeof attrs.parallelIndex === "number") { + const center = (attrs.parallelCount - 1) / 2; + return (attrs.parallelIndex - center) * baseCurvature; + } + + if ((edgeVariant === "bidirectionalCurve" || edgeVariant === "parallelCurve" || attrs.isBidirectional) && sourceId && targetId) { + return sourceId.localeCompare(targetId) <= 0 ? baseCurvature : -baseCurvature; + } + + return baseCurvature; +} + +export function resolveEdgeElementStyle( + theme: GraphTheme, + zoomTier: GraphZoomTier, + state: GraphEdgeVisualState, + attrs: EdgeAttributes, + sourceId?: string, + targetId?: string, +): ResolvedEdgeStyle { + const tierConfig = theme.zoomTiers[zoomTier]; + const stateConfig = theme.edges.states[state]; + const edgeVariant = resolveEdgeVariant(state, attrs); + const variantConfig = theme.edges.variants[edgeVariant]; + const baseSize = Number(attrs.baseSize || attrs.size || 0.9); + const visualPriority = Number(attrs.visualPriority ?? 0); + const belowPriorityThreshold = state === "default" + && visualPriority < tierConfig.edgePriorityThreshold + && edgeVariant === "line"; + + if (stateConfig.hide || belowPriorityThreshold) { + return { + hidden: true, + zIndex: 0, + edgeVariant, + arrowVisibilityPolicy: variantConfig.arrowPolicy, + curveStrength: variantConfig.curveStrength, + curvature: 0, + }; + } + + const sizeMultiplier = (state === "default" ? tierConfig.edgeSizeScale : stateConfig.sizeMultiplier) * variantConfig.sizeMultiplier; + const straightType = resolveStraightEdgeType(theme, zoomTier, state, edgeVariant, attrs); + const useCurvedRenderer = tierConfig.showCurves + && zoomTier !== "overview" + && ( + edgeVariant === "pathSignal" + || state === "selected" + || ((state === "neighbor" || state === "hovered") && (edgeVariant === "bidirectionalCurve" || edgeVariant === "parallelCurve")) + ); + const curvature = useCurvedRenderer + ? resolveEdgeCurvature(theme, state, edgeVariant, attrs, sourceId, targetId) + : 0; + + return { + hidden: false, + type: useCurvedRenderer + ? (straightType === "arrow" ? "curvedArrow" : "curve") + : straightType, + color: resolveEdgeColor(theme, zoomTier, state, attrs, attrs.color), + size: Math.max(baseSize * sizeMultiplier, stateConfig.minSize), + zIndex: stateConfig.zIndex, + edgeVariant, + arrowVisibilityPolicy: variantConfig.arrowPolicy, + curveStrength: variantConfig.curveStrength, + curvature, + }; +} + +export function createFocusedGraph( + nodeId: string, + activePath: string[], + activePathEdgeIds: string[] = [], +): Graph { + const focused = new Graph({ + type: "directed", + multi: true, + allowSelfLoops: false, + }); + + const rankedNeighbors = rankNeighbors(nodeId).slice(0, MAX_FOCUS_NEIGHBORS); + const focusIds = new Set([nodeId, ...rankedNeighbors]); + const labelledNeighborIds = new Set(rankedNeighbors.slice(0, FOCUS_PRIMARY_LABELS)); + const pathNodeIds = new Set(activePath); + const pathEdgeIds = buildPathEdgeSet(graph, activePath, activePathEdgeIds); + + const addNode = (id: string, attrs: NodeAttributes) => { + if (!focused.hasNode(id)) { + focused.addNode(id, attrs); + } + }; + + const selectedAttrs = graph.getNodeAttributes(nodeId) as NodeAttributes; + const selectedState = resolveNodeElementStyle(GRAPH_THEME, "inspection", "selected", selectedAttrs, selectedAttrs.label); + addNode(nodeId, { + ...selectedAttrs, + x: 0, + y: 0, + color: selectedState.color, + size: Math.max(selectedState.size, 22), + baseColor: selectedState.color, + baseSize: Math.max(selectedState.size, 22), + label: selectedState.label, + }); + + rankedNeighbors.forEach((neighborId, index) => { + const baseAttrs = graph.getNodeAttributes(neighborId) as NodeAttributes; + const ring = Math.floor(index / FOCUS_RING_CAPACITY); + const ringIndex = index % FOCUS_RING_CAPACITY; + const itemsInRing = Math.min( + FOCUS_RING_CAPACITY, + rankedNeighbors.length - ring * FOCUS_RING_CAPACITY, + ); + const radius = FOCUS_RING_GAP * (ring + 1); + const angle = (Math.PI * 2 * ringIndex) / itemsInRing - Math.PI / 2; + const visualState: GraphNodeVisualState = pathNodeIds.has(neighborId) + ? "path" + : labelledNeighborIds.has(neighborId) + ? "neighbor" + : "default"; + const style = resolveNodeElementStyle( + GRAPH_THEME, + "inspection", + visualState, + { + ...baseAttrs, + labelPriority: labelledNeighborIds.has(neighborId) || pathNodeIds.has(neighborId) + ? Math.max(Number(baseAttrs.labelPriority ?? 0), 1) + : 0, + }, + baseAttrs.label, + ); + + addNode(neighborId, { + ...baseAttrs, + x: Math.cos(angle) * radius, + y: Math.sin(angle) * radius, + color: style.color, + size: Math.max(style.size, 8.5), + baseColor: style.color, + baseSize: Math.max(style.size, 8.5), + label: style.label, + }); + }); + + for (const source of focusIds) { + for (const target of focusIds) { + if (source === target) { + continue; + } + forEachDirectedEdgeBetween(graph, source, target, (edgeId, attrs) => { + const state: GraphEdgeVisualState = pathEdgeIds.has(edgeId) + ? "path" + : source === nodeId || target === nodeId + ? "selected" + : "neighbor"; + const style = resolveEdgeElementStyle(GRAPH_THEME, "inspection", state, attrs, source, target); + focused.mergeDirectedEdgeWithKey(edgeId, source, target, { + ...attrs, + type: style.type, + size: style.size, + color: style.color, + baseSize: style.size, + baseColor: style.color, + curvature: style.curvature, + }); + }); + } + } + + return focused; +} + +export function resolveDisplayGraph( + selectedNodeId: string, + activePath: string[], + activePathEdgeIds: string[], + viewMode: GraphViewMode, +) { + const isFocusedView = viewMode === "focused" && Boolean(selectedNodeId) && graph.hasNode(selectedNodeId); + return isFocusedView && selectedNodeId ? createFocusedGraph(selectedNodeId, activePath, activePathEdgeIds) : graph; +} + +export function createInteractionState( + hoveredNodeId: string | null, + selectedNodeId: string, + selectedEdgeId: string, + activePath: string[], + activePathEdgeIds: string[], + viewMode: GraphViewMode, + zoomTier: GraphZoomTier, + isLayoutRunning: boolean, +): GraphInteractionState { + return { + hoveredNodeId, + selectedNodeId, + selectedEdgeId, + focusedNodeId: selectedNodeId, + activePath, + activePathEdgeIds, + viewMode, + zoomTier, + isLayoutRunning, + }; +} diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/graphTheme.ts b/semantica-explorer/src/workspaces/GraphWorkspace/graphTheme.ts index a1e1aaa2..bce23092 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/graphTheme.ts +++ b/semantica-explorer/src/workspaces/GraphWorkspace/graphTheme.ts @@ -1,6 +1,6 @@ export type GraphZoomTier = "overview" | "structure" | "inspection"; export type GraphNodeVisualState = "default" | "hovered" | "selected" | "neighbor" | "path" | "inactive" | "muted"; -export type GraphEdgeVisualState = "default" | "hovered" | "selected" | "neighbor" | "path" | "inactive" | "muted"; +export type GraphEdgeVisualState = "default" | "backbone" | "hovered" | "selected" | "neighbor" | "path" | "inactive" | "muted"; export type GraphNodeShapeVariant = "default" | "temporal" | "inferred" | "provenance" | "selected"; export type GraphEdgeVariant = "line" | "directional" | "bidirectionalCurve" | "parallelCurve" | "pathSignal"; export type GraphArrowVisibilityPolicy = "hidden" | "contextual" | "always"; @@ -8,11 +8,24 @@ export type GraphLabelVisibilityPolicy = "none" | "priority" | "local" | "always export type GraphBadgeKind = "inferred" | "temporal" | "provenance"; type GraphNodeColorMode = "base" | "selected" | "hovered" | "path" | "muted"; -type GraphEdgeColorMode = "overview" | "structure" | "inspection" | "hover" | "path" | "focus" | "muted"; +type GraphEdgeColorMode = "overview" | "backbone" | "structure" | "inspection" | "hover" | "path" | "focus" | "muted"; export interface GraphTheme { palette: { semantic: string[]; + overview: { + nodeBase: string; + nodeCore: string; + nodeMuted: string; + nodeBorder: string; + nodeTintMix: number; + nodeCoreMix: number; + nodeShellAlpha: number; + nodeCoreAlpha: number; + edgeBackbone: string; + edgeStructure: string; + edgeInspection: string; + }; accent: { selected: string; hovered: string; @@ -56,6 +69,46 @@ export interface GraphTheme { policies: Record; + chip: { + fontFamily: string; + fontWeight: number; + fontSize: number; + maxFontSize: number; + sizeScale: number; + paddingX: number; + paddingY: number; + radius: number; + offsetX: number; + offsetY: number; + background: string; + borderColor: string; + borderAlpha: number; + textColor: string; + shadowColor: string; + shadowAlpha: number; + shadowBlur: number; + }; + hoverCard: { + fontFamily: string; + titleWeight: number; + titleSize: number; + metaWeight: number; + metaSize: number; + paddingX: number; + paddingY: number; + radius: number; + offsetX: number; + offsetY: number; + metaGap: number; + background: string; + borderColor: string; + borderAlpha: number; + textColor: string; + metaColor: string; + shadowColor: string; + shadowAlpha: number; + shadowBlur: number; + }; }; nodes: { backgroundScale: number; @@ -83,6 +136,7 @@ export interface GraphTheme { selectedRing: { color: string; width: number; + nativeSize: number; glowAlpha: number; visibleFrom: GraphZoomTier; }; @@ -160,6 +214,35 @@ export interface GraphTheme { edgeAlpha: number; edgeLineWidth: number; }; + temporalEmphasis: { + minZoomTier: GraphZoomTier; + maxHighlights: number; + radiusMultiplier: number; + glowAlpha: number; + }; + semanticRegions: { + minZoomTier: GraphZoomTier; + maxRegions: number; + minVisibleSamples: number; + fogResolutionScale: number; + splatRadius: number; + blurPasses: number; + densityThreshold: number; + contourThreshold: number; + minMaskPixels: number; + minOccupancyRatio: number; + dominantMassRatio: number; + outerContourMinMaskPixels: number; + fogAlpha: number; + innerContourAlpha: number; + outerContourAlpha: number; + }; + contours: { + minZoomTier: GraphZoomTier; + maxContours: number; + baseRadius: number; + glowAlpha: number; + }; legend: { maxGroups: number; }; @@ -172,50 +255,62 @@ export interface GraphTheme { export const GRAPH_THEME: GraphTheme = { palette: { semantic: [ - "#63E6FF", - "#30D4C7", - "#72A8FF", - "#8D7CFF", - "#C07CFF", - "#FF67D4", - "#FFB24D", - "#C5F55A", + "#3E79F2", + "#149287", + "#2F9F61", + "#555FD6", + "#8A56D8", + "#B65473", + "#C9922E", ], + overview: { + nodeBase: "#0B1320", + nodeCore: "#435D7A", + nodeMuted: "#121927", + nodeBorder: "#64758C", + nodeTintMix: 0.03, + nodeCoreMix: 0.52, + nodeShellAlpha: 0.97, + nodeCoreAlpha: 1, + edgeBackbone: "rgba(83, 111, 148, 0.04)", + edgeStructure: "rgba(72, 90, 118, 0.009)", + edgeInspection: "rgba(98, 120, 148, 0.026)", + }, accent: { - selected: "#FFC857", - hovered: "#7FE0FF", - path: "#FFB870", - temporal: "#6DD6FF", - provenance: "#A98CFF", - inferred: "#FF9A61", + selected: "#F2D288", + hovered: "#8FE7FF", + path: "#D79056", + temporal: "#49D7FF", + provenance: "#C9A5FF", + inferred: "#D07B4D", }, muted: { - fallback: "rgba(130, 145, 165, 0.12)", - nodeAlpha: 0.12, - edgeOverview: "rgba(116, 166, 255, 0.05)", - edgeStructure: "rgba(109, 164, 255, 0.11)", - edgeInspection: "rgba(146, 194, 255, 0.18)", - edgeFocus: "rgba(162, 184, 255, 0.34)", + fallback: "rgba(96, 112, 136, 0.1)", + nodeAlpha: 0.085, + edgeOverview: "rgba(82, 100, 124, 0.009)", + edgeStructure: "rgba(92, 112, 138, 0.02)", + edgeInspection: "rgba(124, 148, 176, 0.066)", + edgeFocus: "rgba(160, 186, 218, 0.16)", }, background: { - canvas: "#060B17", - shell: "rgba(6, 13, 24, 0.76)", - shellBorder: "rgba(112, 196, 255, 0.14)", - shellGlow: "rgba(53, 123, 255, 0.16)", - grid: "rgba(88, 166, 255, 0.038)", - vignette: "rgba(1, 4, 10, 0.82)", - nodeBorder: "#07111C", + canvas: "#07101A", + shell: "rgba(8, 15, 26, 0.8)", + shellBorder: "rgba(118, 162, 207, 0.14)", + shellGlow: "rgba(48, 88, 140, 0.14)", + grid: "rgba(92, 126, 170, 0.034)", + vignette: "rgba(2, 5, 11, 0.84)", + nodeBorder: "#0C1522", }, }, zoomTiers: { overview: { maxRatio: Number.POSITIVE_INFINITY, - nodeScale: 0.9, + nodeScale: 0.66, labelThreshold: 0.985, - labelBudget: 18, + labelBudget: 10, edgePriorityThreshold: 0.72, arrowPriorityThreshold: Number.POSITIVE_INFINITY, - edgeSizeScale: 0.72, + edgeSizeScale: 0.34, showBadges: false, showCurves: false, showContextualArrows: false, @@ -253,23 +348,63 @@ export const GRAPH_THEME: GraphTheme = { local: { minZoomTier: "structure" }, always: { minZoomTier: "overview" }, }, + chip: { + fontFamily: "\"IBM Plex Sans\", Inter, system-ui, sans-serif", + fontWeight: 500, + fontSize: 10, + maxFontSize: 11, + sizeScale: 0.25, + paddingX: 6, + paddingY: 3, + radius: 6, + offsetX: 12, + offsetY: 10, + background: "rgba(8, 14, 24, 0.9)", + borderColor: "rgba(154, 181, 212, 0.16)", + borderAlpha: 0.28, + textColor: "#EAF3FF", + shadowColor: "rgba(0, 0, 0, 0.6)", + shadowAlpha: 0.26, + shadowBlur: 12, + }, + hoverCard: { + fontFamily: "\"IBM Plex Sans\", Inter, system-ui, sans-serif", + titleWeight: 700, + titleSize: 13, + metaWeight: 500, + metaSize: 10, + paddingX: 10, + paddingY: 7, + radius: 12, + offsetX: 16, + offsetY: 16, + metaGap: 5, + background: "rgba(8, 14, 24, 0.94)", + borderColor: "rgba(154, 181, 212, 0.18)", + borderAlpha: 0.32, + textColor: "#F6FBFF", + metaColor: "rgba(184, 214, 255, 0.58)", + shadowColor: "rgba(0, 0, 0, 0.62)", + shadowAlpha: 0.34, + shadowBlur: 15, + }, }, nodes: { backgroundScale: 0.52, - mutedAlpha: 0.12, + mutedAlpha: 0.08, strokeHierarchy: { - overview: { base: 0.8, emphasis: 1.2, muted: 0.45 }, + overview: { base: 0.05, emphasis: 0.34, muted: 0.02 }, structure: { base: 1.05, emphasis: 1.45, muted: 0.55 }, inspection: { base: 1.2, emphasis: 1.7, muted: 0.6 }, }, states: { - default: { color: "base", sizeMultiplier: 1, minSize: 1.45, forceLabel: false, zIndex: 0, borderBoost: 0 }, - hovered: { color: "hovered", sizeMultiplier: 1.34, minSize: 16, forceLabel: true, zIndex: 4, borderBoost: 0.5 }, - selected: { color: "selected", sizeMultiplier: 1.18, minSize: 12, forceLabel: true, zIndex: 3, borderBoost: 0.42 }, - neighbor: { color: "base", sizeMultiplier: 1.08, minSize: 7.2, forceLabel: true, zIndex: 2, borderBoost: 0.18 }, - path: { color: "path", sizeMultiplier: 1.08, minSize: 7.2, forceLabel: true, zIndex: 2, borderBoost: 0.24 }, - inactive: { color: "muted", sizeMultiplier: 0.52, minSize: 0.8, forceLabel: false, zIndex: 0, borderBoost: -0.15 }, - muted: { color: "muted", sizeMultiplier: 0.52, minSize: 0.8, forceLabel: false, zIndex: 0, borderBoost: -0.15 }, + default: { color: "base", sizeMultiplier: 0.72, minSize: 0.68, forceLabel: false, zIndex: 0, borderBoost: -0.42 }, + hovered: { color: "hovered", sizeMultiplier: 1.18, minSize: 12.5, forceLabel: true, zIndex: 4, borderBoost: 0.22 }, + selected: { color: "selected", sizeMultiplier: 1.06, minSize: 10.5, forceLabel: true, zIndex: 3, borderBoost: 0.2 }, + neighbor: { color: "base", sizeMultiplier: 0.84, minSize: 4.8, forceLabel: true, zIndex: 2, borderBoost: -0.08 }, + path: { color: "path", sizeMultiplier: 1.01, minSize: 6.2, forceLabel: true, zIndex: 2, borderBoost: 0.08 }, + inactive: { color: "muted", sizeMultiplier: 0.32, minSize: 0.46, forceLabel: false, zIndex: 0, borderBoost: -0.42 }, + muted: { color: "muted", sizeMultiplier: 0.32, minSize: 0.46, forceLabel: false, zIndex: 0, borderBoost: -0.42 }, }, variants: { default: { sizeMultiplier: 1, borderBoost: 0, haloBoost: 0, badgeVisibleFrom: "inspection" }, @@ -279,35 +414,37 @@ export const GRAPH_THEME: GraphTheme = { selected: { sizeMultiplier: 1.06, borderBoost: 0.22, haloBoost: 0.16, badgeVisibleFrom: "overview" }, }, selectedRing: { - color: "#FFC857", - width: 2.4, - glowAlpha: 0.38, - visibleFrom: "inspection", + color: "#E7C57C", + width: 1.9, + nativeSize: 2.2, + glowAlpha: 0.2, + visibleFrom: "overview", }, badges: { - inferred: { color: "#FF9A61", label: "I" }, - temporal: { color: "#6DD6FF", label: "T" }, - provenance: { color: "#A98CFF", label: "P" }, + inferred: { color: "#C98658", label: "I" }, + temporal: { color: "#52CDEF", label: "T" }, + provenance: { color: "#A289D0", label: "P" }, }, badge: { radius: 7, offset: 3, fontSize: 8, textColor: "#08111d", - background: "rgba(8, 17, 29, 0.9)", - stroke: "rgba(255,255,255,0.2)", - glowAlpha: 0.34, + background: "rgba(8, 17, 29, 0.84)", + stroke: "rgba(255,255,255,0.14)", + glowAlpha: 0.24, }, }, edges: { states: { - default: { color: "inspection", sizeMultiplier: 1, minSize: 0.72, zIndex: 0, forceArrow: false, hide: false }, - hovered: { color: "hover", sizeMultiplier: 1.55, minSize: 1.8, zIndex: 3, forceArrow: true, hide: false }, - selected: { color: "hover", sizeMultiplier: 1.55, minSize: 1.8, zIndex: 3, forceArrow: true, hide: false }, - neighbor: { color: "focus", sizeMultiplier: 1.08, minSize: 0.95, zIndex: 1, forceArrow: false, hide: false }, - path: { color: "path", sizeMultiplier: 1.7, minSize: 2.2, zIndex: 4, forceArrow: true, hide: false }, - inactive: { color: "muted", sizeMultiplier: 1, minSize: 0.45, zIndex: 0, forceArrow: false, hide: true }, - muted: { color: "muted", sizeMultiplier: 1, minSize: 0.45, zIndex: 0, forceArrow: false, hide: true }, + default: { color: "structure", sizeMultiplier: 0.74, minSize: 0.18, zIndex: 0, forceArrow: false, hide: false }, + backbone: { color: "backbone", sizeMultiplier: 0.72, minSize: 0.18, zIndex: 1, forceArrow: false, hide: false }, + hovered: { color: "hover", sizeMultiplier: 1.42, minSize: 1.45, zIndex: 3, forceArrow: true, hide: false }, + selected: { color: "hover", sizeMultiplier: 1.42, minSize: 1.45, zIndex: 3, forceArrow: true, hide: false }, + neighbor: { color: "focus", sizeMultiplier: 0.92, minSize: 0.5, zIndex: 1, forceArrow: false, hide: false }, + path: { color: "path", sizeMultiplier: 1.5, minSize: 1.8, zIndex: 4, forceArrow: true, hide: false }, + inactive: { color: "muted", sizeMultiplier: 1, minSize: 0.16, zIndex: 0, forceArrow: false, hide: true }, + muted: { color: "muted", sizeMultiplier: 1, minSize: 0.16, zIndex: 0, forceArrow: false, hide: true }, }, variants: { line: { baseType: "line", arrowPolicy: "hidden", curveStrength: 0, sizeMultiplier: 1, glowAlpha: 0 }, @@ -318,8 +455,8 @@ export const GRAPH_THEME: GraphTheme = { }, }, overlays: { - hoverGlowAlpha: 0.26, - pathGlowAlpha: 0.2, + hoverGlowAlpha: 0.18, + pathGlowAlpha: 0.16, glowRadiusMultiplier: 4.8, minGlowRadius: 16, pulseRadius: 11, @@ -360,6 +497,35 @@ export const GRAPH_THEME: GraphTheme = { edgeAlpha: 0.42, edgeLineWidth: 1.8, }, + temporalEmphasis: { + minZoomTier: "structure", + maxHighlights: 48, + radiusMultiplier: 4.2, + glowAlpha: 0.12, + }, + semanticRegions: { + minZoomTier: "overview", + maxRegions: 3, + minVisibleSamples: 14, + fogResolutionScale: 0.22, + splatRadius: 13, + blurPasses: 2, + densityThreshold: 0.16, + contourThreshold: 0.28, + minMaskPixels: 170, + minOccupancyRatio: 0.0022, + dominantMassRatio: 0.62, + outerContourMinMaskPixels: 240, + fogAlpha: 0.11, + innerContourAlpha: 0.16, + outerContourAlpha: 0.045, + }, + contours: { + minZoomTier: "overview", + maxContours: 3, + baseRadius: 88, + glowAlpha: 0.055, + }, legend: { maxGroups: 8, }, @@ -436,6 +602,35 @@ export function darkenHex(hexColor: string, amount: number): string { return `#${[red, green, blue].map((value) => value.toString(16).padStart(2, "0")).join("")}`; } +export function blendHex(baseColor: string, tintColor: string, amount: number): string { + if (!baseColor.startsWith("#") || !tintColor.startsWith("#")) { + return tintColor || baseColor; + } + + const normalize = (value: string) => { + const hex = value.slice(1); + return hex.length === 3 + ? hex.split("").map((char) => `${char}${char}`).join("") + : hex; + }; + + const base = normalize(baseColor); + const tint = normalize(tintColor); + if (base.length !== 6 || tint.length !== 6) { + return tintColor || baseColor; + } + + const mix = clamp(0, amount, 1); + const mixChannel = (left: number, right: number) => Math.round(left + (right - left) * mix); + const channels = [0, 2, 4].map((offset) => { + const left = Number.parseInt(base.slice(offset, offset + 2), 16); + const right = Number.parseInt(tint.slice(offset, offset + 2), 16); + return mixChannel(left, right).toString(16).padStart(2, "0"); + }); + + return `#${channels.join("")}`; +} + export function getZoomTier(ratio: number): GraphZoomTier { if (ratio <= GRAPH_THEME.zoomTiers.inspection.maxRatio) { return "inspection"; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/plugins/explorationEffectsPluginPhaseC.tsx b/semantica-explorer/src/workspaces/GraphWorkspace/plugins/explorationEffectsPluginPhaseC.tsx new file mode 100644 index 00000000..3fb936bb --- /dev/null +++ b/semantica-explorer/src/workspaces/GraphWorkspace/plugins/explorationEffectsPluginPhaseC.tsx @@ -0,0 +1,527 @@ +import type { CSSProperties } from "react"; + +import type { + GraphAnalyticsSnapshot, + GraphDiagnosticsSnapshot, + GraphEffectAvailability, + GraphEffectToggle, +} from "../types"; +import type { GraphPlugin } from "./types"; + +const EFFECTS_PANEL_ID = "effects-panel"; + +type EffectRowConfig = { + key: GraphEffectToggle; + label: string; + description: string; +}; + +const SCENE_EFFECT_ROWS: EffectRowConfig[] = [ + { + key: "pathPulseEnabled", + label: "Path Pulse", + description: "Animated pulse on the active selected path.", + }, + { + key: "pathFlowEnabled", + label: "Path Flow", + description: "Directional flow accents along the active selected path.", + }, + { + key: "lensEnabled", + label: "Neighborhood Lens", + description: "Local emphasis around the hovered or selected node.", + }, + { + key: "temporalEmphasisEnabled", + label: "Temporal Emphasis", + description: "Subtle glow around temporally relevant nodes in the active time window.", + }, + { + key: "semanticRegionsEnabled", + label: "Semantic Regions", + description: "Quiet semantic hulls around the strongest visible topic clusters.", + }, + { + key: "contoursEnabled", + label: "Contours", + description: "Low-contrast density halos around the strongest visible anchors.", + }, + { + key: "legendEnabled", + label: "Regions Summary", + description: "Keep the regions and signals summary visible in the Effects panel.", + }, +]; + +const INTELLIGENCE_EFFECT_ROWS: EffectRowConfig[] = [ + { + key: "pathfindingEnabled", + label: "Directed Pathfinding", + description: "Compare the traced path against a strict local directed shortest path.", + }, + { + key: "communitiesEnabled", + label: "Community Regions", + description: "Detect stable Louvain communities for orientation and scene grouping.", + }, + { + key: "centralityEnabled", + label: "Centrality Ranking", + description: "Rank the strongest graph anchors for labels, regions, and navigation.", + }, +]; + +const AVAILABILITY_KEYS: Record = { + pathPulseEnabled: "pathPulse", + pathFlowEnabled: "pathFlow", + lensEnabled: "lens", + temporalEmphasisEnabled: "temporalEmphasis", + semanticRegionsEnabled: "semanticRegions", + contoursEnabled: "contours", + pathfindingEnabled: "pathfinding", + communitiesEnabled: "communities", + centralityEnabled: "centrality", + legendEnabled: "legend", + diagnosticsEnabled: "diagnostics", +}; + +function renderAvailabilityText(availability: GraphEffectAvailability) { + if (availability.available) { + if (typeof availability.visibleSegments === "number" && typeof availability.segmentCap === "number") { + return `${availability.reason} - ${availability.visibleSegments}/${availability.segmentCap} segments`; + } + return availability.reason; + } + + return availability.detail ? `${availability.reason} - ${availability.detail}` : availability.reason; +} + +function collectFallbackLegendItems(context: Parameters>[0]) { + const groups = new Map(); + context.graph.forEachNode((_nodeId, attrs) => { + const semanticGroup = String(attrs.semanticGroup || attrs.nodeType || "entity"); + const color = String(attrs.baseColor || context.theme.palette.semantic[0]); + const current = groups.get(semanticGroup); + groups.set(semanticGroup, { + count: (current?.count ?? 0) + 1, + color, + }); + }); + + return [...groups.entries()] + .map(([group, data]) => ({ group, ...data })) + .sort((left, right) => right.count - left.count) + .slice(0, context.theme.effects.legend.maxGroups); +} + +function resolveAvailability( + availabilityMap: GraphDiagnosticsSnapshot["effectAvailability"] | undefined, + key: GraphEffectToggle, + enabled: boolean, +): GraphEffectAvailability { + return availabilityMap?.[AVAILABILITY_KEYS[key]] ?? { + enabled, + available: false, + reason: "Waiting for graph runtime", + }; +} + +function EffectToggleRow({ + label, + description, + checked, + availability, + onToggle, +}: { + label: string; + description: string; + checked: boolean; + availability: GraphEffectAvailability; + onToggle: () => void; +}) { + return ( +
+
+
{label}
+
{description}
+
{renderAvailabilityText(availability)}
+
+ +
+ ); +} + +function renderRegionsAndSignals( + context: Parameters>[0], + analytics: GraphAnalyticsSnapshot | null, +) { + const fallbackLegendItems = collectFallbackLegendItems(context); + const semanticRegions = analytics?.semanticRegions.summaries ?? []; + const communities = analytics?.communities.summaries ?? []; + const centrality = analytics?.centrality.topNodes ?? []; + const directedPath = analytics?.directedPath ?? null; + + if (!semanticRegions.length && !communities.length && !centrality.length && !fallbackLegendItems.length && !directedPath) { + return
Regions and intelligence summaries will populate when graph analytics are ready.
; + } + + return ( +
+ {semanticRegions.length ? ( +
+
Semantic regions
+ {semanticRegions.map((region) => ( +
+ +
+
{region.semanticGroup}
+
+ {region.visibleNodeCount.toLocaleString()} visible / {region.nodeCount.toLocaleString()} total +
+
+
{region.anchorLabel}
+
+ ))} +
+ ) : null} + + {communities.length ? ( +
+
Community anchors
+ {communities.slice(0, 3).map((community) => ( +
+
+
{community.anchorLabel}
+
+ Community {community.communityId} - {community.visibleNodeCount} visible / {community.nodeCount} total +
+
+
{community.dominantSemanticGroup}
+
+ ))} +
+ ) : null} + + {centrality.length ? ( +
+
Centrality leaders
+ {centrality.slice(0, 3).map((node) => ( +
+
+
{node.label}
+
+ {node.semanticGroup} - score {node.score.toFixed(3)} +
+
+
deg {node.degree.toFixed(3)}
+
+ ))} +
+ ) : null} + + {directedPath ? ( +
+
Directed pathfinding
+
+
+
{directedPath.ready ? "Local directed path ready" : "Waiting for path context"}
+
{directedPath.reason}
+
+ {directedPath.ready ? ( +
+ {directedPath.length} hops{directedPath.verifiedAgainstActivePath ? " - match" : ""} +
+ ) : null} +
+
+ ) : null} + + {!semanticRegions.length && !communities.length && !centrality.length && fallbackLegendItems.length ? ( +
+
Fallback semantic legend
+ {fallbackLegendItems.map((item) => ( +
+ +
+
{item.group}
+
{item.count.toLocaleString()} nodes
+
+
+ ))} +
+ ) : null} +
+ ); +} + +export const explorationEffectsPluginPhaseC: GraphPlugin = { + id: "exploration-effects", + mount: () => {}, + unmount: () => {}, + onStateChange: () => {}, + toolbarItems: (context) => [ + { + id: "effects-toggle", + label: "Effects", + title: "Open exploration effects controls", + active: context.isPanelOpen(EFFECTS_PANEL_ID), + order: 18, + onClick: () => context.dispatchAction({ type: "togglePanel", panelId: EFFECTS_PANEL_ID }), + }, + ], + renderPanel: (context) => { + if (!context.isPanelOpen(EFFECTS_PANEL_ID)) { + return null; + } + + const effectsState = context.getEffectsState(); + const diagnosticsSnapshot = context.getDiagnosticsSnapshot(); + const analyticsSnapshot = context.getAnalyticsSnapshot(); + const availability = diagnosticsSnapshot?.effectAvailability; + const showSignalsSection = + effectsState.legendEnabled + || effectsState.semanticRegionsEnabled + || effectsState.communitiesEnabled + || effectsState.centralityEnabled + || effectsState.pathfindingEnabled; + + return { + id: EFFECTS_PANEL_ID, + title: "Effects", + placement: "bottom", + order: 8, + defaultOpen: false, + preferredWidth: 460, + preferredHeight: 360, + content: ( +
+
Exploration effects
+ +
+
Scene effects
+ {SCENE_EFFECT_ROWS.map((row) => ( + context.dispatchAction({ type: "toggleEffect", effect: row.key })} + /> + ))} +
+ +
+
Graph intelligence
+ {INTELLIGENCE_EFFECT_ROWS.map((row) => ( + context.dispatchAction({ type: "toggleEffect", effect: row.key })} + /> + ))} +
+ + {showSignalsSection ? ( +
+
Regions and signals
+ {renderRegionsAndSignals(context, analyticsSnapshot)} +
+ ) : null} + + {import.meta.env.DEV ? ( +
+
Diagnostics
+ context.dispatchAction({ type: "toggleEffect", effect: "diagnosticsEnabled" })} + /> + {effectsState.diagnosticsEnabled && diagnosticsSnapshot ? ( +
+ Runtime snapshot +
+                    {JSON.stringify({ diagnostics: diagnosticsSnapshot, analytics: analyticsSnapshot }, null, 2)}
+                  
+
+ ) : null} +
+ ) : null} +
+ ), + }; + }, +}; + +const panelBodyStyle: CSSProperties = { + display: "flex", + flexDirection: "column", + gap: 12, +}; + +const panelEyebrowStyle: CSSProperties = { + color: "#8ea4be", + fontSize: 11, + fontWeight: 700, + letterSpacing: "0.08em", + textTransform: "uppercase", +}; + +const sectionStyle: CSSProperties = { + display: "flex", + flexDirection: "column", + gap: 8, + padding: "10px 12px", + borderRadius: 14, + border: "1px solid rgba(255,255,255,0.06)", + background: "rgba(255,255,255,0.025)", +}; + +const sectionTitleStyle: CSSProperties = { + color: "#dce9f8", + fontSize: 12, + fontWeight: 700, +}; + +const subsectionTitleStyle: CSSProperties = { + color: "#9cc4ec", + fontSize: 11, + fontWeight: 700, + letterSpacing: "0.05em", + textTransform: "uppercase", +}; + +const toggleRowStyle: CSSProperties = { + display: "flex", + alignItems: "center", + gap: 12, + padding: "8px 0", +}; + +const rowTitleStyle: CSSProperties = { + color: "#f3f7fd", + fontSize: 13, + fontWeight: 600, +}; + +const rowDescriptionStyle: CSSProperties = { + color: "#a1b7cf", + fontSize: 12, + lineHeight: 1.45, +}; + +const rowMetaStyle: CSSProperties = { + color: "#7fc6ff", + fontSize: 11, + lineHeight: 1.45, +}; + +const toggleButtonStyle: CSSProperties = { + minWidth: 52, + padding: "8px 10px", + borderRadius: 999, + border: "1px solid rgba(255,255,255,0.08)", + background: "rgba(255,255,255,0.03)", + color: "#cfe0f4", + fontSize: 12, + fontWeight: 700, + cursor: "pointer", +}; + +const toggleButtonActiveStyle: CSSProperties = { + ...toggleButtonStyle, + background: "rgba(31, 111, 235, 0.24)", + border: "1px solid rgba(127, 208, 255, 0.28)", + color: "#eef6ff", +}; + +const legendRowStyle: CSSProperties = { + display: "flex", + alignItems: "center", + gap: 10, + padding: "8px 10px", + borderRadius: 12, + border: "1px solid rgba(255,255,255,0.06)", + background: "rgba(255,255,255,0.025)", +}; + +const legendSwatchStyle: CSSProperties = { + width: 10, + height: 10, + borderRadius: 999, + flexShrink: 0, +}; + +const signalRowStyle: CSSProperties = { + display: "flex", + alignItems: "center", + gap: 10, + padding: "8px 10px", + borderRadius: 12, + border: "1px solid rgba(255,255,255,0.05)", + background: "rgba(255,255,255,0.02)", +}; + +const signalBadgeStyle: CSSProperties = { + padding: "5px 8px", + borderRadius: 999, + background: "rgba(31, 111, 235, 0.16)", + border: "1px solid rgba(127, 208, 255, 0.16)", + color: "#dce9f8", + fontSize: 11, + fontWeight: 700, + whiteSpace: "nowrap", +}; + +const detailsStyle: CSSProperties = { + borderRadius: 12, + border: "1px solid rgba(255,255,255,0.05)", + background: "rgba(0,0,0,0.14)", + overflow: "hidden", +}; + +const summaryStyle: CSSProperties = { + cursor: "pointer", + padding: "10px 12px", + color: "#c6d4e3", + fontSize: 12, + fontWeight: 700, + letterSpacing: "0.04em", + textTransform: "uppercase", +}; + +const diagnosticsPreStyle: CSSProperties = { + margin: 0, + padding: "0 12px 12px", + color: "#dce9f8", + fontSize: 11, + lineHeight: 1.55, + whiteSpace: "pre-wrap", + wordBreak: "break-word", +}; + +const emptyTextStyle: CSSProperties = { + color: "#8ea4be", + fontSize: 12, + lineHeight: 1.5, +}; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/plugins/index.ts b/semantica-explorer/src/workspaces/GraphWorkspace/plugins/index.ts index fa08c51c..379cb59b 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/plugins/index.ts +++ b/semantica-explorer/src/workspaces/GraphWorkspace/plugins/index.ts @@ -1,4 +1,4 @@ -export { explorationEffectsPlugin } from "./explorationEffectsPlugin"; +export { explorationEffectsPluginPhaseC as explorationEffectsPlugin } from "./explorationEffectsPluginPhaseC"; export { legendPlugin } from "./legendPlugin"; export { neighborhoodPanelPlugin } from "./neighborhoodPanelPlugin"; export { temporalOverlayPlugin } from "./temporalOverlayPlugin"; @@ -11,7 +11,6 @@ export type { GraphPluginOverlayDescriptor, GraphPluginPanelDescriptor, GraphPluginRegistryEntry, - GraphPluginRuntime, GraphPluginToolbarItem, GraphTemporalState, } from "./types"; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/plugins/neighborhoodPanelPlugin.tsx b/semantica-explorer/src/workspaces/GraphWorkspace/plugins/neighborhoodPanelPlugin.tsx index 67799567..2fb45de8 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/plugins/neighborhoodPanelPlugin.tsx +++ b/semantica-explorer/src/workspaces/GraphWorkspace/plugins/neighborhoodPanelPlugin.tsx @@ -5,6 +5,14 @@ import type { GraphPlugin } from "./types"; const NEIGHBORHOOD_PANEL_ID = "neighborhood-panel"; const MAX_NEIGHBORS = 10; +function maxWeightBetween(graphRef: any, sourceId: string, targetId: string): number { + let weight = 0; + graphRef.forEachDirectedEdge(sourceId, targetId, (_edgeId: string, attrs: { weight?: number }) => { + weight = Math.max(weight, Number(attrs.weight ?? 0)); + }); + return weight; +} + function formatNeighborMeta(neighbor: { nodeType: string; degree: number; weight: number }) { const parts = [neighbor.nodeType, `degree ${neighbor.degree}`]; if (neighbor.weight > 0) { @@ -51,15 +59,10 @@ export const neighborhoodPanelPlugin: GraphPlugin = { .neighbors(selected.id) .map((neighborId) => { const attrs = context.graph.getNodeAttributes(neighborId); - let weight = 0; - if (context.graph.hasDirectedEdge(selected.id, neighborId)) { - const edge = context.graph.getDirectedEdgeAttributes(selected.id, neighborId) as { weight?: number }; - weight = Math.max(weight, Number(edge.weight ?? 0)); - } - if (context.graph.hasDirectedEdge(neighborId, selected.id)) { - const edge = context.graph.getDirectedEdgeAttributes(neighborId, selected.id) as { weight?: number }; - weight = Math.max(weight, Number(edge.weight ?? 0)); - } + const weight = Math.max( + maxWeightBetween(context.graph, selected.id, neighborId), + maxWeightBetween(context.graph, neighborId, selected.id), + ); return { id: neighborId, label: String(attrs.label || neighborId), diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/plugins/types.ts b/semantica-explorer/src/workspaces/GraphWorkspace/plugins/types.ts index e8238096..8814512f 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/plugins/types.ts +++ b/semantica-explorer/src/workspaces/GraphWorkspace/plugins/types.ts @@ -1,19 +1,23 @@ import type { ReactNode } from "react"; import type Graph from "graphology"; -import type Sigma from "sigma"; import { graph, type EdgeAttributes, type NodeAttributes } from "../../../store/graphStore"; import type { GraphTheme } from "../graphTheme"; +import type { GraphSceneRuntime } from "../scene"; import type { + GraphAnalyticsSnapshot, GraphDiagnosticsSnapshot, GraphEffectsState, GraphEffectToggle, GraphInteractionState, GraphLoadSummary, GraphSelectedNodeState, + GraphTemporalState, GraphViewMode, } from "../types"; +export type { GraphTemporalState } from "../types"; + export type GraphPluginId = string; export type GraphPluginPanelPlacement = "side" | "bottom"; @@ -22,13 +26,6 @@ export interface GraphInspectorState { ownsSelectionDetails: boolean; } -export interface GraphTemporalState { - currentTime: Date | null; - activeNodeCount: number | null; - minDate?: string; - maxDate?: string; -} - export type GraphPluginActionRequest = | { type: "fitView" } | { type: "focusNode"; nodeId: string } @@ -67,14 +64,8 @@ export interface GraphPluginOverlayDescriptor { element: ReactNode; } -export interface GraphPluginRuntime { - sigma: Sigma; - graph: typeof graph | Graph; - displayGraph: typeof graph | Graph; -} - export interface GraphPluginContext { - readonly sigma: Sigma | null; + readonly scene: GraphSceneRuntime | null; readonly graph: typeof graph | Graph; readonly displayGraph: typeof graph | Graph; readonly theme: GraphTheme; @@ -85,6 +76,7 @@ export interface GraphPluginContext { getTemporalState: () => GraphTemporalState | null; getEffectsState: () => GraphEffectsState; getDiagnosticsSnapshot: () => GraphDiagnosticsSnapshot | null; + getAnalyticsSnapshot: () => GraphAnalyticsSnapshot | null; isPanelOpen: (panelId: string) => boolean; dispatchAction: (action: GraphPluginActionRequest) => void; } diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/scene.ts b/semantica-explorer/src/workspaces/GraphWorkspace/scene.ts new file mode 100644 index 00000000..6a099c48 --- /dev/null +++ b/semantica-explorer/src/workspaces/GraphWorkspace/scene.ts @@ -0,0 +1,65 @@ +import type { ForwardRefExoticComponent, ReactNode, RefAttributes } from "react"; +import type Graph from "graphology"; + +import { graph, type EdgeAttributes, type NodeAttributes } from "../../store/graphStore"; +import type { + GraphAnalyticsSnapshot, + GraphCameraState, + GraphDiagnosticsSnapshot, + GraphEffectsState, + GraphInteractionState, + GraphLayoutSource, + GraphLayoutStatus, + GraphTemporalState, + GraphViewMode, +} from "./types"; + +export type GraphSceneGraph = typeof graph | Graph; +export type GraphSceneRenderer = "sigma"; + +export interface GraphSceneRuntime { + renderer: GraphSceneRenderer; + scene: unknown; + graph: GraphSceneGraph; + displayGraph: GraphSceneGraph; + requestRender: () => void; + getCameraState: () => GraphCameraState | null; +} + +export interface GraphSceneEventMap { + onNodeSelect?: (nodeId: string) => void; + onEdgeSelect?: (edgeId: string) => void; + onInteractionStateChange?: (interactionState: GraphInteractionState) => void; + onCameraStateChange?: (cameraState: GraphCameraState) => void; + onDiagnosticsChange?: (effectAvailability: GraphDiagnosticsSnapshot["effectAvailability"]) => void; + onAnalyticsChange?: (analytics: GraphAnalyticsSnapshot | null) => void; + onRuntimeChange?: (runtime: GraphSceneRuntime | null) => void; +} + +export interface GraphSceneProps extends GraphSceneEventMap { + selectedNodeId: string; + selectedEdgeId: string; + activePath?: string[]; + activePathEdgeIds?: string[]; + effectsState: GraphEffectsState; + temporalState?: GraphTemporalState | null; + isLayoutRunning: boolean; + onLayoutRunningChange?: (running: boolean) => void; + layoutSource?: GraphLayoutSource; + onLayoutStatusChange?: (status: GraphLayoutStatus) => void; + viewMode: GraphViewMode; + className?: string; + showFitViewButton?: boolean; + pluginOverlays?: ReactNode[]; +} + +export interface GraphSceneHandle { + fitView: () => void; + focusNode: (nodeId: string) => void; + getRuntime: () => GraphSceneRuntime | null; + setLayoutRunning?: (running: boolean) => void; +} + +export type GraphSceneAdapter = ForwardRefExoticComponent< + GraphSceneProps & RefAttributes +>; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/sigmaNativeRendering.ts b/semantica-explorer/src/workspaces/GraphWorkspace/sigmaNativeRendering.ts new file mode 100644 index 00000000..657c520e --- /dev/null +++ b/semantica-explorer/src/workspaces/GraphWorkspace/sigmaNativeRendering.ts @@ -0,0 +1,336 @@ +import EdgeCurveProgram, { EdgeCurvedArrowProgram } from "@sigma/edge-curve"; +import { NodeProgram, type ProgramInfo } from "sigma/rendering"; +import { DEFAULT_EDGE_PROGRAM_CLASSES, DEFAULT_NODE_PROGRAM_CLASSES } from "sigma/settings"; +import type { NodeDisplayData, RenderParams } from "sigma/types"; +import { floatColor } from "sigma/utils"; +import type { NodeHoverDrawingFunction, NodeLabelDrawingFunction } from "sigma/rendering"; + +import { GRAPH_THEME, withAlpha } from "./graphTheme"; + +type SemanticaNodeDrawData = { + x: number; + y: number; + size: number; + label: string; + color: string; + shellColor?: string; + coreScale?: number; + borderColor?: string; + ringColor?: string; + ringSize?: number; + nodeType?: string; +}; + +const MINERAL_DISC_UNIFORMS = ["u_sizeRatio", "u_correctionRatio", "u_matrix"] as const; + +const MINERAL_DISC_FRAGMENT_SHADER = /* glsl */ ` +precision highp float; + +varying vec4 v_coreColor; +varying vec4 v_shellColor; +varying vec4 v_ringColor; +varying vec4 v_color; +varying vec2 v_diffVector; +varying float v_radius; +varying float v_ringSize; +varying float v_coreScale; + +uniform float u_correctionRatio; + +const float bias = 255.0 / 254.0; +const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0); + +float discMetric(vec2 point) { + return length(point); +} + +void main(void) { + vec2 unit = v_diffVector / max(v_radius, 0.0001); + float metric = discMetric(unit); + float aa = (2.4 * u_correctionRatio) / max(v_radius, 1.0); + float alpha = 1.0 - smoothstep(1.0 - aa, 1.0 + aa, metric); + + #ifdef PICKING_MODE + if (alpha <= 0.0) { + gl_FragColor = transparent; + } else { + gl_FragColor = v_color; + gl_FragColor.a *= bias; + } + #else + if (alpha <= 0.0) { + gl_FragColor = transparent; + return; + } + + float ringNorm = clamp(v_ringSize / max(v_radius, 1.0), 0.0, 0.45); + float ringStart = max(0.0, 1.0 - ringNorm); + float coreEdge = clamp(v_coreScale, 0.06, 0.78); + float coreBlend = 1.0 - smoothstep(max(coreEdge - 0.14, 0.0), coreEdge, metric); + float bodyLight = 1.0 - smoothstep(0.0, 0.82, metric); + vec4 color = mix(v_shellColor, v_coreColor, coreBlend); + color.rgb += vec3(0.022) * pow(bodyLight, 1.45); + + if (ringNorm > 0.0 && metric >= ringStart) { + color = v_ringColor; + } + color.a *= alpha; + gl_FragColor = color; + #endif +} +`; + +const MINERAL_DISC_VERTEX_SHADER = /* glsl */ ` +attribute vec4 a_id; +attribute vec2 a_position; +attribute float a_size; +attribute float a_angle; +attribute vec4 a_coreColor; +attribute vec4 a_shellColor; +attribute vec4 a_ringColor; +attribute float a_ringSize; +attribute float a_coreScale; + +uniform mat3 u_matrix; +uniform float u_sizeRatio; +uniform float u_correctionRatio; + +varying vec4 v_coreColor; +varying vec4 v_shellColor; +varying vec4 v_ringColor; +varying vec4 v_color; +varying vec2 v_diffVector; +varying float v_radius; +varying float v_ringSize; +varying float v_coreScale; + +const float bias = 255.0 / 254.0; + +void main() { + float size = a_size * u_correctionRatio / u_sizeRatio * 4.0; + vec2 diffVector = size * vec2(cos(a_angle), sin(a_angle)); + vec2 position = a_position + diffVector; + + gl_Position = vec4( + (u_matrix * vec3(position, 1)).xy, + 0, + 1 + ); + + v_diffVector = diffVector; + v_radius = size / 2.0; + v_ringSize = a_ringSize; + v_coreScale = a_coreScale; + + #ifdef PICKING_MODE + v_color = a_id; + #else + v_coreColor = a_coreColor; + v_shellColor = a_shellColor; + v_ringColor = a_ringColor; + #endif + + v_color.a *= bias; +} +`; + +class MineralDiscNodeProgram extends NodeProgram<(typeof MINERAL_DISC_UNIFORMS)[number]> { + static readonly ANGLE_1 = 0; + static readonly ANGLE_2 = (2 * Math.PI) / 3; + static readonly ANGLE_3 = (4 * Math.PI) / 3; + + drawLabel = drawSemanticaNodeLabel; + + drawHover = drawSemanticaNodeHover; + + getDefinition() { + return { + VERTICES: 3, + VERTEX_SHADER_SOURCE: MINERAL_DISC_VERTEX_SHADER, + FRAGMENT_SHADER_SOURCE: MINERAL_DISC_FRAGMENT_SHADER, + METHOD: WebGLRenderingContext.TRIANGLES, + UNIFORMS: MINERAL_DISC_UNIFORMS, + ATTRIBUTES: [ + { name: "a_position", size: 2, type: WebGLRenderingContext.FLOAT }, + { name: "a_size", size: 1, type: WebGLRenderingContext.FLOAT }, + { name: "a_coreColor", size: 4, type: WebGLRenderingContext.UNSIGNED_BYTE, normalized: true }, + { name: "a_shellColor", size: 4, type: WebGLRenderingContext.UNSIGNED_BYTE, normalized: true }, + { name: "a_ringColor", size: 4, type: WebGLRenderingContext.UNSIGNED_BYTE, normalized: true }, + { name: "a_ringSize", size: 1, type: WebGLRenderingContext.FLOAT }, + { name: "a_coreScale", size: 1, type: WebGLRenderingContext.FLOAT }, + { name: "a_id", size: 4, type: WebGLRenderingContext.UNSIGNED_BYTE, normalized: true }, + ], + CONSTANT_ATTRIBUTES: [ + { name: "a_angle", size: 1, type: WebGLRenderingContext.FLOAT }, + ], + CONSTANT_DATA: [ + [MineralDiscNodeProgram.ANGLE_1], + [MineralDiscNodeProgram.ANGLE_2], + [MineralDiscNodeProgram.ANGLE_3], + ], + }; + } + + processVisibleItem(nodeIndex: number, startIndex: number, data: NodeDisplayData & SemanticaNodeDrawData): void { + const array = this.array; + const ringColor = resolveAccentBorderColor(data.ringSize, data.ringColor, data.borderColor, GRAPH_THEME.nodes.selectedRing.color); + + array[startIndex++] = data.x; + array[startIndex++] = data.y; + array[startIndex++] = data.size; + array[startIndex++] = floatColor(data.color || GRAPH_THEME.palette.overview.nodeCore); + array[startIndex++] = floatColor(data.shellColor || withAlpha(GRAPH_THEME.palette.overview.nodeBase, GRAPH_THEME.palette.overview.nodeShellAlpha)); + array[startIndex++] = floatColor(ringColor); + array[startIndex++] = data.ringSize || 0; + array[startIndex++] = data.coreScale ?? 0.22; + array[startIndex++] = nodeIndex; + } + + setUniforms(params: RenderParams, { gl, uniformLocations }: ProgramInfo<(typeof MINERAL_DISC_UNIFORMS)[number]>): void { + gl.uniform1f(uniformLocations.u_correctionRatio, params.correctionRatio); + gl.uniform1f(uniformLocations.u_sizeRatio, params.sizeRatio); + gl.uniformMatrix3fv(uniformLocations.u_matrix, false, params.matrix); + } +} + +function resolveAccentBorderColor( + ringSize: number | undefined, + ringColor: string | undefined, + borderColor: string | undefined, + fallbackColor: string, +) { + if (typeof ringSize === "number" && ringSize > 0 && ringColor) { + return ringColor; + } + + return borderColor || fallbackColor; +} + +function drawRoundedRect( + context: CanvasRenderingContext2D, + x: number, + y: number, + width: number, + height: number, + radius: number, +) { + const clampedRadius = Math.max(0, Math.min(radius, Math.min(width, height) / 2)); + context.beginPath(); + context.moveTo(x + clampedRadius, y); + context.lineTo(x + width - clampedRadius, y); + context.quadraticCurveTo(x + width, y, x + width, y + clampedRadius); + context.lineTo(x + width, y + height - clampedRadius); + context.quadraticCurveTo(x + width, y + height, x + width - clampedRadius, y + height); + context.lineTo(x + clampedRadius, y + height); + context.quadraticCurveTo(x, y + height, x, y + height - clampedRadius); + context.lineTo(x, y + clampedRadius); + context.quadraticCurveTo(x, y, x + clampedRadius, y); + context.closePath(); +} + +export const drawSemanticaNodeLabel: NodeLabelDrawingFunction = (context, rawData) => { + const data = rawData as typeof rawData & SemanticaNodeDrawData; + if (!data.label) { + return; + } + + const chipTheme = GRAPH_THEME.labels.chip; + const fontSize = Math.max( + chipTheme.fontSize, + Math.min(chipTheme.maxFontSize, data.size * chipTheme.sizeScale), + ); + const font = `${chipTheme.fontWeight} ${fontSize}px ${chipTheme.fontFamily}`; + const paddingX = chipTheme.paddingX; + const paddingY = chipTheme.paddingY; + const borderColor = resolveAccentBorderColor(data.ringSize, data.ringColor, data.borderColor, chipTheme.borderColor); + + context.save(); + context.font = font; + context.textBaseline = "middle"; + const metrics = context.measureText(data.label); + const width = metrics.width + paddingX * 2; + const height = fontSize + paddingY * 2; + const x = data.x + Math.max(data.size * 0.7, chipTheme.offsetX); + const y = data.y - Math.max(data.size * 0.9, chipTheme.offsetY) - height; + + context.shadowColor = withAlpha(chipTheme.shadowColor, chipTheme.shadowAlpha); + context.shadowBlur = chipTheme.shadowBlur; + context.fillStyle = chipTheme.background; + drawRoundedRect(context, x, y, width, height, chipTheme.radius); + context.fill(); + + context.shadowBlur = 0; + context.strokeStyle = withAlpha(borderColor, chipTheme.borderAlpha); + context.lineWidth = 1; + drawRoundedRect(context, x, y, width, height, chipTheme.radius); + context.stroke(); + + context.fillStyle = chipTheme.textColor; + context.fillText(data.label, x + paddingX, y + height / 2); + context.restore(); +}; + +export const drawSemanticaNodeHover: NodeHoverDrawingFunction = (context, rawData) => { + const data = rawData as typeof rawData & SemanticaNodeDrawData; + if (!data.label) { + return; + } + + const hoverTheme = GRAPH_THEME.labels.hoverCard; + const borderColor = resolveAccentBorderColor(data.ringSize, data.ringColor, data.borderColor, hoverTheme.borderColor); + const metaLabel = (typeof data.nodeType === "string" && data.nodeType.trim().length > 0) + ? data.nodeType.replaceAll("_", " ").toUpperCase() + : "NODE"; + + context.save(); + context.textBaseline = "top"; + + const titleFont = `${hoverTheme.titleWeight} ${hoverTheme.titleSize}px ${hoverTheme.fontFamily}`; + const metaFont = `${hoverTheme.metaWeight} ${hoverTheme.metaSize}px ${hoverTheme.fontFamily}`; + context.font = titleFont; + const titleWidth = context.measureText(data.label).width; + context.font = metaFont; + const metaWidth = context.measureText(metaLabel).width; + + const width = Math.max(titleWidth, metaWidth) + hoverTheme.paddingX * 2; + const height = hoverTheme.paddingY * 2 + hoverTheme.titleSize + hoverTheme.metaGap + hoverTheme.metaSize; + const x = data.x + Math.max(data.size * 0.9, hoverTheme.offsetX); + const y = data.y - Math.max(data.size * 1.1, hoverTheme.offsetY) - height; + + context.shadowColor = withAlpha(hoverTheme.shadowColor, hoverTheme.shadowAlpha); + context.shadowBlur = hoverTheme.shadowBlur; + context.fillStyle = hoverTheme.background; + drawRoundedRect(context, x, y, width, height, hoverTheme.radius); + context.fill(); + + context.shadowBlur = 0; + context.strokeStyle = withAlpha(borderColor, hoverTheme.borderAlpha); + context.lineWidth = 1.2; + drawRoundedRect(context, x, y, width, height, hoverTheme.radius); + context.stroke(); + + context.fillStyle = hoverTheme.textColor; + context.font = titleFont; + context.fillText(data.label, x + hoverTheme.paddingX, y + hoverTheme.paddingY); + + context.fillStyle = hoverTheme.metaColor; + context.font = metaFont; + context.fillText( + metaLabel, + x + hoverTheme.paddingX, + y + hoverTheme.paddingY + hoverTheme.titleSize + hoverTheme.metaGap, + ); + + context.restore(); +}; + +export const SEMANTICA_NODE_PROGRAM_CLASSES = { + ...DEFAULT_NODE_PROGRAM_CLASSES, + circle: MineralDiscNodeProgram, +}; + +export const SEMANTICA_EDGE_PROGRAM_CLASSES = { + ...DEFAULT_EDGE_PROGRAM_CLASSES, + curve: EdgeCurveProgram, + curvedArrow: EdgeCurvedArrowProgram, +}; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/types.ts b/semantica-explorer/src/workspaces/GraphWorkspace/types.ts index 11ff991d..69b73c12 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/types.ts +++ b/semantica-explorer/src/workspaces/GraphWorkspace/types.ts @@ -1,8 +1,17 @@ export type GraphViewMode = "focused" | "full"; export type GraphLayoutSource = "provided" | "carried" | "runtime"; export type GraphLayoutState = "idle" | "bootstrapping" | "running" | "stabilized" | "interactive" | "failed"; +export type GraphLoadPhase = + | "bootstrapping" + | "fetching_nodes" + | "fetching_edges" + | "computing_styling" + | "hydrating_scene" + | "stabilizing_layout" + | "ready"; +export type GraphLoadProgressKind = "determinate" | "indeterminate"; export type GraphNodeInteractionState = "default" | "hovered" | "selected" | "neighbor" | "path" | "inactive" | "muted"; -export type GraphEdgeInteractionState = "default" | "hovered" | "selected" | "neighbor" | "path" | "inactive" | "muted"; +export type GraphEdgeInteractionState = "default" | "backbone" | "hovered" | "selected" | "neighbor" | "path" | "inactive" | "muted"; export interface GraphCameraState { x: number; @@ -13,8 +22,10 @@ export interface GraphCameraState { export interface GraphInteractionState { hoveredNodeId: string | null; selectedNodeId: string; + selectedEdgeId: string; focusedNodeId: string; activePath: string[]; + activePathEdgeIds: string[]; viewMode: GraphViewMode; zoomTier: "overview" | "structure" | "inspection"; isLayoutRunning: boolean; @@ -24,6 +35,12 @@ export type GraphEffectToggle = | "pathPulseEnabled" | "pathFlowEnabled" | "lensEnabled" + | "temporalEmphasisEnabled" + | "semanticRegionsEnabled" + | "contoursEnabled" + | "pathfindingEnabled" + | "communitiesEnabled" + | "centralityEnabled" | "legendEnabled" | "diagnosticsEnabled"; @@ -31,6 +48,12 @@ export interface GraphEffectsState { pathPulseEnabled: boolean; pathFlowEnabled: boolean; lensEnabled: boolean; + temporalEmphasisEnabled: boolean; + semanticRegionsEnabled: boolean; + contoursEnabled: boolean; + pathfindingEnabled: boolean; + communitiesEnabled: boolean; + centralityEnabled: boolean; legendEnabled: boolean; diagnosticsEnabled: boolean; lensMode: "neighborhood"; @@ -55,11 +78,95 @@ export interface GraphDiagnosticsSnapshot { pathPulse: GraphEffectAvailability; pathFlow: GraphEffectAvailability; lens: GraphEffectAvailability; + temporalEmphasis: GraphEffectAvailability; + semanticRegions: GraphEffectAvailability; + contours: GraphEffectAvailability; + pathfinding: GraphEffectAvailability; + communities: GraphEffectAvailability; + centrality: GraphEffectAvailability; legend: GraphEffectAvailability; diagnostics: GraphEffectAvailability; }; } +export interface GraphTemporalState { + currentTime: Date | null; + activeNodeCount: number | null; + minDate?: string; + maxDate?: string; +} + +export interface GraphDirectedPathSnapshot { + ready: boolean; + reason: string; + sourceId: string | null; + targetId: string | null; + path: string[]; + length: number | null; + verifiedAgainstActivePath: boolean; +} + +export interface GraphCommunitySummary { + communityId: string; + nodeCount: number; + visibleNodeCount: number; + dominantSemanticGroup: string; + color: string; + anchorNodeId: string | null; + anchorLabel: string; + prominence: number; +} + +export interface GraphSemanticRegionSummary { + semanticGroup: string; + nodeCount: number; + visibleNodeCount: number; + color: string; + anchorNodeId: string | null; + anchorLabel: string; + dominantCommunityId: string | null; + prominence: number; +} + +export interface GraphCentralityNodeSummary { + id: string; + label: string; + semanticGroup: string; + color: string; + degree: number; + betweenness: number; + score: number; +} + +export interface GraphOverviewBackboneSnapshot { + ready: boolean; + reason: string; + edgeIds: string[]; +} + +export interface GraphAnalyticsSnapshot { + generatedAt: number; + directedPath: GraphDirectedPathSnapshot; + communities: { + ready: boolean; + reason: string; + count: number; + modularity: number | null; + summaries: GraphCommunitySummary[]; + }; + centrality: { + ready: boolean; + reason: string; + topNodes: GraphCentralityNodeSummary[]; + }; + semanticRegions: { + ready: boolean; + reason: string; + summaries: GraphSemanticRegionSummary[]; + }; + overviewBackbone: GraphOverviewBackboneSnapshot; +} + export interface ApiNode { id: string; type: string; @@ -72,6 +179,8 @@ export interface ApiNode { } export interface ApiEdge { + id: string; + familyId: string; source: string; target: string; type: string; @@ -89,13 +198,21 @@ export interface GraphLoadSummary { } export interface GraphLoadProgress { - phase: "nodes" | "edges" | "styling" | "rendering"; + phase: GraphLoadPhase; + title: string; nodesLoaded: number; nodesTotal: number | null; edgesLoaded: number; edgesTotal: number | null; message: string; - progress: number; + progressKind: GraphLoadProgressKind; + loaded: number | null; + total: number | null; + showGraphBehind: boolean; + stageIndex?: number; + stageCount?: number; + layoutSource?: GraphLayoutSource; + layoutState?: GraphLayoutState; } export interface GraphDataSnapshot { @@ -130,6 +247,21 @@ export interface GraphSelectedNodeState { neighborCount: number; } +export interface GraphSelectedEdgeState { + id: string; + familyId: string; + sourceId: string; + sourceLabel: string; + targetId: string; + targetLabel: string; + edgeType: string; + weight: number; + properties: Record; + provenanceCount: number; + familySize: number; + siblingCount: number; +} + export interface GraphStageHandle { fitView: () => void; focusNode: (nodeId: string) => void; diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/useGraphData.ts b/semantica-explorer/src/workspaces/GraphWorkspace/useGraphData.ts index fdd3b4a0..b6380335 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/useGraphData.ts +++ b/semantica-explorer/src/workspaces/GraphWorkspace/useGraphData.ts @@ -1,4 +1,5 @@ import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { createGraphLoadProgress } from "./graphLoading"; import type { ApiEdge, ApiNode, GraphDataSnapshot, GraphLoadProgress, GraphLayoutSource } from "./types"; interface NodeListResponse { @@ -46,8 +47,11 @@ async function fetchAllNodes( total = data.total ?? total; collected.push(...data.nodes); - onProgress?.({ - phase: "nodes", + onProgress?.(createGraphLoadProgress({ + phase: "fetching_nodes", + progressKind: total ? "determinate" : "indeterminate", + loaded: collected.length, + total, nodesLoaded: collected.length, nodesTotal: total, edgesLoaded: 0, @@ -55,8 +59,7 @@ async function fetchAllNodes( message: total ? `Loading nodes ${collected.length.toLocaleString()} of ${total.toLocaleString()}` : `Loading nodes ${collected.length.toLocaleString()}`, - progress: total ? Math.min(collected.length / Math.max(total, 1), 0.45) : 0.18, - }); + })); if (!data.next_cursor) { break; @@ -76,7 +79,9 @@ async function fetchAllEdges( ): Promise { let cursor: string | null = null; const collected: ApiEdge[] = []; + const seenEdgeIds = new Set(); let total: number | null = null; + let warnedOverTotal = false; while (true) { const url = new URL("/api/graph/edges", window.location.origin); @@ -96,19 +101,38 @@ async function fetchAllEdges( } total = data.total ?? total; - const validEdges = data.edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target)); + const validEdges = data.edges.filter((edge) => { + if (!nodeIds.has(edge.source) || !nodeIds.has(edge.target)) { + return false; + } + if (seenEdgeIds.has(edge.id)) { + return false; + } + seenEdgeIds.add(edge.id); + return true; + }); collected.push(...validEdges); - onProgress?.({ - phase: "edges", + const safeLoaded = total ? Math.min(seenEdgeIds.size, total) : seenEdgeIds.size; + if (!warnedOverTotal && total !== null && seenEdgeIds.size > total) { + warnedOverTotal = true; + console.warn("[graph-runtime] edge pagination returned more unique edge ids than total", { + uniqueEdgesLoaded: seenEdgeIds.size, + total, + }); + } + onProgress?.(createGraphLoadProgress({ + phase: "fetching_edges", + progressKind: total ? "determinate" : "indeterminate", + loaded: safeLoaded, + total, nodesLoaded: nodeProgress.loaded, nodesTotal: nodeProgress.total, - edgesLoaded: collected.length, + edgesLoaded: safeLoaded, edgesTotal: total, message: total - ? `Loading edges ${collected.length.toLocaleString()} of ${total.toLocaleString()}` - : `Loading edges ${collected.length.toLocaleString()}`, - progress: total ? 0.45 + Math.min(collected.length / Math.max(total, 1), 1) * 0.33 : 0.68, - }); + ? `Loading edges ${safeLoaded.toLocaleString()} of ${total.toLocaleString()}` + : `Loading edges ${safeLoaded.toLocaleString()}`, + })); if (!data.next_cursor) { break; @@ -145,15 +169,15 @@ export function useGraphData(options: UseGraphDataOptions = {}) { staleTime: Infinity, queryFn: async ({ signal }): Promise => { const startedAt = performance.now(); - onProgress?.({ - phase: "nodes", + onProgress?.(createGraphLoadProgress({ + phase: "bootstrapping", + progressKind: "indeterminate", nodesLoaded: 0, nodesTotal: null, edgesLoaded: 0, edgesTotal: null, - message: "Preparing graph load", - progress: 0.06, - }); + message: "Preparing graph session", + })); const nodes = await fetchAllNodes(signal, onProgress); const nodeIds = new Set(nodes.map((node) => node.id)); @@ -164,15 +188,15 @@ export function useGraphData(options: UseGraphDataOptions = {}) { onProgress, ); - onProgress?.({ - phase: "edges", + onProgress?.(createGraphLoadProgress({ + phase: "hydrating_scene", + progressKind: "indeterminate", nodesLoaded: nodes.length, nodesTotal: nodes.length, edgesLoaded: edges.length, edgesTotal: edges.length, - message: "Preparing graph runtime", - progress: 0.78, - }); + message: "Preparing graph runtime snapshot", + })); return { nodes, diff --git a/semantica-explorer/src/workspaces/GraphWorkspace/useLoadGraph.ts b/semantica-explorer/src/workspaces/GraphWorkspace/useLoadGraph.ts index bfba06b4..fffa6773 100644 --- a/semantica-explorer/src/workspaces/GraphWorkspace/useLoadGraph.ts +++ b/semantica-explorer/src/workspaces/GraphWorkspace/useLoadGraph.ts @@ -1,6 +1,7 @@ import { useQuery, useQueryClient } from "@tanstack/react-query"; import { batchMergeEdges, batchMergeNodes, clearGraph } from "../../store/graphStore"; import type { EdgeAttributes, NodeAttributes } from "../../store/graphStore"; +import { curveGroupForPair, pairRegistryKey } from "../../store/edgePairKeys.js"; import { GRAPH_THEME, clamp, @@ -12,6 +13,8 @@ import { type GraphLabelVisibilityPolicy, type GraphNodeShapeVariant, } from "./graphTheme"; +import { createGraphLoadProgress } from "./graphLoading"; +import type { GraphLoadProgress, GraphLoadSummary } from "./types"; const SEMANTIC_COLOR_FIELDS = [ "community", @@ -110,6 +113,82 @@ function structuralColorKey(nodeId: string, attributes: NodeAttributes): string return `${attributes.nodeType || "entity"}:${shard}`; } +function readFiniteCoordinate(value: unknown): number | null { + const numeric = Number(value); + return Number.isFinite(numeric) ? numeric : null; +} + +function seededUnit(value: string): number { + return (hashString(value) % 10000) / 10000; +} + +function buildClusterSeedPositions( + nodes: Array<{ + id: string; + semanticGroup: string; + priority: number; + }>, +): Map { + const grouped = new Map>(); + nodes.forEach((node) => { + const entry = grouped.get(node.semanticGroup); + if (entry) { + entry.push({ id: node.id, priority: node.priority }); + } else { + grouped.set(node.semanticGroup, [{ id: node.id, priority: node.priority }]); + } + }); + + const groupEntries = [...grouped.entries()] + .sort((left, right) => { + const countDelta = right[1].length - left[1].length; + if (countDelta !== 0) { + return countDelta; + } + return left[0].localeCompare(right[0]); + }); + + const groupCenters = new Map(); + groupEntries.forEach(([group, members], index) => { + const angle = index * 2.399963229728653; + const radius = 170 + Math.sqrt(index + 1) * 195; + const spread = 72 + Math.sqrt(members.length) * 16; + groupCenters.set(group, { + x: Math.cos(angle) * radius * 1.14, + y: Math.sin(angle) * radius * 0.84, + spread, + }); + }); + + const seeded = new Map(); + groupEntries.forEach(([group, members]) => { + const center = groupCenters.get(group); + if (!center) { + return; + } + + members + .sort((left, right) => { + if (right.priority !== left.priority) { + return right.priority - left.priority; + } + return left.id.localeCompare(right.id); + }) + .forEach((member, index) => { + const angle = index * 2.399963229728653 + seededUnit(`${group}:${member.id}:angle`) * 0.72; + const radial = Math.sqrt((index + 0.5) / Math.max(members.length, 1)) * center.spread; + const jitterX = (seededUnit(`${member.id}:jx`) - 0.5) * center.spread * 0.22; + const jitterY = (seededUnit(`${member.id}:jy`) - 0.5) * center.spread * 0.18; + seeded.set(member.id, { + x: center.x + Math.cos(angle) * radial + jitterX, + y: center.y + Math.sin(angle) * radial * 0.86 + jitterY, + }); + }); + }); + + return seeded; +} + function getProvenanceCount(properties: Record): number { return PROVENANCE_KEYS.reduce( (count, key) => (properties[key] !== undefined && properties[key] !== null ? count + 1 : count), @@ -201,6 +280,8 @@ interface ApiNode { } interface ApiEdge { + id: string; + familyId: string; source: string; target: string; type: string; @@ -224,22 +305,6 @@ interface EdgeListResponse { next_cursor?: string | null; } -export interface GraphLoadSummary { - nodeCount: number; - edgeCount: number; - loadTimeMs: number; -} - -export interface GraphLoadProgress { - phase: "nodes" | "edges" | "styling" | "rendering"; - nodesLoaded: number; - nodesTotal: number | null; - edgesLoaded: number; - edgesTotal: number | null; - message: string; - progress: number; -} - const PAGE_LIMIT = 1000; async function fetchAllNodes( @@ -269,8 +334,11 @@ async function fetchAllNodes( total = data.total ?? total; collected.push(...data.nodes); - onProgress?.({ - phase: "nodes", + onProgress?.(createGraphLoadProgress({ + phase: "fetching_nodes", + progressKind: total ? "determinate" : "indeterminate", + loaded: collected.length, + total, nodesLoaded: collected.length, nodesTotal: total, edgesLoaded: 0, @@ -278,8 +346,7 @@ async function fetchAllNodes( message: total ? `Loading nodes ${collected.length.toLocaleString()} of ${total.toLocaleString()}` : `Loading nodes ${collected.length.toLocaleString()}`, - progress: total ? Math.min(collected.length / Math.max(total, 1), 0.45) : 0.18, - }); + })); if (!data.next_cursor) { break; @@ -299,7 +366,9 @@ async function fetchAllEdges( ): Promise { let cursor: string | null = null; const collected: ApiEdge[] = []; + const seenEdgeIds = new Set(); let total: number | null = null; + let warnedOverTotal = false; while (true) { const url = new URL("/api/graph/edges", window.location.origin); @@ -319,19 +388,38 @@ async function fetchAllEdges( } total = data.total ?? total; - const validEdges = data.edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target)); + const validEdges = data.edges.filter((edge) => { + if (!nodeIds.has(edge.source) || !nodeIds.has(edge.target)) { + return false; + } + if (seenEdgeIds.has(edge.id)) { + return false; + } + seenEdgeIds.add(edge.id); + return true; + }); collected.push(...validEdges); - onProgress?.({ - phase: "edges", + const safeLoaded = total ? Math.min(seenEdgeIds.size, total) : seenEdgeIds.size; + if (!warnedOverTotal && total !== null && seenEdgeIds.size > total) { + warnedOverTotal = true; + console.warn("[graph-load] edge pagination returned more unique edge ids than total", { + uniqueEdgesLoaded: seenEdgeIds.size, + total, + }); + } + onProgress?.(createGraphLoadProgress({ + phase: "fetching_edges", + progressKind: total ? "determinate" : "indeterminate", + loaded: safeLoaded, + total, nodesLoaded: nodeProgress.loaded, nodesTotal: nodeProgress.total, - edgesLoaded: collected.length, + edgesLoaded: safeLoaded, edgesTotal: total, message: total - ? `Loading edges ${collected.length.toLocaleString()} of ${total.toLocaleString()}` - : `Loading edges ${collected.length.toLocaleString()}`, - progress: total ? 0.45 + Math.min(collected.length / Math.max(total, 1), 1) * 0.35 : 0.62, - }); + ? `Loading edges ${safeLoaded.toLocaleString()} of ${total.toLocaleString()}` + : `Loading edges ${safeLoaded.toLocaleString()}`, + })); if (!data.next_cursor) { break; @@ -363,17 +451,18 @@ export function useLoadGraph(options: UseLoadGraphOptions = {}) { queryKey: ["graph", "full-load"], enabled, staleTime: Infinity, + retry: 0, queryFn: async ({ signal }): Promise => { const startedAt = performance.now(); - onProgress?.({ - phase: "nodes", + onProgress?.(createGraphLoadProgress({ + phase: "bootstrapping", + progressKind: "indeterminate", nodesLoaded: 0, nodesTotal: null, edgesLoaded: 0, edgesTotal: null, - message: "Preparing graph load", - progress: 0.06, - }); + message: "Preparing graph session", + })); const fetchedNodes = await fetchAllNodes(signal, onProgress); const nodeIds = new Set(fetchedNodes.map((node) => node.id)); @@ -394,33 +483,29 @@ export function useLoadGraph(options: UseLoadGraphOptions = {}) { } const maxDegree = Math.max(...degreeByNode.values(), 1); - const draftAttributes = fetchedNodes.map((node) => { - const x = Number((node.properties as Record)?.x ?? Math.random() * 1000 - 500); - const y = Number((node.properties as Record)?.y ?? Math.random() * 1000 - 500); - return { - id: node.id, - attributes: { - label: node.content || node.id, - x, - y, - nodeType: node.type, - content: node.content, - valid_from: node.valid_from, - valid_until: node.valid_until, - properties: node.properties, - } as NodeAttributes, - }; - }); + const draftAttributes = fetchedNodes.map((node) => ({ + id: node.id, + attributes: { + label: node.content || node.id, + x: 0, + y: 0, + nodeType: node.type, + content: node.content, + valid_from: node.valid_from, + valid_until: node.valid_until, + properties: node.properties, + } as NodeAttributes, + })); - onProgress?.({ - phase: "styling", + onProgress?.(createGraphLoadProgress({ + phase: "computing_styling", + progressKind: "indeterminate", nodesLoaded: fetchedNodes.length, nodesTotal: fetchedNodes.length, edgesLoaded: fetchedEdges.length, edgesTotal: fetchedEdges.length, - message: "Computing graph styling", - progress: 0.86, - }); + message: "Applying semantic color, sizing, and structural styling", + })); const colorAccessor = chooseColorAccessor(draftAttributes); const nodePriorityById = new Map(); @@ -431,95 +516,173 @@ export function useLoadGraph(options: UseLoadGraphOptions = {}) { nodePriorityById.set(nodeId, sizeRatio); } + const semanticKeyByNodeId = new Map(); + draftAttributes.forEach(({ id, attributes }) => { + semanticKeyByNodeId.set(id, colorAccessor(id, attributes)); + }); + + const providedCoordinateCount = fetchedNodes.reduce((count, node) => { + const properties = node.properties as Record; + return readFiniteCoordinate(properties?.x) !== null && readFiniteCoordinate(properties?.y) !== null + ? count + 1 + : count; + }, 0); + const coordinateCoverage = fetchedNodes.length > 0 ? providedCoordinateCount / fetchedNodes.length : 0; + const useProvidedCoordinates = coordinateCoverage >= 0.92; + const seededPositions = useProvidedCoordinates + ? null + : buildClusterSeedPositions( + draftAttributes.map(({ id, attributes }) => ({ + id, + semanticGroup: semanticKeyByNodeId.get(id) ?? structuralColorKey(id, attributes), + priority: nodePriorityById.get(id) ?? 0, + })), + ); + const nodesToMerge = draftAttributes.map(({ id, attributes }) => { - const semanticGroup = colorAccessor(id, attributes); + const semanticGroup = semanticKeyByNodeId.get(id) ?? colorAccessor(id, attributes); const colorIndex = hashString(semanticGroup) % GRAPH_THEME.palette.semantic.length; const baseColor = GRAPH_THEME.palette.semantic[colorIndex]; const sizeRatio = nodePriorityById.get(id) ?? 0; - const dynamicSize = clamp(2.6, 2.6 + 12.4 * sizeRatio, 15.8); + const dynamicSize = clamp(1.8, 1.8 + 8.8 * sizeRatio, 11.8); const hasTemporalBounds = Boolean(attributes.valid_from || attributes.valid_until); const provenanceCount = getProvenanceCount(attributes.properties ?? {}); + const properties = attributes.properties as Record; + const providedX = readFiniteCoordinate(properties?.x); + const providedY = readFiniteCoordinate(properties?.y); + const seededPosition = seededPositions?.get(id); + const x = useProvidedCoordinates + ? providedX ?? 0 + : providedX ?? seededPosition?.x ?? 0; + const y = useProvidedCoordinates + ? providedY ?? 0 + : providedY ?? seededPosition?.y ?? 0; return { id, attributes: { ...attributes, + x, + y, semanticGroup, color: baseColor, baseColor, mutedColor: withAlpha(baseColor, GRAPH_THEME.nodes.mutedAlpha), - glowColor: withAlpha(baseColor, 0.34), + glowColor: withAlpha(baseColor, 0.24), size: dynamicSize, baseSize: dynamicSize, visualPriority: sizeRatio, labelPriority: sizeRatio, strokeColor: darkenHex(baseColor, 112), borderColor: darkenHex(baseColor, 112), - borderSize: 0.85, + borderSize: 0.72, ...resolveNodeVariantMetadata(baseColor, sizeRatio, hasTemporalBounds, provenanceCount), } as NodeAttributes, }; }); - const edgeKeys = new Set(fetchedEdges.map((edge) => `${edge.source}::${edge.target}`)); + const edgeKeys = new Set(fetchedEdges.map((edge) => pairRegistryKey(edge.source, edge.target))); + const parallelCounts = new Map(); + const familyCounts = new Map(); + fetchedEdges.forEach((edge) => { + const pairKey = pairRegistryKey(edge.source, edge.target); + parallelCounts.set(pairKey, (parallelCounts.get(pairKey) ?? 0) + 1); + familyCounts.set(edge.familyId, (familyCounts.get(edge.familyId) ?? 0) + 1); + }); + const parallelOffsets = new Map(); const edgesToMerge = fetchedEdges.map((edge) => { const sourcePriority = nodePriorityById.get(edge.source) ?? 0; const targetPriority = nodePriorityById.get(edge.target) ?? 0; - const isBidirectional = edgeKeys.has(`${edge.target}::${edge.source}`); + const isBidirectional = edgeKeys.has(pairRegistryKey(edge.target, edge.source)); + const pairKey = pairRegistryKey(edge.source, edge.target); + const parallelIndex = parallelOffsets.get(pairKey) ?? 0; + parallelOffsets.set(pairKey, parallelIndex + 1); + const parallelCount = parallelCounts.get(pairKey) ?? 1; return { + id: edge.id, + familyId: edge.familyId, source: edge.source, target: edge.target, attributes: { + edgeId: edge.id, + familyId: edge.familyId, + sourceId: edge.source, + targetId: edge.target, weight: edge.weight, edgeType: edge.type, properties: edge.properties, - size: clamp(0.45, 0.5 + Math.sqrt(Math.max(Number(edge.weight) || 1, 1)) * 0.38, 1.8), - baseSize: clamp(0.45, 0.5 + Math.sqrt(Math.max(Number(edge.weight) || 1, 1)) * 0.38, 1.8), + size: clamp(0.18, 0.22 + Math.sqrt(Math.max(Number(edge.weight) || 1, 1)) * 0.2, 0.88), + baseSize: clamp(0.18, 0.22 + Math.sqrt(Math.max(Number(edge.weight) || 1, 1)) * 0.2, 0.88), color: GRAPH_THEME.palette.muted.edgeStructure, baseColor: GRAPH_THEME.palette.muted.edgeStructure, mutedColor: GRAPH_THEME.palette.muted.edgeOverview, visualPriority: Math.max(sourcePriority, targetPriority), isBidirectional, edgeFamily: isBidirectional ? "bidirectional" : "line", - curveGroup: isBidirectional - ? [edge.source, edge.target].sort().join("::") - : null, + curveGroup: curveGroupForPair(edge.source, edge.target), type: "line", + isParallelPair: parallelCount > 1, + parallelIndex, + parallelCount, + familySize: familyCounts.get(edge.familyId) ?? 1, ...resolveEdgeVariantMetadata(edge, sourcePriority, targetPriority, isBidirectional), } as EdgeAttributes, }; }); - onProgress?.({ - phase: "rendering", + onProgress?.(createGraphLoadProgress({ + phase: "hydrating_scene", + progressKind: "indeterminate", nodesLoaded: nodesToMerge.length, nodesTotal: nodesToMerge.length, edgesLoaded: edgesToMerge.length, edgesTotal: edgesToMerge.length, - message: "Rendering graph", - progress: 0.96, - }); + message: "Preparing renderer and hydrating graph scene", + })); - clearGraph(); - batchMergeNodes(nodesToMerge); - batchMergeEdges(edgesToMerge); + try { + clearGraph(); + } catch (error) { + console.error("[graph-load] clearGraph failed", error); + throw error; + } + + try { + batchMergeNodes(nodesToMerge); + } catch (error) { + console.error("[graph-load] batchMergeNodes failed", error); + throw error; + } + + try { + batchMergeEdges(edgesToMerge); + } catch (error) { + console.error("[graph-load] batchMergeEdges failed", error); + throw error; + } const summary = { nodeCount: nodesToMerge.length, edgeCount: edgesToMerge.length, loadTimeMs: Math.round(performance.now() - startedAt), + hasCoordinates: useProvidedCoordinates, + layoutSource: useProvidedCoordinates ? "provided" : "runtime", + layoutReady: useProvidedCoordinates, } satisfies GraphLoadSummary; - onProgress?.({ - phase: "rendering", + onProgress?.(createGraphLoadProgress({ + phase: summary.layoutReady ? "ready" : "stabilizing_layout", + progressKind: "indeterminate", nodesLoaded: summary.nodeCount, nodesTotal: summary.nodeCount, edgesLoaded: summary.edgeCount, edgesTotal: summary.edgeCount, - message: "Graph ready", - progress: 1, - }); + message: summary.layoutReady ? "Graph ready" : "Settling runtime layout", + showGraphBehind: !summary.layoutReady, + layoutSource: summary.layoutSource, + layoutState: summary.layoutReady ? "interactive" : "bootstrapping", + })); onGraphReady?.(summary); return summary; diff --git a/semantica-explorer/tests/graphStore.multi-edge.test.mjs b/semantica-explorer/tests/graphStore.multi-edge.test.mjs new file mode 100644 index 00000000..09bf4486 --- /dev/null +++ b/semantica-explorer/tests/graphStore.multi-edge.test.mjs @@ -0,0 +1,111 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import Graph from "graphology"; + +import { curveGroupForPair, pairRegistryKey } from "../src/store/edgePairKeys.js"; + +function normalizeParallelMetadataForPair(graph, source, target) { + const edgeIds = []; + graph.forEachDirectedEdge(source, target, (edgeId) => { + edgeIds.push(String(edgeId)); + }); + + const pairCount = edgeIds.length; + const familyCounts = new Map(); + edgeIds.forEach((edgeId) => { + const attrs = graph.getEdgeAttributes(edgeId); + const familyId = String(attrs.familyId || edgeId); + familyCounts.set(familyId, (familyCounts.get(familyId) ?? 0) + 1); + }); + + edgeIds + .sort((left, right) => left.localeCompare(right)) + .forEach((edgeId, index) => { + const attrs = graph.getEdgeAttributes(edgeId); + const familyId = String(attrs.familyId || edgeId); + graph.mergeEdgeAttributes(edgeId, { + edgeId, + familyId, + sourceId: source, + targetId: target, + isParallelPair: pairCount > 1, + parallelIndex: index, + parallelCount: pairCount, + familySize: familyCounts.get(familyId) ?? 1, + curveGroup: curveGroupForPair(source, target), + }); + }); +} + +function batchMergeEdges(graph, edges) { + const touchedPairs = new Map(); + + for (const { id, familyId, source, target, attributes } of edges) { + const edgeId = String(attributes.edgeId || id); + const resolvedFamilyId = String(attributes.familyId || familyId || edgeId); + + if (graph.hasNode(source) && graph.hasNode(target)) { + graph.mergeDirectedEdgeWithKey(edgeId, source, target, { + ...attributes, + edgeId, + familyId: resolvedFamilyId, + sourceId: source, + targetId: target, + }); + touchedPairs.set(pairRegistryKey(source, target), { source, target }); + } + } + + touchedPairs.forEach(({ source, target }) => { + normalizeParallelMetadataForPair(graph, source, target); + }); +} + +test("structured pair keys support node ids containing double colons", () => { + const graph = new Graph({ type: "directed", multi: true, allowSelfLoops: false }); + + graph.addNode("gene/protein::10"); + graph.addNode("gene/protein::472"); + graph.addNode("gene/protein::500"); + + assert.doesNotThrow(() => { + batchMergeEdges(graph, [ + { + id: "edge-a", + familyId: "family-1", + source: "gene/protein::10", + target: "gene/protein::472", + attributes: { edgeType: "protein_protein", weight: 1, properties: {} }, + }, + { + id: "edge-b", + familyId: "family-2", + source: "gene/protein::10", + target: "gene/protein::472", + attributes: { edgeType: "protein_protein", weight: 1, properties: {} }, + }, + { + id: "edge-c", + familyId: "family-3", + source: "gene/protein::10", + target: "gene/protein::500", + attributes: { edgeType: "protein_protein", weight: 1, properties: {} }, + }, + ]); + }); + + const edgeA = graph.getEdgeAttributes("edge-a"); + const edgeB = graph.getEdgeAttributes("edge-b"); + const edgeC = graph.getEdgeAttributes("edge-c"); + + assert.equal(edgeA.sourceId, "gene/protein::10"); + assert.equal(edgeA.targetId, "gene/protein::472"); + assert.equal(edgeA.parallelCount, 2); + assert.equal(edgeB.parallelCount, 2); + assert.equal(edgeA.isParallelPair, true); + assert.equal(edgeB.isParallelPair, true); + assert.equal(edgeC.parallelCount, 1); + assert.equal(edgeC.isParallelPair, false); + assert.equal(edgeA.curveGroup, JSON.stringify(["gene/protein::10", "gene/protein::472"])); + assert.equal(edgeC.curveGroup, JSON.stringify(["gene/protein::10", "gene/protein::500"])); +}); diff --git a/semantica/context/context_graph.py b/semantica/context/context_graph.py index fd09c3dd..f8d6ca22 100644 --- a/semantica/context/context_graph.py +++ b/semantica/context/context_graph.py @@ -108,6 +108,7 @@ Production Use Cases: from collections import defaultdict, deque from dataclasses import dataclass, field from datetime import datetime, timezone +import json import threading import itertools from typing import Any, Dict, List, Optional, Set, Tuple, Union @@ -188,6 +189,62 @@ def _pick_first(*values: Any) -> Any: return None +def _default_edge_id( + source_id: str, + target_id: str, + edge_type: str, + weight: float, + metadata: Dict[str, Any], + valid_from: Optional[str], + valid_until: Optional[str], +) -> str: + payload = json.dumps( + { + "source": source_id, + "target": target_id, + "type": edge_type, + "weight": weight, + "valid_from": valid_from, + "valid_until": valid_until, + "metadata": metadata, + }, + sort_keys=True, + default=str, + separators=(",", ":"), + ) + return str(uuid.uuid5(uuid.NAMESPACE_URL, payload)) + + +def _resolve_edge_identity( + *, + source_id: str, + target_id: str, + edge_type: str, + weight: float, + metadata: Dict[str, Any], + valid_from: Optional[str], + valid_until: Optional[str], + edge_id: Any = None, + family_id: Any = None, +) -> Tuple[str, str]: + resolved_edge_id = str( + _pick_first( + edge_id, + _default_edge_id( + source_id=source_id, + target_id=target_id, + edge_type=edge_type, + weight=weight, + metadata=metadata, + valid_from=valid_from, + valid_until=valid_until, + ), + ) + ) + resolved_family_id = str(_pick_first(family_id, resolved_edge_id)) + return resolved_edge_id, resolved_family_id + + def _coerce_metadata_map(*values: Any) -> Dict[str, Any]: merged: Dict[str, Any] = {} for value in values: @@ -282,10 +339,31 @@ class ContextEdge: source_id: str target_id: str edge_type: str + edge_id: str = "" weight: float = 1.0 + family_id: Optional[str] = None metadata: Dict[str, Any] = field(default_factory=dict) valid_from: Optional[str] = None valid_until: Optional[str] = None + + def __post_init__(self) -> None: + self.source_id = str(self.source_id) + self.target_id = str(self.target_id) + self.edge_type = str(self.edge_type or "related_to") + self.weight = _coerce_float(self.weight, default=1.0) + if not isinstance(self.metadata, dict): + self.metadata = {} + self.edge_id, self.family_id = _resolve_edge_identity( + source_id=self.source_id, + target_id=self.target_id, + edge_type=self.edge_type, + weight=self.weight, + metadata=self.metadata, + valid_from=self.valid_from, + valid_until=self.valid_until, + edge_id=self.edge_id, + family_id=self.family_id, + ) def is_active(self, at_time: Optional[datetime] = None) -> bool: """Return True if this edge is active at the given time (defaults to now). @@ -308,6 +386,8 @@ class ContextEdge: def to_dict(self) -> Dict[str, Any]: """Convert to dictionary format.""" d = { + "id": self.edge_id, + "familyId": self.family_id or self.edge_id, "source_id": self.source_id, "target_id": self.target_id, "type": self.edge_type, @@ -529,7 +609,19 @@ class ContextGraph: valid_from = _pick_first(raw_edge.get("valid_from"), edge_props.get("valid_from")) valid_until = _pick_first(raw_edge.get("valid_until"), edge_props.get("valid_until")) weight = _coerce_float(_pick_first(raw_edge.get("weight"), edge_props.get("weight")), default=1.0) - internal_edge = ContextEdge( + explicit_edge_id = _pick_first( + raw_edge.get("id"), + raw_edge.get("edge_id"), + edge_props.pop("id", None), + edge_props.pop("edge_id", None), + ) + explicit_family_id = _pick_first( + raw_edge.get("familyId"), + raw_edge.get("family_id"), + edge_props.pop("familyId", None), + edge_props.pop("family_id", None), + ) + edge_id, family_id = _resolve_edge_identity( source_id=source_id, target_id=target_id, edge_type=str(edge_type or "related_to"), @@ -537,6 +629,19 @@ class ContextGraph: metadata=edge_props, valid_from=valid_from, valid_until=valid_until, + edge_id=explicit_edge_id, + family_id=explicit_family_id, + ) + internal_edge = ContextEdge( + edge_id=edge_id, + source_id=source_id, + target_id=target_id, + edge_type=str(edge_type or "related_to"), + family_id=str(family_id) if family_id is not None else edge_id, + weight=weight, + metadata=edge_props, + valid_from=valid_from, + valid_until=valid_until, ) if self._add_internal_edge(internal_edge): @@ -619,6 +724,8 @@ class ContextGraph: for edge in self._adjacency.get(source_id, []): if edge.target_id == target_id: data = edge.metadata.copy() + data["id"] = edge.edge_id + data["familyId"] = edge.family_id or edge.edge_id data["type"] = edge.edge_type data["weight"] = edge.weight return data @@ -785,12 +892,27 @@ class ContextGraph: """ valid_from = properties.pop("valid_from", None) valid_until = properties.pop("valid_until", None) + explicit_edge_id = properties.pop("id", properties.pop("edge_id", None)) + explicit_family_id = properties.pop("familyId", properties.pop("family_id", None)) + edge_id, family_id = _resolve_edge_identity( + source_id=source_id, + target_id=target_id, + edge_type=edge_type, + weight=weight, + metadata=properties, + valid_from=valid_from, + valid_until=valid_until, + edge_id=explicit_edge_id, + family_id=explicit_family_id, + ) with self._lock: return self._add_internal_edge( ContextEdge( + edge_id=edge_id, source_id=source_id, target_id=target_id, edge_type=edge_type, + family_id=str(family_id) if family_id is not None else edge_id, weight=weight, metadata=properties, valid_from=valid_from, @@ -1118,11 +1240,15 @@ class ContextGraph: gen = ( { + "id": e.edge_id, + "familyId": e.family_id or e.edge_id, "source": e.source_id, "target": e.target_id, "type": e.edge_type, "weight": e.weight, "metadata": e.metadata, + "valid_from": e.valid_from, + "valid_until": e.valid_until, } for e in source ) @@ -1243,14 +1369,11 @@ class ContextGraph: if getattr(self, "mutation_callback", None) and not getattr( self, "_suspend_mutation_callback", False ): - import json - - edge_id = json.dumps([edge.source_id, edge.edge_type, edge.target_id]) try: - self.mutation_callback("ADD_EDGE", edge_id, edge.to_dict()) + self.mutation_callback("ADD_EDGE", edge.edge_id, edge.to_dict()) except Exception as e: self.logger.warning( - f"Audit trail callback failed for edge {edge_id}: {e}" + f"Audit trail callback failed for edge {edge.edge_id}: {e}" ) return True @@ -1508,11 +1631,15 @@ class ContextGraph: edges_out = [] for e in self.edges: entry = { + "id": e.edge_id, + "familyId": e.family_id or e.edge_id, "source": e.source_id, "target": e.target_id, "type": e.edge_type, "weight": e.weight, } + if e.metadata: + entry["metadata"] = e.metadata if e.valid_from is not None: entry["valid_from"] = e.valid_from if e.valid_until is not None: @@ -1549,12 +1676,27 @@ class ContextGraph: # Add edges — restore validity windows if present for edge_data in graph_dict.get("edges", []): - edge = ContextEdge( + edge_metadata = edge_data.get("metadata", edge_data.get("properties", {})) or {} + edge_weight = edge_data.get("weight", 1.0) + edge_id, family_id = _resolve_edge_identity( source_id=edge_data["source"], target_id=edge_data["target"], edge_type=edge_data["type"], - weight=edge_data.get("weight", 1.0), - metadata=edge_data.get("metadata", {}), + weight=edge_weight, + metadata=edge_metadata, + valid_from=edge_data.get("valid_from"), + valid_until=edge_data.get("valid_until"), + edge_id=edge_data.get("id", edge_data.get("edge_id")), + family_id=edge_data.get("familyId", edge_data.get("family_id")), + ) + edge = ContextEdge( + edge_id=edge_id, + source_id=edge_data["source"], + target_id=edge_data["target"], + edge_type=edge_data["type"], + weight=edge_weight, + family_id=family_id, + metadata=edge_metadata, valid_from=edge_data.get("valid_from"), valid_until=edge_data.get("valid_until"), ) diff --git a/semantica/explorer/routes/export_import.py b/semantica/explorer/routes/export_import.py index 7cd36805..97d05149 100644 --- a/semantica/explorer/routes/export_import.py +++ b/semantica/explorer/routes/export_import.py @@ -79,13 +79,18 @@ async def import_file( target = raw_edge.get("target") or raw_edge.get("target_id") or raw_edge.get("end") or raw_edge.get("end_id") or raw_edge.get("END_ID") if not source or not target: continue + edge_properties = raw_edge.get("metadata", raw_edge.get("properties", {})) or {} edges.append( { + "id": raw_edge.get("id", raw_edge.get("edge_id")), + "familyId": raw_edge.get("familyId", raw_edge.get("family_id")), "source_id": str(source), "target_id": str(target), "type": raw_edge.get("type", raw_edge.get("relationship", "related_to")), "weight": float(raw_edge.get("weight", 1.0)), - "properties": raw_edge.get("metadata", raw_edge.get("properties", {})) or {}, + "properties": edge_properties, + "valid_from": raw_edge.get("valid_from", edge_properties.get("valid_from")), + "valid_until": raw_edge.get("valid_until", edge_properties.get("valid_until")), } ) @@ -111,10 +116,29 @@ async def import_file( edge_props = { key: value for key, value in row.items() - if key not in {"source", "source_id", "target", "target_id", "type", "relationship", "weight", ":START_ID", "START_ID", ":END_ID", "END_ID", ":TYPE"} + if key not in { + "id", + "edge_id", + "familyId", + "family_id", + "source", + "source_id", + "target", + "target_id", + "type", + "relationship", + "weight", + ":START_ID", + "START_ID", + ":END_ID", + "END_ID", + ":TYPE", + } } edges.append( { + "id": row.get("id") or row.get("edge_id"), + "familyId": row.get("familyId") or row.get("family_id"), "source_id": str(source), "target_id": str(target), "type": row.get("type") or row.get("relationship") or row.get(":TYPE") or "related_to", @@ -165,11 +189,20 @@ async def export_graph( output = io.StringIO() writer = csv.writer(output) - writer.writerow(["kind", "id", "type", "content", "source", "target", "weight"]) + writer.writerow(["kind", "id", "familyId", "type", "content", "source", "target", "weight"]) for node in graph_dict.get("entities", []): - writer.writerow(["node", node.get("id"), node.get("type"), node.get("text"), "", "", ""]) + writer.writerow(["node", node.get("id"), "", node.get("type"), node.get("text"), "", "", ""]) for edge in graph_dict.get("relationships", []): - writer.writerow(["edge", "", edge.get("type"), "", edge.get("source"), edge.get("target"), edge.get("metadata", {}).get("weight", "")]) + writer.writerow([ + "edge", + edge.get("id"), + edge.get("familyId"), + edge.get("type"), + "", + edge.get("source"), + edge.get("target"), + edge.get("metadata", {}).get("weight", edge.get("weight", "")), + ]) content = output.getvalue() media_type = "text/csv" diff --git a/semantica/explorer/routes/graph.py b/semantica/explorer/routes/graph.py index 7df87f94..43851e63 100644 --- a/semantica/explorer/routes/graph.py +++ b/semantica/explorer/routes/graph.py @@ -156,12 +156,14 @@ async def find_path( path_nodes = result.get("path", []) if isinstance(result, dict) else (result or []) total_weight = result.get("total_weight", 0.0) if isinstance(result, dict) else 0.0 + edge_ids = await asyncio.to_thread(session.resolve_path_edge_ids, path_nodes) return PathResponse( source=node_id, target=target, algorithm=algorithm, path=path_nodes, + edge_ids=edge_ids, total_weight=total_weight, ) diff --git a/semantica/explorer/schemas.py b/semantica/explorer/schemas.py index 6f41b919..9bdfbbca 100644 --- a/semantica/explorer/schemas.py +++ b/semantica/explorer/schemas.py @@ -22,6 +22,8 @@ class NodeResponse(BaseModel): class EdgeResponse(BaseModel): + id: str + familyId: str source: str target: str type: str @@ -63,6 +65,7 @@ class PathResponse(BaseModel): target: str algorithm: str path: List[str] + edge_ids: List[str] = Field(default_factory=list) total_weight: float = 0.0 diff --git a/semantica/explorer/session.py b/semantica/explorer/session.py index baf3fbfa..73dfa0bb 100644 --- a/semantica/explorer/session.py +++ b/semantica/explorer/session.py @@ -9,7 +9,7 @@ import uuid from datetime import datetime, UTC from typing import Any, Dict, Iterable, List, Optional -from ..context.context_graph import ContextGraph +from ..context.context_graph import ContextGraph, _resolve_edge_identity _KG_AVAILABLE = False try: @@ -220,7 +220,31 @@ class GraphSession: if valid_until is not None: properties["valid_until"] = valid_until + edge_id, family_id = _resolve_edge_identity( + source_id=str(edge.get("source", edge.get("source_id", ""))), + target_id=str(edge.get("target", edge.get("target_id", ""))), + edge_type=str(edge.get("type", "related_to")), + weight=weight, + metadata=properties, + valid_from=valid_from, + valid_until=valid_until, + edge_id=( + edge.get("id") + or edge.get("edge_id") + or meta.get("id") + or meta.get("edge_id") + ), + family_id=( + edge.get("familyId") + or edge.get("family_id") + or meta.get("familyId") + or meta.get("family_id") + ), + ) + return { + "id": edge_id, + "familyId": family_id, "source": str(edge.get("source", edge.get("source_id", ""))), "target": str(edge.get("target", edge.get("target_id", ""))), "type": str(edge.get("type", "related_to")), @@ -323,10 +347,7 @@ class GraphSession: continue if target and normalized["target"] != target: continue - edge_key = json.dumps( - [normalized["source"], normalized["type"], normalized["target"]], - separators=(",", ":"), - ) + edge_key = str(normalized["id"]) normalized_edges.append(normalized) keys.append(edge_key) @@ -344,9 +365,7 @@ class GraphSession: next_cursor = None if start_index + limit < total and page_edges: last = page_edges[-1] - next_cursor = self._encode_cursor( - json.dumps([last["source"], last["type"], last["target"]], separators=(",", ":")) - ) + next_cursor = self._encode_cursor(str(last["id"])) return page_edges, total, next_cursor @@ -532,15 +551,43 @@ class GraphSession: ], "relationships": [ { + "id": edge.get("id"), + "familyId": edge.get("familyId"), "source": edge.get("source"), "target": edge.get("target"), "type": edge.get("type", "related_to"), + "weight": edge.get("weight", 1.0), "metadata": edge.get("properties", {}), } for edge in edges ], } + def resolve_path_edge_ids(self, path_nodes: List[str]) -> List[str]: + if len(path_nodes) < 2: + return [] + + edge_ids: List[str] = [] + with self._lock: + for index in range(len(path_nodes) - 1): + source_id = path_nodes[index] + target_id = path_nodes[index + 1] + candidates = [ + edge for edge in self.graph._adjacency.get(source_id, []) + if edge.target_id == target_id + ] + if not candidates: + continue + candidates.sort( + key=lambda edge: ( + -float(edge.weight), + str(edge.edge_type), + str(edge.edge_id), + ) + ) + edge_ids.append(str(candidates[0].edge_id)) + return edge_ids + def add_nodes(self, nodes: List[Dict[str, Any]]) -> int: with self._lock: return self.graph.add_nodes(nodes) diff --git a/semantica/static/assets/DecisionWorkspace-DOZnUOYv.js b/semantica/static/assets/DecisionWorkspace-CkoD0QKe.js similarity index 97% rename from semantica/static/assets/DecisionWorkspace-DOZnUOYv.js rename to semantica/static/assets/DecisionWorkspace-CkoD0QKe.js index 3f96fb82..3e60ab00 100644 --- a/semantica/static/assets/DecisionWorkspace-DOZnUOYv.js +++ b/semantica/static/assets/DecisionWorkspace-CkoD0QKe.js @@ -1,4 +1,4 @@ -import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{T as t,a as n}from"./query-vendor-Cbp9LWgA.js";import{r}from"./index-BVBOQ8an.js";var i=r(),a=e(t(),1),o=n(),s=` +import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{T as t,a as n}from"./query-vendor-Cbp9LWgA.js";import{r}from"./index-DDOaKEbH.js";var i=r(),a=e(t(),1),o=n(),s=` .glass-panel { background: linear-gradient(135deg, rgba(13,17,23,0.75), rgba(22,27,34,0.6)); backdrop-filter: blur(16px) saturate(1.2); diff --git a/semantica/static/assets/DiffMergeWorkspace-BP5v4yP2.js b/semantica/static/assets/DiffMergeWorkspace-DDK7n-jO.js similarity index 97% rename from semantica/static/assets/DiffMergeWorkspace-BP5v4yP2.js rename to semantica/static/assets/DiffMergeWorkspace-DDK7n-jO.js index f7e75561..63f37392 100644 --- a/semantica/static/assets/DiffMergeWorkspace-BP5v4yP2.js +++ b/semantica/static/assets/DiffMergeWorkspace-DDK7n-jO.js @@ -1,4 +1,4 @@ -import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{T as t,a as n}from"./query-vendor-Cbp9LWgA.js";import{r}from"./index-BVBOQ8an.js";var i=r(),a=e(t(),1),o=n(),s=` +import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{T as t,a as n}from"./query-vendor-Cbp9LWgA.js";import{r}from"./index-DDOaKEbH.js";var i=r(),a=e(t(),1),o=n(),s=` .glass-panel { background: linear-gradient(135deg, rgba(13,17,23,0.75), rgba(22,27,34,0.6)); backdrop-filter: blur(16px) saturate(1.2); diff --git a/semantica/static/assets/GraphInspectorPanel-CbpkpjNw.js b/semantica/static/assets/GraphInspectorPanel-MLghMyni.js similarity index 98% rename from semantica/static/assets/GraphInspectorPanel-CbpkpjNw.js rename to semantica/static/assets/GraphInspectorPanel-MLghMyni.js index 5e0f541c..b65905c4 100644 --- a/semantica/static/assets/GraphInspectorPanel-CbpkpjNw.js +++ b/semantica/static/assets/GraphInspectorPanel-MLghMyni.js @@ -1 +1 @@ -import{a as e}from"./query-vendor-Cbp9LWgA.js";import{r as t}from"./index-BVBOQ8an.js";import{d as n,t as r}from"./graphTheme-CLhhQXPS.js";var ee=t(),i=e(),a=[`source`,`source_url`,`pmid`,`pmids`,`evidence`,`provenance`,`confidence`];function te(e){return a.filter(t=>t in e).map(t=>({key:t,value:e[t]}))}function o(e){let t=(0,ee.c)(108),{nodeId:r,predictions:a,predictionType:o,onPredictionTypeChange:s,onRunPredictions:c,pathTargetId:u,onPathTargetChange:d,onTracePath:f,pathResult:p,onDownloadProvenance:m}=e;if(!r){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,i.jsx)(`div`,{style:{padding:32,textAlign:`center`},children:(0,i.jsx)(`p`,{style:{color:`#8b949e`,fontSize:14,margin:0},children:`Search for a node or click one in the canvas to inspect its properties.`})}),t[0]=e):e=t[0],e}let h,g,_,v,y,b,x,S,C,w,T;if(t[1]!==r||t[2]!==m||t[3]!==d||t[4]!==s||t[5]!==c||t[6]!==f||t[7]!==p||t[8]!==u||t[9]!==o||t[10]!==a){let e=n.getNodeAttributes(r),ee=e?.properties??{},E=te(ee),D=e?.color||`#58a6ff`,O=Object.entries(ee).filter(ae),k,A;t[22]===Symbol.for(`react.memo_cache_sentinel`)?(x={padding:24,display:`flex`,flexDirection:`column`,gap:18},k={borderBottom:`1px solid rgba(88, 166, 255, 0.2)`,paddingBottom:16},A={display:`flex`,alignItems:`center`,gap:10,marginBottom:8},t[22]=k,t[23]=A,t[24]=x):(k=t[22],A=t[23],x=t[24]);let pe=(0,i.jsxs)(`div`,{style:A,children:[(0,i.jsx)(`span`,{style:{background:D,boxShadow:`0 0 10px ${D}`,width:8,height:8,borderRadius:`50%`}}),(0,i.jsx)(`span`,{style:{color:D,fontSize:12,fontWeight:700},children:e?.nodeType||`Entity`})]}),me;t[25]===Symbol.for(`react.memo_cache_sentinel`)?(me={margin:0,color:`#fff`,fontSize:20,fontWeight:700,wordBreak:`break-word`},t[25]=me):me=t[25];let he=String(e?.label??r),j;t[26]===he?j=t[27]:(j=(0,i.jsx)(`h3`,{style:me,children:he}),t[26]=he,t[27]=j);let M;t[28]===Symbol.for(`react.memo_cache_sentinel`)?(M={color:`#8b949e`,fontSize:12,marginTop:6},t[28]=M):M=t[28];let N;t[29]===r?N=t[30]:(N=(0,i.jsx)(`div`,{style:M,children:r}),t[29]=r,t[30]=N);let P;t[31]===Symbol.for(`react.memo_cache_sentinel`)?(P={display:`flex`,gap:8,flexWrap:`wrap`,marginTop:12},t[31]=P):P=t[31];let ge=e?.valid_from||e?.valid_until?(0,i.jsx)(`span`,{style:ue,children:`temporal`}):null,_e=E.length?(0,i.jsxs)(`span`,{style:ue,children:[E.length,` source fields`]}):null,F;t[32]===a.length?F=t[33]:(F=a.length?(0,i.jsxs)(`span`,{style:ue,children:[a.length,` candidate links`]}):null,t[32]=a.length,t[33]=F);let I;t[34]!==ge||t[35]!==_e||t[36]!==F?(I=(0,i.jsxs)(`div`,{style:P,children:[ge,_e,F]}),t[34]=ge,t[35]=_e,t[36]=F,t[37]=I):I=t[37],t[38]!==pe||t[39]!==j||t[40]!==N||t[41]!==I?(S=(0,i.jsxs)(`div`,{style:k,children:[pe,j,N,I]}),t[38]=pe,t[39]=j,t[40]=N,t[41]=I,t[42]=S):S=t[42],C=(e?.valid_from||e?.valid_until)&&(0,i.jsxs)(`div`,{style:{padding:`10px 12px`,background:`rgba(88, 166, 255, 0.08)`,border:`1px solid rgba(88, 166, 255, 0.2)`,borderRadius:8,fontSize:12,color:`#79c0ff`,fontFamily:`monospace`},children:[e?.valid_from?(0,i.jsxs)(`div`,{children:[`from: `,e.valid_from]}):null,e?.valid_until?(0,i.jsxs)(`div`,{children:[`until: `,e.valid_until]}):null]});let L,R,z;t[43]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,i.jsx)(`div`,{style:fe,children:`Actions`}),R={display:`flex`,flexDirection:`column`,gap:10},z={...se,width:`100%`,justifyContent:`center`},t[43]=L,t[44]=R,t[45]=z):(L=t[43],R=t[44],z=t[45]);let B;t[46]===c?B=t[47]:(B=(0,i.jsx)(`button`,{style:z,onClick:c,children:`Run Link Prediction`}),t[46]=c,t[47]=B);let V;t[48]===Symbol.for(`react.memo_cache_sentinel`)?(V={display:`flex`,gap:8,flexWrap:`wrap`},t[48]=V):V=t[48];let H;t[49]===m?H=t[50]:(H=(0,i.jsx)(`button`,{style:ce,onClick:()=>m(`json`),children:`Provenance JSON`}),t[49]=m,t[50]=H);let U;t[51]===m?U=t[52]:(U=(0,i.jsx)(`button`,{style:ce,onClick:()=>m(`markdown`),children:`Provenance MD`}),t[51]=m,t[52]=U);let W;t[53]!==H||t[54]!==U?(W=(0,i.jsxs)(`div`,{style:V,children:[H,U]}),t[53]=H,t[54]=U,t[55]=W):W=t[55];let G;t[56]!==B||t[57]!==W?(G=(0,i.jsxs)(`div`,{style:R,children:[B,W]}),t[56]=B,t[57]=W,t[58]=G):G=t[58];let K;t[59]===s?K=t[60]:(K=e=>s(e.target.value),t[59]=s,t[60]=K);let q;t[61]!==o||t[62]!==K?(q=(0,i.jsx)(`input`,{value:o,onChange:K,placeholder:`Optional candidate type filter, e.g. disease`,style:oe}),t[61]=o,t[62]=K,t[63]=q):q=t[63],t[64]!==G||t[65]!==q?(w=(0,i.jsxs)(`section`,{style:de,children:[L,G,q]}),t[64]=G,t[65]=q,t[66]=w):w=t[66];let J;t[67]===Symbol.for(`react.memo_cache_sentinel`)?(J=(0,i.jsx)(`div`,{style:fe,children:`Trace Path`}),t[67]=J):J=t[67];let Y;t[68]===d?Y=t[69]:(Y=e=>d(e.target.value),t[68]=d,t[69]=Y);let X;t[70]!==u||t[71]!==Y?(X=(0,i.jsx)(`input`,{value:u,onChange:Y,placeholder:`Target node ID`,style:oe}),t[70]=u,t[71]=Y,t[72]=X):X=t[72];let Z;t[73]===f?Z=t[74]:(Z=(0,i.jsx)(`button`,{style:se,onClick:f,children:`Trace Causal Path`}),t[73]=f,t[74]=Z);let Q;t[75]===p?Q=t[76]:(Q=p?.path?.length?(0,i.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6,marginTop:10},children:[p.path.map(ie),(0,i.jsxs)(`div`,{style:{color:`#79c0ff`,fontSize:12,marginTop:4},children:[`total weight: `,p.total_weight.toFixed(3)]})]}):(0,i.jsx)(`div`,{style:l,children:`Choose a target or click a candidate prediction to prepare a path trace.`}),t[75]=p,t[76]=Q),t[77]!==X||t[78]!==Z||t[79]!==Q?(T=(0,i.jsxs)(`section`,{style:de,children:[J,X,Z,Q]}),t[77]=X,t[78]=Z,t[79]=Q,t[80]=T):T=t[80];let ve=a.length>0,ye;t[81]===Symbol.for(`react.memo_cache_sentinel`)?(ye=(0,i.jsx)(`summary`,{className:`node-panel-summary`,children:`Candidate Links`}),t[81]=ye):ye=t[81];let $;t[82]!==d||t[83]!==a?($=(0,i.jsx)(`div`,{className:`node-panel-body`,children:a.length>0?(0,i.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:a.map(e=>(0,i.jsxs)(`button`,{style:le,onClick:()=>d(e.target),children:[(0,i.jsx)(`div`,{style:{color:`#fff`,fontWeight:600},children:e.label||e.target}),(0,i.jsx)(`div`,{style:{color:`#8b949e`,fontSize:12},children:e.type}),(0,i.jsxs)(`div`,{style:{color:`#58a6ff`,fontSize:12,marginTop:4},children:[`confidence `,e.score.toFixed(3)]})]},`${e.target}-${e.type}`))}):(0,i.jsx)(`div`,{style:l,children:`Run link prediction to surface likely next-hop relationships.`})}),t[82]=d,t[83]=a,t[84]=$):$=t[84],t[85]!==ve||t[86]!==$?(g=(0,i.jsxs)(`details`,{className:`node-panel-collapse`,open:ve,children:[ye,$]}),t[85]=ve,t[86]=$,t[87]=g):g=t[87];let be;t[88]===Symbol.for(`react.memo_cache_sentinel`)?(be=(0,i.jsx)(`summary`,{className:`node-panel-summary`,children:`Source Attribution`}),t[88]=be):be=t[88];let xe=E.length?(0,i.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:E.map(re)}):(0,i.jsx)(`div`,{style:l,children:`No explicit attribution metadata was found on this node.`});t[89]===xe?_=t[90]:(_=(0,i.jsxs)(`details`,{className:`node-panel-collapse`,children:[be,(0,i.jsx)(`div`,{className:`node-panel-body`,children:xe})]}),t[89]=xe,t[90]=_),y=`node-panel-collapse`,t[91]===Symbol.for(`react.memo_cache_sentinel`)?(b=(0,i.jsx)(`summary`,{className:`node-panel-summary`,children:`Properties`}),t[91]=b):b=t[91],h=`node-panel-body`,v=O.length?(0,i.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:O.map(ne)}):(0,i.jsx)(`div`,{style:l,children:`No additional properties are attached to this node.`}),t[1]=r,t[2]=m,t[3]=d,t[4]=s,t[5]=c,t[6]=f,t[7]=p,t[8]=u,t[9]=o,t[10]=a,t[11]=h,t[12]=g,t[13]=_,t[14]=v,t[15]=y,t[16]=b,t[17]=x,t[18]=S,t[19]=C,t[20]=w,t[21]=T}else h=t[11],g=t[12],_=t[13],v=t[14],y=t[15],b=t[16],x=t[17],S=t[18],C=t[19],w=t[20],T=t[21];let E;t[92]!==h||t[93]!==v?(E=(0,i.jsx)(`div`,{className:h,children:v}),t[92]=h,t[93]=v,t[94]=E):E=t[94];let D;t[95]!==E||t[96]!==y||t[97]!==b?(D=(0,i.jsxs)(`details`,{className:y,children:[b,E]}),t[95]=E,t[96]=y,t[97]=b,t[98]=D):D=t[98];let O;return t[99]!==g||t[100]!==_||t[101]!==D||t[102]!==x||t[103]!==S||t[104]!==C||t[105]!==w||t[106]!==T?(O=(0,i.jsxs)(`aside`,{style:x,children:[S,C,w,T,g,_,D]}),t[99]=g,t[100]=_,t[101]=D,t[102]=x,t[103]=S,t[104]=C,t[105]=w,t[106]=T,t[107]=O):O=t[107],O}function ne(e){let[t,n]=e;return(0,i.jsxs)(`div`,{style:c,children:[(0,i.jsx)(`div`,{style:{color:`rgba(88, 166, 255, 0.7)`,fontSize:11,marginBottom:4},children:t}),(0,i.jsx)(`div`,{style:{color:`#e6edf3`,fontSize:13,wordBreak:`break-word`},children:typeof n==`object`?JSON.stringify(n):String(n)})]},t)}function re(e){let{key:t,value:n}=e;return(0,i.jsxs)(`div`,{style:c,children:[(0,i.jsx)(`div`,{style:{color:`rgba(88, 166, 255, 0.7)`,fontSize:11,marginBottom:4},children:t}),(0,i.jsx)(`div`,{style:{color:`#e6edf3`,fontSize:13,wordBreak:`break-word`},children:typeof n==`object`?JSON.stringify(n):String(n)})]},t)}function ie(e,t){return(0,i.jsxs)(`div`,{style:s,children:[t+1,`. `,e]},`${e}-${t}`)}function ae(e){let[t]=e;return![`x`,`y`,`valid_from`,`valid_until`,`content`,`source`,`source_url`,`pmid`,`pmids`,`evidence`,`provenance`,`confidence`].includes(t)}var oe={width:`100%`,background:`rgba(4, 10, 18, 0.5)`,border:`1px solid ${r.palette.background.shellBorder}`,color:`#edf5ff`,borderRadius:12,padding:`11px 13px`,fontSize:13,boxShadow:`inset 0 1px 0 rgba(255,255,255,0.03)`},se={background:`linear-gradient(135deg, rgba(24, 63, 133, 0.42), rgba(35, 85, 176, 0.28))`,color:`#fff`,border:`1px solid ${r.palette.background.shellBorder}`,borderRadius:12,padding:`9px 12px`,cursor:`pointer`,fontWeight:700,fontSize:12,display:`inline-flex`,alignItems:`center`,justifyContent:`center`,boxShadow:`0 8px 22px ${r.palette.background.shellGlow}`},ce={...se,background:`rgba(255, 255, 255, 0.03)`,border:`1px solid rgba(255, 255, 255, 0.08)`,color:`#c6d4e3`,fontWeight:600},le={textAlign:`left`,padding:12,background:`rgba(88, 166, 255, 0.08)`,border:`1px solid rgba(88, 166, 255, 0.12)`,borderRadius:10,cursor:`pointer`},s={color:`#e6edf3`,fontSize:13,padding:`8px 10px`,background:`rgba(255, 255, 255, 0.03)`,borderRadius:8},c={background:`rgba(0, 0, 0, 0.2)`,padding:`10px 12px`,borderRadius:10,border:`1px solid rgba(255, 255, 255, 0.05)`},l={color:`#8b949e`,fontSize:12,lineHeight:1.5},ue={background:`rgba(255, 255, 255, 0.04)`,color:`#9fb6d2`,padding:`4px 8px`,borderRadius:999,fontSize:11,border:`1px solid rgba(255, 255, 255, 0.06)`},de={display:`flex`,flexDirection:`column`,gap:10,padding:14,background:`linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.015))`,border:`1px solid rgba(255, 255, 255, 0.06)`,borderRadius:14},fe={color:`#8b949e`,fontSize:11,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.08em`};export{o as GraphInspectorPanel}; \ No newline at end of file +import{a as e}from"./query-vendor-Cbp9LWgA.js";import{r as t}from"./index-DDOaKEbH.js";import{f as n,t as r}from"./graphTheme-aSRma4TX.js";var ee=t(),i=e(),a=[`source`,`source_url`,`pmid`,`pmids`,`evidence`,`provenance`,`confidence`];function te(e){return a.filter(t=>t in e).map(t=>({key:t,value:e[t]}))}function o(e){let t=(0,ee.c)(108),{nodeId:r,predictions:a,predictionType:o,onPredictionTypeChange:s,onRunPredictions:c,pathTargetId:u,onPathTargetChange:d,onTracePath:f,pathResult:p,onDownloadProvenance:m}=e;if(!r){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,i.jsx)(`div`,{style:{padding:32,textAlign:`center`},children:(0,i.jsx)(`p`,{style:{color:`#8b949e`,fontSize:14,margin:0},children:`Search for a node or click one in the canvas to inspect its properties.`})}),t[0]=e):e=t[0],e}let h,g,_,v,y,b,x,S,C,w,T;if(t[1]!==r||t[2]!==m||t[3]!==d||t[4]!==s||t[5]!==c||t[6]!==f||t[7]!==p||t[8]!==u||t[9]!==o||t[10]!==a){let e=n.getNodeAttributes(r),ee=e?.properties??{},E=te(ee),D=e?.color||`#58a6ff`,O=Object.entries(ee).filter(ae),k,A;t[22]===Symbol.for(`react.memo_cache_sentinel`)?(x={padding:24,display:`flex`,flexDirection:`column`,gap:18},k={borderBottom:`1px solid rgba(88, 166, 255, 0.2)`,paddingBottom:16},A={display:`flex`,alignItems:`center`,gap:10,marginBottom:8},t[22]=k,t[23]=A,t[24]=x):(k=t[22],A=t[23],x=t[24]);let pe=(0,i.jsxs)(`div`,{style:A,children:[(0,i.jsx)(`span`,{style:{background:D,boxShadow:`0 0 10px ${D}`,width:8,height:8,borderRadius:`50%`}}),(0,i.jsx)(`span`,{style:{color:D,fontSize:12,fontWeight:700},children:e?.nodeType||`Entity`})]}),me;t[25]===Symbol.for(`react.memo_cache_sentinel`)?(me={margin:0,color:`#fff`,fontSize:20,fontWeight:700,wordBreak:`break-word`},t[25]=me):me=t[25];let he=String(e?.label??r),j;t[26]===he?j=t[27]:(j=(0,i.jsx)(`h3`,{style:me,children:he}),t[26]=he,t[27]=j);let M;t[28]===Symbol.for(`react.memo_cache_sentinel`)?(M={color:`#8b949e`,fontSize:12,marginTop:6},t[28]=M):M=t[28];let N;t[29]===r?N=t[30]:(N=(0,i.jsx)(`div`,{style:M,children:r}),t[29]=r,t[30]=N);let P;t[31]===Symbol.for(`react.memo_cache_sentinel`)?(P={display:`flex`,gap:8,flexWrap:`wrap`,marginTop:12},t[31]=P):P=t[31];let ge=e?.valid_from||e?.valid_until?(0,i.jsx)(`span`,{style:ue,children:`temporal`}):null,_e=E.length?(0,i.jsxs)(`span`,{style:ue,children:[E.length,` source fields`]}):null,F;t[32]===a.length?F=t[33]:(F=a.length?(0,i.jsxs)(`span`,{style:ue,children:[a.length,` candidate links`]}):null,t[32]=a.length,t[33]=F);let I;t[34]!==ge||t[35]!==_e||t[36]!==F?(I=(0,i.jsxs)(`div`,{style:P,children:[ge,_e,F]}),t[34]=ge,t[35]=_e,t[36]=F,t[37]=I):I=t[37],t[38]!==pe||t[39]!==j||t[40]!==N||t[41]!==I?(S=(0,i.jsxs)(`div`,{style:k,children:[pe,j,N,I]}),t[38]=pe,t[39]=j,t[40]=N,t[41]=I,t[42]=S):S=t[42],C=(e?.valid_from||e?.valid_until)&&(0,i.jsxs)(`div`,{style:{padding:`10px 12px`,background:`rgba(88, 166, 255, 0.08)`,border:`1px solid rgba(88, 166, 255, 0.2)`,borderRadius:8,fontSize:12,color:`#79c0ff`,fontFamily:`monospace`},children:[e?.valid_from?(0,i.jsxs)(`div`,{children:[`from: `,e.valid_from]}):null,e?.valid_until?(0,i.jsxs)(`div`,{children:[`until: `,e.valid_until]}):null]});let L,R,z;t[43]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,i.jsx)(`div`,{style:fe,children:`Actions`}),R={display:`flex`,flexDirection:`column`,gap:10},z={...se,width:`100%`,justifyContent:`center`},t[43]=L,t[44]=R,t[45]=z):(L=t[43],R=t[44],z=t[45]);let B;t[46]===c?B=t[47]:(B=(0,i.jsx)(`button`,{style:z,onClick:c,children:`Run Link Prediction`}),t[46]=c,t[47]=B);let V;t[48]===Symbol.for(`react.memo_cache_sentinel`)?(V={display:`flex`,gap:8,flexWrap:`wrap`},t[48]=V):V=t[48];let H;t[49]===m?H=t[50]:(H=(0,i.jsx)(`button`,{style:ce,onClick:()=>m(`json`),children:`Provenance JSON`}),t[49]=m,t[50]=H);let U;t[51]===m?U=t[52]:(U=(0,i.jsx)(`button`,{style:ce,onClick:()=>m(`markdown`),children:`Provenance MD`}),t[51]=m,t[52]=U);let W;t[53]!==H||t[54]!==U?(W=(0,i.jsxs)(`div`,{style:V,children:[H,U]}),t[53]=H,t[54]=U,t[55]=W):W=t[55];let G;t[56]!==B||t[57]!==W?(G=(0,i.jsxs)(`div`,{style:R,children:[B,W]}),t[56]=B,t[57]=W,t[58]=G):G=t[58];let K;t[59]===s?K=t[60]:(K=e=>s(e.target.value),t[59]=s,t[60]=K);let q;t[61]!==o||t[62]!==K?(q=(0,i.jsx)(`input`,{value:o,onChange:K,placeholder:`Optional candidate type filter, e.g. disease`,style:oe}),t[61]=o,t[62]=K,t[63]=q):q=t[63],t[64]!==G||t[65]!==q?(w=(0,i.jsxs)(`section`,{style:de,children:[L,G,q]}),t[64]=G,t[65]=q,t[66]=w):w=t[66];let J;t[67]===Symbol.for(`react.memo_cache_sentinel`)?(J=(0,i.jsx)(`div`,{style:fe,children:`Trace Path`}),t[67]=J):J=t[67];let Y;t[68]===d?Y=t[69]:(Y=e=>d(e.target.value),t[68]=d,t[69]=Y);let X;t[70]!==u||t[71]!==Y?(X=(0,i.jsx)(`input`,{value:u,onChange:Y,placeholder:`Target node ID`,style:oe}),t[70]=u,t[71]=Y,t[72]=X):X=t[72];let Z;t[73]===f?Z=t[74]:(Z=(0,i.jsx)(`button`,{style:se,onClick:f,children:`Trace Causal Path`}),t[73]=f,t[74]=Z);let Q;t[75]===p?Q=t[76]:(Q=p?.path?.length?(0,i.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:6,marginTop:10},children:[p.path.map(ie),(0,i.jsxs)(`div`,{style:{color:`#79c0ff`,fontSize:12,marginTop:4},children:[`total weight: `,p.total_weight.toFixed(3)]})]}):(0,i.jsx)(`div`,{style:l,children:`Choose a target or click a candidate prediction to prepare a path trace.`}),t[75]=p,t[76]=Q),t[77]!==X||t[78]!==Z||t[79]!==Q?(T=(0,i.jsxs)(`section`,{style:de,children:[J,X,Z,Q]}),t[77]=X,t[78]=Z,t[79]=Q,t[80]=T):T=t[80];let ve=a.length>0,ye;t[81]===Symbol.for(`react.memo_cache_sentinel`)?(ye=(0,i.jsx)(`summary`,{className:`node-panel-summary`,children:`Candidate Links`}),t[81]=ye):ye=t[81];let $;t[82]!==d||t[83]!==a?($=(0,i.jsx)(`div`,{className:`node-panel-body`,children:a.length>0?(0,i.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:a.map(e=>(0,i.jsxs)(`button`,{style:le,onClick:()=>d(e.target),children:[(0,i.jsx)(`div`,{style:{color:`#fff`,fontWeight:600},children:e.label||e.target}),(0,i.jsx)(`div`,{style:{color:`#8b949e`,fontSize:12},children:e.type}),(0,i.jsxs)(`div`,{style:{color:`#58a6ff`,fontSize:12,marginTop:4},children:[`confidence `,e.score.toFixed(3)]})]},`${e.target}-${e.type}`))}):(0,i.jsx)(`div`,{style:l,children:`Run link prediction to surface likely next-hop relationships.`})}),t[82]=d,t[83]=a,t[84]=$):$=t[84],t[85]!==ve||t[86]!==$?(g=(0,i.jsxs)(`details`,{className:`node-panel-collapse`,open:ve,children:[ye,$]}),t[85]=ve,t[86]=$,t[87]=g):g=t[87];let be;t[88]===Symbol.for(`react.memo_cache_sentinel`)?(be=(0,i.jsx)(`summary`,{className:`node-panel-summary`,children:`Source Attribution`}),t[88]=be):be=t[88];let xe=E.length?(0,i.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:E.map(re)}):(0,i.jsx)(`div`,{style:l,children:`No explicit attribution metadata was found on this node.`});t[89]===xe?_=t[90]:(_=(0,i.jsxs)(`details`,{className:`node-panel-collapse`,children:[be,(0,i.jsx)(`div`,{className:`node-panel-body`,children:xe})]}),t[89]=xe,t[90]=_),y=`node-panel-collapse`,t[91]===Symbol.for(`react.memo_cache_sentinel`)?(b=(0,i.jsx)(`summary`,{className:`node-panel-summary`,children:`Properties`}),t[91]=b):b=t[91],h=`node-panel-body`,v=O.length?(0,i.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:O.map(ne)}):(0,i.jsx)(`div`,{style:l,children:`No additional properties are attached to this node.`}),t[1]=r,t[2]=m,t[3]=d,t[4]=s,t[5]=c,t[6]=f,t[7]=p,t[8]=u,t[9]=o,t[10]=a,t[11]=h,t[12]=g,t[13]=_,t[14]=v,t[15]=y,t[16]=b,t[17]=x,t[18]=S,t[19]=C,t[20]=w,t[21]=T}else h=t[11],g=t[12],_=t[13],v=t[14],y=t[15],b=t[16],x=t[17],S=t[18],C=t[19],w=t[20],T=t[21];let E;t[92]!==h||t[93]!==v?(E=(0,i.jsx)(`div`,{className:h,children:v}),t[92]=h,t[93]=v,t[94]=E):E=t[94];let D;t[95]!==E||t[96]!==y||t[97]!==b?(D=(0,i.jsxs)(`details`,{className:y,children:[b,E]}),t[95]=E,t[96]=y,t[97]=b,t[98]=D):D=t[98];let O;return t[99]!==g||t[100]!==_||t[101]!==D||t[102]!==x||t[103]!==S||t[104]!==C||t[105]!==w||t[106]!==T?(O=(0,i.jsxs)(`aside`,{style:x,children:[S,C,w,T,g,_,D]}),t[99]=g,t[100]=_,t[101]=D,t[102]=x,t[103]=S,t[104]=C,t[105]=w,t[106]=T,t[107]=O):O=t[107],O}function ne(e){let[t,n]=e;return(0,i.jsxs)(`div`,{style:c,children:[(0,i.jsx)(`div`,{style:{color:`rgba(88, 166, 255, 0.7)`,fontSize:11,marginBottom:4},children:t}),(0,i.jsx)(`div`,{style:{color:`#e6edf3`,fontSize:13,wordBreak:`break-word`},children:typeof n==`object`?JSON.stringify(n):String(n)})]},t)}function re(e){let{key:t,value:n}=e;return(0,i.jsxs)(`div`,{style:c,children:[(0,i.jsx)(`div`,{style:{color:`rgba(88, 166, 255, 0.7)`,fontSize:11,marginBottom:4},children:t}),(0,i.jsx)(`div`,{style:{color:`#e6edf3`,fontSize:13,wordBreak:`break-word`},children:typeof n==`object`?JSON.stringify(n):String(n)})]},t)}function ie(e,t){return(0,i.jsxs)(`div`,{style:s,children:[t+1,`. `,e]},`${e}-${t}`)}function ae(e){let[t]=e;return![`x`,`y`,`valid_from`,`valid_until`,`content`,`source`,`source_url`,`pmid`,`pmids`,`evidence`,`provenance`,`confidence`].includes(t)}var oe={width:`100%`,background:`rgba(4, 10, 18, 0.5)`,border:`1px solid ${r.palette.background.shellBorder}`,color:`#edf5ff`,borderRadius:12,padding:`11px 13px`,fontSize:13,boxShadow:`inset 0 1px 0 rgba(255,255,255,0.03)`},se={background:`linear-gradient(135deg, rgba(24, 63, 133, 0.42), rgba(35, 85, 176, 0.28))`,color:`#fff`,border:`1px solid ${r.palette.background.shellBorder}`,borderRadius:12,padding:`9px 12px`,cursor:`pointer`,fontWeight:700,fontSize:12,display:`inline-flex`,alignItems:`center`,justifyContent:`center`,boxShadow:`0 8px 22px ${r.palette.background.shellGlow}`},ce={...se,background:`rgba(255, 255, 255, 0.03)`,border:`1px solid rgba(255, 255, 255, 0.08)`,color:`#c6d4e3`,fontWeight:600},le={textAlign:`left`,padding:12,background:`rgba(88, 166, 255, 0.08)`,border:`1px solid rgba(88, 166, 255, 0.12)`,borderRadius:10,cursor:`pointer`},s={color:`#e6edf3`,fontSize:13,padding:`8px 10px`,background:`rgba(255, 255, 255, 0.03)`,borderRadius:8},c={background:`rgba(0, 0, 0, 0.2)`,padding:`10px 12px`,borderRadius:10,border:`1px solid rgba(255, 255, 255, 0.05)`},l={color:`#8b949e`,fontSize:12,lineHeight:1.5},ue={background:`rgba(255, 255, 255, 0.04)`,color:`#9fb6d2`,padding:`4px 8px`,borderRadius:999,fontSize:11,border:`1px solid rgba(255, 255, 255, 0.06)`},de={display:`flex`,flexDirection:`column`,gap:10,padding:14,background:`linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.015))`,border:`1px solid rgba(255, 255, 255, 0.06)`,borderRadius:14},fe={color:`#8b949e`,fontSize:11,fontWeight:700,textTransform:`uppercase`,letterSpacing:`0.08em`};export{o as GraphInspectorPanel}; \ No newline at end of file diff --git a/semantica/static/assets/GraphWorkspace-Bqx0S-ru.js b/semantica/static/assets/GraphWorkspace-Bqx0S-ru.js new file mode 100644 index 00000000..5bdd5fd9 --- /dev/null +++ b/semantica/static/assets/GraphWorkspace-Bqx0S-ru.js @@ -0,0 +1,698 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/TimelinePanel-DZ8Z1JsZ.js","assets/rolldown-runtime-B1FJdls4.js","assets/index-DDOaKEbH.js","assets/query-vendor-Cbp9LWgA.js","assets/index-Bw-pAf6p.css","assets/timeline-vendor-DxuOyw5t.js","assets/timeline-vendor-5-TIXSrZ.css","assets/GraphInspectorPanel-MLghMyni.js","assets/graphTheme-aSRma4TX.js","assets/graph-vendor-pbzH-eyf.js","assets/explorationEffectsPluginPhaseC-D23Zx1hX.js","assets/explorationEffectsPluginPhaseC-D5jYu8XU.js","assets/neighborhoodPanelPlugin-DtCzBl4D.js","assets/neighborhoodPanelPlugin-qsLfEPn1.js","assets/temporalOverlayPlugin-tGkpBW1s.js","assets/temporalOverlayPlugin-l3pE8rf_.js"])))=>i.map(i=>d[i]); +import{i as e,t}from"./rolldown-runtime-B1FJdls4.js";import{T as n,a as r,i,n as a}from"./query-vendor-Cbp9LWgA.js";import{r as o,t as s}from"./index-DDOaKEbH.js";import{a as c,c as l,d as u,i as d,l as f,n as p,o as m,r as h,s as g,t as _,u as v}from"./graph-vendor-pbzH-eyf.js";import{a as y,c as b,d as x,f as S,i as C,l as w,m as T,n as E,o as D,p as O,r as k,s as A,t as j,u as M}from"./graphTheme-aSRma4TX.js";import"./explorationEffectsPluginPhaseC-D5jYu8XU.js";import"./neighborhoodPanelPlugin-qsLfEPn1.js";import"./temporalOverlayPlugin-l3pE8rf_.js";var N=e(n(),1),P=o(),F=r();function I(...e){return e.filter(Boolean).join(` `)}function L(e){let t=(0,P.c)(10),{children:n,tone:r,padding:i,className:a,style:o}=e,s=r===void 0?`default`:r,c=i===void 0?`default`:i,l=s!==`default`&&`sem-surface--${s}`,u;t[0]!==a||t[1]!==l?(u=I(`sem-surface`,l,a),t[0]=a,t[1]=l,t[2]=u):u=t[2];let d;t[3]!==n||t[4]!==c?(d=c===`none`?n:(0,F.jsx)(`div`,{className:I(`sem-surface-body`,c===`tight`&&`sem-surface-body--tight`),children:n}),t[3]=n,t[4]=c,t[5]=d):d=t[5];let f;return t[6]!==o||t[7]!==u||t[8]!==d?(f=(0,F.jsx)(`div`,{className:u,style:o,children:d}),t[6]=o,t[7]=u,t[8]=d,t[9]=f):f=t[9],f}function R(e){let t=(0,P.c)(5),{children:n,tone:r}=e,i=r===void 0?`default`:r,a=i!==`default`&&`sem-chip--${i}`,o;t[0]===a?o=t[1]:(o=I(`sem-chip`,a),t[0]=a,t[1]=o);let s;return t[2]!==n||t[3]!==o?(s=(0,F.jsx)(`span`,{className:o,children:n}),t[2]=n,t[3]=o,t[4]=s):s=t[4],s}function z(e){let t=(0,P.c)(8),{children:n,open:r,className:i}=e,a=r===void 0?!0:r,o;t[0]===i?o=t[1]:(o=I(`sem-inspector`,i),t[0]=i,t[1]=o);let s=a?`block`:`none`,c;t[2]===s?c=t[3]:(c={display:s},t[2]=s,t[3]=c);let l;return t[4]!==n||t[5]!==o||t[6]!==c?(l=(0,F.jsx)(L,{className:o,padding:`none`,style:c,children:n}),t[4]=n,t[5]=o,t[6]=c,t[7]=l):l=t[7],l}var ee=e(_(),1),te={id:`hover-activation`,attach:()=>{},detach:()=>{},onNodeEnter:(e,t)=>{e.setHoveredNodeId(t)},onNodeLeave:(e,t)=>{e.getInteractionState().hoveredNodeId===t&&e.setHoveredNodeId(null)}},B={id:`click-selection`,attach:()=>{},detach:()=>{},onNodeClick:(e,t)=>{e.setHoveredNodeId(t),e.onEdgeSelectionChange(``),e.onNodeSelectionChange(t)},onEdgeClick:(e,t)=>{e.setHoveredNodeId(null),e.onEdgeSelectionChange(t)},onStageClick:e=>{e.setHoveredNodeId(null),e.onEdgeSelectionChange(``),e.onNodeSelectionChange(``)}},ne={id:`focus-camera`,attach:()=>{},detach:()=>{},performAction:(e,t)=>t.type===`focusNode`?(e.focusNodeInView(t.nodeId),!0):!1};function re(){let e=``;return{id:`search-focus`,attach:()=>{},detach:()=>{e=``},onStateChange:(t,n)=>{let r=n.focusedNodeId;if(!r||r===e){e=r;return}e=r,t.dispatchAction({type:`focusNode`,nodeId:r})}}}function V(){let e=``;return{id:`path-highlight`,attach:()=>{},detach:()=>{e=``},onStateChange:(t,n)=>{let r=n.activePath.join(`::`);r!==e&&(e=r,t.sigma.refresh())}}}var ie={id:`fit-view`,attach:()=>{},detach:()=>{},performAction:(e,t)=>t.type===`fitView`?(e.fitCurrentView(),!0):!1};function ae(){let e=null;return{id:`view-mode-switch`,attach:()=>{},detach:()=>{e=null},onStateChange:(t,n)=>{if(n.viewMode!==e){if(e=n.viewMode,n.focusedNodeId){t.dispatchAction({type:`focusNode`,nodeId:n.focusedNodeId});return}t.dispatchAction({type:`fitView`})}}}}var H=j.focus.maxNeighbors,U=j.focus.ringCapacity,oe=j.focus.ringGap,W=j.focus.primaryLabels;function se(e){return k(0,Math.log2(Math.max(e,1))/1.85,1)}function ce(e,t,n,r){e.forEachDirectedEdge(t,n,(e,t)=>{r(String(e),t)})}function G(e,t,n){let r=[];return ce(e,t,n,e=>{r.push(e)}),r}function K(e,t,n=[]){if(n.length>0)return new Set(n.filter(t=>e.hasEdge(t)));let r=new Set;for(let n=0;nr.add(e));return r}function q(e,...t){let n=new Set;return t.forEach(t=>{if(!t||!e.hasEdge(t))return;let[r,i]=e.extremities(t);n.add(r),n.add(i)}),n}function J(e,t){let n=new Set,r=Array.from(t);for(let t=0;tn.add(e))}}return n}function Y(e,t){if(!t)return new Set;let n=new Set(t.activePath),r=t.hoveredNodeId||t.selectedNodeId;return r&&e.hasNode(r)&&de(r).forEach(e=>n.add(e)),q(e,t.selectedEdgeId).forEach(e=>n.add(e)),n}function X(e,t){if(!t)return new Set;let n=new Set(K(e,t.activePath,t.activePathEdgeIds)),r=t.hoveredNodeId||t.selectedNodeId;return r&&e.hasNode(r)&&J(e,de(r)).forEach(e=>n.add(e)),t.selectedEdgeId&&n.add(t.selectedEdgeId),n}function Z(e,t){return Array.from(t).filter(t=>e.hasEdge(t))}function le(e,t,n){let r=new Set,i=new Set;return Y(e,t).forEach(e=>r.add(e)),Y(e,n).forEach(e=>r.add(e)),X(e,t).forEach(e=>i.add(e)),X(e,n).forEach(e=>i.add(e)),{nodes:Array.from(r).filter(t=>e.hasNode(t)),edges:Z(e,i)}}function ue(e,t){let n=0;return ce(S,e,t,(e,t)=>{n=Math.max(n,Number(t?.weight??0))}),ce(S,t,e,(e,t)=>{n=Math.max(n,Number(t?.weight??0))}),n}function Q(e){return S.neighbors(e).map(t=>({id:t,weight:ue(e,t),degree:S.degree(t)})).sort((e,t)=>t.weight===e.weight?t.degree===e.degree?e.id.localeCompare(t.id):t.degree-e.degree:t.weight-e.weight).map(e=>e.id)}function de(e){let t=Q(e).slice(0,H);return new Set([e,...t])}function fe(e,t,n,r,i,a){if(K(e,t.activePath,t.activePathEdgeIds).has(n)||t.selectedEdgeId===n)return!0;let o=t.selectedNodeId;if(o&&e.hasNode(o)){if(r===o||i===o)return!0;let e=de(o);return e.has(r)&&e.has(i)}return t.zoomTier===`inspection`?Number(a.visualPriority??0)>=j.zoomTiers[t.zoomTier].edgePriorityThreshold:!1}function pe(e,t,n,r,i,a){let o=String(r.baseColor||a||e.palette.semantic[0]),s=n===`neighbor`?e.palette.overview.nodeTintMix+.09:e.palette.overview.nodeTintMix,c=E(e.palette.overview.nodeCore,o,Math.min(.74,e.palette.overview.nodeCoreMix+s));switch(e.nodes.states[n].color){case`selected`:return e.palette.accent.selected;case`hovered`:return e.palette.accent.hovered;case`path`:return e.palette.accent.path;case`muted`:return t===`overview`?A(e.palette.overview.nodeMuted,.42):String(r.mutedColor||A(o,e.nodes.mutedAlpha));default:if(t===`overview`){let t=se(i);return A(E(c,o,.3+.26*t),Math.min(.98,e.palette.overview.nodeCoreAlpha+t*.18))}return o}}function me(e,t,n,r,i,a){let o=String(r.baseColor||a||e.palette.semantic[0]),s=se(i),c=E(e.palette.overview.nodeBase,o,(n===`neighbor`?.02:.012)+s*.024);return t===`overview`?n===`selected`?A(E(e.palette.overview.nodeBase,e.palette.accent.selected,.05),.98):n===`hovered`?A(E(e.palette.overview.nodeBase,e.palette.accent.hovered,.06),.98):n===`path`?A(E(e.palette.overview.nodeBase,e.palette.accent.path,.06),.97):n===`muted`||n===`inactive`?A(e.palette.overview.nodeMuted,.22):A(c,e.palette.overview.nodeShellAlpha):A(E(e.palette.overview.nodeBase,o,.26),.95)}function he(e,t,n){let r=se(n);if(e===`overview`)switch(t){case`selected`:return .34+r*.08;case`hovered`:return .32+r*.08;case`path`:return .28+r*.07;case`neighbor`:return .2+r*.06;case`muted`:case`inactive`:return .08+r*.03;default:return .16+r*.08}switch(t){case`selected`:return .52;case`hovered`:return .48;case`path`:return .44;case`neighbor`:return .3;case`muted`:case`inactive`:return .1;default:return e===`structure`?.22:.28}}function ge(e,t,n,r,i){let a=t===`overview`?e.palette.overview.edgeInspection:e.palette.muted.edgeInspection,o=String(r.baseColor||i||a);switch(e.edges.states[n].color){case`hover`:return e.palette.accent.hovered;case`path`:return e.palette.accent.path;case`backbone`:return t===`overview`?e.palette.overview.edgeBackbone:e.palette.muted.edgeFocus;case`focus`:return e.palette.muted.edgeFocus;case`overview`:return e.palette.muted.edgeOverview;case`structure`:return t===`overview`?e.palette.overview.edgeStructure:e.palette.muted.edgeStructure;case`inspection`:return t===`overview`?e.palette.overview.edgeInspection:e.palette.muted.edgeInspection;case`muted`:return t===`overview`?e.palette.overview.edgeStructure:String(r.mutedColor||e.palette.muted.edgeOverview);default:return o}}function _e(e,t,n){if(t===`selected`)return n.ringColor||e.nodes.selectedRing.color;if(t===`hovered`)return e.palette.accent.hovered;if(t===`path`)return e.palette.accent.path}function ve(e,t,n){return t===`selected`&&b(n,e.nodes.selectedRing.visibleFrom)?e.nodes.selectedRing.nativeSize:t===`hovered`?Math.max(1.45,e.nodes.selectedRing.nativeSize-.35):t===`path`?Math.max(1.2,e.nodes.selectedRing.nativeSize-.55):0}function ye(e,t,n,r,i,a,o,s){return n&&e===n?`hovered`:r&&e===r?`selected`:s.has(e)?`path`:a.has(e)||o.has(e)?`neighbor`:n||r||i||s.size>0?t===`overview`?`default`:`muted`:`default`}function be(e,t,n,r,i,a,o,s,c,l){let u=i||a;return c.has(e)?`path`:o&&e===o?`selected`:u&&(t===u||n===u)?i?`hovered`:`selected`:r!==`overview`&&s.has(t)&&s.has(n)?`neighbor`:r===`overview`&&l.has(e)?`backbone`:i||a||o||c.size>0?`muted`:r===`overview`?`inactive`:`default`}function xe(e,t){return e===`selected`?`selected`:t.nodeShapeVariant||t.nodeVariant||`default`}function Se(e,t){return e===`path`?`pathSignal`:(t.parallelCount??1)>1?`parallelCurve`:t.edgeVariant?t.edgeVariant:t.isBidirectional?`bidirectionalCurve`:t.arrowVisibilityPolicy===`contextual`?`directional`:`line`}function $(e,t,n,r,i){let a=e.zoomTiers[t],o=e.labels.forceVisibleStates.includes(n),s=r.labelVisibilityPolicy||`priority`;if(o||e.nodes.states[n].forceLabel)return!0;switch(s){case`always`:return!0;case`local`:return t!==`overview`&&n!==`default`&&n!==`muted`&&n!==`inactive`;case`priority`:return i>=a.labelThreshold;default:return!1}}function Ce(e,t,n,r,i,a){return n===`selected`||r===`selected`?i.ringColor||e.nodes.selectedRing.color:n===`hovered`?e.palette.accent.hovered:n===`path`?e.palette.accent.path:n===`muted`||n===`inactive`?A(i.strokeColor||i.borderColor||e.palette.overview.nodeBorder||e.palette.background.nodeBorder,t===`overview`?.26:.7):r===`temporal`?e.palette.accent.temporal:r===`provenance`?e.palette.accent.provenance:r===`inferred`?e.palette.accent.inferred:t===`overview`?A(E(e.palette.overview.nodeBorder,a,n===`neighbor`?.08:.03),n===`neighbor`?.24:.06):i.strokeColor||i.borderColor||e.palette.background.nodeBorder||a}function we(e,t,n,r,i,a=1){let o=e.zoomTiers[t],s=e.nodes.states[n],c=xe(n,r),l=e.nodes.variants[c],u=Number(r.baseSize||r.size||4),d=Number(r.labelPriority??0),f=pe(e,t,n,r,a,r.color),p=me(e,t,n,r,a,r.color),m=(n===`default`?o.nodeScale:s.sizeMultiplier)*l.sizeMultiplier,h=t===`overview`?1+se(a)*1.2:1,g=$(e,t,n,r,d),_=r.badgeKind||l.badgeKind,v=e.labels.forceVisibleStates.includes(n),y=!!(_&&(v||o.showBadges&&b(t,l.badgeVisibleFrom))&&n!==`muted`&&n!==`inactive`),x=ve(e,n,t),S=_e(e,n,r),C=x>0,w=n===`hovered`||n===`selected`||n===`path`,T=n===`muted`||n===`inactive`?e.nodes.strokeHierarchy[t].muted:v?e.nodes.strokeHierarchy[t].emphasis:e.nodes.strokeHierarchy[t].base;return{color:f,shellColor:p,coreScale:he(t,n,a),size:Math.max(u*m*h,s.minSize),forceLabel:g,label:g?i:``,zIndex:g&&s.zIndex===0?1:s.zIndex,hidden:!1,borderColor:Ce(e,t,n,c,r,f),borderSize:Math.max(.4,Number(r.borderSize??.85)+T+s.borderBoost+l.borderBoost-.8),nodeVariant:c,badgeKind:_,badgeCount:r.badgeCount,showBadge:y,showRing:C,ringColor:S,ringSize:x,showHalo:w,haloColor:r.haloColor||r.glowColor||A(f,e.overlays.hoverGlowAlpha+l.haloBoost)}}function Te(e,t,n,r,i){let a=e.edges.variants[r];return e.edges.states[n].forceArrow||a.arrowPolicy===`always`||a.arrowPolicy===`contextual`&&e.zoomTiers[t].showContextualArrows?`arrow`:n===`default`?Number(i.visualPriority??0)>=e.zoomTiers[t].arrowPriorityThreshold&&e.zoomTiers[t].showContextualArrows?`arrow`:`line`:i.type||a.baseType}function Ee(e,t,n,r,i,a){let o=e.edges.variants[n],s=n===`line`&&t===`selected`?Math.max(o.curveStrength,.14):o.curveStrength;if(s===0)return 0;if(typeof r.parallelCount==`number`&&r.parallelCount>1&&typeof r.parallelIndex==`number`){let e=(r.parallelCount-1)/2;return(r.parallelIndex-e)*s}return(n===`bidirectionalCurve`||n===`parallelCurve`||r.isBidirectional)&&i&&a?i.localeCompare(a)<=0?s:-s:s}function De(e,t,n,r,i,a){let o=e.zoomTiers[t],s=e.edges.states[n],c=Se(n,r),l=e.edges.variants[c],u=Number(r.baseSize||r.size||.9),d=Number(r.visualPriority??0),f=n===`default`&&d{r.hasNode(e)||r.addNode(e,t)},d=S.getNodeAttributes(e),f=we(j,`inspection`,`selected`,d,d.label);l(e,{...d,x:0,y:0,color:f.color,size:Math.max(f.size,22),baseColor:f.color,baseSize:Math.max(f.size,22),label:f.label}),i.forEach((e,t)=>{let n=S.getNodeAttributes(e),r=Math.floor(t/U),a=t%U,c=Math.min(U,i.length-r*U),u=oe*(r+1),d=Math.PI*2*a/c-Math.PI/2,f=we(j,`inspection`,s.has(e)?`path`:o.has(e)?`neighbor`:`default`,{...n,labelPriority:o.has(e)||s.has(e)?Math.max(Number(n.labelPriority??0),1):0},n.label);l(e,{...n,x:Math.cos(d)*u,y:Math.sin(d)*u,color:f.color,size:Math.max(f.size,8.5),baseColor:f.color,baseSize:Math.max(f.size,8.5),label:f.label})});for(let t of a)for(let n of a)t!==n&&ce(S,t,n,(i,a)=>{let o=De(j,`inspection`,c.has(i)?`path`:t===e||n===e?`selected`:`neighbor`,a,t,n);r.mergeDirectedEdgeWithKey(i,t,n,{...a,type:o.type,size:o.size,color:o.color,baseSize:o.size,baseColor:o.color,curvature:o.curvature})});return r}function ke(e,t,n,r){return r===`focused`&&e&&S.hasNode(e)&&e?Oe(e,t,n):S}function Ae(e,t,n,r,i,a,o,s){return{hoveredNodeId:e,selectedNodeId:t,selectedEdgeId:n,focusedNodeId:t,activePath:r,activePathEdgeIds:i,viewMode:a,zoomTier:o,isLayoutRunning:s}}var je=t(((e,t)=>{function n(e){return!e||typeof e!=`object`||typeof e==`function`||Array.isArray(e)||e instanceof Set||e instanceof Map||e instanceof RegExp||e instanceof Date}function r(e,t){e||={};var i={};for(var a in t){var o=e[a],s=t[a];if(!n(s)){i[a]=r(o,s);continue}o===void 0?i[a]=s:i[a]=o}return i}t.exports=r})),Me=t(((e,t)=>{var n=m();t.exports=function(e){if(!n(e))throw Error(`graphology-utils/infer-type: expecting a valid graphology instance.`);var t=e.type;return t===`mixed`?e.directedSize===0&&e.undirectedSize===0||e.directedSize>0&&e.undirectedSize>0?`mixed`:e.directedSize>0?`directed`:`undirected`:t}})),Ne=t(((e,t)=>{function n(e){if(typeof e!=`function`)throw Error(`obliterator/iterator: expecting a function!`);this.next=e}typeof Symbol<`u`&&(n.prototype[Symbol.iterator]=function(){return this}),n.of=function(){var e=arguments,t=e.length,r=0;return new n(function(){return r>=t?{done:!0}:{done:!1,value:e[r++]}})},n.empty=function(){return new n(function(){return{done:!0}})},n.fromSequence=function(e){var t=0,r=e.length;return new n(function(){return t>=r?{done:!0}:{done:!1,value:e[t++]}})},n.is=function(e){return e instanceof n?!0:typeof e==`object`&&!!e&&typeof e.next==`function`},t.exports=n})),Pe=t((e=>{var t=2**8-1,n=2**16-1,r=2**32-1,i=2**7-1,a=2**15-1,o=2**31-1;e.getPointerArray=function(e){var i=e-1;if(i<=t)return Uint8Array;if(i<=n)return Uint16Array;if(i<=r)return Uint32Array;throw Error(`mnemonist: Pointer Array of size > 4294967295 is not supported.`)},e.getSignedPointerArray=function(e){var t=e-1;return t<=i?Int8Array:t<=a?Int16Array:t<=o?Int32Array:Float64Array},e.getNumberType=function(e){return e===(e|0)?Math.sign(e)===-1?e<=127&&e>=-128?Int8Array:e<=32767&&e>=-32768?Int16Array:Int32Array:e<=255?Uint8Array:e<=65535?Uint16Array:Uint32Array:Float64Array};var s={Uint8Array:1,Int8Array:2,Uint16Array:3,Int16Array:4,Uint32Array:5,Int32Array:6,Float32Array:7,Float64Array:8};e.getMinimalRepresentation=function(t,n){var r=null,i=0,a,o,c,l,u;for(l=0,u=t.length;li&&(i=a,r=o);return r},e.isTypedArray=function(e){return typeof ArrayBuffer<`u`&&ArrayBuffer.isView(e)},e.concat=function(){var e=0,t,n,r;for(t=0,r=arguments.length;t{var n=Ne(),r=Pe().getPointerArray;function i(e,t){arguments.length<2&&(t=e,e=Array);var n=r(t);this.size=0,this.length=t,this.dense=new n(t),this.sparse=new n(t),this.vals=new e(t)}i.prototype.clear=function(){this.size=0},i.prototype.has=function(e){var t=this.sparse[e];return t=this.size||this.dense[t]!==e?!1:(t=this.dense[this.size-1],this.dense[this.sparse[e]]=t,this.sparse[t]=this.sparse[e],this.size--,!0)},i.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var n=0;n{var n=Ne(),r=Pe().getPointerArray;function i(e){var t=r(e);this.start=0,this.size=0,this.capacity=e,this.dense=new t(e),this.sparse=new t(e)}i.prototype.clear=function(){this.start=0,this.size=0},i.prototype.has=function(e){if(this.size===0)return!1;var t=this.sparse[e];return(t=this.start&&t=this.start&&t1?t:this;for(var n=this.capacity,r=this.size,i=this.start,a=0;a=r)return{done:!0};var n=e[i];return i++,a++,i===t&&(i=0),{value:n,done:!1}})},typeof Symbol<`u`&&(i.prototype[Symbol.iterator]=i.prototype.values),i.prototype.inspect=function(){var e=[];return this.forEach(function(t){e.push(t)}),Object.defineProperty(e,`constructor`,{value:i,enumerable:!1}),e.capacity=this.capacity,e},typeof Symbol<`u`&&(i.prototype[Symbol.for(`nodejs.util.inspect.custom`)]=i.prototype.inspect),t.exports=i})),Le=t(((e,t)=>{function n(e){return function(t){return typeof t!=`number`&&(t=t.length),Math.floor(e()*t)}}var r=n(Math.random);r.createRandomIndex=n,t.exports=r})),Re=t((e=>{var t=Pe(),n=je(),r=p().createEdgeWeightGetter,i=Symbol.for(`nodejs.util.inspect.custom`),a={getEdgeWeight:`weight`,keepDendrogram:!1,resolution:1};function o(e,i){i=n(i,a);var o=i.resolution,s=r(i.getEdgeWeight).fromEntry,c=(e.size-e.selfLoopCount)*2,l=t.getPointerArray(c),u=t.getPointerArray(e.order+1),d=i.getEdgeWeight?Float64Array:t.getPointerArray(e.size*2);this.C=e.order,this.M=0,this.E=c,this.U=0,this.resolution=o,this.level=0,this.graph=e,this.nodes=Array(e.order),this.keepDendrogram=i.keepDendrogram,this.neighborhood=new u(c),this.weights=new d(c),this.loops=new d(e.order),this.starts=new l(e.order+1),this.belongings=new u(e.order),this.dendrogram=[],this.mapping=null,this.counts=new u(e.order),this.unused=new u(e.order),this.totalWeights=new d(e.order);var f={},p,m=0,h=0,g=this;e.forEachNode(function(t){g.nodes[m]=t,f[t]=m,h+=e.undirectedDegreeWithoutSelfLoops(t),g.starts[m]=h,g.belongings[m]=m,g.counts[m]=1,m++}),e.forEachEdge(function(e,t,n,r,i,a,o){if(p=s(e,t,n,r,i,a,o),n=f[n],r=f[r],g.M+=p,n===r)g.totalWeights[n]+=p*2,g.loops[n]=p*2;else{g.totalWeights[n]+=p,g.totalWeights[r]+=p;var c=--g.starts[n],l=--g.starts[r];g.neighborhood[c]=r,g.neighborhood[l]=n,g.weights[c]=p,g.weights[l]=p}}),this.starts[m]=this.E,this.keepDendrogram?this.dendrogram.push(this.belongings.slice()):this.mapping=this.belongings.slice()}o.prototype.isolate=function(e,t){var n=this.belongings[e];if(this.counts[n]===1)return n;var r=this.unused[--this.U],i=this.loops[e];return this.totalWeights[n]-=t+i,this.totalWeights[r]+=t+i,this.belongings[e]=r,this.counts[n]--,this.counts[r]++,r},o.prototype.move=function(e,t,n){var r=this.belongings[e],i=this.loops[e];this.totalWeights[r]-=t+i,this.totalWeights[n]+=t+i,this.belongings[e]=n;var a=this.counts[r]--===1;this.counts[n]++,a&&(this.unused[this.U++]=r)},o.prototype.computeNodeDegree=function(e){var t,n,r,i=0;for(t=this.starts[e],n=this.starts[e+1];t{var n=je(),r=m(),i=Me(),a=Fe(),o=Ie(),s=Le().createRandomIndex,c=Re(),l=c.UndirectedLouvainIndex,u=c.DirectedLouvainIndex,d={nodeCommunityAttribute:`community`,getEdgeWeight:`weight`,fastLocalMoves:!0,randomWalk:!0,resolution:1,rng:Math.random};function f(e,t,n){var r=e.get(t);r===void 0&&(r=0),r+=n,e.set(t,r)}var p=1e-10;function h(e,t,n,r,i){return Math.abs(r-i)e:r>i}function g(e,t,n){var r=new l(t,{getEdgeWeight:n.getEdgeWeight,keepDendrogram:e,resolution:n.resolution}),i=s(n.rng),c=!0,u=!0,d,p,m=new a(Float64Array,r.C),g,_,v,y,b,x,S,C,w,T,E,D,O,k,A,j,M=0,N=0,P=[],F,I;for(n.fastLocalMoves&&(g=new o(r.C));c;){if(T=r.C,c=!1,u=!0,n.fastLocalMoves){for(I=0,x=n.randomWalk?i(T):0,S=0;S{e.ARRAY_BUFFER_SUPPORT=typeof ArrayBuffer<`u`,e.SYMBOL_SUPPORT=typeof Symbol<`u`})),Ve=t(((e,t)=>{var n=Be(),r=n.ARRAY_BUFFER_SUPPORT,i=n.SYMBOL_SUPPORT;t.exports=function(e,t){var n,a,o,s,c;if(!e)throw Error(`obliterator/forEach: invalid iterable.`);if(typeof t!=`function`)throw Error(`obliterator/forEach: expecting a callback.`);if(Array.isArray(e)||r&&ArrayBuffer.isView(e)||typeof e==`string`||e.toString()===`[object Arguments]`){for(o=0,s=e.length;o{var n=Ne(),r=Ve();function i(){this.clear()}i.prototype.clear=function(){this.items=[],this.offset=0,this.size=0},i.prototype.enqueue=function(e){return this.items.push(e),++this.size},i.prototype.dequeue=function(){if(this.size){var e=this.items[this.offset];return++this.offset*2>=this.items.length&&(this.items=this.items.slice(this.offset),this.offset=0),this.size--,e}},i.prototype.peek=function(){if(this.size)return this.items[this.offset]},i.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var n=this.offset,r=0,i=this.items.length;n=e.length)return{done:!0};var n=e[t];return t++,{value:n,done:!1}})},i.prototype.entries=function(){var e=this.items,t=this.offset,r=0;return new n(function(){if(t>=e.length)return{done:!0};var n=e[t];return t++,{value:[r++,n],done:!1}})},typeof Symbol<`u`&&(i.prototype[Symbol.iterator]=i.prototype.values),i.prototype.toString=function(){return this.toArray().join(`,`)},i.prototype.toJSON=function(){return this.toArray()},i.prototype.inspect=function(){var e=this.toArray();return Object.defineProperty(e,`constructor`,{value:i,enumerable:!1}),e},typeof Symbol<`u`&&(i.prototype[Symbol.for(`nodejs.util.inspect.custom`)]=i.prototype.inspect),i.from=function(e){var t=new i;return r(e,function(e){t.enqueue(e)}),t},i.of=function(){return i.from(arguments)},t.exports=i})),Ue=t(((e,t)=>{t.exports=function(e,t){var n=t.length;if(n!==0){var r=e.length;e.length+=n;for(var i=0;i{var t=m(),n=He(),r=Ue();function i(e,n,r){if(!t(e))throw Error(`graphology-shortest-path: invalid graphology instance.`);if(arguments.length<3)throw Error(`graphology-shortest-path: invalid number of arguments. Expecting at least 3.`);if(!e.hasNode(n))throw Error(`graphology-shortest-path: the "`+n+`" source node does not exist in the given graph.`);if(!e.hasNode(r))throw Error(`graphology-shortest-path: the "`+r+`" target node does not exist in the given graph.`);if(n=``+n,r=``+r,n===r)return[n];var i=e.inboundNeighbors.bind(e),a=e.outboundNeighbors.bind(e),o={},s={};o[n]=null,s[r]=null;var c=[n],l=[r],u,d,f,p,m,h,g,_,v=!1;outer:for(;c.length&&l.length;)if(c.length<=l.length){for(u=c,c=[],m=0,g=u.length;m{var t=function(){return!0};e.edgePathFromNodePath=function(e,n){var r=n.length,i,a,o,s;if(r<2)return a=n[0],s=e.multi?e.findEdge(a,a,t):e.edge(a,a),s?[s]:[];r--;var c=Array(r);for(i=0;i{var t=function(e,t){return et?1:0},n=function(e,t){return et?-1:0};function r(e){return function(t,n){return e(n,t)}}function i(e){return e===2?function(e,t){return e[0]t[0]?1:e[1]t[1]?1:0}:function(t,n){for(var r=0;rn[r])return 1;r++}return 0}}e.DEFAULT_COMPARATOR=t,e.DEFAULT_REVERSE_COMPARATOR=n,e.reverseComparator=r,e.createTupleComparator=i})),qe=t((e=>{var t=Ve(),n=Pe();function r(e){return Array.isArray(e)||n.isTypedArray(e)}function i(e){if(typeof e.length==`number`)return e.length;if(typeof e.size==`number`)return e.size}function a(e){var n=i(e),r=typeof n==`number`?Array(n):[],a=0;return t(e,function(e){r[a++]=e}),r}function o(e){var r=i(e),a=typeof r==`number`?n.getPointerArray(r):Array,o=typeof r==`number`?Array(r):[],s=typeof r==`number`?new a(r):[],c=0;return t(e,function(e){o[c]=e,s[c]=c++}),[o,s]}e.isArrayLike=r,e.guessLength=i,e.toArray=a,e.toArrayWithIndices=o})),Je=t(((e,t)=>{var n=Ve(),r=Ke(),i=qe(),a=r.DEFAULT_COMPARATOR,o=r.reverseComparator;function s(e,t,n,r){for(var i=t[r],a,o;r>n;){if(a=r-1>>1,o=t[a],e(i,o)<0){t[r]=o,r=a;continue}break}t[r]=i}function c(e,t,n){for(var r=t.length,i=n,a=t[n],o=2*n+1,c;o=0&&(o=c),t[n]=t[o],n=o,o=2*n+1;t[n]=a,s(e,t,i,n)}function l(e,t,n){t.push(n),s(e,t,0,t.length-1)}function u(e,t){var n=t.pop();if(t.length!==0){var r=t[0];return t[0]=n,c(e,t,0),r}return n}function d(e,t,n){if(t.length===0)throw Error(`mnemonist/heap.replace: cannot pop an empty heap.`);var r=t[0];return t[0]=n,c(e,t,0),r}function f(e,t,n){var r;return t.length!==0&&e(t[0],n)<0&&(r=t[0],t[0]=n,n=r,c(e,t,0)),n}function p(e,t){for(var n=t.length>>1;--n>=0;)c(e,t,n)}function m(e,t){for(var n=t.length,r=0,i=Array(n);r=r.length)return r.slice().sort(e);for(m=r.slice(0,t),p(s,m),c=t,l=r.length;c0&&d(s,m,r[c]);return m.sort(e)}var h=i.guessLength(r);return h!==null&&h0&&d(s,m,e)),c++}),m.length>c&&(m.length=c),m.sort(e)}function g(e,t,r){arguments.length===2&&(r=t,t=e,e=a);var s=o(e),c,l,u,f=-1/0,m;if(t===1){if(i.isArrayLike(r)){for(c=0,l=r.length;c0)&&(f=u);return m=new r.constructor(1),m[0]=f,m}return n(r,function(t){(f===-1/0||e(t,f)>0)&&(f=t)}),[f]}if(i.isArrayLike(r)){if(t>=r.length)return r.slice().sort(s);for(m=r.slice(0,t),p(e,m),c=t,l=r.length;c0&&d(e,m,r[c]);return m.sort(s)}var h=i.guessLength(r);return h!==null&&h0&&d(e,m,n)),c++}),m.length>c&&(m.length=c),m.sort(s)}function _(e){if(this.clear(),this.comparator=e||a,typeof this.comparator!=`function`)throw Error(`mnemonist/Heap.constructor: given comparator should be a function.`)}_.prototype.clear=function(){this.items=[],this.size=0},_.prototype.push=function(e){return l(this.comparator,this.items,e),++this.size},_.prototype.peek=function(){return this.items[0]},_.prototype.pop=function(){return this.size!==0&&this.size--,u(this.comparator,this.items)},_.prototype.replace=function(e){return d(this.comparator,this.items,e)},_.prototype.pushpop=function(e){return f(this.comparator,this.items,e)},_.prototype.consume=function(){return this.size=0,m(this.comparator,this.items)},_.prototype.toArray=function(){return m(this.comparator,this.items.slice())},_.prototype.inspect=function(){var e=this.toArray();return Object.defineProperty(e,`constructor`,{value:_,enumerable:!1}),e},typeof Symbol<`u`&&(_.prototype[Symbol.for(`nodejs.util.inspect.custom`)]=_.prototype.inspect);function v(e){if(this.clear(),this.comparator=e||a,typeof this.comparator!=`function`)throw Error(`mnemonist/MaxHeap.constructor: given comparator should be a function.`);this.comparator=o(this.comparator)}v.prototype=_.prototype,_.from=function(e,t){var n=new _(t),r=i.isArrayLike(e)?e.slice():i.toArray(e);return p(n.comparator,r),n.items=r,n.size=r.length,n},v.from=function(e,t){var n=new v(t),r=i.isArrayLike(e)?e.slice():i.toArray(e);return p(n.comparator,r),n.items=r,n.size=r.length,n},_.siftUp=c,_.siftDown=s,_.push=l,_.pop=u,_.replace=d,_.pushpop=f,_.heapify=p,_.consume=m,_.nsmallest=h,_.nlargest=g,_.MinHeap=_,_.MaxHeap=v,t.exports=_})),Ye=t((e=>{var t=m(),n=p().createEdgeWeightGetter,r=Je(),i=`weight`;function a(e,t){return e[0]>t[0]?1:e[0]t[1]?1:e[1]t[2]?1:e[2]t[0]?1:e[0]t[1]?1:e[1]t[2]?1:e[2]t[3]?1:e[3]b)&&(m=b,p=u[0][S].concat(u[1][S].slice(0,-1).reverse()))))}}return[1/0,null]}function c(e,o,s,c,l,u){if(!t(e))throw Error(`graphology-shortest-path/dijkstra: invalid graphology instance.`);if(l&&!e.hasNode(l))throw Error(`graphology-shortest-path/dijkstra: the "`+l+`" target node does not exist in the given graph.`);s=n(s||i).fromMinimalEntry;var d={},f={},p=new r(a),m=0,h,g,_,v,y,b,x,S,C,w,T;for(S=0,w=o.length;Sc)){if(y in d&&_{var t=m(),n=p().createEdgeWeightGetter,r=Je(),i=`weight`;function a(e,t){return e[0]>t[0]?1:e[0]t[1]?1:e[1]u.cutoff||(p[E]=[T,C],f.push([T+C,d++,E,T,g]))}}for(;f.size!==0;){if(h=f.pop(),g=h[2],v=h[3],y=h[4],g===s){for(b=[g],x=y;x!==null;)b.push(x),x=m[x];return b.reverse(),b}m.hasOwnProperty(g)&&(m[g]===null||(S=p[g][0],S{var t=We(),n=Ge();e.dijkstra=Ye(),e.astar=Xe(),e.bidirectional=t.bidirectional,e.singleSource=t.singleSource,e.singleSourceLength=t.singleSourceLength,e.undirectedSingleSourceLength=t.undirectedSingleSourceLength,e.brandes=t.brandes,e.edgePathFromNodePath=n.edgePathFromNodePath})),Qe=t(((e,t)=>{var n=qe(),r=Ne();function i(e,t){if(arguments.length<2)throw Error(`mnemonist/fixed-deque: expecting an Array class and a capacity.`);if(typeof t!=`number`||t<=0)throw Error("mnemonist/fixed-deque: `capacity` should be a positive number.");this.ArrayClass=e,this.capacity=t,this.items=new e(this.capacity),this.clear()}i.prototype.clear=function(){this.start=0,this.size=0},i.prototype.push=function(e){if(this.size===this.capacity)throw Error(`mnemonist/fixed-deque.push: deque capacity (`+this.capacity+`) exceeded!`);var t=this.start+this.size;return t>=this.capacity&&(t-=this.capacity),this.items[t]=e,++this.size},i.prototype.unshift=function(e){if(this.size===this.capacity)throw Error(`mnemonist/fixed-deque.unshift: deque capacity (`+this.capacity+`) exceeded!`);var t=this.start-1;return this.start===0&&(t=this.capacity-1),this.items[t]=e,this.start=t,++this.size},i.prototype.pop=function(){if(this.size!==0){this.size--;var e=this.start+this.size;return e>=this.capacity&&(e-=this.capacity),this.items[e]}},i.prototype.shift=function(){if(this.size!==0){var e=this.start;return this.size--,this.start++,this.start===this.capacity&&(this.start=0),this.items[e]}},i.prototype.peekFirst=function(){if(this.size!==0)return this.items[this.start]},i.prototype.peekLast=function(){if(this.size!==0){var e=this.start+this.size-1;return e>=this.capacity&&(e-=this.capacity),this.items[e]}},i.prototype.get=function(e){if(!(this.size===0||e>=this.capacity))return e=this.start+e,e>=this.capacity&&(e-=this.capacity),this.items[e]},i.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var n=this.capacity,r=this.size,i=this.start,a=0;a=n)return{done:!0};var r=e[i];return i++,a++,i===t&&(i=0),{value:r,done:!1}})},i.prototype.entries=function(){var e=this.items,t=this.capacity,n=this.size,i=this.start,a=0;return new r(function(){if(a>=n)return{done:!0};var r=e[i];return i++,i===t&&(i=0),{value:[a++,r],done:!1}})},typeof Symbol<`u`&&(i.prototype[Symbol.iterator]=i.prototype.values),i.prototype.inspect=function(){var e=this.toArray();return e.type=this.ArrayClass.name,e.capacity=this.capacity,Object.defineProperty(e,`constructor`,{value:i,enumerable:!1}),e},typeof Symbol<`u`&&(i.prototype[Symbol.for(`nodejs.util.inspect.custom`)]=i.prototype.inspect),i.from=function(e,t,r){if(arguments.length<3&&(r=n.guessLength(e),typeof r!=`number`))throw Error(`mnemonist/fixed-deque.from: could not guess iterable length. Please provide desired capacity as last argument.`);var a=new i(t,r);if(n.isArrayLike(e)){var o,s;for(o=0,s=e.length;o{var n=Ne(),r=qe();function i(e,t){if(arguments.length<2)throw Error(`mnemonist/fixed-stack: expecting an Array class and a capacity.`);if(typeof t!=`number`||t<=0)throw Error("mnemonist/fixed-stack: `capacity` should be a positive number.");this.capacity=t,this.ArrayClass=e,this.items=new this.ArrayClass(this.capacity),this.clear()}i.prototype.clear=function(){this.size=0},i.prototype.push=function(e){if(this.size===this.capacity)throw Error(`mnemonist/fixed-stack.push: stack capacity (`+this.capacity+`) exceeded!`);return this.items[this.size++]=e,this.size},i.prototype.pop=function(){if(this.size!==0)return this.items[--this.size]},i.prototype.peek=function(){return this.items[this.size-1]},i.prototype.forEach=function(e,t){t=arguments.length>1?t:this;for(var n=0,r=this.items.length;n=t)return{done:!0};var n=e[t-r-1];return r++,{value:n,done:!1}})},i.prototype.entries=function(){var e=this.items,t=this.size,r=0;return new n(function(){if(r>=t)return{done:!0};var n=e[t-r-1];return{value:[r++,n],done:!1}})},typeof Symbol<`u`&&(i.prototype[Symbol.iterator]=i.prototype.values),i.prototype.toString=function(){return this.toArray().join(`,`)},i.prototype.toJSON=function(){return this.toArray()},i.prototype.inspect=function(){var e=this.toArray();return e.type=this.ArrayClass.name,e.capacity=this.capacity,Object.defineProperty(e,`constructor`,{value:i,enumerable:!1}),e},typeof Symbol<`u`&&(i.prototype[Symbol.for(`nodejs.util.inspect.custom`)]=i.prototype.inspect),i.from=function(e,t,n){if(arguments.length<3&&(n=r.guessLength(e),typeof n!=`number`))throw Error(`mnemonist/fixed-stack.from: could not guess iterable length. Please provide desired capacity as last argument.`);var a=new i(t,n);if(r.isArrayLike(e)){var o,s;for(o=0,s=e.length;o{var t=Pe(),n=p().createEdgeWeightGetter;function r(e,t){return e===`outbound`||e===`inbound`?t.directedSize+t.undirectedSize*2:e===`in`||e===`out`||e===`directed`?t.directedSize:t.undirectedSize*2}function i(e,n){n||=`outbound`;var i=e[n+`Neighbors`].bind(e),a=r(n,e),o=t.getPointerArray(a),s=t.getPointerArray(e.order);this.graph=e,this.neighborhood=new s(a),this.starts=new o(e.order+1),this.nodes=e.nodes();var c={},l,u,d,f,p,m,h=0;for(l=0,u=e.order;l{var t=Qe(),n=$e(),r=Je(),i=Pe(),a=et(),o=a.NeighborhoodIndex,s=a.WeightedNeighborhoodIndex;e.createUnweightedIndexedBrandes=function(e){var r=new o(e),a=r.neighborhood,s=r.starts,c=e.order,l=new n(i.getPointerArray(c),c),u=new Uint32Array(c),d=Array(c),f=new Int32Array(c),p=new t(Uint32Array,c),m=function(e){var t,n,r,i,o,m,h;for(m=0;mt[0]?1:e[0]t[1]?1:e[1]t[2]?1:e[2]t[3]?1:e[3]{var n=m(),r=tt(),i=je(),a=r.createUnweightedIndexedBrandes,o=r.createDijkstraIndexedBrandes,s={nodeCentralityAttribute:`betweennessCentrality`,getEdgeWeight:`weight`,normalized:!0};function c(e,t,r){if(!n(t))throw Error(`graphology-centrality/beetweenness-centrality: the given graph is not a valid graphology instance.`);r=i(r,s);var c=r.nodeCentralityAttribute,l=r.normalized,u=r.getEdgeWeight?o(t,r.getEdgeWeight):a(t),d=t.order,f,p,m,h,g,_,v,y,b,x,S=new Float64Array(d),C=new Float64Array(d);for(_=0;_{var t=m();function n(e,n,r,i){var a=n+`Centrality`;if(!t(r))throw Error(`graphology-centrality/`+a+`: the given graph is not a valid graphology instance.`);if(n!==`degree`&&r.type===`undirected`)throw Error(`graphology-centrality/`+a+`: cannot compute `+n+` centrality on an undirected graph.`);i||={};var o=i.nodeCentralityAttribute||a,s=r.order-1,c=r[n].bind(r);if(e){r.updateEachNodeAttributes(function(e,t){return t[o]=c(e)/s,t},{attributes:[o]});return}var l={};return r.forEachNode(function(e){l[e]=c(e)/s}),l}var r=n.bind(null,!1,`degree`),i=n.bind(null,!1,`inDegree`),a=n.bind(null,!1,`outDegree`);r.assign=n.bind(null,!0,`degree`),i.assign=n.bind(null,!0,`inDegree`),a.assign=n.bind(null,!0,`outDegree`),e.degreeCentrality=r,e.inDegreeCentrality=i,e.outDegreeCentrality=a})),it=e(ze(),1),at=Ze(),ot=e(nt(),1),st=rt(),ct=1400,lt=6,ut=6,dt=6,ft=4,pt=2,mt=4;function ht(e,t){let n=e.getNodeAttributes(t);return String(n.label||n.content||t)}function gt(e,t){let n=e.getNodeAttributes(t);return String(n.baseColor||n.color||`#63E6FF`)}function _t(e,t){let n=e.getNodeAttributes(t);return String(n.semanticGroup||n.nodeType||`entity`)}function vt(e,t){if(!t)return new Set(e.nodes());let n=new Set;for(let r of t)e.hasNode(r)&&n.add(r);return n.size?n:new Set(e.nodes())}function yt(e,t){let n=(0,st.degreeCentrality)(e),r=(0,st.inDegreeCentrality)(e),i=(0,st.outDegreeCentrality)(e),a=t?(0,ot.default)(e,{normalized:!0,getEdgeWeight:`weight`}):{},o=new Map;return e.forEachNode(e=>{let t=Number(n[e]??0),s=Number(a[e]??0),c=Number(r[e]??0),l=Number(i[e]??0);o.set(e,{degree:t,inDegree:c,outDegree:l,betweenness:s,score:t*.7+s*.3})}),{centralityByNode:o,topNodeIds:e.nodes().sort((e,t)=>{let n=o.get(e)?.score??0,r=o.get(t)?.score??0;return r===n?e.localeCompare(t):r-n}),betweennessReady:t}}function bt(e,t){let n=t?.computeCommunities??!0,r=t?.computeCentrality??!0,i=new Map,a=0,o=null;if(n&&e.order>1&&e.size>0)try{let t=it.default.detailed(e,{getEdgeWeight:`weight`});o=Number(t.modularity??0),a=Number(t.count??0),Object.entries(t.communities).forEach(([e,t])=>{i.set(e,Number(t))})}catch(e){console.error(`[GraphAnalytics] community detection failed`,e)}if(!r||e.order===0)return{communitiesByNode:i,communityCount:a,modularity:o,centralityByNode:new Map,topNodeIds:[],betweennessReady:!1};let s=yt(e,e.order<=ct);return{communitiesByNode:i,communityCount:a,modularity:o,...s}}function xt(e,t,n){let r=new Map;return e.forEachNode(i=>{let a=n.communitiesByNode.get(i);if(a===void 0)return;let o=r.get(a)??{nodeCount:0,visibleNodeCount:0,semanticCounts:new Map,anchorNodeId:null,prominence:0,color:gt(e,i)};o.nodeCount+=1,t.has(i)&&(o.visibleNodeCount+=1);let s=_t(e,i);o.semanticCounts.set(s,(o.semanticCounts.get(s)??0)+1);let c=n.centralityByNode.get(i)?.score??0;(!o.anchorNodeId||c>(n.centralityByNode.get(o.anchorNodeId)?.score??-1))&&(o.anchorNodeId=i,o.color=gt(e,i)),o.prominence+=t.has(i)?1+c:c*.15,r.set(a,o)}),[...r.entries()].map(([t,n])=>{let r=[...n.semanticCounts.entries()].sort((e,t)=>t[1]-e[1])[0]?.[0]??`entity`;return{communityId:String(t),nodeCount:n.nodeCount,visibleNodeCount:n.visibleNodeCount,dominantSemanticGroup:r,color:n.color,anchorNodeId:n.anchorNodeId,anchorLabel:n.anchorNodeId?ht(e,n.anchorNodeId):`Community anchor`,prominence:n.prominence}}).filter(e=>e.visibleNodeCount>0).sort((e,t)=>t.prominence-e.prominence).slice(0,lt)}function St(e,t,n){let r=new Map;return e.forEachNode(i=>{let a=_t(e,i),o=r.get(a)??{nodeCount:0,visibleNodeCount:0,communityCounts:new Map,anchorNodeId:null,prominence:0,color:gt(e,i)};o.nodeCount+=1,t.has(i)&&(o.visibleNodeCount+=1);let s=n.communitiesByNode.get(i);if(s!==void 0){let e=String(s);o.communityCounts.set(e,(o.communityCounts.get(e)??0)+1)}let c=n.centralityByNode.get(i)?.score??0;(!o.anchorNodeId||c>(n.centralityByNode.get(o.anchorNodeId)?.score??-1))&&(o.anchorNodeId=i,o.color=gt(e,i)),o.prominence+=t.has(i)?1+c:c*.1,r.set(a,o)}),[...r.entries()].map(([t,n])=>({semanticGroup:t,nodeCount:n.nodeCount,visibleNodeCount:n.visibleNodeCount,color:n.color,anchorNodeId:n.anchorNodeId,anchorLabel:n.anchorNodeId?ht(e,n.anchorNodeId):t,dominantCommunityId:[...n.communityCounts.entries()].sort((e,t)=>t[1]-e[1])[0]?.[0]??null,prominence:n.prominence})).filter(e=>e.visibleNodeCount>0).sort((e,t)=>t.prominence-e.prominence).slice(0,ut)}function Ct(e,t,n){let r=n.topNodeIds.filter(e=>t.has(e));return(r.length?r:n.topNodeIds).slice(0,dt).map(t=>{let r=n.centralityByNode.get(t)??{degree:0,betweenness:0,score:0};return{id:t,label:ht(e,t),semanticGroup:_t(e,t),color:gt(e,t),degree:Number(r.degree??0),betweenness:Number(r.betweenness??0),score:Number(r.score??0)}})}function wt(e,t,n){let r=[];return e.forEachOutEdge(t,(e,t,i,a)=>{n.has(a)&&r.push({edgeId:String(e),source:i,target:a,attrs:t})}),e.forEachInEdge(t,(e,t,i,a)=>{n.has(i)&&r.push({edgeId:String(e),source:i,target:a,attrs:t})}),r}function Tt(e,t,n,r){let i=r.centralityByNode.get(t)?.score??0,a=r.centralityByNode.get(n)?.score??0,o=Number(e.weight??0),s=Number(e.visualPriority??0),c=Number(e.parallelCount??1)>1?.14:0,l=e.isBidirectional?.18:0;return o*1.4+(i+a)*2.4+s*.6+c+l}function Et(e,t,n,r,i){if(t.size===0)return{ready:!1,reason:`No visible nodes are available for overview backbone selection.`,edgeIds:[]};let a=new Set,o=new Map;t.forEach(t=>{o.set(t,_t(e,t))});let s=new Set(r.slice(0,3).map(e=>e.semanticGroup)),c=new Set(i.slice(0,ft*2).map(e=>e.id).filter(e=>t.has(e))),l=i.slice(0,ft).map(e=>e.id).filter(e=>t.has(e)),u=new Map;l.forEach(r=>{wt(e,r,t).filter(e=>{let t=e.source===r?e.target:e.source;if(!c.has(t))return!1;let n=o.get(e.source),i=o.get(e.target);return!!(n&&i&&(s.has(n)||s.has(i)))}).forEach(e=>{let t=[e.source,e.target].sort().join(`::`),r=o.get(e.source),i=o.get(e.target),a=r&&i&&r!==i?.28:0,s=Tt(e.attrs,e.source,e.target,n)+a,c=u.get(t);(!c||s>c.score||s===c.score&&e.edgeId.localeCompare(c.edgeId)<0)&&u.set(t,{edgeId:e.edgeId,score:s})})});let d=new Map;e.forEachEdge((e,r,i,a)=>{if(!t.has(i)||!t.has(a))return;let c=o.get(i),l=o.get(a);if(!c||!l||c===l||!s.has(c)&&!s.has(l))return;let u=[c,l].sort().join(`::`),f=Tt(r,i,a,n)+.36,p=d.get(u);(!p||f>p.score||f===p.score&&String(e).localeCompare(p.edgeId)<0)&&d.set(u,{edgeId:String(e),score:f})}),[...d.values()].sort((e,t)=>t.score===e.score?e.edgeId.localeCompare(t.edgeId):t.score-e.score).slice(0,mt).forEach(e=>a.add(e.edgeId)),[...u.values()].sort((e,t)=>t.score===e.score?e.edgeId.localeCompare(t.edgeId):t.score-e.score).slice(0,pt).forEach(e=>a.add(e.edgeId));let f=[...a].filter(t=>e.hasEdge(t)).sort((e,t)=>e.localeCompare(t));return{ready:f.length>0,reason:f.length>0?`Ready`:`No overview backbone edges met the current visibility thresholds.`,edgeIds:f}}function Dt(e,t){if(t.activePath.length<2)return{ready:!1,reason:`Trace a path to compare it against local strict directed shortest pathfinding.`,sourceId:t.selectedNodeId||null,targetId:null,path:[],length:null,verifiedAgainstActivePath:!1};let n=t.activePath[0]??null,r=t.activePath[t.activePath.length-1]??null;if(!n||!r||!e.hasNode(n)||!e.hasNode(r))return{ready:!1,reason:`Active path endpoints are not available in the current graph view.`,sourceId:n,targetId:r,path:[],length:null,verifiedAgainstActivePath:!1};try{let i=at.dijkstra.bidirectional(e,n,r,`weight`)??[];return{ready:i.length>1,reason:i.length>1?`Ready`:`No strict directed shortest path found in the current graph view.`,sourceId:n,targetId:r,path:i,length:i.length>1?i.length-1:null,verifiedAgainstActivePath:i.join(`::`)===t.activePath.join(`::`)}}catch(e){return console.error(`[GraphAnalytics] directed pathfinding failed`,e),{ready:!1,reason:`Directed pathfinding failed for the current graph snapshot.`,sourceId:n,targetId:r,path:[],length:null,verifiedAgainstActivePath:!1}}}function Ot(e){let{graphRef:t,interactionState:n,base:r}=e,i=vt(t,e.visibleNodeIds),a=Dt(t,n),o=r.communitiesByNode.size?xt(t,i,r):[],s=St(t,i,r),c=Ct(t,i,r),l=Et(t,i,r,s,c);return{generatedAt:Date.now(),directedPath:a,communities:{ready:o.length>0,reason:o.length>0?`Ready`:r.communitiesByNode.size>0?`No visible communities in the current graph context.`:`Community detection has not produced summaries yet.`,count:r.communityCount,modularity:r.modularity,summaries:o},centrality:{ready:c.length>0,reason:c.length>0?r.betweennessReady?`Ready`:`Ready (degree-biased while betweenness is bounded for large graphs).`:`Centrality ranking is waiting for graph data.`,topNodes:c},semanticRegions:{ready:s.length>0,reason:s.length>0?`Ready`:`No semantic regions are visible in the current graph context.`,summaries:s},overviewBackbone:l}}function kt(e,t,n,r=96){return e.x>=-r&&e.y>=-r&&e.x<=t+r&&e.y<=n+r}function At(e,t,n,r,i){let a=e.createRadialGradient(t,n,0,t,n,r);a.addColorStop(0,i),a.addColorStop(1,`rgba(0,0,0,0)`),e.fillStyle=a,e.beginPath(),e.arc(t,n,r,0,Math.PI*2),e.fill()}function jt(e,t){let n=document.createElement(`canvas`);return n.width=e,n.height=t,n}function Mt(e){if(e.startsWith(`#`)){let t=e.slice(1),n=t.length===3?t.split(``).map(e=>`${e}${e}`).join(``):t;if(n.length===6)return{r:Number.parseInt(n.slice(0,2),16),g:Number.parseInt(n.slice(2,4),16),b:Number.parseInt(n.slice(4,6),16)}}let t=e.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/i);return t?{r:Number.parseInt(t[1],10),g:Number.parseInt(t[2],10),b:Number.parseInt(t[3],10)}:{r:130,g:145,b:165}}function Nt(e,t,n,r){let i=new Uint8Array(t*n),a=0,o=0,s=0,c=0;for(let l=0;l0?{x:o/c,y:s/c}:{x:t/2,y:n/2};return{mask:i,count:a,centroid:l}}function Pt(e,t,n,r){if(r<=0)return e;let i=e;for(let e=0;e=n))for(let e=-1;e<=1;e+=1){let n=a+e;n<0||n>=t||(o+=i[c*t+n],s+=1)}}e[r*t+a]=Math.round(o/Math.max(s,1))}i=e}return i}function Ft(e,t,n,r){let i=new Uint8Array(e.length),a=new Int32Array(e.length),o=[],s=0;for(let r=0;r=e.length||i[c]||!e[c]||r===0&&o===0||r===1&&o===t-1||r===2&&s===0||r===3&&s===n-1||(i[c]=1,a[l++]=c)}}s+=u.length,u.length>o.length&&(o=u)}let c=new Uint8Array(e.length),l=0,u=0,d=0;return o.forEach(e=>{c[e]=1;let n=r[e],i=e%t,a=Math.floor(e/t);l+=i*n,u+=a*n,d+=n}),{mask:c,count:o.length,centroid:d>0?{x:l/d,y:u/d}:{x:t/2,y:n/2},occupancyRatio:o.length/Math.max(t*n,1),dominantMassRatio:o.length/Math.max(s,1)}}function It(e,t,n){let r=j.effects.semanticRegions.fogResolutionScale,i=Math.max(72,Math.round(t*r)),a=Math.max(72,Math.round(n*r)),o=jt(i,a),s=o.getContext(`2d`);if(!s)return null;s.clearRect(0,0,i,a),s.globalCompositeOperation=`source-over`,e.forEach(e=>{let t=e.point.x*r,n=e.point.y*r,i=Math.max(2.5,(j.effects.semanticRegions.splatRadius+e.size*.9)*r),a=s.createRadialGradient(t,n,0,t,n,i);a.addColorStop(0,`rgba(255,255,255,0.22)`),a.addColorStop(.58,`rgba(255,255,255,0.08)`),a.addColorStop(1,`rgba(255,255,255,0)`),s.fillStyle=a,s.beginPath(),s.arc(t,n,i,0,Math.PI*2),s.fill()});let c=s.getImageData(0,0,i,a),l=new Uint8ClampedArray(i*a),u=0;for(let e=0;eu&&(u=t)}if(u<=0)return null;let d=Pt(l,i,a,j.effects.semanticRegions.blurPasses),f=d.reduce((e,t)=>Math.max(e,t),0);return f<=0?null:{canvas:o,gridWidth:i,gridHeight:a,alphaValues:d,maxAlpha:f,scale:r}}function Lt(e,t,n,r){if(!t)return;let{gridWidth:i,gridHeight:a,alphaValues:o}=t,s=jt(i,a),c=s.getContext(`2d`);if(!c)return;let l=c.createImageData(i,a),u=Mt(n);for(let e=0;e{let o=e.getNodeDisplayData(t);if(!o)return;let s=e.graphToViewport({x:o.x,y:o.y});kt(s,n,r,84)&&i.push({nodeId:t,point:s,size:o.size,attrs:a})}),i}function Vt(e,t,n,r,i){let a=r.length>22?`${r.slice(0,21)}…`:r;e.save(),e.font=`600 11px "IBM Plex Sans", Inter, system-ui, sans-serif`,e.textBaseline=`middle`;let o=e.measureText(a).width+14,s=t-o/2,c=n-22/2;e.fillStyle=`rgba(8, 14, 24, 0.84)`,e.strokeStyle=A(i,.24),e.lineWidth=1,e.beginPath(),e.roundRect(s,c,o,22,999),e.fill(),e.stroke(),e.fillStyle=`rgba(235, 244, 255, 0.88)`,e.fillText(a,s+7,n),e.restore()}function Ht(e,t,n,r,i){if(!i.semanticRegionsEnabled||!t?.semanticRegions.ready||!b(r.zoomTier,j.effects.semanticRegions.minZoomTier))return;let a=new Map;n.forEach(e=>{let t=String(e.attrs.semanticGroup||e.attrs.nodeType||`entity`),n=a.get(t);n?n.push(e):a.set(t,[e])});let o=t.semanticRegions.summaries.slice(0,j.effects.semanticRegions.maxRegions),s=o.reduce((e,t)=>Math.max(e,t.prominence),1),c=j.effects.semanticRegions;o.forEach(t=>{let n=a.get(t.semanticGroup);if(!n||n.length=c.outerContourMinMaskPixels&&h.dominantMassRatio>=c.dominantMassRatio&&Rt(e,h.mask,r.gridWidth,r.gridHeight,g.outerContourColor,c.outerContourAlpha*i),Rt(e,m.mask,r.gridWidth,r.gridHeight,g.innerContourColor,c.innerContourAlpha*i),t.visibleNodeCount>=18&&Vt(e,d.centroid.x/r.scale,d.centroid.y/r.scale-18,t.semanticGroup,g.labelBorderColor)})}function Ut(e,t,n,r,i){if(!i.contoursEnabled||!t?.centrality.ready||!b(r.zoomTier,j.effects.contours.minZoomTier))return;let a=new Map(n.map(e=>[e.nodeId,e]));t.centrality.topNodes.slice(0,j.effects.contours.maxContours).forEach(t=>{let n=a.get(t.id);n&&At(e,n.point.x,n.point.y,j.effects.contours.baseRadius+n.size*3.2,A(t.color,j.effects.contours.glowAlpha))})}function Wt(e,t){if(!t||!e.valid_from&&!e.valid_until)return!1;let n=t.getTime(),r=e.valid_from?new Date(e.valid_from).getTime():-1/0,i=e.valid_until?new Date(e.valid_until).getTime():1/0;return n>=r&&n<=i}function Gt(e,t,n,r,i){!i.temporalEmphasisEnabled||!n?.currentTime||b(r.zoomTier,j.effects.temporalEmphasis.minZoomTier)&&t.filter(e=>Wt(e.attrs,n.currentTime)).slice(0,j.effects.temporalEmphasis.maxHighlights).forEach(t=>{At(e,t.point.x,t.point.y,Math.max(t.size*j.effects.temporalEmphasis.radiusMultiplier,14),A(j.palette.accent.temporal,j.effects.temporalEmphasis.glowAlpha))})}function Kt(e,t,n,r){let i=t.getNodeDisplayData(n);if(!i)return;let a=t.graphToViewport({x:i.x,y:i.y});At(e,a.x,a.y,j.effects.lens.radius,A(j.palette.accent.hovered,j.effects.lens.glowAlpha)),r.forEach(r=>{if(r===n||!S.hasNode(r)||!S.hasDirectedEdge(n,r)&&!S.hasDirectedEdge(r,n))return;let i=t.getNodeDisplayData(r);if(!i)return;let o=t.graphToViewport({x:i.x,y:i.y});e.strokeStyle=A(j.palette.accent.hovered,j.effects.lens.edgeAlpha*.38),e.lineWidth=j.effects.lens.edgeLineWidth+3.2,e.lineCap=`round`,e.beginPath(),e.moveTo(a.x,a.y),e.lineTo(o.x,o.y),e.stroke(),e.strokeStyle=A(j.palette.accent.hovered,j.effects.lens.edgeAlpha),e.lineWidth=j.effects.lens.edgeLineWidth,e.beginPath(),e.moveTo(a.x,a.y),e.lineTo(o.x,o.y),e.stroke()})}function qt(e,t,n,r,i){n.pathFlowEnabled&&r.pathFlow.available&&t.forEach((t,n)=>{let r=(i*j.effects.pathFlow.speed+n*j.effects.pathFlow.spacing)%1,a=t.source.x+(t.target.x-t.source.x)*r,o=t.source.y+(t.target.y-t.source.y)*r,s=Math.max(0,r-.08),c=t.source.x+(t.target.x-t.source.x)*s,l=t.source.y+(t.target.y-t.source.y)*s;e.strokeStyle=A(t.color,.28),e.lineWidth=Math.max(t.size+3.6,4.6),e.lineCap=`round`,e.beginPath(),e.moveTo(c,l),e.lineTo(a,o),e.stroke(),e.strokeStyle=A(j.palette.accent.selected,j.effects.pathFlow.opacity),e.lineWidth=Math.max(t.size+1.3,2.4),e.beginPath(),e.moveTo(c,l),e.lineTo(a,o),e.stroke()}),n.pathPulseEnabled&&r.pathPulse.available&&t.forEach((t,n)=>{let r=(i*j.effects.pathPulse.speed+n*.17)%1,a=t.source.x+(t.target.x-t.source.x)*r,o=t.source.y+(t.target.y-t.source.y)*r,s=e.createRadialGradient(a,o,0,a,o,j.effects.pathPulse.radius);s.addColorStop(0,A(j.palette.accent.path,j.effects.pathPulse.glowAlpha)),s.addColorStop(1,`rgba(0,0,0,0)`),e.fillStyle=s,e.beginPath(),e.arc(a,o,j.effects.pathPulse.radius,0,Math.PI*2),e.fill()})}function Jt(e,t){if(typeof e!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(typeof r!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function Yt(e){var t=Jt(e,`string`);return typeof t==`symbol`?t:t+``}function Xt(e,t,n){return(t=Yt(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Zt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function Qt(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);nL){var R=`…`;for(p+=R,I=e.measureText(p).width;I>L&&p.length>1;)p=p.slice(0,-2)+R,I=e.measureText(p).width;if(p.length<4)return}for(var z={},ee=0,te=p.length;ee 0.0 && metric >= ringStart) { + color = v_ringColor; + } + color.a *= alpha; + gl_FragColor = color; + #endif +} +`,jn=` +attribute vec4 a_id; +attribute vec2 a_position; +attribute float a_size; +attribute float a_angle; +attribute vec4 a_coreColor; +attribute vec4 a_shellColor; +attribute vec4 a_ringColor; +attribute float a_ringSize; +attribute float a_coreScale; + +uniform mat3 u_matrix; +uniform float u_sizeRatio; +uniform float u_correctionRatio; + +varying vec4 v_coreColor; +varying vec4 v_shellColor; +varying vec4 v_ringColor; +varying vec4 v_color; +varying vec2 v_diffVector; +varying float v_radius; +varying float v_ringSize; +varying float v_coreScale; + +const float bias = 255.0 / 254.0; + +void main() { + float size = a_size * u_correctionRatio / u_sizeRatio * 4.0; + vec2 diffVector = size * vec2(cos(a_angle), sin(a_angle)); + vec2 position = a_position + diffVector; + + gl_Position = vec4( + (u_matrix * vec3(position, 1)).xy, + 0, + 1 + ); + + v_diffVector = diffVector; + v_radius = size / 2.0; + v_ringSize = a_ringSize; + v_coreScale = a_coreScale; + + #ifdef PICKING_MODE + v_color = a_id; + #else + v_coreColor = a_coreColor; + v_shellColor = a_shellColor; + v_ringColor = a_ringColor; + #endif + + v_color.a *= bias; +} +`,Mn=class e extends f{static ANGLE_1=0;static ANGLE_2=2*Math.PI/3;static ANGLE_3=4*Math.PI/3;drawLabel=Fn;drawHover=In;getDefinition(){return{VERTICES:3,VERTEX_SHADER_SOURCE:jn,FRAGMENT_SHADER_SOURCE:An,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:kn,ATTRIBUTES:[{name:`a_position`,size:2,type:WebGLRenderingContext.FLOAT},{name:`a_size`,size:1,type:WebGLRenderingContext.FLOAT},{name:`a_coreColor`,size:4,type:WebGLRenderingContext.UNSIGNED_BYTE,normalized:!0},{name:`a_shellColor`,size:4,type:WebGLRenderingContext.UNSIGNED_BYTE,normalized:!0},{name:`a_ringColor`,size:4,type:WebGLRenderingContext.UNSIGNED_BYTE,normalized:!0},{name:`a_ringSize`,size:1,type:WebGLRenderingContext.FLOAT},{name:`a_coreScale`,size:1,type:WebGLRenderingContext.FLOAT},{name:`a_id`,size:4,type:WebGLRenderingContext.UNSIGNED_BYTE,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:`a_angle`,size:1,type:WebGLRenderingContext.FLOAT}],CONSTANT_DATA:[[e.ANGLE_1],[e.ANGLE_2],[e.ANGLE_3]]}}processVisibleItem(e,t,n){let r=this.array,i=Nn(n.ringSize,n.ringColor,n.borderColor,j.nodes.selectedRing.color);r[t++]=n.x,r[t++]=n.y,r[t++]=n.size,r[t++]=v(n.color||j.palette.overview.nodeCore),r[t++]=v(n.shellColor||A(j.palette.overview.nodeBase,j.palette.overview.nodeShellAlpha)),r[t++]=v(i),r[t++]=n.ringSize||0,r[t++]=n.coreScale??.22,r[t++]=e}setUniforms(e,{gl:t,uniformLocations:n}){t.uniform1f(n.u_correctionRatio,e.correctionRatio),t.uniform1f(n.u_sizeRatio,e.sizeRatio),t.uniformMatrix3fv(n.u_matrix,!1,e.matrix)}};function Nn(e,t,n,r){return typeof e==`number`&&e>0&&t?t:n||r}function Pn(e,t,n,r,i,a){let o=Math.max(0,Math.min(a,Math.min(r,i)/2));e.beginPath(),e.moveTo(t+o,n),e.lineTo(t+r-o,n),e.quadraticCurveTo(t+r,n,t+r,n+o),e.lineTo(t+r,n+i-o),e.quadraticCurveTo(t+r,n+i,t+r-o,n+i),e.lineTo(t+o,n+i),e.quadraticCurveTo(t,n+i,t,n+i-o),e.lineTo(t,n+o),e.quadraticCurveTo(t,n,t+o,n),e.closePath()}var Fn=(e,t)=>{let n=t;if(!n.label)return;let r=j.labels.chip,i=Math.max(r.fontSize,Math.min(r.maxFontSize,n.size*r.sizeScale)),a=`${r.fontWeight} ${i}px ${r.fontFamily}`,o=r.paddingX,s=r.paddingY,c=Nn(n.ringSize,n.ringColor,n.borderColor,r.borderColor);e.save(),e.font=a,e.textBaseline=`middle`;let l=e.measureText(n.label).width+o*2,u=i+s*2,d=n.x+Math.max(n.size*.7,r.offsetX),f=n.y-Math.max(n.size*.9,r.offsetY)-u;e.shadowColor=A(r.shadowColor,r.shadowAlpha),e.shadowBlur=r.shadowBlur,e.fillStyle=r.background,Pn(e,d,f,l,u,r.radius),e.fill(),e.shadowBlur=0,e.strokeStyle=A(c,r.borderAlpha),e.lineWidth=1,Pn(e,d,f,l,u,r.radius),e.stroke(),e.fillStyle=r.textColor,e.fillText(n.label,d+o,f+u/2),e.restore()},In=(e,t)=>{let n=t;if(!n.label)return;let r=j.labels.hoverCard,i=Nn(n.ringSize,n.ringColor,n.borderColor,r.borderColor),a=typeof n.nodeType==`string`&&n.nodeType.trim().length>0?n.nodeType.replaceAll(`_`,` `).toUpperCase():`NODE`;e.save(),e.textBaseline=`top`;let o=`${r.titleWeight} ${r.titleSize}px ${r.fontFamily}`,s=`${r.metaWeight} ${r.metaSize}px ${r.fontFamily}`;e.font=o;let c=e.measureText(n.label).width;e.font=s;let l=e.measureText(a).width,u=Math.max(c,l)+r.paddingX*2,d=r.paddingY*2+r.titleSize+r.metaGap+r.metaSize,f=n.x+Math.max(n.size*.9,r.offsetX),p=n.y-Math.max(n.size*1.1,r.offsetY)-d;e.shadowColor=A(r.shadowColor,r.shadowAlpha),e.shadowBlur=r.shadowBlur,e.fillStyle=r.background,Pn(e,f,p,u,d,r.radius),e.fill(),e.shadowBlur=0,e.strokeStyle=A(i,r.borderAlpha),e.lineWidth=1.2,Pn(e,f,p,u,d,r.radius),e.stroke(),e.fillStyle=r.textColor,e.font=o,e.fillText(n.label,f+r.paddingX,p+r.paddingY),e.fillStyle=r.metaColor,e.font=s,e.fillText(a,f+r.paddingX,p+r.paddingY+r.titleSize+r.metaGap),e.restore()},Ln={...c,circle:Mn},Rn={...d,curve:Dn,curvedArrow:On},zn={iterations:50,settings:{barnesHutOptimize:!0,barnesHutTheta:.5,adjustSizes:!1,gravity:.16,scalingRatio:7.5,edgeWeightInfluence:.3,linLogMode:!0,strongGravityMode:!1,slowDown:18}},Bn={allowInvalidContainer:!0,labelRenderedSizeThreshold:4,defaultNodeType:`circle`,defaultEdgeType:`line`,hideLabelsOnMove:!0,hideEdgesOnMove:!0,enableEdgeEvents:!0,renderEdgeLabels:!1,labelDensity:.86,labelGridCellSize:100,zIndex:!0,webGLTarget:`webgl2`,nodeProgramClasses:Ln,edgeProgramClasses:Rn,defaultDrawNodeLabel:Fn,defaultDrawNodeHover:In};function Vn(e,t,n,r=96){return e.x>=-r&&e.y>=-r&&e.x<=t+r&&e.y<=n+r}function Hn(e,t,n,r,i,a){let o=[];for(let s=0;s1,l=b(e.zoomTier,j.effects.pathPulse.minZoomTier),u=b(e.zoomTier,j.effects.pathFlow.minZoomTier),d=b(e.zoomTier,j.effects.lens.minZoomTier),f=b(e.zoomTier,j.effects.temporalEmphasis.minZoomTier),p=b(e.zoomTier,j.effects.semanticRegions.minZoomTier),m=b(e.zoomTier,j.effects.contours.minZoomTier),h=!!(e.hoveredNodeId||e.selectedNodeId);return{pathPulse:t.pathPulseEnabled?c?l?s===0?{enabled:!0,available:!1,reason:`Path is off-screen`}:s>j.effects.pathPulse.maxSegments?{enabled:!0,available:!1,reason:`Disabled by path size cap`,detail:`${s} visible segments`,visibleSegments:s,segmentCap:j.effects.pathPulse.maxSegments}:{enabled:!0,available:!0,reason:`Ready`,visibleSegments:s,segmentCap:j.effects.pathPulse.maxSegments}:{enabled:!0,available:!1,reason:`Disabled by zoom tier`,detail:`Requires ${j.effects.pathPulse.minZoomTier}`}:{enabled:!0,available:!1,reason:`No active path`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},pathFlow:t.pathFlowEnabled?c?u?s===0?{enabled:!0,available:!1,reason:`Path is off-screen`}:s>j.effects.pathFlow.maxSegments?{enabled:!0,available:!1,reason:`Disabled by path size cap`,detail:`${s} visible segments`,visibleSegments:s,segmentCap:j.effects.pathFlow.maxSegments}:{enabled:!0,available:!0,reason:`Ready`,visibleSegments:s,segmentCap:j.effects.pathFlow.maxSegments}:{enabled:!0,available:!1,reason:`Disabled by zoom tier`,detail:`Requires ${j.effects.pathFlow.minZoomTier}`}:{enabled:!0,available:!1,reason:`No active path`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},lens:t.lensEnabled?h?d?{enabled:!0,available:!0,reason:`Ready`}:{enabled:!0,available:!1,reason:`Disabled by zoom tier`,detail:`Requires ${j.effects.lens.minZoomTier}`}:{enabled:!0,available:!1,reason:`No focal node`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},temporalEmphasis:t.temporalEmphasisEnabled?n?.currentTime?f?{enabled:!0,available:!0,reason:`Ready`}:{enabled:!0,available:!1,reason:`Disabled by zoom tier`,detail:`Requires ${j.effects.temporalEmphasis.minZoomTier}`}:{enabled:!0,available:!1,reason:`No temporal focus time`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},semanticRegions:t.semanticRegionsEnabled?p?r?.semanticRegions.ready?{enabled:!0,available:!0,reason:r.semanticRegions.reason}:{enabled:!0,available:!1,reason:r?.semanticRegions.reason??`Waiting for semantic region summaries`}:{enabled:!0,available:!1,reason:`Disabled by zoom tier`,detail:`Requires ${j.effects.semanticRegions.minZoomTier}`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},contours:t.contoursEnabled?m?r?.centrality.ready?{enabled:!0,available:!0,reason:r.centrality.reason}:{enabled:!0,available:!1,reason:r?.centrality.reason??`Waiting for centrality ranking`}:{enabled:!0,available:!1,reason:`Disabled by zoom tier`,detail:`Requires ${j.effects.contours.minZoomTier}`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},pathfinding:t.pathfindingEnabled?r?.directedPath.ready?{enabled:!0,available:!0,reason:r.directedPath.verifiedAgainstActivePath?`Ready · local path matches traced path`:`Ready · local directed path differs from traced path`}:{enabled:!0,available:!1,reason:r?.directedPath.reason??`Waiting for a traced path`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},communities:t.communitiesEnabled?r?.communities.ready?{enabled:!0,available:!0,reason:r.communities.modularity===null?r.communities.reason:`Ready · modularity ${r.communities.modularity.toFixed(3)}`}:{enabled:!0,available:!1,reason:r?.communities.reason??`Waiting for community summaries`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},centrality:t.centralityEnabled?r?.centrality.ready?{enabled:!0,available:!0,reason:r.centrality.reason}:{enabled:!0,available:!1,reason:r?.centrality.reason??`Waiting for centrality ranking`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},legend:t.legendEnabled?{enabled:!0,available:!0,reason:`Panel enabled`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},diagnostics:j.effects.diagnostics.enabledInDev?t.diagnosticsEnabled?{enabled:!0,available:!0,reason:`Ready`}:{enabled:!1,available:!1,reason:`Disabled by toggle`}:{enabled:!1,available:!1,reason:`Disabled in production`}}}function Wn(e,t,n,r,i){let a=e.createRadialGradient(t,n,0,t,n,r);a.addColorStop(0,i),a.addColorStop(1,`rgba(0,0,0,0)`),e.fillStyle=a,e.beginPath(),e.arc(t,n,r,0,Math.PI*2),e.fill()}function Gn(e,t,n,r,i,a){let o=j.nodes.badges[i],s=j.nodes.badge.radius,c=j.nodes.badge.offset,l=t+Math.max(r*.62,s+c),u=n-Math.max(r*.62,s+c);Wn(e,l,u,j.overlays.badgeGlowRadius,A(o.color,j.nodes.badge.glowAlpha)),e.fillStyle=o.color,e.beginPath(),e.arc(l,u,s,0,Math.PI*2),e.fill(),e.strokeStyle=j.nodes.badge.stroke,e.lineWidth=1,e.beginPath(),e.arc(l,u,s,0,Math.PI*2),e.stroke(),e.fillStyle=j.nodes.badge.textColor,e.font=`700 ${j.nodes.badge.fontSize}px Inter, system-ui, sans-serif`,e.textAlign=`center`,e.textBaseline=`middle`;let d=i===`provenance`&&a&&a>1?String(Math.min(9,a)):o.label;e.fillText(d,l,u+.5)}function Kn(e,t,n,r,i){let{zoomTier:a,hoveredNodeId:o,selectedNodeId:s,selectedEdgeId:c,activePath:l}=n,u=o||s,d=u&&S.hasNode(u)?de(u):new Set,f=q(t,c),p=new Set(l),m=K(t,l,n.activePathEdgeIds),h=new Set(r?.overviewBackbone.edgeIds??[]),g=e.getCamera().getState().ratio;if(e.setSetting(`nodeReducer`,(e,t)=>{let n=t,r=we(j,a,ye(e,a,o,s,c,d,f,p),n,t.label,g);return{...t,color:r.color,shellColor:r.shellColor,coreScale:r.coreScale,size:r.size,forceLabel:r.forceLabel,label:r.label,zIndex:r.zIndex,hidden:r.hidden,borderColor:r.borderColor,borderSize:r.borderSize,ringColor:r.showRing?r.ringColor:r.borderColor,ringSize:r.ringSize}}),e.setSetting(`edgeReducer`,(e,n)=>{let r=n,[i,l]=t.extremities(e),u=De(j,a,be(String(e),i,l,a,o,s,c,d,m,h),r,i,l);return{...n,hidden:u.hidden,type:u.type,color:u.color,size:u.size,zIndex:u.zIndex,curvature:u.curvature}}),(i?.nodes?.length??0)>0||(i?.edges?.length??0)>0){e.scheduleRefresh({partialGraph:{nodes:i?.nodes,edges:i?.edges}});return}e.scheduleRefresh()}function qn(e,t,n){for(let r of e)if(r.performAction?.(t,n))return}var Jn=(0,N.forwardRef)(function({onNodeClick:e,onEdgeClick:t,selectedNodeId:n,selectedEdgeId:r,activePath:i=[],activePathEdgeIds:a=[],effectsState:o,temporalState:s,isLayoutRunning:c,viewMode:l,className:u,showFitViewButton:d=!0,pluginOverlays:f=[],onSceneRuntimeChange:p,onInteractionStateChange:m,onCameraStateChange:g,onDiagnosticsChange:_,onAnalyticsChange:v},b){let x=(0,N.useRef)(null),C=(0,N.useRef)(null),w=(0,N.useRef)(null),T=(0,N.useRef)(null),E=(0,N.useRef)(null),[D,O]=(0,N.useState)(null),[k,M]=(0,N.useState)(`overview`),[P,I]=(0,N.useState)(null),L=(0,N.useMemo)(()=>[te,B,ne,re(),V(),ie,ae()],[]),R=l===`focused`&&!!n&&S.hasNode(n),z=(0,N.useMemo)(()=>ke(n,i,a,l),[i,a,n,l]),H=(0,N.useMemo)(()=>Ae(D,n,r,i,a,l,k,c),[i,a,D,c,r,n,l,k]),U=(0,N.useRef)(H);U.current=H;let oe=(0,N.useRef)(null),W=o.communitiesEnabled||o.semanticRegionsEnabled,se=o.centralityEnabled||o.semanticRegionsEnabled||o.contoursEnabled,ce=(0,N.useMemo)(()=>bt(z,{computeCommunities:W,computeCentrality:se}),[z,se,W]),G=(0,N.useCallback)(e=>{let t=w.current;if(!t)return;if(R){t.getCamera().animatedReset({duration:j.motion.cameraMs}),t.refresh();return}let n=t.getNodeDisplayData(e);if(!n){t.getCamera().animatedReset({duration:j.motion.cameraMs});return}t.getCamera().animate({x:n.x,y:n.y,ratio:.3},{duration:j.motion.cameraMs,easing:`quadraticOut`})},[R]),K=(0,N.useCallback)(()=>{let e=w.current;if(e){if(n){G(n);return}e.getCamera().animatedReset({duration:j.motion.cameraMs})}},[G,n]),J=(0,N.useCallback)(e=>{let t=E.current;t&&qn(L,t,e)},[L]),Y=(0,N.useCallback)(n=>{let r=n??w.current;if(!r)return null;let i={sigma:r,graph:S,displayGraph:z,getInteractionState:()=>U.current,setHoveredNodeId:O,onNodeSelectionChange:e,onEdgeSelectionChange:t??(()=>{}),focusNodeInView:G,fitCurrentView:K,dispatchAction:J};return E.current=i,i},[z,J,K,G,t,e]),X=(0,N.useCallback)((e,...t)=>{let n=Y();if(n)for(let r of L){let i=r[e];typeof i==`function`&&i(n,...t)}},[L,Y]);(0,N.useImperativeHandle)(b,()=>({fitView:()=>J({type:`fitView`}),focusNode:e=>J({type:`focusNode`,nodeId:e}),requestRender:()=>w.current?.scheduleRefresh(),getCameraState:()=>{let e=w.current;if(!e)return null;let t=e.getCamera().getState();return{x:t.x,y:t.y,ratio:t.ratio}}}),[J]),(0,N.useEffect)(()=>{if(!x.current)return;let e=new h(z,x.current,Bn);w.current=e;let t=e.getCamera();p?.({renderer:`sigma`,scene:e,graph:S,displayGraph:z,requestRender:()=>e.scheduleRefresh(),getCameraState:()=>{let e=t.getState();return{x:e.x,y:e.y,ratio:e.ratio}}});let n=Y(e);if(n)for(let e of L)e.attach(n);let r=()=>{let e={x:t.getState().x,y:t.getState().y,ratio:t.getState().ratio},n=y(e.ratio);M(e=>e===n?e:n),g?.(e),X(`onCameraChange`,e)},i=new ResizeObserver(()=>{x.current&&x.current.offsetWidth>0&&e.scheduleRefresh()});return i.observe(x.current),t.on(`updated`,r),e.on(`clickNode`,({node:e})=>X(`onNodeClick`,e)),e.on(`clickEdge`,({edge:e})=>{let[t,n]=z.extremities(e),r=String(e),i=z.getEdgeAttributes(e);fe(z,U.current,r,t,n,i)&&X(`onEdgeClick`,r)}),e.on(`clickStage`,()=>X(`onStageClick`)),e.on(`enterNode`,({node:e})=>X(`onNodeEnter`,e)),e.on(`leaveNode`,({node:e})=>X(`onNodeLeave`,e)),e.on(`enterEdge`,({edge:e})=>{let t=x.current;if(!t)return;let[n,r]=z.extremities(e),i=String(e),a=z.getEdgeAttributes(e);t.style.cursor=fe(z,U.current,i,n,r,a)?`pointer`:``}),e.on(`leaveEdge`,()=>{x.current&&(x.current.style.cursor=``)}),requestAnimationFrame(()=>{r(),J({type:`fitView`})}),()=>{if(n)for(let e of L)e.detach(n);t.off(`updated`,r),i.disconnect(),x.current&&(x.current.style.cursor=``),e.kill(),E.current=null,w.current=null,p?.(null)}},[L,J,X,z,Y,g,p]),(0,N.useEffect)(()=>{let e=Y();if(e){for(let t of L)t.onStateChange?.(e,H);for(let t of L)t.apply?.(e,H);m?.(H)}},[L,Y,H,m]),(0,N.useEffect)(()=>{let e=w.current,t=x.current;if(!e||!t){I(null),v?.(null);return}let n=Ot({graphRef:z,interactionState:H,base:ce,visibleNodeIds:Bt(e,z,t.clientWidth,t.clientHeight).map(e=>e.nodeId)});I(n),v?.(n)},[ce,z,H,v]),(0,N.useEffect)(()=>{if(!_)return;let e=w.current,t=x.current;_(Un(H,o,s,P,e,t?.clientWidth??0,t?.clientHeight??0))},[P,o,H,_,s]),(0,N.useEffect)(()=>{oe.current=null},[z]),(0,N.useEffect)(()=>{let e=w.current;if(!e)return;let t=oe.current;Kn(e,z,H,P,t?le(z,t,H):void 0),oe.current=H},[P,z,H]),(0,N.useEffect)(()=>{let e=w.current,t=C.current,n=x.current;if(!e||!t||!n)return;let r=0,i=()=>{let a=n.getBoundingClientRect(),c=window.devicePixelRatio||1;(t.width!==Math.floor(a.width*c)||t.height!==Math.floor(a.height*c))&&(t.width=Math.floor(a.width*c),t.height=Math.floor(a.height*c),t.style.width=`${a.width}px`,t.style.height=`${a.height}px`);let l=t.getContext(`2d`);if(!l){r=window.requestAnimationFrame(i);return}l.setTransform(c,0,0,c,0,0),l.clearRect(0,0,a.width,a.height);let u=H.hoveredNodeId||H.selectedNodeId,d=u&&S.hasNode(u)?de(u):new Set,f=q(z,H.selectedEdgeId),p=new Set(H.activePath),m=Hn(e,H.activePath,H.activePathEdgeIds,H.zoomTier,a.width,a.height),h=Bt(e,z,a.width,a.height),g=Un(H,o,s,P,e,a.width,a.height),_=e.getCamera().getState().ratio,v=new Set([...d,...f,...p,...u?[u]:[]]),y=performance.now()/1e3;Ut(l,P,h,H,o),Ht(l,P,h,H,o),Gt(l,h,s,H,o),v.forEach(t=>{let n=e.getNodeDisplayData(t);if(!n)return;let r=S.getNodeAttributes(t),i=ye(t,H.zoomTier,H.hoveredNodeId,H.selectedNodeId,H.selectedEdgeId,d,f,p),a=we(j,H.zoomTier,i,r,r.label,_),o=e.graphToViewport({x:n.x,y:n.y});if(a.showHalo){let e=Math.max(n.size*j.overlays.glowRadiusMultiplier*(a.nodeVariant===`selected`?1.08:1),j.overlays.minGlowRadius);Wn(l,o.x,o.y,e,A(a.haloColor,t===u?j.overlays.hoverGlowAlpha:j.overlays.pathGlowAlpha))}a.showBadge&&a.badgeKind&&Gn(l,o.x,o.y,n.size,a.badgeKind,a.badgeCount)}),u&&g.lens.available&&Kt(l,e,u,d),qt(l,m,o,g,y),r=window.requestAnimationFrame(i)};return i(),()=>{window.cancelAnimationFrame(r)}},[P,z,o,H,s]),(0,N.useEffect)(()=>{if(n||R){T.current?.stop();return}return c?(T.current||=new ee.default(S,zn),T.current.start()):T.current?.stop(),()=>{T.current?.stop()}},[R,c,n]),(0,N.useEffect)(()=>()=>{T.current?.kill(),T.current=null},[]);let Z=(0,N.useCallback)(()=>{K()},[K]);return(0,F.jsxs)(`div`,{style:{position:`relative`,width:`100%`,height:`100%`},children:[(0,F.jsx)(`div`,{ref:x,className:u,style:{width:`100%`,height:`100%`,background:`transparent`}}),(0,F.jsx)(`canvas`,{ref:C,style:{position:`absolute`,inset:0,width:`100%`,height:`100%`,pointerEvents:`none`,zIndex:4}}),f.length?(0,F.jsx)(`div`,{style:{position:`absolute`,inset:0,pointerEvents:`none`,zIndex:6},children:f.map((e,t)=>(0,F.jsx)(`div`,{style:{position:`absolute`,inset:0},children:e},`graph-plugin-overlay-${t}`))}):null,d?(0,F.jsx)(`button`,{id:`graph-fit-view-btn`,onClick:Z,style:{position:`absolute`,bottom:24,left:24,padding:`8px 16px`,background:`linear-gradient(135deg, rgba(27, 79, 170, 0.9), rgba(53, 123, 255, 0.84))`,color:`#fff`,border:`1px solid ${j.palette.background.shellBorder}`,borderRadius:10,cursor:`pointer`,fontWeight:700,zIndex:10,backdropFilter:`blur(10px)`,boxShadow:`0 10px 28px ${j.palette.background.shellGlow}`,fontSize:12,letterSpacing:`0.01em`},children:`Fit View`}):null]})}),Yn=(0,N.forwardRef)(function(e,t){let n=(0,P.c)(25),r,i,a,o,s,c,l,u,d;n[0]===e?(r=n[1],i=n[2],a=n[3],o=n[4],s=n[5],c=n[6],l=n[7],u=n[8],d=n[9]):({onNodeSelect:l,onEdgeSelect:o,onInteractionStateChange:s,onCameraStateChange:i,onDiagnosticsChange:a,onAnalyticsChange:r,onRuntimeChange:u,onLayoutRunningChange:c,...d}=e,n[0]=e,n[1]=r,n[2]=i,n[3]=a,n[4]=o,n[5]=s,n[6]=c,n[7]=l,n[8]=u,n[9]=d);let f=(0,N.useRef)(null),p=(0,N.useRef)(null),m,h;n[10]===c?(m=n[11],h=n[12]):(m=()=>({fitView:()=>f.current?.fitView(),focusNode:e=>f.current?.focusNode(e),getRuntime:()=>p.current,setLayoutRunning:c?e=>{c(e)}:void 0}),h=[c],n[10]=c,n[11]=m,n[12]=h),(0,N.useImperativeHandle)(t,m,h);let g=l??Xn,_;n[13]===u?_=n[14]:(_=e=>{p.current=e,u?.(e)},n[13]=u,n[14]=_);let v;return n[15]!==r||n[16]!==i||n[17]!==a||n[18]!==o||n[19]!==s||n[20]!==c||n[21]!==d||n[22]!==g||n[23]!==_?(v=(0,F.jsx)(Jn,{ref:f,onNodeClick:g,onEdgeClick:o,onInteractionStateChange:s,onCameraStateChange:i,onDiagnosticsChange:a,onAnalyticsChange:r,onSceneRuntimeChange:_,onLayoutRunningChange:c,...d}),n[15]=r,n[16]=i,n[17]=a,n[18]=o,n[19]=s,n[20]=c,n[21]=d,n[22]=g,n[23]=_,n[24]=v):v=n[24],v});function Xn(){}var Zn=[`bootstrapping`,`fetching_nodes`,`fetching_edges`,`computing_styling`,`hydrating_scene`,`stabilizing_layout`];function Qn(e){switch(e){case`bootstrapping`:return`Preparing graph session`;case`fetching_nodes`:return`Loading nodes`;case`fetching_edges`:return`Loading relationships`;case`computing_styling`:return`Computing node styling`;case`hydrating_scene`:return`Hydrating graph scene`;case`stabilizing_layout`:return`Stabilizing layout`;default:return`Graph ready`}}function $n(e){switch(e){case`bootstrapping`:return`Prepare`;case`fetching_nodes`:return`Nodes`;case`fetching_edges`:return`Relations`;case`computing_styling`:return`Styling`;case`hydrating_scene`:return`Scene`;case`stabilizing_layout`:return`Layout`;default:return`Stage`}}function er(e){let t=Zn.indexOf(e.phase);return{phase:e.phase,title:Qn(e.phase),message:e.message,progressKind:e.progressKind,loaded:e.loaded??null,total:e.total??null,nodesLoaded:e.nodesLoaded??0,nodesTotal:e.nodesTotal??null,edgesLoaded:e.edgesLoaded??0,edgesTotal:e.edgesTotal??null,showGraphBehind:e.showGraphBehind??!1,stageIndex:t>=0?t+1:Zn.length,stageCount:Zn.length,layoutSource:e.layoutSource,layoutState:e.layoutState}}var tr=[`community`,`cluster`,`module`,`group`,`category`,`domain`,`layer`,`source`,`nodeType`],nr=[`source`,`source_url`,`pmid`,`pmids`,`evidence`,`provenance`,`confidence`];function rr(e,t){if(t===`nodeType`){let t=e.nodeType;return typeof t==`string`&&t.trim()?t:null}let n=e.properties?.[t];return typeof n==`string`&&n.trim()?n:null}function ir(e,t){if(e.length<=1||t<=0)return 0;let n=0;for(let r of e){let e=r/t;n-=e*Math.log(e)}return n/Math.log(e.length)}function ar(e){let t=null,n=0;for(let r of tr){let i=new Map,a=0;for(let t of e){let e=rr(t.attributes,r);e&&(a+=1,i.set(e,(i.get(e)??0)+1))}let o=i.size;if(a===0||o<=1)continue;let s=[...i.values()],c=a/e.length,l=Math.max(...s)/a,u=ir(s,a),d=Math.min(o,j.palette.semantic.length)/j.palette.semantic.length,f=u*.65+d*.2+c*.15;c>=.45&&u>=.45&&l<=.88&&f>n&&(t=r,n=f)}return t?(e,n)=>rr(n,t)??or(e,n):(e,t)=>or(e,t)}function or(e,t){let n=D(e)%j.palette.semantic.length;return`${t.nodeType||`entity`}:${n}`}function sr(e){let t=Number(e);return Number.isFinite(t)?t:null}function cr(e){return D(e)%1e4/1e4}function lr(e){let t=new Map;e.forEach(e=>{let n=t.get(e.semanticGroup);n?n.push({id:e.id,priority:e.priority}):t.set(e.semanticGroup,[{id:e.id,priority:e.priority}])});let n=[...t.entries()].sort((e,t)=>{let n=t[1].length-e[1].length;return n===0?e[0].localeCompare(t[0]):n}),r=new Map;n.forEach(([e,t],n)=>{let i=n*2.399963229728653,a=170+Math.sqrt(n+1)*195,o=72+Math.sqrt(t.length)*16;r.set(e,{x:Math.cos(i)*a*1.14,y:Math.sin(i)*a*.84,spread:o})});let i=new Map;return n.forEach(([e,t])=>{let n=r.get(e);n&&t.sort((e,t)=>t.priority===e.priority?e.id.localeCompare(t.id):t.priority-e.priority).forEach((r,a)=>{let o=a*2.399963229728653+cr(`${e}:${r.id}:angle`)*.72,s=Math.sqrt((a+.5)/Math.max(t.length,1))*n.spread,c=(cr(`${r.id}:jx`)-.5)*n.spread*.22,l=(cr(`${r.id}:jy`)-.5)*n.spread*.18;i.set(r.id,{x:n.x+Math.cos(o)*s+c,y:n.y+Math.sin(o)*s*.86+l})})}),i}function ur(e){return nr.reduce((t,n)=>e[n]!==void 0&&e[n]!==null?t+1:t,0)}function dr(e,t,n,r){let i=`default`,a,o;n?(i=`temporal`,a=`temporal`):r>0&&(i=`provenance`,a=`provenance`,o=r);let s=`none`;return t>=.86?s=`always`:a?s=`local`:t>=.56&&(s=`priority`),{nodeVariant:i,nodeShapeVariant:i,badgeKind:a,badgeCount:o,ringColor:j.nodes.selectedRing.color,haloColor:A(e,.38),labelVisibilityPolicy:s}}function fr(e,t,n,r){let i=k(.12,.18+Math.log(Math.max(Number(e.weight)||1,1))/Math.log(12),1),a=`line`;return r?a=`bidirectionalCurve`:Math.max(t,n,i)>=.58&&(a=`directional`),{edgeVariant:a,arrowVisibilityPolicy:a===`line`?`hidden`:`contextual`,relationshipStrength:i,isParallelPair:!1,parallelIndex:0,parallelCount:1}}var pr=1e3;async function mr(e,t){let n=null,r=[],i=null;for(;;){let a=new URL(`/api/graph/nodes`,window.location.origin);a.searchParams.set(`limit`,String(pr)),n&&a.searchParams.set(`cursor`,n);let o=await fetch(a.toString(),{signal:e});if(!o.ok)throw Error(`Fetch failed: ${o.status}`);let s=await o.json();if(!s.nodes?.length||(i=s.total??i,r.push(...s.nodes),t?.(er({phase:`fetching_nodes`,progressKind:i?`determinate`:`indeterminate`,loaded:r.length,total:i,nodesLoaded:r.length,nodesTotal:i,edgesLoaded:0,edgesTotal:null,message:i?`Loading nodes ${r.length.toLocaleString()} of ${i.toLocaleString()}`:`Loading nodes ${r.length.toLocaleString()}`})),!s.next_cursor))break;n=s.next_cursor,await gr()}return r}async function hr(e,t,n,r){let i=null,a=[],o=new Set,s=null,c=!1;for(;;){let l=new URL(`/api/graph/edges`,window.location.origin);l.searchParams.set(`limit`,String(pr)),i&&l.searchParams.set(`cursor`,i);let u=await fetch(l.toString(),{signal:e});if(!u.ok)throw Error(`Fetch failed: ${u.status}`);let d=await u.json();if(!d.edges?.length)break;s=d.total??s;let f=d.edges.filter(e=>!t.has(e.source)||!t.has(e.target)||o.has(e.id)?!1:(o.add(e.id),!0));a.push(...f);let p=s?Math.min(o.size,s):o.size;if(!c&&s!==null&&o.size>s&&(c=!0,console.warn(`[graph-load] edge pagination returned more unique edge ids than total`,{uniqueEdgesLoaded:o.size,total:s})),r?.(er({phase:`fetching_edges`,progressKind:s?`determinate`:`indeterminate`,loaded:p,total:s,nodesLoaded:n.loaded,nodesTotal:n.total,edgesLoaded:p,edgesTotal:s,message:s?`Loading edges ${p.toLocaleString()} of ${s.toLocaleString()}`:`Loading edges ${p.toLocaleString()}`})),!d.next_cursor)break;i=d.next_cursor,await gr()}return a}function gr(){return`scheduler`in window&&typeof window.scheduler?.yield==`function`?window.scheduler.yield():new Promise(e=>setTimeout(e,0))}function _r(e){let t=(0,P.c)(9),n;t[0]===e?n=t[1]:(n=e===void 0?{}:e,t[0]=e,t[1]=n);let{enabled:r,onGraphReady:i,onProgress:o}=n,s=r===void 0?!0:r,c;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(c=[`graph`,`full-load`],t[2]=c):c=t[2];let l;t[3]!==i||t[4]!==o?(l=async e=>{let{signal:t}=e,n=performance.now();o?.(er({phase:`bootstrapping`,progressKind:`indeterminate`,nodesLoaded:0,nodesTotal:null,edgesLoaded:0,edgesTotal:null,message:`Preparing graph session`}));let r=await mr(t,o),a=new Set(r.map(xr)),s=await hr(t,a,{loaded:r.length,total:r.length},o),c=new Map;for(let e of a)c.set(e,0);for(let e of s)c.set(e.source,(c.get(e.source)??0)+1),c.set(e.target,(c.get(e.target)??0)+1);let l=Math.max(...c.values(),1),u=r.map(br);o?.(er({phase:`computing_styling`,progressKind:`indeterminate`,nodesLoaded:r.length,nodesTotal:r.length,edgesLoaded:s.length,edgesTotal:s.length,message:`Applying semantic color, sizing, and structural styling`}));let d=ar(u),f=new Map;for(let e of a){let t=c.get(e)??0,n=Math.log(t+1)/Math.log(l+1);f.set(e,n)}let p=new Map;u.forEach(e=>{let{id:t,attributes:n}=e;p.set(t,d(t,n))});let m=r.reduce(yr,0),h=(r.length>0?m/r.length:0)>=.92,g=h?null:lr(u.map(e=>{let{id:t,attributes:n}=e;return{id:t,semanticGroup:p.get(t)??or(t,n),priority:f.get(t)??0}})),_=u.map(e=>{let{id:t,attributes:n}=e,r=p.get(t)??d(t,n),i=D(r)%j.palette.semantic.length,a=j.palette.semantic[i],o=f.get(t)??0,s=k(1.8,1.8+8.8*o,11.8),c=!!(n.valid_from||n.valid_until),l=ur(n.properties??{}),u=n.properties,m=sr(u?.x),_=sr(u?.y),v=g?.get(t),y=h?m??0:m??v?.x??0,b=h?_??0:_??v?.y??0;return{id:t,attributes:{...n,x:y,y:b,semanticGroup:r,color:a,baseColor:a,mutedColor:A(a,j.nodes.mutedAlpha),glowColor:A(a,.24),size:s,baseSize:s,visualPriority:o,labelPriority:o,strokeColor:C(a,112),borderColor:C(a,112),borderSize:.72,...dr(a,o,c,l)}}}),v=new Set(s.map(vr)),y=new Map,b=new Map;s.forEach(e=>{let t=T(e.source,e.target);y.set(t,(y.get(t)??0)+1),b.set(e.familyId,(b.get(e.familyId)??0)+1)});let S=new Map,E=s.map(e=>{let t=f.get(e.source)??0,n=f.get(e.target)??0,r=v.has(T(e.target,e.source)),i=T(e.source,e.target),a=S.get(i)??0;S.set(i,a+1);let o=y.get(i)??1;return{id:e.id,familyId:e.familyId,source:e.source,target:e.target,attributes:{edgeId:e.id,familyId:e.familyId,sourceId:e.source,targetId:e.target,weight:e.weight,edgeType:e.type,properties:e.properties,size:k(.18,.22+Math.sqrt(Math.max(Number(e.weight)||1,1))*.2,.88),baseSize:k(.18,.22+Math.sqrt(Math.max(Number(e.weight)||1,1))*.2,.88),color:j.palette.muted.edgeStructure,baseColor:j.palette.muted.edgeStructure,mutedColor:j.palette.muted.edgeOverview,visualPriority:Math.max(t,n),isBidirectional:r,edgeFamily:r?`bidirectional`:`line`,curveGroup:O(e.source,e.target),type:`line`,isParallelPair:o>1,parallelIndex:a,parallelCount:o,familySize:b.get(e.familyId)??1,...fr(e,t,n,r)}}});o?.(er({phase:`hydrating_scene`,progressKind:`indeterminate`,nodesLoaded:_.length,nodesTotal:_.length,edgesLoaded:E.length,edgesTotal:E.length,message:`Preparing renderer and hydrating graph scene`}));try{x()}catch(e){let t=e;throw console.error(`[graph-load] clearGraph failed`,t),t}try{M(_)}catch(e){let t=e;throw console.error(`[graph-load] batchMergeNodes failed`,t),t}try{w(E)}catch(e){let t=e;throw console.error(`[graph-load] batchMergeEdges failed`,t),t}let N={nodeCount:_.length,edgeCount:E.length,loadTimeMs:Math.round(performance.now()-n),hasCoordinates:h,layoutSource:h?`provided`:`runtime`,layoutReady:h};return o?.(er({phase:N.layoutReady?`ready`:`stabilizing_layout`,progressKind:`indeterminate`,nodesLoaded:N.nodeCount,nodesTotal:N.nodeCount,edgesLoaded:N.edgeCount,edgesTotal:N.edgeCount,message:N.layoutReady?`Graph ready`:`Settling runtime layout`,showGraphBehind:!N.layoutReady,layoutSource:N.layoutSource,layoutState:N.layoutReady?`interactive`:`bootstrapping`})),i?.(N),N},t[3]=i,t[4]=o,t[5]=l):l=t[5];let u;return t[6]!==s||t[7]!==l?(u={queryKey:c,enabled:s,staleTime:1/0,retry:0,queryFn:l},t[6]=s,t[7]=l,t[8]=u):u=t[8],a(u)}function vr(e){return T(e.source,e.target)}function yr(e,t){let n=t.properties;return sr(n?.x)!==null&&sr(n?.y)!==null?e+1:e}function br(e){return{id:e.id,attributes:{label:e.content||e.id,x:0,y:0,nodeType:e.type,content:e.content,valid_from:e.valid_from,valid_until:e.valid_until,properties:e.properties}}}function xr(e){return e.id}function Sr(){let e=(0,P.c)(2),t=i(),n;return e[0]===t?n=e[1]:(n=()=>t.invalidateQueries({queryKey:[`graph`,`full-load`]}),e[0]=t,e[1]=n),n}var Cr=` + .graph-stage-loader { + position: absolute; + inset: 0; + z-index: 9; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; + opacity: 1; + transition: opacity 220ms ease, transform 220ms ease; + } + .graph-stage-loader[data-exiting="true"] { + opacity: 0; + transform: scale(0.985); + } + .graph-stage-loader-card { + width: min(540px, calc(100% - 48px)); + border-radius: 24px; + padding: 20px 20px 18px; + border: 1px solid rgba(127, 208, 255, 0.18); + background: + radial-gradient(circle at top right, rgba(242, 182, 109, 0.12), transparent 28%), + radial-gradient(circle at top left, rgba(127, 208, 255, 0.14), transparent 30%), + linear-gradient(145deg, rgba(7, 17, 31, 0.94), rgba(12, 25, 43, 0.82)); + box-shadow: 0 26px 90px rgba(0, 0, 0, 0.34), inset 0 1px 0 rgba(255,255,255,0.05); + backdrop-filter: blur(18px) saturate(1.08); + -webkit-backdrop-filter: blur(18px) saturate(1.08); + } + .graph-stage-loader-card[data-live="true"] { + width: min(500px, calc(100% - 56px)); + background: + radial-gradient(circle at top right, rgba(242, 182, 109, 0.08), transparent 26%), + radial-gradient(circle at top left, rgba(127, 208, 255, 0.12), transparent 28%), + linear-gradient(145deg, rgba(7, 17, 31, 0.84), rgba(11, 24, 40, 0.72)); + box-shadow: 0 18px 54px rgba(0, 0, 0, 0.26), inset 0 1px 0 rgba(255,255,255,0.04); + } + .graph-stage-loader-beacon { + position: relative; + width: 12px; + height: 12px; + border-radius: 999px; + background: linear-gradient(135deg, rgba(127, 208, 255, 0.98), rgba(242, 182, 109, 0.94)); + box-shadow: 0 0 18px rgba(127, 208, 255, 0.4); + } + .graph-stage-loader-beacon::after { + content: ""; + position: absolute; + inset: -7px; + border-radius: inherit; + border: 1px solid rgba(127, 208, 255, 0.18); + animation: graph-loader-beacon 1.9s ease-out infinite; + } + .graph-stage-loader-track { + display: grid; + grid-template-columns: repeat(6, minmax(0, 1fr)); + gap: 8px; + } + .graph-stage-loader-step { + border-radius: 999px; + padding: 7px 0; + text-align: center; + font-size: 10px; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + border: 1px solid rgba(127, 208, 255, 0.08); + color: rgba(143, 168, 198, 0.72); + background: rgba(255, 255, 255, 0.02); + } + .graph-stage-loader-step[data-state="done"] { + color: rgba(214, 232, 250, 0.92); + border-color: rgba(127, 208, 255, 0.18); + background: rgba(89, 155, 220, 0.14); + } + .graph-stage-loader-step[data-state="active"] { + color: #eff7ff; + border-color: rgba(242, 182, 109, 0.24); + background: linear-gradient(135deg, rgba(49, 108, 172, 0.28), rgba(242, 182, 109, 0.16)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06); + } + .graph-stage-loader-bar { + position: relative; + width: 100%; + height: 12px; + overflow: hidden; + border-radius: 999px; + border: 1px solid rgba(127, 208, 255, 0.1); + background: rgba(255, 255, 255, 0.05); + } + .graph-stage-loader-bar-fill { + display: block; + height: 100%; + border-radius: inherit; + background: linear-gradient(90deg, rgba(74, 163, 255, 0.9), rgba(127, 208, 255, 0.96), rgba(242, 182, 109, 0.92)); + box-shadow: 0 0 30px rgba(74, 163, 255, 0.28); + transition: width 220ms ease; + } + .graph-stage-loader-bar-indeterminate::before { + content: ""; + position: absolute; + top: 1px; + bottom: 1px; + width: 34%; + border-radius: 999px; + background: linear-gradient(90deg, rgba(74, 163, 255, 0), rgba(127, 208, 255, 0.94), rgba(242, 182, 109, 0.82), rgba(74, 163, 255, 0)); + box-shadow: 0 0 26px rgba(127, 208, 255, 0.18); + animation: graph-loader-sweep 1.5s cubic-bezier(0.22, 1, 0.36, 1) infinite; + } + @keyframes graph-loader-beacon { + 0% { transform: scale(0.72); opacity: 0.6; } + 100% { transform: scale(1.44); opacity: 0; } + } + @keyframes graph-loader-sweep { + 0% { transform: translateX(-120%); } + 100% { transform: translateX(360%); } + } +`;function wr(e){switch(e){case`provided`:return`Persisted layout`;case`carried`:return`Preserved layout`;case`runtime`:return`Runtime layout`;default:return null}}function Tr(e){switch(e){case`bootstrapping`:return`Bootstrapping`;case`running`:return`Settling`;case`interactive`:return`Interactive`;case`stabilized`:return`Stable`;case`failed`:return`Fallback`;default:return null}}var Er={display:`inline-flex`,alignItems:`center`,gap:6,padding:`7px 10px`,borderRadius:999,border:`1px solid rgba(127, 208, 255, 0.12)`,background:`rgba(255, 255, 255, 0.03)`,color:`#b8cade`,fontSize:11,fontWeight:600};function Dr(e){let t=(0,P.c)(97),{progress:n,visible:r,showGraphBehind:i}=e,[a,o]=(0,N.useState)(r),[s,c]=(0,N.useState)(!1),l;t[0]===n?l=t[1]:(l=n??er({phase:`bootstrapping`,message:`Preparing graph session`,progressKind:`indeterminate`}),t[0]=n,t[1]=l);let[u,d]=(0,N.useState)(l),f=(0,N.useRef)(null),p,m;t[2]===n?(p=t[3],m=t[4]):(p=()=>{n&&d(n)},m=[n],t[2]=n,t[3]=p,t[4]=m),(0,N.useEffect)(p,m);let h,g;if(t[5]!==a||t[6]!==r?(h=()=>{if(r){f.current!==null&&(window.clearTimeout(f.current),f.current=null),o(!0),c(!1);return}if(a)return c(!0),f.current=window.setTimeout(()=>{o(!1),c(!1),f.current=null},220),()=>{f.current!==null&&(window.clearTimeout(f.current),f.current=null)}},g=[a,r],t[5]=a,t[6]=r,t[7]=h,t[8]=g):(h=t[7],g=t[8]),(0,N.useEffect)(h,g),!a)return null;let _=n??u,v=_.phase===`stabilizing_layout`||_.showGraphBehind||i,y=v?`linear-gradient(180deg, rgba(1,4,9,0.04), rgba(1,4,9,0.18))`:`linear-gradient(180deg, rgba(1,4,9,0.22), rgba(1,4,9,0.5))`,b=_.progressKind===`determinate`&&_.total?Math.max(.05,Math.min(_.loaded??0,_.total)/Math.max(_.total,1)):null,x;t[9]===_.layoutSource?x=t[10]:(x=wr(_.layoutSource),t[9]=_.layoutSource,t[10]=x);let S=x,C;t[11]===_.layoutState?C=t[12]:(C=Tr(_.layoutState),t[11]=_.layoutState,t[12]=C);let w=C,T;t[13]===y?T=t[14]:(T={background:y},t[13]=y,t[14]=T);let E;t[15]===Symbol.for(`react.memo_cache_sentinel`)?(E=(0,F.jsx)(`style`,{children:Cr}),t[15]=E):E=t[15];let D,O,k;t[16]===Symbol.for(`react.memo_cache_sentinel`)?(D={display:`flex`,alignItems:`flex-start`,justifyContent:`space-between`,gap:14,marginBottom:14},O={minWidth:0},k={color:`#ffffff`,fontSize:20,fontWeight:700,letterSpacing:`-0.03em`,marginBottom:6},t[16]=D,t[17]=O,t[18]=k):(D=t[16],O=t[17],k=t[18]);let M;t[19]===_.title?M=t[20]:(M=(0,F.jsx)(`div`,{style:k,children:_.title}),t[19]=_.title,t[20]=M);let I;t[21]===Symbol.for(`react.memo_cache_sentinel`)?(I={color:`#8fa8c6`,fontSize:13,lineHeight:1.5},t[21]=I):I=t[21];let L;t[22]===_.message?L=t[23]:(L=(0,F.jsx)(`div`,{style:I,children:_.message}),t[22]=_.message,t[23]=L);let R;t[24]!==M||t[25]!==L?(R=(0,F.jsxs)(`div`,{style:O,children:[M,L]}),t[24]=M,t[25]=L,t[26]=R):R=t[26];let z,ee,te;t[27]===Symbol.for(`react.memo_cache_sentinel`)?(z={display:`inline-flex`,alignItems:`center`,gap:10,flexShrink:0},ee=(0,F.jsx)(`div`,{className:`graph-stage-loader-beacon`,"aria-hidden":`true`}),te={color:`#d7e9fb`,fontSize:11,fontWeight:700,letterSpacing:`0.08em`,textTransform:`uppercase`},t[27]=z,t[28]=ee,t[29]=te):(z=t[27],ee=t[28],te=t[29]);let B=_.stageIndex??1,ne=_.stageCount??Zn.length,re;t[30]!==B||t[31]!==ne?(re=(0,F.jsxs)(`div`,{style:z,children:[ee,(0,F.jsxs)(`div`,{style:te,children:[`Stage `,B,`/`,ne]})]}),t[30]=B,t[31]=ne,t[32]=re):re=t[32];let V;t[33]!==R||t[34]!==re?(V=(0,F.jsxs)(`div`,{style:D,children:[R,re]}),t[33]=R,t[34]=re,t[35]=V):V=t[35];let ie;t[36]===Symbol.for(`react.memo_cache_sentinel`)?(ie={marginBottom:14},t[36]=ie):ie=t[36];let ae;t[37]===_.stageIndex?ae=t[38]:(ae=Zn.map((e,t)=>{let n=_.stageIndex??1,r=t+1s(()=>import(`./TimelinePanel-DZ8Z1JsZ.js`).then(e=>({default:e.TimelinePanel})),__vite__mapDeps([0,1,2,3,4,5,6]))),jr=(0,N.lazy)(()=>s(()=>import(`./GraphInspectorPanel-MLghMyni.js`).then(e=>({default:e.GraphInspectorPanel})),__vite__mapDeps([7,2,1,3,4,8,9]))),Mr=()=>s(()=>import(`./explorationEffectsPluginPhaseC-D23Zx1hX.js`).then(e=>e.explorationEffectsPluginPhaseC),__vite__mapDeps([10,11,2,1,3,4])),Nr=()=>s(()=>import(`./neighborhoodPanelPlugin-DtCzBl4D.js`).then(e=>e.neighborhoodPanelPlugin),__vite__mapDeps([12,13,3,1])),Pr=()=>s(()=>import(`./temporalOverlayPlugin-tGkpBW1s.js`).then(e=>e.temporalOverlayPlugin),__vite__mapDeps([14,15,3,1]));function Fr(e,t){let n=(0,P.c)(4),[r,i]=(0,N.useState)(e),a,o;return n[0]!==t||n[1]!==e?(a=()=>{let n=setTimeout(()=>i(e),t);return()=>clearTimeout(n)},o=[t,e],n[0]=t,n[1]=e,n[2]=a,n[3]=o):(a=n[2],o=n[3]),(0,N.useEffect)(a,o),r}var Ir=` + .palantir-bg { + background: + radial-gradient(circle at top, rgba(77, 157, 255, 0.08), transparent 22%), + linear-gradient(180deg, #060b17 0%, #02060d 100%); + } + .palantir-grid { + position: absolute; + inset: 0; + background-image: + linear-gradient(rgba(88, 166, 255, 0.038) 1px, transparent 1px), + linear-gradient(90deg, rgba(88, 166, 255, 0.038) 1px, transparent 1px); + background-size: 42px 42px; + pointer-events: none; + z-index: 1; + } + .palantir-vignette { + position: absolute; + inset: 0; + background: radial-gradient(ellipse at center, transparent 34%, rgba(1, 4, 10, 0.78) 100%); + pointer-events: none; + z-index: 2; + } + .glass-header { + background: linear-gradient(180deg, rgba(7, 14, 25, 0.88) 0%, rgba(10, 18, 31, 0.62) 100%); + border-bottom: 1px solid rgba(112, 196, 255, 0.1); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + } + .glass-hud { + background: linear-gradient(135deg, rgba(8, 15, 27, 0.76), rgba(10, 19, 32, 0.58)); + backdrop-filter: blur(14px) saturate(1.08); + -webkit-backdrop-filter: blur(14px) saturate(1.08); + border-left: 1px solid rgba(112, 196, 255, 0.14); + box-shadow: -10px 0 28px rgba(0, 0, 0, 0.34), inset 1px 0 0 rgba(255, 255, 255, 0.04); + } + .hud-scrollbar::-webkit-scrollbar { width: 6px; } + .hud-scrollbar::-webkit-scrollbar-track { background: transparent; } + .hud-scrollbar::-webkit-scrollbar-thumb { background: rgba(88, 166, 255, 0.25); border-radius: 6px; } + .node-panel-collapse { + border: 1px solid rgba(255, 255, 255, 0.05); + border-radius: 12px; + background: rgba(0, 0, 0, 0.14); + overflow: hidden; + } + .node-panel-collapse + .node-panel-collapse { + margin-top: 12px; + } + .node-panel-summary { + list-style: none; + cursor: pointer; + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 12px 14px; + color: #c6d4e3; + font-size: 12px; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; + } + .node-panel-summary::-webkit-details-marker { + display: none; + } + .node-panel-summary::after { + content: "+"; + color: rgba(127, 208, 255, 0.8); + font-size: 16px; + line-height: 1; + } + .node-panel-collapse[open] .node-panel-summary::after { + content: "−"; + } + .node-panel-body { + padding: 0 14px 14px; + } + .graph-loading-overlay { + position: absolute; + inset: 0; + z-index: 9; + display: flex; + align-items: center; + justify-content: center; + pointer-events: none; + } + .graph-loading-card { + width: min(460px, calc(100% - 48px)); + border-radius: 20px; + padding: 22px 22px 18px; + background: linear-gradient(135deg, rgba(7, 17, 31, 0.9), rgba(14, 28, 48, 0.78)); + border: 1px solid rgba(127, 208, 255, 0.16); + box-shadow: 0 24px 80px rgba(0, 0, 0, 0.38), inset 0 1px 0 rgba(255,255,255,0.04); + backdrop-filter: blur(18px); + -webkit-backdrop-filter: blur(18px); + } + .graph-loading-dots { + display: inline-flex; + gap: 8px; + align-items: center; + } + .graph-loading-dot { + width: 10px; + height: 10px; + border-radius: 999px; + background: linear-gradient(135deg, rgba(127, 208, 255, 0.96), rgba(242, 182, 109, 0.96)); + box-shadow: 0 0 18px rgba(127, 208, 255, 0.35); + animation: sem-loader-pulse 1.2s ease-in-out infinite; + } + .graph-loading-dot:nth-child(2) { + animation-delay: 0.14s; + } + .graph-loading-dot:nth-child(3) { + animation-delay: 0.28s; + } + @keyframes sem-loader-pulse { + 0%, 100% { + transform: translateY(0) scale(0.92); + opacity: 0.55; + } + 50% { + transform: translateY(-4px) scale(1.08); + opacity: 1; + } + } + .graph-loading-bar { + width: 100%; + height: 10px; + border-radius: 999px; + overflow: hidden; + background: rgba(255, 255, 255, 0.06); + border: 1px solid rgba(127, 208, 255, 0.1); + } + .graph-loading-bar > span { + display: block; + height: 100%; + border-radius: 999px; + background: linear-gradient(90deg, rgba(74, 163, 255, 0.9), rgba(127, 208, 255, 0.95), rgba(242, 182, 109, 0.92)); + box-shadow: 0 0 28px rgba(74, 163, 255, 0.3); + transition: width 180ms ease; + } + .explore-shell { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + padding: 12px; + display: flex; + flex-direction: column; + gap: 10px; + } + .explore-command-deck { + position: relative; + z-index: 3; + } + .explore-command-grid { + display: grid; + grid-template-columns: minmax(260px, 0.9fr) minmax(0, 1.4fr); + gap: 16px; + } + .explore-main-grid { + position: relative; + z-index: 3; + min-height: 0; + flex: 1; + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(340px, 380px); + gap: 12px; + } + .explore-scene-stack { + min-height: 0; + display: flex; + flex-direction: column; + gap: 14px; + } + .explore-scene-card { + min-height: 0; + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; + } + .explore-scene-shell { + position: relative; + min-height: 0; + flex: 1; + overflow: hidden; + border-radius: 20px 20px 0 0; + } + .explore-scene-stage { + position: relative; + z-index: 3; + width: 100%; + height: 100%; + } + .explore-scene-footer { + position: relative; + z-index: 3; + border-top: 1px solid rgba(112, 196, 255, 0.1); + background: linear-gradient(180deg, rgba(5, 11, 20, 0.94), rgba(5, 11, 20, 0.82)); + } + .explore-plugin-dock { + position: relative; + z-index: 3; + } + .explore-plugin-dock-tabs { + display: flex; + align-items: center; + gap: 6px; + flex-wrap: wrap; + } + .explore-plugin-dock-tab { + border: 1px solid rgba(127, 208, 255, 0.14); + background: rgba(255, 255, 255, 0.03); + color: #a9bfd7; + border-radius: 999px; + padding: 6px 10px; + font-size: 11px; + font-weight: 600; + cursor: pointer; + } + .explore-plugin-dock-tab[data-active="true"] { + color: #eef6ff; + background: rgba(74, 163, 255, 0.16); + border-color: rgba(127, 208, 255, 0.28); + } + .explore-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + flex-wrap: wrap; + } + .explore-toolbar-groups { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; + flex: 1; + justify-content: flex-end; + } + .explore-toolbar-group { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 3px; + border-radius: 14px; + border: 1px solid rgba(127, 208, 255, 0.08); + background: rgba(255, 255, 255, 0.02); + } + .explore-search-results { + display: flex; + flex-direction: column; + gap: 8px; + max-height: 260px; + overflow-y: auto; + padding-right: 4px; + } + .explore-inspector-shell { + min-height: 0; + display: flex; + flex-direction: column; + } + .explore-inspector-card { + min-height: 0; + flex: 1; + overflow: hidden; + } + .explore-inspector-scroll { + height: 100%; + overflow-y: auto; + } + @media (max-width: 1260px) { + .explore-main-grid { + grid-template-columns: 1fr; + } + } + @media (max-width: 980px) { + .explore-shell { + padding: 10px; + gap: 10px; + } + .explore-command-grid { + grid-template-columns: 1fr; + } + } +`;function Lr(e){return Or.reduce((t,n)=>e[n]!==void 0&&e[n]!==null?t+1:t,0)}function Rr(e){let t=e.properties||{},n=String(t.content||e.id),r=j.palette.accent.path,i=!!(t.valid_from||t.valid_until),a=Lr(t);return{label:n,x:Number(t.x??Math.random()*1e3-500),y:Number(t.y??Math.random()*1e3-500),nodeType:e.type||`inferred`,content:n,valid_from:t.valid_from??null,valid_until:t.valid_until??null,properties:t,size:8,baseSize:8,semanticGroup:e.type||`inferred`,color:r,baseColor:r,mutedColor:A(r,j.nodes.mutedAlpha),glowColor:A(r,.36),visualPriority:.82,labelPriority:.82,strokeColor:j.palette.background.nodeBorder,borderColor:j.palette.background.nodeBorder,borderSize:.85,nodeVariant:`inferred`,nodeShapeVariant:`inferred`,badgeKind:i?`temporal`:a>0?`provenance`:`inferred`,badgeCount:a||void 0,ringColor:j.nodes.selectedRing.color,haloColor:A(r,.42),labelVisibilityPolicy:`local`}}function zr(e){let t=e.properties||{},n=!!t.inferred,r=S.hasDirectedEdge(e.target_id,e.source_id),i=n?j.palette.accent.path:j.palette.muted.edgeStructure;return{edgeId:e.id,familyId:e.familyId||e.id,sourceId:e.source_id,targetId:e.target_id,weight:Number(e.weight??1),edgeType:e.type||`related_to`,properties:t,size:1,baseSize:1,color:i,baseColor:i,mutedColor:j.palette.muted.edgeOverview,visualPriority:n?.95:.5,isBidirectional:r,edgeFamily:n?`path`:r?`bidirectional`:`line`,curveGroup:r?O(e.source_id,e.target_id):null,type:`line`,edgeVariant:n?`pathSignal`:r?`bidirectionalCurve`:`directional`,arrowVisibilityPolicy:n?`always`:`contextual`,relationshipStrength:n?.95:.52,isParallelPair:!1,parallelIndex:0,parallelCount:1,familySize:1}}function Br(e){if(!e||!S.hasNode(e))return null;let t=S.getNodeAttributes(e);return{id:e,label:String(t.label??e),content:String(t.content??t.label??e),nodeType:String(t.nodeType??`Entity`),color:typeof t.color==`string`?t.color:void 0,valid_from:t.valid_from??null,valid_until:t.valid_until??null,properties:t.properties??{},neighborCount:S.neighbors(e).length}}function Vr(e){if(!e||!S.hasEdge(e))return null;let[t,n]=S.extremities(e),r=S.getEdgeAttributes(e),i=S.getNodeAttributes(t),a=S.getNodeAttributes(n),o=r.properties??{},s=String(r.familyId||e),c=0,l=0;return S.forEachEdge((e,r)=>{let i=r,[a,o]=S.extremities(e);String(i.familyId||e)===s&&(c+=1),a===t&&o===n&&(l+=1)}),{id:e,familyId:s,sourceId:t,sourceLabel:String(i.label??i.content??t),targetId:n,targetLabel:String(a.label??a.content??n),edgeType:String(r.edgeType??`related_to`),weight:Number(r.weight??1),properties:o,provenanceCount:Lr(o),familySize:c,siblingCount:l}}function Hr(e,t){let n=[];for(let r of e)try{let e=r.renderPanel?.(t);if(!e)continue;Array.isArray(e)?n.push(...e):n.push(e)}catch(e){console.error(`[GraphPlugin:${r.id}] panel render failed`,e)}return n.sort((e,t)=>(e.order??0)-(t.order??0))}function Ur(e,t){let n=[];for(let r of e)try{let e=r.renderOverlay?.(t);if(!e)continue;Array.isArray(e)?n.push(...e):n.push(e)}catch(e){console.error(`[GraphPlugin:${r.id}] overlay render failed`,e)}return n.sort((e,t)=>(e.layer??0)===(t.layer??0)?(e.order??0)-(t.order??0):(e.layer??0)-(t.layer??0))}function Wr(){let[e,t]=(0,N.useState)(``),[n,r]=(0,N.useState)(``),[i,a]=(0,N.useState)(!1),[o,s]=(0,N.useState)(`focused`),[c,l]=(0,N.useState)(``),[u,d]=(0,N.useState)([]),[f,p]=(0,N.useState)(``),[m,h]=(0,N.useState)(``),[g,_]=(0,N.useState)([]),[v,y]=(0,N.useState)(``),[b,x]=(0,N.useState)(null),[C,T]=(0,N.useState)(null),[E,D]=(0,N.useState)(null),[O,k]=(0,N.useState)(null),[A,P]=(0,N.useState)(null),[I,ee]=(0,N.useState)({"effects-panel":!1,"neighborhood-panel":!1,"temporal-panel":!1}),[te,B]=(0,N.useState)(null),[ne,re]=(0,N.useState)(0),[V,ie]=(0,N.useState)(kr),[ae,H]=(0,N.useState)(null),[U,oe]=(0,N.useState)(null),[W,se]=(0,N.useState)({}),ce=Fr(O,150),G=(0,N.useRef)(new Set),K=(0,N.useRef)(null),q=(0,N.useRef)(null),J=(0,N.useRef)(null),Y=(0,N.useRef)({hoveredNodeId:null,selectedNodeId:``,selectedEdgeId:``,focusedNodeId:``,activePath:[],activePathEdgeIds:[],viewMode:`focused`,zoomTier:`overview`,isLayoutRunning:!1}),X=Sr(),{data:Z,isLoading:le,isFetching:ue}=_r({enabled:!0,onGraphReady:e=>{if(a(!e.layoutReady),J.current!==null&&(window.clearTimeout(J.current),J.current=null),e.layoutReady){P(null);return}P(er({phase:`stabilizing_layout`,progressKind:`indeterminate`,nodesLoaded:e.nodeCount,nodesTotal:e.nodeCount,edgesLoaded:e.edgeCount,edgesTotal:e.edgeCount,message:`Settling runtime layout`,showGraphBehind:!0,layoutSource:e.layoutSource,layoutState:`bootstrapping`})),J.current=window.setTimeout(()=>{P(e=>e?.phase===`stabilizing_layout`?null:e),J.current=null},900)},onProgress:P});(0,N.useEffect)(()=>()=>{J.current!==null&&window.clearTimeout(J.current)},[]),(0,N.useEffect)(()=>{let e=!1;return(async()=>{try{let t=await fetch(`/api/temporal/bounds`);if(!t.ok||e)return;let n=await t.json();e||D(n)}catch{e||D(null)}})(),()=>{e=!0}},[Z?.nodeCount,Z?.edgeCount]),(0,N.useEffect)(()=>{if(!ce||le)return;let e=!1;return(async()=>{try{let t=ce.toISOString(),n=await fetch(`/api/temporal/snapshot?at=${encodeURIComponent(t)}`);if(!n.ok||e)return;let r=await n.json();if(e)return;let i=new Set(r.active_node_ids);requestAnimationFrame(()=>{e||(G.current.forEach(e=>{!i.has(e)&&S.hasNode(e)&&S.setNodeAttribute(e,`hidden`,!0)}),i.forEach(e=>{S.hasNode(e)&&S.setNodeAttribute(e,`hidden`,!1)}),G.current=i,T(r.active_node_count),K.current?.getRuntime()?.requestRender())})}catch(t){e||console.error(`[Temporal] Snapshot fetch failed`,t)}})(),()=>{e=!0}},[ce,le]);let Q=(0,N.useCallback)(e=>{t(e),r(``),x(null),d([]),p(``),e&&a(!1)},[]),de=(0,N.useCallback)(e=>{r(e)},[]),fe=(0,N.useCallback)(async()=>{if(!c.trim()){d([]);return}p(``);try{let e=await fetch(`/api/graph/search`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({query:c,limit:8})});if(!e.ok)throw Error(`Search failed with status ${e.status}`);d((await e.json()).results||[])}catch(e){p(e instanceof Error?e.message:`Search failed`)}},[c]),pe=(0,N.useCallback)(async()=>{if(e)try{let t=await fetch(`/api/enrich/links`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({node_id:e,top_n:6,candidate_type:m||void 0,min_score:0})});if(!t.ok)throw Error(`Link prediction failed with status ${t.status}`);_((await t.json()).predictions||[])}catch(e){console.error(`[GraphWorkspace] prediction failed`,e),_([])}},[m,e]),me=(0,N.useCallback)(async()=>{if(!(!e||!v.trim()))try{let t=await fetch(`/api/graph/node/${encodeURIComponent(e)}/path?target=${encodeURIComponent(v.trim())}&algorithm=dijkstra`);if(!t.ok)throw Error(`Path lookup failed with status ${t.status}`);let n=await t.json();if(x(n),n.path?.length){let e=n.path[n.path.length-1];S.hasNode(e)&&K.current?.focusNode(e)}}catch(e){console.error(`[GraphWorkspace] path trace failed`,e),x(null)}},[v,e]),he=(0,N.useCallback)(async t=>{if(!e)return;let n=await fetch(`/api/provenance/report?node_id=${encodeURIComponent(e)}&format=${t===`markdown`?`markdown`:`json`}`);if(!n.ok)throw Error(`Provenance report failed with status ${n.status}`);let r=await n.blob(),i=window.URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=`${e}_provenance.${t===`markdown`?`md`:`json`}`,document.body.appendChild(a),a.click(),window.URL.revokeObjectURL(i),document.body.removeChild(a)},[e]);(0,N.useEffect)(()=>{let e=window.location.protocol===`https:`?`wss:`:`ws:`,t=new WebSocket(`${e}//${window.location.host}/ws/graph-updates`);return t.onmessage=e=>{try{let t=JSON.parse(e.data);if(t.event===`connection_ack`||t.event!==`graph_mutation`)return;let n=t.data?.event_type,r=t.data?.payload;n===`ADD_NODE`&&r?.id&&(M([{id:r.id,attributes:Rr(r)}]),K.current?.getRuntime()?.requestRender()),n===`ADD_EDGE`&&(w([{id:String(r.id),familyId:r.familyId?String(r.familyId):String(r.id),source:r.source_id,target:r.target_id,attributes:zr(r)}]),K.current?.getRuntime()?.requestRender())}catch(e){console.error(`[GraphWorkspace] websocket update failed`,e)}},()=>{t.close()}},[]);let ge=(0,N.useMemo)(()=>{if(!e||!S.hasNode(e))return null;let t=S.neighbors(e).length;return o===`focused`?`${Math.min(t,16)+1} nodes in focused view`:`${t} direct neighbors highlighted`},[e,o]),_e=le||ue||A?.phase===`stabilizing_layout`,ve=!!Z?.nodeCount,ye=b?.path??[],be=b?.edge_ids??[],xe=Z,Se=(0,N.useMemo)(()=>Br(e),[e,Z?.nodeCount,Z?.edgeCount]),$=(0,N.useMemo)(()=>Vr(n),[n,Z?.nodeCount,Z?.edgeCount]),Ce=(0,N.useMemo)(()=>({currentTime:O,activeNodeCount:C,minDate:E?.min??void 0,maxDate:E?.max??void 0}),[C,O,E?.max,E?.min]),we=(0,N.useMemo)(()=>[{id:`exploration-effects`,panelId:`effects-panel`,label:`Effects`,title:`Open exploration effects controls`,order:18,load:Mr,shouldLoad:({panelState:e})=>!!e[`effects-panel`]},{id:`neighborhood-panel`,panelId:`neighborhood-panel`,label:`Neighbors`,title:`Toggle neighborhood panel`,order:30,load:Nr,shouldLoad:({panelState:e})=>!!e[`neighborhood-panel`]},{id:`temporal-overlay`,panelId:`temporal-panel`,label:`Temporal`,title:`Toggle temporal context panel`,order:40,load:Pr,shouldLoad:({panelState:e,temporalState:t})=>!!(e[`temporal-panel`]||t?.currentTime)}],[]),Te=(0,N.useMemo)(()=>we.map(e=>W[e.id]).filter(e=>!!e),[W,we]);(0,N.useEffect)(()=>{let e=!1;return we.forEach(t=>{W[t.id]||t.shouldLoad({panelState:I,temporalState:Ce})&&t.load().then(n=>{e||se(e=>e[t.id]?e:{...e,[t.id]:n})}).catch(e=>{console.error(`[GraphPlugin:${t.id}] lazy load failed`,e)})}),()=>{e=!0}},[W,I,we,Ce]);let Ee=(0,N.useCallback)((e,t)=>{ie(n=>{let r=typeof t==`function`?t(n[e]):t;return e===`diagnosticsEnabled`&&!j.effects.diagnostics.enabledInDev||n[e]===r?n:{...n,[e]:r}})},[]),De=(0,N.useCallback)(e=>{switch(e.type){case`fitView`:K.current?.fitView();return;case`focusNode`:K.current?.focusNode(e.nodeId);return;case`selectNode`:Q(e.nodeId);return;case`setViewMode`:s(e.viewMode);return;case`toggleEffect`:Ee(e.effect,e=>!e);return;case`setEffect`:Ee(e.effect,e.enabled);return;case`togglePanel`:ee(t=>{let n=!t[e.panelId];return B(t=>n?e.panelId:t===e.panelId?null:t),{...t,[e.panelId]:n}});return;case`openPanel`:B(e.panelId),ee(t=>({...t,[e.panelId]:!0}));return;case`closePanel`:ee(t=>({...t,[e.panelId]:!1})),B(t=>t===e.panelId?null:t);return}},[Q,Ee]),Oe=(0,N.useMemo)(()=>!j.effects.diagnostics.enabledInDev||!ae?null:{interactionState:Y.current,activePluginIds:Te.map(e=>e.id),openPanelIds:Object.entries(I).filter(([,e])=>e).map(([e])=>e),effectsState:V,effectAvailability:ae},[Te,V,ae,I]),ke=(0,N.useMemo)(()=>({get scene(){return q.current},get graph(){return S},get displayGraph(){return q.current?.displayGraph??S},theme:j,getInteractionState:()=>Y.current,getSelectedNodeState:()=>Se,getInspectorState:()=>({selectedNodeId:e||null,ownsSelectionDetails:!0}),getGraphSummary:()=>xe,getTemporalState:()=>Ce,getEffectsState:()=>V,getDiagnosticsSnapshot:()=>Oe,getAnalyticsSnapshot:()=>U,isPanelOpen:e=>!!I[e],dispatchAction:De}),[U,Oe,V,xe,De,I,e,Se,Ce]),Ae=(0,N.useCallback)(e=>{q.current=e,e||oe(null),re(e=>e+1)},[]),je=(0,N.useCallback)(e=>{Y.current=e;for(let t of Te)try{t.onStateChange(ke,e)}catch(e){console.error(`[GraphPlugin:${t.id}] state update failed`,e)}},[Te,ke]),Me=(0,N.useCallback)(e=>{j.effects.diagnostics.enabledInDev&&H(e)},[]),Ne=(0,N.useCallback)(e=>{oe(e)},[]);(0,N.useEffect)(()=>{if(!q.current)return;let e=[];for(let t of Te)try{t.mount(ke),e.push(t)}catch(e){console.error(`[GraphPlugin:${t.id}] mount failed`,e)}return()=>{for(let t of e.reverse())try{t.unmount(ke)}catch(e){console.error(`[GraphPlugin:${t.id}] unmount failed`,e)}}},[Te,ke,ne]);let Pe=(0,N.useMemo)(()=>we.map(e=>({id:`${e.id}-toggle`,label:e.label,title:e.title,active:ke.isPanelOpen(e.panelId),order:e.order,onClick:()=>ke.dispatchAction({type:`togglePanel`,panelId:e.panelId})})),[ke,we]),Fe=(0,N.useMemo)(()=>Hr(Te,ke),[Te,ke]),Ie=(0,N.useMemo)(()=>Ur(Te,ke),[Te,ke]),Le=(0,N.useMemo)(()=>we.filter(e=>I[e.panelId]&&!W[e.id]).map(e=>({id:e.panelId,title:e.label,placement:`bottom`,order:e.order,content:(0,F.jsxs)(`div`,{style:ei,children:[`Loading `,e.label.toLowerCase(),`…`]})})),[W,I,we]),Re=[...Fe,...Le].filter(e=>e.placement===`bottom`||e.placement===`side`).sort((e,t)=>(e.order??0)-(t.order??0)).filter(e=>I[e.id]),ze=Re.find(e=>e.id===te)??Re[0]??null,Be={showInspector:!!e,showPluginDock:Re.length>0};(0,N.useEffect)(()=>{if(!Re.length){B(null);return}(!te||!Re.some(e=>e.id===te))&&B(Re[0].id)},[te,Re]);let Ve=(0,N.useMemo)(()=>{let t=[];return e&&t.push({id:`view-mode`,items:[{id:`view-focused`,label:`Focused`,title:`Inspect the selected node in a focused local graph`,active:o===`focused`,onClick:()=>s(`focused`)},{id:`view-full`,label:`Full Graph`,title:`Return to the full graph context`,active:o===`full`,onClick:()=>s(`full`)}]}),t.push({id:`graph-actions`,items:[{id:`search-submit`,label:`Search`,title:`Search for the current query`,tone:`primary`,disabled:_e||!c.trim(),onClick:()=>void fe()},{id:`fit-view`,label:`Fit View`,title:`Reset the camera to the current view`,onClick:()=>K.current?.fitView()},{id:`layout-toggle`,label:i?`Pause Layout`:`Run Layout`,title:`Toggle the layout worker`,active:i,disabled:_e,onClick:()=>a(e=>!e)},{id:`reload`,label:`Reload`,title:`Reload the graph data`,disabled:_e,onClick:X}]}),Pe.length&&t.push({id:`plugin-tools`,items:Pe.map(e=>({id:e.id,label:e.label,title:e.title,active:e.active,onClick:e.onClick}))}),t},[i,Pe,X,c,e,_e,o]),He={onNodeSelect:Q,onEdgeSelect:de,selectedNodeId:e,selectedEdgeId:n,activePath:ye,activePathEdgeIds:be,effectsState:V,temporalState:Ce,isLayoutRunning:i,viewMode:o,showFitViewButton:!1,pluginOverlays:Ie.map(e=>e.element),onRuntimeChange:Ae,onInteractionStateChange:je,onDiagnosticsChange:Me,onAnalyticsChange:Ne};return(0,F.jsxs)(`div`,{className:`palantir-bg`,style:{position:`relative`,width:`100%`,height:`100%`,overflow:`hidden`},children:[(0,F.jsx)(`style`,{children:Ir}),(0,F.jsx)(`div`,{className:`palantir-grid`}),(0,F.jsx)(`div`,{className:`palantir-vignette`}),(0,F.jsxs)(`div`,{className:`explore-shell`,children:[(0,F.jsx)(`section`,{className:`explore-command-deck`,children:(0,F.jsx)(L,{tone:`subtle`,children:(0,F.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:12},children:[(0,F.jsxs)(`div`,{className:`explore-toolbar`,children:[(0,F.jsxs)(`div`,{style:{display:`flex`,gap:8,flexWrap:`wrap`,alignItems:`center`},children:[_e&&A?(0,F.jsx)(R,{children:Qn(A.phase)}):null,Z?(0,F.jsxs)(R,{children:[Z.nodeCount.toLocaleString(),` nodes · `,Z.edgeCount.toLocaleString(),` edges`]}):null,C===null?null:(0,F.jsxs)(R,{tone:`success`,children:[C.toLocaleString(),` active`]}),ge?(0,F.jsx)(R,{tone:`warm`,children:ge}):null]}),(0,F.jsxs)(`div`,{className:`explore-toolbar-groups`,children:[(0,F.jsx)(`div`,{style:{minWidth:280,flex:`1 1 320px`},children:(0,F.jsx)(`input`,{value:c,onChange:e=>l(e.target.value),onKeyDown:e=>{e.key===`Enter`&&fe()},placeholder:`Search a node, e.g. Metformin`,style:{...Gr,margin:0,minHeight:38}})}),Ve.map(e=>(0,F.jsx)(`div`,{className:`explore-toolbar-group`,children:e.items.map(e=>{let t=e.tone===`primary`?Kr:qr;return(0,F.jsx)(`button`,{onClick:e.onClick,title:e.title,disabled:e.disabled,style:{...t,minHeight:36,padding:`8px 12px`,background:e.active?`rgba(31, 111, 235, 0.28)`:t.background,border:e.active?`1px solid rgba(127, 208, 255, 0.35)`:t.border,color:e.active?`#e6f2ff`:t.color,boxShadow:e.active?`0 0 0 1px rgba(127, 208, 255, 0.12)`:t.boxShadow},children:e.label},e.id)})},e.id))]})]}),f?(0,F.jsx)(`div`,{style:{color:`#ff7b72`,fontSize:12},children:f}):null,u.length?(0,F.jsx)(`div`,{className:`explore-search-results hud-scrollbar`,style:ti,children:u.map(e=>(0,F.jsx)(`button`,{style:Jr,onClick:()=>Q(e.node.id),children:(0,F.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,gap:12},children:[(0,F.jsxs)(`div`,{style:{minWidth:0},children:[(0,F.jsx)(`div`,{style:{color:`#fff`,fontWeight:600},children:e.node.content||e.node.id}),(0,F.jsx)(`div`,{style:{color:`#8b949e`,fontSize:12},children:e.node.type})]}),(0,F.jsx)(`div`,{style:{color:`#58a6ff`,fontSize:12,whiteSpace:`nowrap`},children:e.score.toFixed(3)})]})},e.node.id))}):null,$?(0,F.jsxs)(`div`,{style:Yr,children:[(0,F.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,gap:12,alignItems:`flex-start`},children:[(0,F.jsxs)(`div`,{style:{minWidth:0},children:[(0,F.jsx)(`div`,{style:{color:`rgba(127, 208, 255, 0.76)`,fontSize:11,fontWeight:700,letterSpacing:`0.08em`,textTransform:`uppercase`},children:`Relationship`}),(0,F.jsx)(`div`,{style:{color:`#f4f8ff`,fontSize:15,fontWeight:700,marginTop:6},children:$.edgeType})]}),(0,F.jsx)(`button`,{onClick:()=>r(``),style:{...qr,minHeight:30,padding:`6px 10px`},children:`Close`})]}),(0,F.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,flexWrap:`wrap`},children:[(0,F.jsx)(`button`,{style:Xr,onClick:()=>Q($.sourceId),children:$.sourceLabel}),(0,F.jsx)(`span`,{style:{color:`#7fa7ce`,fontSize:12},children:`→`}),(0,F.jsx)(`button`,{style:Xr,onClick:()=>Q($.targetId),children:$.targetLabel})]}),(0,F.jsxs)(`div`,{style:{display:`flex`,gap:8,flexWrap:`wrap`},children:[(0,F.jsxs)(R,{tone:`warm`,children:[`weight `,$.weight.toFixed(2)]}),(0,F.jsxs)(R,{children:[$.siblingCount,` parallel lane`,$.siblingCount===1?``:`s`]}),(0,F.jsxs)(R,{children:[$.familySize,` family member`,$.familySize===1?``:`s`]}),$.provenanceCount>0?(0,F.jsxs)(R,{children:[$.provenanceCount,` provenance fields`]}):null]}),Object.keys($.properties).length?(0,F.jsx)(`div`,{style:Zr,children:Object.entries($.properties).slice(0,4).map(([e,t])=>(0,F.jsxs)(`div`,{style:Qr,children:[(0,F.jsx)(`div`,{style:{color:`rgba(127, 208, 255, 0.68)`,fontSize:10,letterSpacing:`0.06em`,textTransform:`uppercase`},children:e}),(0,F.jsx)(`div`,{style:{color:`#dce7f4`,fontSize:12,marginTop:4,wordBreak:`break-word`},children:typeof t==`object`?JSON.stringify(t):String(t)})]},e))}):null]}):null]})})}),(0,F.jsxs)(`div`,{className:`explore-main-grid`,style:{gridTemplateColumns:Be.showInspector?`minmax(0, 1fr) minmax(320px, 360px)`:`minmax(0, 1fr)`},children:[(0,F.jsx)(`div`,{className:`explore-scene-stack`,children:(0,F.jsxs)(L,{padding:`none`,className:`explore-scene-card`,children:[(0,F.jsxs)(`div`,{className:`explore-scene-shell`,children:[(0,F.jsx)(`div`,{className:`palantir-grid`}),(0,F.jsx)(`div`,{className:`palantir-vignette`}),(0,F.jsxs)(`div`,{className:`explore-scene-stage`,children:[(0,F.jsx)(Yn,{ref:K,...He}),(0,F.jsx)(Dr,{progress:A,visible:_e,showGraphBehind:ve||!!A?.showGraphBehind})]})]}),Be.showPluginDock?(0,F.jsx)(`div`,{className:`explore-plugin-dock`,children:(0,F.jsx)(L,{tone:`subtle`,style:{borderRadius:0,borderLeft:`none`,borderRight:`none`,borderBottom:`none`},children:(0,F.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:10},children:[(0,F.jsx)(`div`,{style:{display:`flex`,justifyContent:`space-between`,gap:12,alignItems:`center`},children:(0,F.jsxs)(`div`,{className:`explore-plugin-dock-tabs`,children:[Re.map(e=>(0,F.jsx)(`button`,{className:`explore-plugin-dock-tab`,"data-active":ze?.id===e.id,onClick:()=>B(e.id),children:e.title},e.id)),ze?(0,F.jsx)(`button`,{className:`explore-plugin-dock-tab`,onClick:()=>De({type:`closePanel`,panelId:ze.id}),children:`×`}):null]})}),ze?(0,F.jsx)(`div`,{style:$r,children:ze.content}):null]})})}):null,(0,F.jsx)(`div`,{className:`explore-scene-footer`,children:(0,F.jsx)(N.Suspense,{fallback:(0,F.jsx)(`div`,{style:ri,children:`Loading timeline…`}),children:(0,F.jsx)(Ar,{onTimeChange:k,minDate:E?.min??void 0,maxDate:E?.max??void 0})})})]})}),Be.showInspector?(0,F.jsx)(`div`,{className:`explore-inspector-shell`,children:(0,F.jsx)(z,{open:Be.showInspector,className:`explore-inspector-card`,children:(0,F.jsx)(`div`,{className:`explore-inspector-scroll hud-scrollbar`,children:(0,F.jsx)(N.Suspense,{fallback:(0,F.jsx)(`div`,{style:ni,children:`Loading inspector…`}),children:(0,F.jsx)(jr,{nodeId:e,predictions:g,predictionType:m,onPredictionTypeChange:h,onRunPredictions:()=>void pe(),pathTargetId:v,onPathTargetChange:y,onTracePath:()=>void me(),pathResult:b,onDownloadProvenance:e=>void he(e)})})})})}):null]})]})]})}var Gr={width:`100%`,background:`rgba(4, 10, 18, 0.5)`,border:`1px solid ${j.palette.background.shellBorder}`,color:`#edf5ff`,borderRadius:12,padding:`11px 13px`,fontSize:13,boxShadow:`inset 0 1px 0 rgba(255,255,255,0.03)`},Kr={background:`linear-gradient(135deg, rgba(24, 63, 133, 0.42), rgba(35, 85, 176, 0.28))`,color:`#fff`,border:`1px solid ${j.palette.background.shellBorder}`,borderRadius:12,padding:`9px 12px`,cursor:`pointer`,fontWeight:700,fontSize:12,display:`inline-flex`,alignItems:`center`,justifyContent:`center`,boxShadow:`0 8px 22px ${j.palette.background.shellGlow}`},qr={...Kr,background:`rgba(255, 255, 255, 0.03)`,border:`1px solid rgba(255, 255, 255, 0.08)`,color:`#c6d4e3`,fontWeight:600},Jr={textAlign:`left`,padding:12,background:`rgba(88, 166, 255, 0.08)`,border:`1px solid rgba(88, 166, 255, 0.12)`,borderRadius:10,cursor:`pointer`},Yr={display:`flex`,flexDirection:`column`,gap:12,padding:14,background:`linear-gradient(135deg, rgba(88, 166, 255, 0.1), rgba(88, 166, 255, 0.04))`,border:`1px solid rgba(127, 208, 255, 0.16)`,borderRadius:14,boxShadow:`inset 0 1px 0 rgba(255,255,255,0.03)`},Xr={...qr,minHeight:32,padding:`7px 12px`,whiteSpace:`nowrap`},Zr={display:`grid`,gridTemplateColumns:`repeat(auto-fit, minmax(160px, 1fr))`,gap:8},Qr={borderRadius:10,padding:10,background:`rgba(255, 255, 255, 0.03)`,border:`1px solid rgba(255, 255, 255, 0.06)`},$r={borderRadius:16,border:`1px solid rgba(255, 255, 255, 0.06)`,background:`rgba(255, 255, 255, 0.02)`,padding:14},ei={color:`#8ea4be`,fontSize:12,padding:10},ti={display:`grid`,gridTemplateColumns:`repeat(auto-fit, minmax(220px, 1fr))`,gap:10,maxHeight:186,overflowY:`auto`},ni={padding:24,color:`#8ea4be`,fontSize:12},ri={height:`90px`,display:`flex`,alignItems:`center`,padding:`0 18px`,color:`#8ea4be`,fontSize:12,borderTop:`1px solid rgba(88, 166, 255, 0.2)`,background:`rgba(1, 4, 9, 0.88)`};export{Wr as GraphWorkspace}; \ No newline at end of file diff --git a/semantica/static/assets/GraphWorkspace-DGFkh5CZ.js b/semantica/static/assets/GraphWorkspace-DGFkh5CZ.js deleted file mode 100644 index f07d980c..00000000 --- a/semantica/static/assets/GraphWorkspace-DGFkh5CZ.js +++ /dev/null @@ -1,288 +0,0 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/TimelinePanel-YrOmsTlw.js","assets/rolldown-runtime-B1FJdls4.js","assets/index-BVBOQ8an.js","assets/query-vendor-Cbp9LWgA.js","assets/index-Bw-pAf6p.css","assets/timeline-vendor-DxuOyw5t.js","assets/timeline-vendor-5-TIXSrZ.css","assets/GraphInspectorPanel-CbpkpjNw.js","assets/graphTheme-CLhhQXPS.js","assets/graph-vendor-DFSl_YWi.js","assets/explorationEffectsPlugin-BUgXLTPa.js","assets/explorationEffectsPlugin-BhFwJ4hP.js","assets/neighborhoodPanelPlugin-CJEfjLxQ.js","assets/neighborhoodPanelPlugin-Dra5vWrD.js","assets/temporalOverlayPlugin-tGkpBW1s.js","assets/temporalOverlayPlugin-l3pE8rf_.js"])))=>i.map(i=>d[i]); -import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{T as t,a as n,i as r,n as i}from"./query-vendor-Cbp9LWgA.js";import{r as a,t as o}from"./index-BVBOQ8an.js";import{n as s,r as c,t as l}from"./graph-vendor-DFSl_YWi.js";import{a as u,c as d,d as f,i as p,l as m,n as h,o as g,r as _,s as v,t as y,u as b}from"./graphTheme-CLhhQXPS.js";import"./explorationEffectsPlugin-BhFwJ4hP.js";import"./neighborhoodPanelPlugin-Dra5vWrD.js";import"./temporalOverlayPlugin-l3pE8rf_.js";var x=e(t(),1),S=a(),C=n();function w(...e){return e.filter(Boolean).join(` `)}function T(e){let t=(0,S.c)(10),{children:n,tone:r,padding:i,className:a,style:o}=e,s=r===void 0?`default`:r,c=i===void 0?`default`:i,l=s!==`default`&&`sem-surface--${s}`,u;t[0]!==a||t[1]!==l?(u=w(`sem-surface`,l,a),t[0]=a,t[1]=l,t[2]=u):u=t[2];let d;t[3]!==n||t[4]!==c?(d=c===`none`?n:(0,C.jsx)(`div`,{className:w(`sem-surface-body`,c===`tight`&&`sem-surface-body--tight`),children:n}),t[3]=n,t[4]=c,t[5]=d):d=t[5];let f;return t[6]!==o||t[7]!==u||t[8]!==d?(f=(0,C.jsx)(`div`,{className:u,style:o,children:d}),t[6]=o,t[7]=u,t[8]=d,t[9]=f):f=t[9],f}function E(e){let t=(0,S.c)(5),{children:n,tone:r}=e,i=r===void 0?`default`:r,a=i!==`default`&&`sem-chip--${i}`,o;t[0]===a?o=t[1]:(o=w(`sem-chip`,a),t[0]=a,t[1]=o);let s;return t[2]!==n||t[3]!==o?(s=(0,C.jsx)(`span`,{className:o,children:n}),t[2]=n,t[3]=o,t[4]=s):s=t[4],s}function D(e){let t=(0,S.c)(8),{children:n,open:r,className:i}=e,a=r===void 0?!0:r,o;t[0]===i?o=t[1]:(o=w(`sem-inspector`,i),t[0]=i,t[1]=o);let s=a?`block`:`none`,c;t[2]===s?c=t[3]:(c={display:s},t[2]=s,t[3]=c);let l;return t[4]!==n||t[5]!==o||t[6]!==c?(l=(0,C.jsx)(T,{className:o,padding:`none`,style:c,children:n}),t[4]=n,t[5]=o,t[6]=c,t[7]=l):l=t[7],l}var O=e(l(),1),k={id:`hover-activation`,attach:()=>{},detach:()=>{},onNodeEnter:(e,t)=>{e.setHoveredNodeId(t)},onNodeLeave:(e,t)=>{e.getInteractionState().hoveredNodeId===t&&e.setHoveredNodeId(null)}},A={id:`click-selection`,attach:()=>{},detach:()=>{},onNodeClick:(e,t)=>{e.setHoveredNodeId(t),e.onNodeSelectionChange(t)},onStageClick:e=>{e.setHoveredNodeId(null),e.onNodeSelectionChange(``)}},j={id:`focus-camera`,attach:()=>{},detach:()=>{},performAction:(e,t)=>t.type===`focusNode`?(e.focusNodeInView(t.nodeId),!0):!1};function M(){let e=``;return{id:`search-focus`,attach:()=>{},detach:()=>{e=``},onStateChange:(t,n)=>{let r=n.focusedNodeId;if(!r||r===e){e=r;return}e=r,t.dispatchAction({type:`focusNode`,nodeId:r})}}}function ee(){let e=``;return{id:`path-highlight`,attach:()=>{},detach:()=>{e=``},onStateChange:(t,n)=>{let r=n.activePath.join(`::`);r!==e&&(e=r,t.sigma.refresh())}}}var te={id:`fit-view`,attach:()=>{},detach:()=>{},performAction:(e,t)=>t.type===`fitView`?(e.fitCurrentView(),!0):!1};function ne(){let e=null;return{id:`view-mode-switch`,attach:()=>{},detach:()=>{e=null},onStateChange:(t,n)=>{if(n.viewMode!==e){if(e=n.viewMode,n.focusedNodeId){t.dispatchAction({type:`focusNode`,nodeId:n.focusedNodeId});return}t.dispatchAction({type:`fitView`})}}}}var re={iterations:50,settings:{barnesHutOptimize:!0,barnesHutTheta:.5,adjustSizes:!1,gravity:1,slowDown:10}},N={allowInvalidContainer:!0,labelRenderedSizeThreshold:3,defaultNodeType:`circle`,defaultEdgeType:`line`,hideEdgesOnMove:!0,webGLTarget:`webgl2`},P=y.focus.maxNeighbors,F=y.focus.ringCapacity,I=y.focus.ringGap,L=y.focus.primaryLabels;function R(e){let t=new Set;for(let n=0;n=-r&&e.y>=-r&&e.x<=t+r&&e.y<=n+r}function ie(e,t,n,r,i){let a=[];for(let o=0;o1,s=v(e.zoomTier,y.effects.pathPulse.minZoomTier),c=v(e.zoomTier,y.effects.pathFlow.minZoomTier),l=v(e.zoomTier,y.effects.lens.minZoomTier),u=!!(e.hoveredNodeId||e.selectedNodeId);return{pathPulse:t.pathPulseEnabled?o?s?a===0?{enabled:!0,available:!1,reason:`Path is off-screen`}:a>y.effects.pathPulse.maxSegments?{enabled:!0,available:!1,reason:`Disabled by path size cap`,detail:`${a} visible segments`,visibleSegments:a,segmentCap:y.effects.pathPulse.maxSegments}:{enabled:!0,available:!0,reason:`Ready`,visibleSegments:a,segmentCap:y.effects.pathPulse.maxSegments}:{enabled:!0,available:!1,reason:`Disabled by zoom tier`,detail:`Requires ${y.effects.pathPulse.minZoomTier}`}:{enabled:!0,available:!1,reason:`No active path`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},pathFlow:t.pathFlowEnabled?o?c?a===0?{enabled:!0,available:!1,reason:`Path is off-screen`}:a>y.effects.pathFlow.maxSegments?{enabled:!0,available:!1,reason:`Disabled by path size cap`,detail:`${a} visible segments`,visibleSegments:a,segmentCap:y.effects.pathFlow.maxSegments}:{enabled:!0,available:!0,reason:`Ready`,visibleSegments:a,segmentCap:y.effects.pathFlow.maxSegments}:{enabled:!0,available:!1,reason:`Disabled by zoom tier`,detail:`Requires ${y.effects.pathFlow.minZoomTier}`}:{enabled:!0,available:!1,reason:`No active path`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},lens:t.lensEnabled?u?l?{enabled:!0,available:!0,reason:`Ready`}:{enabled:!0,available:!1,reason:`Disabled by zoom tier`,detail:`Requires ${y.effects.lens.minZoomTier}`}:{enabled:!0,available:!1,reason:`No focal node`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},legend:t.legendEnabled?{enabled:!0,available:!0,reason:`Panel enabled`}:{enabled:!1,available:!1,reason:`Disabled by toggle`},diagnostics:y.effects.diagnostics.enabledInDev?t.diagnosticsEnabled?{enabled:!0,available:!0,reason:`Ready`}:{enabled:!1,available:!1,reason:`Disabled by toggle`}:{enabled:!1,available:!1,reason:`Disabled in production`}}}function B(e,t){let n=0;if(f.hasDirectedEdge(e,t)){let r=f.getDirectedEdgeAttributes(e,t);n=Math.max(n,Number(r?.weight??0))}if(f.hasDirectedEdge(t,e)){let r=f.getDirectedEdgeAttributes(t,e);n=Math.max(n,Number(r?.weight??0))}return n}function V(e){return f.neighbors(e).map(t=>({id:t,weight:B(e,t),degree:f.degree(t)})).sort((e,t)=>t.weight===e.weight?t.degree===e.degree?e.id.localeCompare(t.id):t.degree-e.degree:t.weight-e.weight).map(e=>e.id)}function oe(e){let t=V(e).slice(0,P);return new Set([e,...t])}function H(e,t,n,r){let i=String(n.baseColor||r||e.palette.semantic[0]);switch(e.nodes.states[t].color){case`selected`:return e.palette.accent.selected;case`hovered`:return e.palette.accent.hovered;case`path`:return e.palette.accent.path;case`muted`:return String(n.mutedColor||g(i,e.nodes.mutedAlpha));default:return i}}function U(e,t,n,r){let i=String(n.baseColor||r||e.palette.muted.edgeInspection);switch(e.edges.states[t].color){case`hover`:return e.palette.accent.hovered;case`path`:return e.palette.accent.path;case`focus`:return e.palette.muted.edgeFocus;case`overview`:return e.palette.muted.edgeOverview;case`structure`:return e.palette.muted.edgeStructure;case`inspection`:return e.palette.muted.edgeInspection;case`muted`:return String(n.mutedColor||e.palette.muted.edgeOverview);default:return i}}function W(e,t,n,r,i){return t&&e===t?`hovered`:n&&e===n?`selected`:i.has(e)?`path`:r.has(e)?`neighbor`:t||n||i.size>0?`muted`:`default`}function G(e,t,n,r,i,a){let o=`${e}::${t}`,s=n||r;return a.has(o)?`path`:s&&(e===s||t===s)?n?`hovered`:`selected`:i.has(e)&&i.has(t)?`neighbor`:n||r||a.size>0?`muted`:`default`}function se(e,t){return e===`selected`?`selected`:t.nodeShapeVariant||t.nodeVariant||`default`}function ce(e,t){return e===`path`?`pathSignal`:t.edgeVariant?t.edgeVariant:t.isBidirectional?`bidirectionalCurve`:t.arrowVisibilityPolicy===`contextual`?`directional`:`line`}function K(e,t,n,r,i){let a=e.zoomTiers[t],o=e.labels.forceVisibleStates.includes(n),s=r.labelVisibilityPolicy||`priority`;if(o||e.nodes.states[n].forceLabel)return!0;switch(s){case`always`:return!0;case`local`:return t!==`overview`&&n!==`default`&&n!==`muted`&&n!==`inactive`;case`priority`:return i>=a.labelThreshold;default:return!1}}function le(e,t,n,r,i){return t===`selected`||n===`selected`?r.ringColor||e.nodes.selectedRing.color:t===`hovered`?e.palette.accent.hovered:t===`path`?e.palette.accent.path:t===`muted`||t===`inactive`?g(r.strokeColor||r.borderColor||e.palette.background.nodeBorder,.7):n===`temporal`?e.palette.accent.temporal:n===`provenance`?e.palette.accent.provenance:n===`inferred`?e.palette.accent.inferred:r.strokeColor||r.borderColor||e.palette.background.nodeBorder||i}function ue(e,t,n,r,i){let a=e.zoomTiers[t],o=e.nodes.states[n],s=se(n,r),c=e.nodes.variants[s],l=Number(r.baseSize||r.size||4),u=Number(r.labelPriority??0),d=H(e,n,r,r.color),f=(n===`default`?a.nodeScale:o.sizeMultiplier)*c.sizeMultiplier,p=K(e,t,n,r,u),m=r.badgeKind||c.badgeKind,h=e.labels.forceVisibleStates.includes(n),_=!!(m&&(h||a.showBadges&&v(t,c.badgeVisibleFrom))&&n!==`muted`&&n!==`inactive`),y=n===`selected`&&v(t,e.nodes.selectedRing.visibleFrom),b=n===`hovered`||n===`selected`||n===`path`,x=n===`muted`||n===`inactive`?e.nodes.strokeHierarchy[t].muted:h?e.nodes.strokeHierarchy[t].emphasis:e.nodes.strokeHierarchy[t].base;return{color:d,size:Math.max(l*f,o.minSize),forceLabel:p,label:p?i:``,zIndex:p&&o.zIndex===0?1:o.zIndex,hidden:!1,borderColor:le(e,n,s,r,d),borderSize:Math.max(.4,Number(r.borderSize??.85)+x+o.borderBoost+c.borderBoost-.8),nodeVariant:s,badgeKind:m,badgeCount:r.badgeCount,showBadge:_,showRing:y,ringColor:r.ringColor||e.nodes.selectedRing.color,showHalo:b,haloColor:r.haloColor||r.glowColor||g(d,e.overlays.hoverGlowAlpha+c.haloBoost)}}function de(e,t,n,r,i){let a=e.edges.variants[r];return e.edges.states[n].forceArrow||a.arrowPolicy===`always`||a.arrowPolicy===`contextual`&&e.zoomTiers[t].showContextualArrows?`arrow`:n===`default`?Number(i.visualPriority??0)>=e.zoomTiers[t].arrowPriorityThreshold&&e.zoomTiers[t].showContextualArrows?`arrow`:`line`:i.type||a.baseType}function q(e,t,n,r){let i=e.zoomTiers[t],a=e.edges.states[n],o=ce(n,r),s=e.edges.variants[o],c=Number(r.baseSize||r.size||.9),l=Number(r.visualPriority??0),u=n===`default`&&l{n.hasNode(e)||n.addNode(e,t)},u=f.getNodeAttributes(e),d=ue(y,`inspection`,`selected`,u,u.label);l(e,{...u,x:0,y:0,color:d.color,size:Math.max(d.size,22),label:d.label}),r.forEach((e,t)=>{let n=f.getNodeAttributes(e),i=Math.floor(t/F),s=t%F,c=Math.min(F,r.length-i*F),u=I*(i+1),d=Math.PI*2*s/c-Math.PI/2,p=ue(y,`inspection`,o.has(e)?`path`:a.has(e)?`neighbor`:`default`,{...n,labelPriority:a.has(e)||o.has(e)?Math.max(Number(n.labelPriority??0),1):0},n.label);l(e,{...n,x:Math.cos(d)*u,y:Math.sin(d)*u,color:p.color,size:Math.max(p.size,8.5),label:p.label})});for(let t of i)for(let r of i){if(t===r||!f.hasDirectedEdge(t,r))continue;let i=f.getDirectedEdgeAttributes(t,r),a=q(y,`inspection`,s.has(`${t}::${r}`)?`path`:t===e||r===e?`selected`:`neighbor`,i);n.mergeDirectedEdge(t,r,{...i,type:a.type,size:a.size,color:a.color})}return n}function J(e,t,n,r,i){let a=e.createRadialGradient(t,n,0,t,n,r);a.addColorStop(0,i),a.addColorStop(1,`rgba(0,0,0,0)`),e.fillStyle=a,e.beginPath(),e.arc(t,n,r,0,Math.PI*2),e.fill()}function pe(e,t,n,r,i,a,o){e.strokeStyle=g(i,o),e.lineWidth=a*2.4,e.beginPath(),e.arc(t,n,r+a*1.9,0,Math.PI*2),e.stroke(),e.strokeStyle=i,e.lineWidth=a,e.beginPath(),e.arc(t,n,r+a*1.45,0,Math.PI*2),e.stroke()}function me(e,t,n,r,i,a){let o=y.nodes.badges[i],s=y.nodes.badge.radius,c=y.nodes.badge.offset,l=t+Math.max(r*.62,s+c),u=n-Math.max(r*.62,s+c);J(e,l,u,y.overlays.badgeGlowRadius,g(o.color,y.nodes.badge.glowAlpha)),e.fillStyle=o.color,e.beginPath(),e.arc(l,u,s,0,Math.PI*2),e.fill(),e.strokeStyle=y.nodes.badge.stroke,e.lineWidth=1,e.beginPath(),e.arc(l,u,s,0,Math.PI*2),e.stroke(),e.fillStyle=y.nodes.badge.textColor,e.font=`700 ${y.nodes.badge.fontSize}px Inter, system-ui, sans-serif`,e.textAlign=`center`,e.textBaseline=`middle`;let d=i===`provenance`&&a&&a>1?String(Math.min(9,a)):o.label;e.fillText(d,l,u+.5)}function Y(e,t,n,r,i,a,o){let s=n.x-t.x,c=n.y-t.y,l=Math.max(Math.hypot(s,c),1),u=-c/l,d=s/l,f=l*a,p=(t.x+n.x)/2+u*f,m=(t.y+n.y)/2+d*f;e.strokeStyle=g(r,o),e.lineWidth=i+y.overlays.curveGlowWidth,e.beginPath(),e.moveTo(t.x,t.y),e.quadraticCurveTo(p,m,n.x,n.y),e.stroke(),e.strokeStyle=r,e.lineWidth=i,e.beginPath(),e.moveTo(t.x,t.y),e.quadraticCurveTo(p,m,n.x,n.y),e.stroke()}function he(e,t,n){t.forEach((t,r)=>{let i=(n*y.effects.pathPulse.speed+r*.17)%1,a=t.source.x+(t.target.x-t.source.x)*i,o=t.source.y+(t.target.y-t.source.y)*i,s=e.createRadialGradient(a,o,0,a,o,y.effects.pathPulse.radius);s.addColorStop(0,g(y.palette.accent.path,y.effects.pathPulse.glowAlpha)),s.addColorStop(1,`rgba(0,0,0,0)`),e.fillStyle=s,e.beginPath(),e.arc(a,o,y.effects.pathPulse.radius,0,Math.PI*2),e.fill()})}function ge(e,t,n){t.forEach((t,r)=>{let i=(n*y.effects.pathFlow.speed+r*y.effects.pathFlow.spacing)%1,a=t.source.x+(t.target.x-t.source.x)*i,o=t.source.y+(t.target.y-t.source.y)*i,s=Math.max(0,i-.08),c=t.source.x+(t.target.x-t.source.x)*s,l=t.source.y+(t.target.y-t.source.y)*s;e.strokeStyle=g(t.color,.28),e.lineWidth=Math.max(t.size+3.6,4.6),e.lineCap=`round`,e.beginPath(),e.moveTo(c,l),e.lineTo(a,o),e.stroke(),e.strokeStyle=g(y.palette.accent.selected,y.effects.pathFlow.opacity),e.lineWidth=Math.max(t.size+1.3,2.4),e.beginPath(),e.moveTo(c,l),e.lineTo(a,o),e.stroke(),J(e,a,o,y.effects.pathFlow.radius,g(y.palette.accent.selected,.32))})}function _e(e,t,n,r){let i=t.getNodeDisplayData(n);if(!i)return;let a=t.graphToViewport({x:i.x,y:i.y});J(e,a.x,a.y,y.effects.lens.radius,g(y.palette.accent.hovered,y.effects.lens.glowAlpha)),r.forEach(r=>{if(r===n||!f.hasNode(r)||!f.hasDirectedEdge(n,r)&&!f.hasDirectedEdge(r,n))return;let i=t.getNodeDisplayData(r);if(!i)return;let o=t.graphToViewport({x:i.x,y:i.y});e.strokeStyle=g(y.palette.accent.hovered,y.effects.lens.edgeAlpha*.38),e.lineWidth=y.effects.lens.edgeLineWidth+3.2,e.lineCap=`round`,e.beginPath(),e.moveTo(a.x,a.y),e.lineTo(o.x,o.y),e.stroke(),e.strokeStyle=g(y.palette.accent.hovered,y.effects.lens.edgeAlpha),e.lineWidth=y.effects.lens.edgeLineWidth,e.beginPath(),e.moveTo(a.x,a.y),e.lineTo(o.x,o.y),e.stroke(),J(e,o.x,o.y,y.effects.lens.feather*.18,g(y.palette.accent.hovered,.12))})}function ve(e,t){let{zoomTier:n,hoveredNodeId:r,selectedNodeId:i,activePath:a}=t,o=r||i,s=o&&f.hasNode(o)?oe(o):new Set,c=new Set(a),l=R(a);e.setSetting(`nodeReducer`,(e,t)=>{let a=t,o=ue(y,n,W(e,r,i,s,c),a,t.label);return{...t,color:o.color,size:o.size,forceLabel:o.forceLabel,label:o.label,zIndex:o.zIndex,hidden:o.hidden,borderColor:o.borderColor,borderSize:o.borderSize}}),e.setSetting(`edgeReducer`,(e,t)=>{let a=t,[o,c]=f.extremities(e),u=q(y,n,G(o,c,r,i,s,l),a);return{...t,hidden:u.hidden,type:u.type,color:u.color,size:u.size,zIndex:u.zIndex}}),e.refresh()}function ye(e,t,n,r,i,a){return{hoveredNodeId:e,selectedNodeId:t,focusedNodeId:t,activePath:n,viewMode:r,zoomTier:i,isLayoutRunning:a}}function X(e,t,n){for(let r of e)if(r.performAction?.(t,n))return}var be=(0,x.forwardRef)(function({onNodeClick:e,selectedNodeId:t,activePath:n=[],effectsState:r,isLayoutRunning:i,viewMode:a,className:o,showFitViewButton:c=!0,pluginOverlays:l=[],onPluginRuntimeChange:u,onInteractionStateChange:d,onDiagnosticsChange:m},h){let _=(0,x.useRef)(null),v=(0,x.useRef)(null),b=(0,x.useRef)(null),S=(0,x.useRef)(null),w=(0,x.useRef)(null),[T,E]=(0,x.useState)(null),[D,P]=(0,x.useState)(`overview`),F=(0,x.useMemo)(()=>[k,A,j,M(),ee(),te,ne()],[]),I=a===`focused`&&!!t&&f.hasNode(t),L=(0,x.useMemo)(()=>I&&t?fe(t,n):f,[n,I,t]),R=(0,x.useMemo)(()=>ye(T,t,n,a,D,i),[n,T,i,t,a,D]),z=(0,x.useRef)(R);z.current=R;let B=(0,x.useCallback)(e=>{let t=b.current;if(!t)return;if(I){t.getCamera().animatedReset({duration:y.motion.cameraMs}),t.refresh();return}let n=t.getNodeDisplayData(e);if(!n){t.getCamera().animatedReset({duration:y.motion.cameraMs});return}t.getCamera().animate({x:n.x,y:n.y,ratio:.3},{duration:y.motion.cameraMs,easing:`quadraticOut`})},[I]),V=(0,x.useCallback)(()=>{let e=b.current;if(e){if(t){B(t);return}e.getCamera().animatedReset({duration:y.motion.cameraMs})}},[B,t]),H=(0,x.useCallback)(e=>{let t=w.current;t&&X(F,t,e)},[F]),U=(0,x.useCallback)(t=>{let n=t??b.current;if(!n)return null;let r={sigma:n,graph:f,displayGraph:L,getInteractionState:()=>z.current,setHoveredNodeId:E,onNodeSelectionChange:e,focusNodeInView:B,fitCurrentView:V,dispatchAction:H};return w.current=r,r},[L,H,V,B,e]),G=(0,x.useCallback)((e,...t)=>{let n=U();if(n)for(let r of F){let i=r[e];typeof i==`function`&&i(n,...t)}},[F,U]);(0,x.useImperativeHandle)(h,()=>({getSigma:()=>b.current,fitView:()=>H({type:`fitView`}),focusNode:e=>H({type:`focusNode`,nodeId:e})}),[H]),(0,x.useEffect)(()=>{if(!_.current)return;let e=new s(L,_.current,N);b.current=e,u?.({sigma:e,graph:f,displayGraph:L});let t=e.getCamera(),n=U(e);if(n)for(let e of F)e.attach(n);let r=()=>{let e={x:t.getState().x,y:t.getState().y,ratio:t.getState().ratio},n=p(e.ratio);P(e=>e===n?e:n),G(`onCameraChange`,e)},i=new ResizeObserver(()=>{_.current&&_.current.offsetWidth>0&&e.refresh()});return i.observe(_.current),t.on(`updated`,r),e.on(`clickNode`,({node:e})=>G(`onNodeClick`,e)),e.on(`clickStage`,()=>G(`onStageClick`)),e.on(`enterNode`,({node:e})=>G(`onNodeEnter`,e)),e.on(`leaveNode`,({node:e})=>G(`onNodeLeave`,e)),requestAnimationFrame(()=>{r(),H({type:`fitView`})}),()=>{if(n)for(let e of F)e.detach(n);t.off(`updated`,r),i.disconnect(),e.kill(),w.current=null,b.current=null,u?.(null)}},[F,H,G,L,U,u]),(0,x.useEffect)(()=>{let e=U();if(e){for(let t of F)t.onStateChange?.(e,R);for(let t of F)t.apply?.(e,R);d?.(R)}},[F,U,R,d]),(0,x.useEffect)(()=>{if(!m)return;let e=b.current,t=_.current;m(ae(R,r,e,t?.clientWidth??0,t?.clientHeight??0))},[r,R,m]),(0,x.useEffect)(()=>{let e=b.current;!e||L!==f||ve(e,R)},[L,R]),(0,x.useEffect)(()=>{let e=b.current,t=v.current,n=_.current;if(!e||!t||!n)return;let i=0,a=()=>{let o=n.getBoundingClientRect(),s=window.devicePixelRatio||1;(t.width!==Math.floor(o.width*s)||t.height!==Math.floor(o.height*s))&&(t.width=Math.floor(o.width*s),t.height=Math.floor(o.height*s),t.style.width=`${o.width}px`,t.style.height=`${o.height}px`);let c=t.getContext(`2d`);if(!c){i=window.requestAnimationFrame(a);return}c.setTransform(s,0,0,s,0,0),c.clearRect(0,0,o.width,o.height);let l=R.hoveredNodeId||R.selectedNodeId,u=l&&f.hasNode(l)?oe(l):new Set,d=new Set(R.activePath),p=ie(e,R.activePath,R.zoomTier,o.width,o.height),m=ae(R,r,e,o.width,o.height),h=new Set([...u,...d,...l?[l]:[]]),_=performance.now()/1e3;if(h.forEach(t=>{let n=e.getNodeDisplayData(t);if(!n)return;let r=f.getNodeAttributes(t),i=W(t,R.hoveredNodeId,R.selectedNodeId,u,d),a=ue(y,R.zoomTier,i,r,r.label),o=e.graphToViewport({x:n.x,y:n.y});if(a.showHalo){let e=Math.max(n.size*y.overlays.glowRadiusMultiplier*(a.nodeVariant===`selected`?1.08:1),y.overlays.minGlowRadius);J(c,o.x,o.y,e,g(a.haloColor,t===l?y.overlays.hoverGlowAlpha:y.overlays.pathGlowAlpha))}a.showRing&&pe(c,o.x,o.y,n.size,a.ringColor||y.nodes.selectedRing.color,y.nodes.selectedRing.width,y.nodes.selectedRing.glowAlpha),a.showBadge&&a.badgeKind&&me(c,o.x,o.y,n.size,a.badgeKind,a.badgeCount)}),l&&m.lens.available&&_e(c,e,l,u),y.zoomTiers[R.zoomTier].showCurves&&l){let t=new Set;u.forEach(n=>{u.forEach(r=>{if(n>=r||!f.hasDirectedEdge(n,r)||!f.hasDirectedEdge(r,n))return;let i=[n,r].sort().join(`::`);if(t.has(i))return;t.add(i);let a=e.getNodeDisplayData(n),o=e.getNodeDisplayData(r);if(!a||!o)return;let s=f.getDirectedEdgeAttributes(n,r),u=n===l||r===l?R.hoveredNodeId?`hovered`:`selected`:`neighbor`,d=q(y,R.zoomTier,u,s);!d.drawCurvedOverlay||!d.color||!d.size||Y(c,e.graphToViewport({x:a.x,y:a.y}),e.graphToViewport({x:o.x,y:o.y}),d.color,Math.max(d.size,y.overlays.curveLineWidth),d.curveStrength,y.edges.variants.bidirectionalCurve.glowAlpha)})})}p.length>0&&p.forEach(e=>{Y(c,e.source,e.target,e.color,Math.max(e.size,y.overlays.curveLineWidth+.4),e.curveStrength,y.edges.variants.pathSignal.glowAlpha)}),m.pathFlow.available&&ge(c,p,_),m.pathPulse.available&&he(c,p,_),i=window.requestAnimationFrame(a)};return a(),()=>{window.cancelAnimationFrame(i)}},[r,R]),(0,x.useEffect)(()=>{if(t||I){S.current?.stop();return}return i?(S.current||=new O.default(f,re),S.current.start()):S.current?.stop(),()=>{S.current?.stop()}},[I,i,t]),(0,x.useEffect)(()=>()=>{S.current?.kill(),S.current=null},[]);let se=(0,x.useCallback)(()=>{V()},[V]);return(0,C.jsxs)(`div`,{style:{position:`relative`,width:`100%`,height:`100%`},children:[(0,C.jsx)(`div`,{ref:_,className:o,style:{width:`100%`,height:`100%`,background:`transparent`}}),(0,C.jsx)(`canvas`,{ref:v,style:{position:`absolute`,inset:0,width:`100%`,height:`100%`,pointerEvents:`none`,zIndex:4}}),l.length?(0,C.jsx)(`div`,{style:{position:`absolute`,inset:0,pointerEvents:`none`,zIndex:6},children:l.map((e,t)=>(0,C.jsx)(`div`,{style:{position:`absolute`,inset:0},children:e},`graph-plugin-overlay-${t}`))}):null,c?(0,C.jsx)(`button`,{id:`graph-fit-view-btn`,onClick:se,style:{position:`absolute`,bottom:24,left:24,padding:`8px 16px`,background:`linear-gradient(135deg, rgba(27, 79, 170, 0.9), rgba(53, 123, 255, 0.84))`,color:`#fff`,border:`1px solid ${y.palette.background.shellBorder}`,borderRadius:10,cursor:`pointer`,fontWeight:700,zIndex:10,backdropFilter:`blur(10px)`,boxShadow:`0 10px 28px ${y.palette.background.shellGlow}`,fontSize:12,letterSpacing:`0.01em`},children:`Fit View`}):null]})}),Z=[`community`,`cluster`,`module`,`group`,`category`,`domain`,`layer`,`source`,`nodeType`],xe=[`source`,`source_url`,`pmid`,`pmids`,`evidence`,`provenance`,`confidence`];function Se(e,t){if(t===`nodeType`){let t=e.nodeType;return typeof t==`string`&&t.trim()?t:null}let n=e.properties?.[t];return typeof n==`string`&&n.trim()?n:null}function Ce(e,t){if(e.length<=1||t<=0)return 0;let n=0;for(let r of e){let e=r/t;n-=e*Math.log(e)}return n/Math.log(e.length)}function Q(e){let t=null,n=0;for(let r of Z){let i=new Map,a=0;for(let t of e){let e=Se(t.attributes,r);e&&(a+=1,i.set(e,(i.get(e)??0)+1))}let o=i.size;if(a===0||o<=1)continue;let s=[...i.values()],c=a/e.length,l=Math.max(...s)/a,u=Ce(s,a),d=Math.min(o,y.palette.semantic.length)/y.palette.semantic.length,f=u*.65+d*.2+c*.15;c>=.45&&u>=.45&&l<=.88&&f>n&&(t=r,n=f)}return t?(e,n)=>Se(n,t)??we(e,n):(e,t)=>we(e,t)}function we(e,t){let n=u(e)%y.palette.semantic.length;return`${t.nodeType||`entity`}:${n}`}function Te(e){return xe.reduce((t,n)=>e[n]!==void 0&&e[n]!==null?t+1:t,0)}function Ee(e,t,n,r){let i=`default`,a,o;n?(i=`temporal`,a=`temporal`):r>0&&(i=`provenance`,a=`provenance`,o=r);let s=`none`;return t>=.86?s=`always`:a?s=`local`:t>=.56&&(s=`priority`),{nodeVariant:i,nodeShapeVariant:i,badgeKind:a,badgeCount:o,ringColor:y.nodes.selectedRing.color,haloColor:g(e,.38),labelVisibilityPolicy:s}}function De(e,t,n,r){let i=h(.12,.18+Math.log(Math.max(Number(e.weight)||1,1))/Math.log(12),1),a=`line`;return r?a=`bidirectionalCurve`:Math.max(t,n,i)>=.58&&(a=`directional`),{edgeVariant:a,arrowVisibilityPolicy:a===`line`?`hidden`:`contextual`,relationshipStrength:i,isParallelPair:!1,parallelIndex:0,parallelCount:1}}var Oe=1e3;async function ke(e,t){let n=null,r=[],i=null;for(;;){let a=new URL(`/api/graph/nodes`,window.location.origin);a.searchParams.set(`limit`,String(Oe)),n&&a.searchParams.set(`cursor`,n);let o=await fetch(a.toString(),{signal:e});if(!o.ok)throw Error(`Fetch failed: ${o.status}`);let s=await o.json();if(!s.nodes?.length||(i=s.total??i,r.push(...s.nodes),t?.({phase:`nodes`,nodesLoaded:r.length,nodesTotal:i,edgesLoaded:0,edgesTotal:null,message:i?`Loading nodes ${r.length.toLocaleString()} of ${i.toLocaleString()}`:`Loading nodes ${r.length.toLocaleString()}`,progress:i?Math.min(r.length/Math.max(i,1),.45):.18}),!s.next_cursor))break;n=s.next_cursor,await $()}return r}async function Ae(e,t,n,r){let i=null,a=[],o=null;for(;;){let s=new URL(`/api/graph/edges`,window.location.origin);s.searchParams.set(`limit`,String(Oe)),i&&s.searchParams.set(`cursor`,i);let c=await fetch(s.toString(),{signal:e});if(!c.ok)throw Error(`Fetch failed: ${c.status}`);let l=await c.json();if(!l.edges?.length)break;o=l.total??o;let u=l.edges.filter(e=>t.has(e.source)&&t.has(e.target));if(a.push(...u),r?.({phase:`edges`,nodesLoaded:n.loaded,nodesTotal:n.total,edgesLoaded:a.length,edgesTotal:o,message:o?`Loading edges ${a.length.toLocaleString()} of ${o.toLocaleString()}`:`Loading edges ${a.length.toLocaleString()}`,progress:o?.45+Math.min(a.length/Math.max(o,1),1)*.35:.62}),!l.next_cursor)break;i=l.next_cursor,await $()}return a}function $(){return`scheduler`in window&&typeof window.scheduler?.yield==`function`?window.scheduler.yield():new Promise(e=>setTimeout(e,0))}function je(e){let t=(0,S.c)(9),n;t[0]===e?n=t[1]:(n=e===void 0?{}:e,t[0]=e,t[1]=n);let{enabled:r,onGraphReady:a,onProgress:o}=n,s=r===void 0?!0:r,c;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(c=[`graph`,`full-load`],t[2]=c):c=t[2];let l;t[3]!==a||t[4]!==o?(l=async e=>{let{signal:t}=e,n=performance.now();o?.({phase:`nodes`,nodesLoaded:0,nodesTotal:null,edgesLoaded:0,edgesTotal:null,message:`Preparing graph load`,progress:.06});let r=await ke(t,o),i=new Set(r.map(Pe)),s=await Ae(t,i,{loaded:r.length,total:r.length},o),c=new Map;for(let e of i)c.set(e,0);for(let e of s)c.set(e.source,(c.get(e.source)??0)+1),c.set(e.target,(c.get(e.target)??0)+1);let l=Math.max(...c.values(),1),f=r.map(Ne);o?.({phase:`styling`,nodesLoaded:r.length,nodesTotal:r.length,edgesLoaded:s.length,edgesTotal:s.length,message:`Computing graph styling`,progress:.86});let p=Q(f),v=new Map;for(let e of i){let t=c.get(e)??0,n=Math.log(t+1)/Math.log(l+1);v.set(e,n)}let x=f.map(e=>{let{id:t,attributes:n}=e,r=p(t,n),i=u(r)%y.palette.semantic.length,a=y.palette.semantic[i],o=v.get(t)??0,s=h(2.6,2.6+12.4*o,15.8),c=!!(n.valid_from||n.valid_until),l=Te(n.properties??{});return{id:t,attributes:{...n,semanticGroup:r,color:a,baseColor:a,mutedColor:g(a,y.nodes.mutedAlpha),glowColor:g(a,.34),size:s,baseSize:s,visualPriority:o,labelPriority:o,strokeColor:_(a,112),borderColor:_(a,112),borderSize:.85,...Ee(a,o,c,l)}}}),S=new Set(s.map(Me)),C=s.map(e=>{let t=v.get(e.source)??0,n=v.get(e.target)??0,r=S.has(`${e.target}::${e.source}`);return{source:e.source,target:e.target,attributes:{weight:e.weight,edgeType:e.type,properties:e.properties,size:h(.45,.5+Math.sqrt(Math.max(Number(e.weight)||1,1))*.38,1.8),baseSize:h(.45,.5+Math.sqrt(Math.max(Number(e.weight)||1,1))*.38,1.8),color:y.palette.muted.edgeStructure,baseColor:y.palette.muted.edgeStructure,mutedColor:y.palette.muted.edgeOverview,visualPriority:Math.max(t,n),isBidirectional:r,edgeFamily:r?`bidirectional`:`line`,curveGroup:r?[e.source,e.target].sort().join(`::`):null,type:`line`,...De(e,t,n,r)}}});o?.({phase:`rendering`,nodesLoaded:x.length,nodesTotal:x.length,edgesLoaded:C.length,edgesTotal:C.length,message:`Rendering graph`,progress:.96}),b(),m(x),d(C);let w={nodeCount:x.length,edgeCount:C.length,loadTimeMs:Math.round(performance.now()-n)};return o?.({phase:`rendering`,nodesLoaded:w.nodeCount,nodesTotal:w.nodeCount,edgesLoaded:w.edgeCount,edgesTotal:w.edgeCount,message:`Graph ready`,progress:1}),a?.(w),w},t[3]=a,t[4]=o,t[5]=l):l=t[5];let f;return t[6]!==s||t[7]!==l?(f={queryKey:c,enabled:s,staleTime:1/0,queryFn:l},t[6]=s,t[7]=l,t[8]=f):f=t[8],i(f)}function Me(e){return`${e.source}::${e.target}`}function Ne(e){let t=Number(e.properties?.x??Math.random()*1e3-500),n=Number(e.properties?.y??Math.random()*1e3-500);return{id:e.id,attributes:{label:e.content||e.id,x:t,y:n,nodeType:e.type,content:e.content,valid_from:e.valid_from,valid_until:e.valid_until,properties:e.properties}}}function Pe(e){return e.id}function Fe(){let e=(0,S.c)(2),t=r(),n;return e[0]===t?n=e[1]:(n=()=>t.invalidateQueries({queryKey:[`graph`,`full-load`]}),e[0]=t,e[1]=n),n}var Ie=[`source`,`source_url`,`pmid`,`pmids`,`evidence`,`provenance`,`confidence`],Le={pathPulseEnabled:!1,pathFlowEnabled:!1,lensEnabled:!1,legendEnabled:!1,diagnosticsEnabled:!1,lensMode:`neighborhood`,effectQuality:`bounded`},Re=(0,x.lazy)(()=>o(()=>import(`./TimelinePanel-YrOmsTlw.js`).then(e=>({default:e.TimelinePanel})),__vite__mapDeps([0,1,2,3,4,5,6]))),ze=(0,x.lazy)(()=>o(()=>import(`./GraphInspectorPanel-CbpkpjNw.js`).then(e=>({default:e.GraphInspectorPanel})),__vite__mapDeps([7,2,1,3,4,8,9]))),Be=()=>o(()=>import(`./explorationEffectsPlugin-BUgXLTPa.js`).then(e=>e.explorationEffectsPlugin),__vite__mapDeps([10,11,2,1,3,4])),Ve=()=>o(()=>import(`./neighborhoodPanelPlugin-CJEfjLxQ.js`).then(e=>e.neighborhoodPanelPlugin),__vite__mapDeps([12,13,3,1])),He=()=>o(()=>import(`./temporalOverlayPlugin-tGkpBW1s.js`).then(e=>e.temporalOverlayPlugin),__vite__mapDeps([14,15,3,1]));function Ue(e,t){let n=(0,S.c)(4),[r,i]=(0,x.useState)(e),a,o;return n[0]!==t||n[1]!==e?(a=()=>{let n=setTimeout(()=>i(e),t);return()=>clearTimeout(n)},o=[t,e],n[0]=t,n[1]=e,n[2]=a,n[3]=o):(a=n[2],o=n[3]),(0,x.useEffect)(a,o),r}var We=` - .palantir-bg { - background: - radial-gradient(circle at top, rgba(77, 157, 255, 0.08), transparent 22%), - linear-gradient(180deg, #060b17 0%, #02060d 100%); - } - .palantir-grid { - position: absolute; - inset: 0; - background-image: - linear-gradient(rgba(88, 166, 255, 0.038) 1px, transparent 1px), - linear-gradient(90deg, rgba(88, 166, 255, 0.038) 1px, transparent 1px); - background-size: 42px 42px; - pointer-events: none; - z-index: 1; - } - .palantir-vignette { - position: absolute; - inset: 0; - background: radial-gradient(ellipse at center, transparent 34%, rgba(1, 4, 10, 0.78) 100%); - pointer-events: none; - z-index: 2; - } - .glass-header { - background: linear-gradient(180deg, rgba(7, 14, 25, 0.88) 0%, rgba(10, 18, 31, 0.62) 100%); - border-bottom: 1px solid rgba(112, 196, 255, 0.1); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - } - .glass-hud { - background: linear-gradient(135deg, rgba(8, 15, 27, 0.76), rgba(10, 19, 32, 0.58)); - backdrop-filter: blur(14px) saturate(1.08); - -webkit-backdrop-filter: blur(14px) saturate(1.08); - border-left: 1px solid rgba(112, 196, 255, 0.14); - box-shadow: -10px 0 28px rgba(0, 0, 0, 0.34), inset 1px 0 0 rgba(255, 255, 255, 0.04); - } - .hud-scrollbar::-webkit-scrollbar { width: 6px; } - .hud-scrollbar::-webkit-scrollbar-track { background: transparent; } - .hud-scrollbar::-webkit-scrollbar-thumb { background: rgba(88, 166, 255, 0.25); border-radius: 6px; } - .node-panel-collapse { - border: 1px solid rgba(255, 255, 255, 0.05); - border-radius: 12px; - background: rgba(0, 0, 0, 0.14); - overflow: hidden; - } - .node-panel-collapse + .node-panel-collapse { - margin-top: 12px; - } - .node-panel-summary { - list-style: none; - cursor: pointer; - display: flex; - align-items: center; - justify-content: space-between; - gap: 12px; - padding: 12px 14px; - color: #c6d4e3; - font-size: 12px; - font-weight: 700; - letter-spacing: 0.04em; - text-transform: uppercase; - } - .node-panel-summary::-webkit-details-marker { - display: none; - } - .node-panel-summary::after { - content: "+"; - color: rgba(127, 208, 255, 0.8); - font-size: 16px; - line-height: 1; - } - .node-panel-collapse[open] .node-panel-summary::after { - content: "−"; - } - .node-panel-body { - padding: 0 14px 14px; - } - .graph-loading-overlay { - position: absolute; - inset: 0; - z-index: 9; - display: flex; - align-items: center; - justify-content: center; - pointer-events: none; - } - .graph-loading-card { - width: min(460px, calc(100% - 48px)); - border-radius: 20px; - padding: 22px 22px 18px; - background: linear-gradient(135deg, rgba(7, 17, 31, 0.9), rgba(14, 28, 48, 0.78)); - border: 1px solid rgba(127, 208, 255, 0.16); - box-shadow: 0 24px 80px rgba(0, 0, 0, 0.38), inset 0 1px 0 rgba(255,255,255,0.04); - backdrop-filter: blur(18px); - -webkit-backdrop-filter: blur(18px); - } - .graph-loading-dots { - display: inline-flex; - gap: 8px; - align-items: center; - } - .graph-loading-dot { - width: 10px; - height: 10px; - border-radius: 999px; - background: linear-gradient(135deg, rgba(127, 208, 255, 0.96), rgba(242, 182, 109, 0.96)); - box-shadow: 0 0 18px rgba(127, 208, 255, 0.35); - animation: sem-loader-pulse 1.2s ease-in-out infinite; - } - .graph-loading-dot:nth-child(2) { - animation-delay: 0.14s; - } - .graph-loading-dot:nth-child(3) { - animation-delay: 0.28s; - } - @keyframes sem-loader-pulse { - 0%, 100% { - transform: translateY(0) scale(0.92); - opacity: 0.55; - } - 50% { - transform: translateY(-4px) scale(1.08); - opacity: 1; - } - } - .graph-loading-bar { - width: 100%; - height: 10px; - border-radius: 999px; - overflow: hidden; - background: rgba(255, 255, 255, 0.06); - border: 1px solid rgba(127, 208, 255, 0.1); - } - .graph-loading-bar > span { - display: block; - height: 100%; - border-radius: 999px; - background: linear-gradient(90deg, rgba(74, 163, 255, 0.9), rgba(127, 208, 255, 0.95), rgba(242, 182, 109, 0.92)); - box-shadow: 0 0 28px rgba(74, 163, 255, 0.3); - transition: width 180ms ease; - } - .explore-shell { - position: relative; - width: 100%; - height: 100%; - overflow: hidden; - padding: 12px; - display: flex; - flex-direction: column; - gap: 10px; - } - .explore-command-deck { - position: relative; - z-index: 3; - } - .explore-command-grid { - display: grid; - grid-template-columns: minmax(260px, 0.9fr) minmax(0, 1.4fr); - gap: 16px; - } - .explore-main-grid { - position: relative; - z-index: 3; - min-height: 0; - flex: 1; - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(340px, 380px); - gap: 12px; - } - .explore-scene-stack { - min-height: 0; - display: flex; - flex-direction: column; - gap: 14px; - } - .explore-scene-card { - min-height: 0; - flex: 1; - display: flex; - flex-direction: column; - overflow: hidden; - } - .explore-scene-shell { - position: relative; - min-height: 0; - flex: 1; - overflow: hidden; - border-radius: 20px 20px 0 0; - } - .explore-scene-stage { - position: relative; - z-index: 3; - width: 100%; - height: 100%; - } - .explore-scene-footer { - position: relative; - z-index: 3; - border-top: 1px solid rgba(112, 196, 255, 0.1); - background: linear-gradient(180deg, rgba(5, 11, 20, 0.94), rgba(5, 11, 20, 0.82)); - } - .explore-plugin-dock { - position: relative; - z-index: 3; - } - .explore-plugin-dock-tabs { - display: flex; - align-items: center; - gap: 6px; - flex-wrap: wrap; - } - .explore-plugin-dock-tab { - border: 1px solid rgba(127, 208, 255, 0.14); - background: rgba(255, 255, 255, 0.03); - color: #a9bfd7; - border-radius: 999px; - padding: 6px 10px; - font-size: 11px; - font-weight: 600; - cursor: pointer; - } - .explore-plugin-dock-tab[data-active="true"] { - color: #eef6ff; - background: rgba(74, 163, 255, 0.16); - border-color: rgba(127, 208, 255, 0.28); - } - .explore-toolbar { - display: flex; - align-items: center; - justify-content: space-between; - gap: 10px; - flex-wrap: wrap; - } - .explore-toolbar-groups { - display: flex; - align-items: center; - gap: 8px; - flex-wrap: wrap; - flex: 1; - justify-content: flex-end; - } - .explore-toolbar-group { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 3px; - border-radius: 14px; - border: 1px solid rgba(127, 208, 255, 0.08); - background: rgba(255, 255, 255, 0.02); - } - .explore-search-results { - display: flex; - flex-direction: column; - gap: 8px; - max-height: 260px; - overflow-y: auto; - padding-right: 4px; - } - .explore-inspector-shell { - min-height: 0; - display: flex; - flex-direction: column; - } - .explore-inspector-card { - min-height: 0; - flex: 1; - overflow: hidden; - } - .explore-inspector-scroll { - height: 100%; - overflow-y: auto; - } - @media (max-width: 1260px) { - .explore-main-grid { - grid-template-columns: 1fr; - } - } - @media (max-width: 980px) { - .explore-shell { - padding: 10px; - gap: 10px; - } - .explore-command-grid { - grid-template-columns: 1fr; - } - } -`;function Ge(e){switch(e){case`nodes`:return`Loading nodes`;case`edges`:return`Loading edges`;case`styling`:return`Computing layout and styling`;case`rendering`:return`Rendering graph`;default:return`Loading graph`}}function Ke(e){let t=(0,S.c)(48),{progress:n,showGraphBehind:r}=e,i;t[0]===n?i=t[1]:(i=n??{phase:`nodes`,nodesLoaded:0,nodesTotal:null,edgesLoaded:0,edgesTotal:null,message:`Preparing graph load`,progress:.06},t[0]=n,t[1]=i);let a=i,o=r?`linear-gradient(180deg, rgba(1,4,9,0.08), rgba(1,4,9,0.28))`:`linear-gradient(180deg, rgba(1,4,9,0.32), rgba(1,4,9,0.58))`,s;t[2]===o?s=t[3]:(s={background:o},t[2]=o,t[3]=s);let c,l,u;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(c={display:`flex`,alignItems:`center`,justifyContent:`space-between`,gap:14,marginBottom:14},l=(0,C.jsx)(`div`,{style:{color:`#ffffff`,fontSize:18,fontWeight:700,marginBottom:4},children:`Loading Graph`}),u={color:`#8fa8c6`,fontSize:13},t[4]=c,t[5]=l,t[6]=u):(c=t[4],l=t[5],u=t[6]);let d;t[7]===a.phase?d=t[8]:(d=Ge(a.phase),t[7]=a.phase,t[8]=d);let f;t[9]===d?f=t[10]:(f=(0,C.jsxs)(`div`,{children:[l,(0,C.jsx)(`div`,{style:u,children:d})]}),t[9]=d,t[10]=f);let p;t[11]===Symbol.for(`react.memo_cache_sentinel`)?(p=(0,C.jsxs)(`div`,{className:`graph-loading-dots`,"aria-hidden":`true`,children:[(0,C.jsx)(`span`,{className:`graph-loading-dot`}),(0,C.jsx)(`span`,{className:`graph-loading-dot`}),(0,C.jsx)(`span`,{className:`graph-loading-dot`})]}),t[11]=p):p=t[11];let m;t[12]===f?m=t[13]:(m=(0,C.jsxs)(`div`,{style:c,children:[f,p]}),t[12]=f,t[13]=m);let h;t[14]===Symbol.for(`react.memo_cache_sentinel`)?(h={color:`#c6d4e3`,fontSize:13,marginBottom:12},t[14]=h):h=t[14];let g;t[15]===a.message?g=t[16]:(g=(0,C.jsx)(`div`,{style:h,children:a.message}),t[15]=a.message,t[16]=g);let _;t[17]===Symbol.for(`react.memo_cache_sentinel`)?(_={marginBottom:14},t[17]=_):_=t[17];let v;t[18]===a.progress?v=t[19]:(v=Math.round(Math.max(6,a.progress*100)),t[18]=a.progress,t[19]=v);let y=`${v}%`,b;t[20]===y?b=t[21]:(b=(0,C.jsx)(`div`,{className:`graph-loading-bar`,style:_,children:(0,C.jsx)(`span`,{style:{width:y}})}),t[20]=y,t[21]=b);let x;t[22]===Symbol.for(`react.memo_cache_sentinel`)?(x={display:`flex`,gap:10,flexWrap:`wrap`},t[22]=x):x=t[22];let w;t[23]===a.nodesLoaded?w=t[24]:(w=a.nodesLoaded.toLocaleString(),t[23]=a.nodesLoaded,t[24]=w);let T;t[25]===a.nodesTotal?T=t[26]:(T=a.nodesTotal?` / ${a.nodesTotal.toLocaleString()}`:``,t[25]=a.nodesTotal,t[26]=T);let E;t[27]!==w||t[28]!==T?(E=(0,C.jsxs)(`span`,{style:lt,children:[w,T,` nodes`]}),t[27]=w,t[28]=T,t[29]=E):E=t[29];let D;t[30]===a.edgesLoaded?D=t[31]:(D=a.edgesLoaded.toLocaleString(),t[30]=a.edgesLoaded,t[31]=D);let O;t[32]===a.edgesTotal?O=t[33]:(O=a.edgesTotal?` / ${a.edgesTotal.toLocaleString()}`:``,t[32]=a.edgesTotal,t[33]=O);let k;t[34]!==D||t[35]!==O?(k=(0,C.jsxs)(`span`,{style:lt,children:[D,O,` edges`]}),t[34]=D,t[35]=O,t[36]=k):k=t[36];let A;t[37]!==E||t[38]!==k?(A=(0,C.jsxs)(`div`,{style:x,children:[E,k]}),t[37]=E,t[38]=k,t[39]=A):A=t[39];let j;t[40]!==m||t[41]!==g||t[42]!==b||t[43]!==A?(j=(0,C.jsxs)(`div`,{className:`graph-loading-card`,children:[m,g,b,A]}),t[40]=m,t[41]=g,t[42]=b,t[43]=A,t[44]=j):j=t[44];let M;return t[45]!==j||t[46]!==s?(M=(0,C.jsx)(`div`,{className:`graph-loading-overlay`,style:s,children:j}),t[45]=j,t[46]=s,t[47]=M):M=t[47],M}function qe(e){return Ie.reduce((t,n)=>e[n]!==void 0&&e[n]!==null?t+1:t,0)}function Je(e){let t=e.properties||{},n=String(t.content||e.id),r=y.palette.accent.path,i=!!(t.valid_from||t.valid_until),a=qe(t);return{label:n,x:Number(t.x??Math.random()*1e3-500),y:Number(t.y??Math.random()*1e3-500),nodeType:e.type||`inferred`,content:n,valid_from:t.valid_from??null,valid_until:t.valid_until??null,properties:t,size:8,baseSize:8,semanticGroup:e.type||`inferred`,color:r,baseColor:r,mutedColor:g(r,y.nodes.mutedAlpha),glowColor:g(r,.36),visualPriority:.82,labelPriority:.82,strokeColor:y.palette.background.nodeBorder,borderColor:y.palette.background.nodeBorder,borderSize:.85,nodeVariant:`inferred`,nodeShapeVariant:`inferred`,badgeKind:i?`temporal`:a>0?`provenance`:`inferred`,badgeCount:a||void 0,ringColor:y.nodes.selectedRing.color,haloColor:g(r,.42),labelVisibilityPolicy:`local`}}function Ye(e){let t=e.properties||{},n=!!t.inferred,r=f.hasDirectedEdge(e.target_id,e.source_id),i=n?y.palette.accent.path:y.palette.muted.edgeStructure;return{weight:Number(e.weight??1),edgeType:e.type||`related_to`,properties:t,size:1,baseSize:1,color:i,baseColor:i,mutedColor:y.palette.muted.edgeOverview,visualPriority:n?.95:.5,isBidirectional:r,edgeFamily:n?`path`:r?`bidirectional`:`line`,curveGroup:r?[e.source_id,e.target_id].sort().join(`::`):null,type:`line`,edgeVariant:n?`pathSignal`:r?`bidirectionalCurve`:`directional`,arrowVisibilityPolicy:n?`always`:`contextual`,relationshipStrength:n?.95:.52,isParallelPair:!1,parallelIndex:0,parallelCount:1}}function Xe(e){if(!e||!f.hasNode(e))return null;let t=f.getNodeAttributes(e);return{id:e,label:String(t.label??e),content:String(t.content??t.label??e),nodeType:String(t.nodeType??`Entity`),color:typeof t.color==`string`?t.color:void 0,valid_from:t.valid_from??null,valid_until:t.valid_until??null,properties:t.properties??{},neighborCount:f.neighbors(e).length}}function Ze(e,t){let n=[];for(let r of e)try{let e=r.renderPanel?.(t);if(!e)continue;Array.isArray(e)?n.push(...e):n.push(e)}catch(e){console.error(`[GraphPlugin:${r.id}] panel render failed`,e)}return n.sort((e,t)=>(e.order??0)-(t.order??0))}function Qe(e,t){let n=[];for(let r of e)try{let e=r.renderOverlay?.(t);if(!e)continue;Array.isArray(e)?n.push(...e):n.push(e)}catch(e){console.error(`[GraphPlugin:${r.id}] overlay render failed`,e)}return n.sort((e,t)=>(e.layer??0)===(t.layer??0)?(e.order??0)-(t.order??0):(e.layer??0)-(t.layer??0))}function $e(){let[e,t]=(0,x.useState)(``),[n,r]=(0,x.useState)(!1),[i,a]=(0,x.useState)(`focused`),[o,s]=(0,x.useState)(``),[c,l]=(0,x.useState)([]),[u,p]=(0,x.useState)(``),[h,g]=(0,x.useState)(``),[_,v]=(0,x.useState)([]),[b,S]=(0,x.useState)(``),[w,O]=(0,x.useState)(null),[k,A]=(0,x.useState)(null),[j,M]=(0,x.useState)(null),[ee,te]=(0,x.useState)(null),[ne,re]=(0,x.useState)(null),[N,P]=(0,x.useState)({"effects-panel":!1,"neighborhood-panel":!1,"temporal-panel":!1}),[F,I]=(0,x.useState)(null),[L,R]=(0,x.useState)(0),[z,ie]=(0,x.useState)(Le),[ae,B]=(0,x.useState)(null),[V,oe]=(0,x.useState)({}),H=Ue(ee,150),U=(0,x.useRef)(new Set),W=(0,x.useRef)(null),G=(0,x.useRef)(null),se=(0,x.useRef)({hoveredNodeId:null,selectedNodeId:``,focusedNodeId:``,activePath:[],viewMode:`focused`,zoomTier:`overview`,isLayoutRunning:!1}),ce=Fe(),{data:K,isLoading:le,isFetching:ue}=je({enabled:!0,onGraphReady:()=>{r(!0),re(null)},onProgress:re});(0,x.useEffect)(()=>{let e=!1;return(async()=>{try{let t=await fetch(`/api/temporal/bounds`);if(!t.ok||e)return;let n=await t.json();e||M(n)}catch{e||M(null)}})(),()=>{e=!0}},[K?.nodeCount,K?.edgeCount]),(0,x.useEffect)(()=>{if(!H||le)return;let e=!1;return(async()=>{try{let t=H.toISOString(),n=await fetch(`/api/temporal/snapshot?at=${encodeURIComponent(t)}`);if(!n.ok||e)return;let r=await n.json();if(e)return;let i=new Set(r.active_node_ids);requestAnimationFrame(()=>{e||(U.current.forEach(e=>{!i.has(e)&&f.hasNode(e)&&f.setNodeAttribute(e,`hidden`,!0)}),i.forEach(e=>{f.hasNode(e)&&f.setNodeAttribute(e,`hidden`,!1)}),U.current=i,A(r.active_node_count),W.current?.getSigma()?.refresh())})}catch(t){e||console.error(`[Temporal] Snapshot fetch failed`,t)}})(),()=>{e=!0}},[H,le]);let de=(0,x.useCallback)(e=>{t(e),O(null),l([]),p(``),e&&r(!1)},[]),q=(0,x.useCallback)(async()=>{if(!o.trim()){l([]);return}p(``);try{let e=await fetch(`/api/graph/search`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({query:o,limit:8})});if(!e.ok)throw Error(`Search failed with status ${e.status}`);l((await e.json()).results||[])}catch(e){p(e instanceof Error?e.message:`Search failed`)}},[o]),fe=(0,x.useCallback)(async()=>{if(e)try{let t=await fetch(`/api/enrich/links`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({node_id:e,top_n:6,candidate_type:h||void 0,min_score:0})});if(!t.ok)throw Error(`Link prediction failed with status ${t.status}`);v((await t.json()).predictions||[])}catch(e){console.error(`[GraphWorkspace] prediction failed`,e),v([])}},[h,e]),J=(0,x.useCallback)(async()=>{if(!(!e||!b.trim()))try{let t=await fetch(`/api/graph/node/${encodeURIComponent(e)}/path?target=${encodeURIComponent(b.trim())}&algorithm=dijkstra`);if(!t.ok)throw Error(`Path lookup failed with status ${t.status}`);let n=await t.json();if(O(n),n.path?.length){let e=n.path[n.path.length-1];f.hasNode(e)&&W.current?.focusNode(e)}}catch(e){console.error(`[GraphWorkspace] path trace failed`,e),O(null)}},[b,e]),pe=(0,x.useCallback)(async t=>{if(!e)return;let n=await fetch(`/api/provenance/report?node_id=${encodeURIComponent(e)}&format=${t===`markdown`?`markdown`:`json`}`);if(!n.ok)throw Error(`Provenance report failed with status ${n.status}`);let r=await n.blob(),i=window.URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=`${e}_provenance.${t===`markdown`?`md`:`json`}`,document.body.appendChild(a),a.click(),window.URL.revokeObjectURL(i),document.body.removeChild(a)},[e]);(0,x.useEffect)(()=>{let e=window.location.protocol===`https:`?`wss:`:`ws:`,t=new WebSocket(`${e}//${window.location.host}/ws/graph-updates`);return t.onmessage=e=>{try{let t=JSON.parse(e.data);if(t.event===`connection_ack`||t.event!==`graph_mutation`)return;let n=t.data?.event_type,r=t.data?.payload;n===`ADD_NODE`&&r?.id&&(m([{id:r.id,attributes:Je(r)}]),W.current?.getSigma()?.refresh()),n===`ADD_EDGE`&&(d([{source:r.source_id,target:r.target_id,attributes:Ye(r)}]),W.current?.getSigma()?.refresh())}catch(e){console.error(`[GraphWorkspace] websocket update failed`,e)}},()=>{t.close()}},[]);let me=(0,x.useMemo)(()=>{if(!e||!f.hasNode(e))return null;let t=f.neighbors(e).length;return i===`focused`?`${Math.min(t,16)+1} nodes in focused view`:`${t} direct neighbors highlighted`},[e,i]),Y=le||ue,he=!!K?.nodeCount,ge=w?.path??[],_e=K,ve=(0,x.useMemo)(()=>Xe(e),[e,K?.nodeCount,K?.edgeCount]),ye=(0,x.useMemo)(()=>({currentTime:ee,activeNodeCount:k,minDate:j?.min??void 0,maxDate:j?.max??void 0}),[k,ee,j?.max,j?.min]),X=(0,x.useMemo)(()=>[{id:`exploration-effects`,panelId:`effects-panel`,label:`Effects`,title:`Open exploration effects controls`,order:18,load:Be,shouldLoad:({panelState:e})=>!!e[`effects-panel`]},{id:`neighborhood-panel`,panelId:`neighborhood-panel`,label:`Neighbors`,title:`Toggle neighborhood panel`,order:30,load:Ve,shouldLoad:({panelState:e})=>!!e[`neighborhood-panel`]},{id:`temporal-overlay`,panelId:`temporal-panel`,label:`Temporal`,title:`Toggle temporal context panel`,order:40,load:He,shouldLoad:({panelState:e,temporalState:t})=>!!(e[`temporal-panel`]||t?.currentTime)}],[]),Z=(0,x.useMemo)(()=>X.map(e=>V[e.id]).filter(e=>!!e),[V,X]);(0,x.useEffect)(()=>{let e=!1;return X.forEach(t=>{V[t.id]||t.shouldLoad({panelState:N,temporalState:ye})&&t.load().then(n=>{e||oe(e=>e[t.id]?e:{...e,[t.id]:n})}).catch(e=>{console.error(`[GraphPlugin:${t.id}] lazy load failed`,e)})}),()=>{e=!0}},[V,N,X,ye]);let xe=(0,x.useCallback)((e,t)=>{ie(n=>{let r=typeof t==`function`?t(n[e]):t;return e===`diagnosticsEnabled`&&!y.effects.diagnostics.enabledInDev||n[e]===r?n:{...n,[e]:r}})},[]),Se=(0,x.useCallback)(e=>{switch(e.type){case`fitView`:W.current?.fitView();return;case`focusNode`:W.current?.focusNode(e.nodeId);return;case`selectNode`:de(e.nodeId);return;case`setViewMode`:a(e.viewMode);return;case`toggleEffect`:xe(e.effect,e=>!e);return;case`setEffect`:xe(e.effect,e.enabled);return;case`togglePanel`:P(t=>{let n=!t[e.panelId];return I(t=>n?e.panelId:t===e.panelId?null:t),{...t,[e.panelId]:n}});return;case`openPanel`:I(e.panelId),P(t=>({...t,[e.panelId]:!0}));return;case`closePanel`:P(t=>({...t,[e.panelId]:!1})),I(t=>t===e.panelId?null:t);return}},[de,xe]),Ce=(0,x.useMemo)(()=>!y.effects.diagnostics.enabledInDev||!ae?null:{interactionState:se.current,activePluginIds:Z.map(e=>e.id),openPanelIds:Object.entries(N).filter(([,e])=>e).map(([e])=>e),effectsState:z,effectAvailability:ae},[Z,z,ae,N]),Q=(0,x.useMemo)(()=>({get sigma(){return G.current?.sigma??null},get graph(){return f},get displayGraph(){return G.current?.displayGraph??f},theme:y,getInteractionState:()=>se.current,getSelectedNodeState:()=>ve,getInspectorState:()=>({selectedNodeId:e||null,ownsSelectionDetails:!0}),getGraphSummary:()=>_e,getTemporalState:()=>ye,getEffectsState:()=>z,getDiagnosticsSnapshot:()=>Ce,isPanelOpen:e=>!!N[e],dispatchAction:Se}),[Ce,z,_e,Se,N,e,ve,ye]),we=(0,x.useCallback)(e=>{G.current=e,R(e=>e+1)},[]),Te=(0,x.useCallback)(e=>{se.current=e;for(let t of Z)try{t.onStateChange(Q,e)}catch(e){console.error(`[GraphPlugin:${t.id}] state update failed`,e)}},[Z,Q]),Ee=(0,x.useCallback)(e=>{y.effects.diagnostics.enabledInDev&&B(e)},[]);(0,x.useEffect)(()=>{if(!G.current)return;let e=[];for(let t of Z)try{t.mount(Q),e.push(t)}catch(e){console.error(`[GraphPlugin:${t.id}] mount failed`,e)}return()=>{for(let t of e.reverse())try{t.unmount(Q)}catch(e){console.error(`[GraphPlugin:${t.id}] unmount failed`,e)}}},[Z,Q,L]);let De=(0,x.useMemo)(()=>X.map(e=>({id:`${e.id}-toggle`,label:e.label,title:e.title,active:Q.isPanelOpen(e.panelId),order:e.order,onClick:()=>Q.dispatchAction({type:`togglePanel`,panelId:e.panelId})})),[Q,X]),Oe=(0,x.useMemo)(()=>Ze(Z,Q),[Z,Q]),ke=(0,x.useMemo)(()=>Qe(Z,Q),[Z,Q]),Ae=(0,x.useMemo)(()=>X.filter(e=>N[e.panelId]&&!V[e.id]).map(e=>({id:e.panelId,title:e.label,placement:`bottom`,order:e.order,content:(0,C.jsxs)(`div`,{style:at,children:[`Loading `,e.label.toLowerCase(),`…`]})})),[V,N,X]),$=[...Oe,...Ae].filter(e=>e.placement===`bottom`||e.placement===`side`).sort((e,t)=>(e.order??0)-(t.order??0)).filter(e=>N[e.id]),Me=$.find(e=>e.id===F)??$[0]??null,Ne={showInspector:!!e,showPluginDock:$.length>0};(0,x.useEffect)(()=>{if(!$.length){I(null);return}(!F||!$.some(e=>e.id===F))&&I($[0].id)},[F,$]);let Pe=(0,x.useMemo)(()=>{let t=[];return e&&t.push({id:`view-mode`,items:[{id:`view-focused`,label:`Focused`,title:`Inspect the selected node in a focused local graph`,active:i===`focused`,onClick:()=>a(`focused`)},{id:`view-full`,label:`Full Graph`,title:`Return to the full graph context`,active:i===`full`,onClick:()=>a(`full`)}]}),t.push({id:`graph-actions`,items:[{id:`search-submit`,label:`Search`,title:`Search for the current query`,tone:`primary`,disabled:Y||!o.trim(),onClick:()=>void q()},{id:`fit-view`,label:`Fit View`,title:`Reset the camera to the current view`,onClick:()=>W.current?.fitView()},{id:`layout-toggle`,label:n?`Pause Layout`:`Run Layout`,title:`Toggle the layout worker`,active:n,disabled:Y,onClick:()=>r(e=>!e)},{id:`reload`,label:`Reload`,title:`Reload the graph data`,disabled:Y,onClick:ce}]}),De.length&&t.push({id:`plugin-tools`,items:De.map(e=>({id:e.id,label:e.label,title:e.title,active:e.active,onClick:e.onClick}))}),t},[n,De,ce,o,e,Y,i]);return(0,C.jsxs)(`div`,{className:`palantir-bg`,style:{position:`relative`,width:`100%`,height:`100%`,overflow:`hidden`},children:[(0,C.jsx)(`style`,{children:We}),(0,C.jsx)(`div`,{className:`palantir-grid`}),(0,C.jsx)(`div`,{className:`palantir-vignette`}),(0,C.jsxs)(`div`,{className:`explore-shell`,children:[(0,C.jsx)(`section`,{className:`explore-command-deck`,children:(0,C.jsx)(T,{tone:`subtle`,children:(0,C.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:12},children:[(0,C.jsxs)(`div`,{className:`explore-toolbar`,children:[(0,C.jsxs)(`div`,{style:{display:`flex`,gap:8,flexWrap:`wrap`,alignItems:`center`},children:[Y&&ne?(0,C.jsx)(E,{children:Ge(ne.phase)}):null,K?(0,C.jsxs)(E,{children:[K.nodeCount.toLocaleString(),` nodes · `,K.edgeCount.toLocaleString(),` edges`]}):null,k===null?null:(0,C.jsxs)(E,{tone:`success`,children:[k.toLocaleString(),` active`]}),me?(0,C.jsx)(E,{tone:`warm`,children:me}):null]}),(0,C.jsxs)(`div`,{className:`explore-toolbar-groups`,children:[(0,C.jsx)(`div`,{style:{minWidth:280,flex:`1 1 320px`},children:(0,C.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),onKeyDown:e=>{e.key===`Enter`&&q()},placeholder:`Search a node, e.g. Metformin`,style:{...et,margin:0,minHeight:38}})}),Pe.map(e=>(0,C.jsx)(`div`,{className:`explore-toolbar-group`,children:e.items.map(e=>{let t=e.tone===`primary`?tt:nt;return(0,C.jsx)(`button`,{onClick:e.onClick,title:e.title,disabled:e.disabled,style:{...t,minHeight:36,padding:`8px 12px`,background:e.active?`rgba(31, 111, 235, 0.28)`:t.background,border:e.active?`1px solid rgba(127, 208, 255, 0.35)`:t.border,color:e.active?`#e6f2ff`:t.color,boxShadow:e.active?`0 0 0 1px rgba(127, 208, 255, 0.12)`:t.boxShadow},children:e.label},e.id)})},e.id))]})]}),u?(0,C.jsx)(`div`,{style:{color:`#ff7b72`,fontSize:12},children:u}):null,c.length?(0,C.jsx)(`div`,{className:`explore-search-results hud-scrollbar`,style:ot,children:c.map(e=>(0,C.jsx)(`button`,{style:rt,onClick:()=>de(e.node.id),children:(0,C.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,gap:12},children:[(0,C.jsxs)(`div`,{style:{minWidth:0},children:[(0,C.jsx)(`div`,{style:{color:`#fff`,fontWeight:600},children:e.node.content||e.node.id}),(0,C.jsx)(`div`,{style:{color:`#8b949e`,fontSize:12},children:e.node.type})]}),(0,C.jsx)(`div`,{style:{color:`#58a6ff`,fontSize:12,whiteSpace:`nowrap`},children:e.score.toFixed(3)})]})},e.node.id))}):null]})})}),(0,C.jsxs)(`div`,{className:`explore-main-grid`,style:{gridTemplateColumns:Ne.showInspector?`minmax(0, 1fr) minmax(320px, 360px)`:`minmax(0, 1fr)`},children:[(0,C.jsx)(`div`,{className:`explore-scene-stack`,children:(0,C.jsxs)(T,{padding:`none`,className:`explore-scene-card`,children:[(0,C.jsxs)(`div`,{className:`explore-scene-shell`,children:[(0,C.jsx)(`div`,{className:`palantir-grid`}),(0,C.jsx)(`div`,{className:`palantir-vignette`}),(0,C.jsxs)(`div`,{className:`explore-scene-stage`,children:[(0,C.jsx)(be,{ref:W,onNodeClick:de,selectedNodeId:e,activePath:ge,effectsState:z,isLayoutRunning:n,viewMode:i,showFitViewButton:!1,pluginOverlays:ke.map(e=>e.element),onPluginRuntimeChange:we,onInteractionStateChange:Te,onDiagnosticsChange:Ee}),Y?(0,C.jsx)(Ke,{progress:ne,showGraphBehind:he}):null]})]}),Ne.showPluginDock?(0,C.jsx)(`div`,{className:`explore-plugin-dock`,children:(0,C.jsx)(T,{tone:`subtle`,style:{borderRadius:0,borderLeft:`none`,borderRight:`none`,borderBottom:`none`},children:(0,C.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:10},children:[(0,C.jsx)(`div`,{style:{display:`flex`,justifyContent:`space-between`,gap:12,alignItems:`center`},children:(0,C.jsxs)(`div`,{className:`explore-plugin-dock-tabs`,children:[$.map(e=>(0,C.jsx)(`button`,{className:`explore-plugin-dock-tab`,"data-active":Me?.id===e.id,onClick:()=>I(e.id),children:e.title},e.id)),Me?(0,C.jsx)(`button`,{className:`explore-plugin-dock-tab`,onClick:()=>Se({type:`closePanel`,panelId:Me.id}),children:`×`}):null]})}),Me?(0,C.jsx)(`div`,{style:it,children:Me.content}):null]})})}):null,(0,C.jsx)(`div`,{className:`explore-scene-footer`,children:(0,C.jsx)(x.Suspense,{fallback:(0,C.jsx)(`div`,{style:ct,children:`Loading timeline…`}),children:(0,C.jsx)(Re,{onTimeChange:te,minDate:j?.min??void 0,maxDate:j?.max??void 0})})})]})}),Ne.showInspector?(0,C.jsx)(`div`,{className:`explore-inspector-shell`,children:(0,C.jsx)(D,{open:Ne.showInspector,className:`explore-inspector-card`,children:(0,C.jsx)(`div`,{className:`explore-inspector-scroll hud-scrollbar`,children:(0,C.jsx)(x.Suspense,{fallback:(0,C.jsx)(`div`,{style:st,children:`Loading inspector…`}),children:(0,C.jsx)(ze,{nodeId:e,predictions:_,predictionType:h,onPredictionTypeChange:g,onRunPredictions:()=>void fe(),pathTargetId:b,onPathTargetChange:S,onTracePath:()=>void J(),pathResult:w,onDownloadProvenance:e=>void pe(e)})})})})}):null]})]})]})}var et={width:`100%`,background:`rgba(4, 10, 18, 0.5)`,border:`1px solid ${y.palette.background.shellBorder}`,color:`#edf5ff`,borderRadius:12,padding:`11px 13px`,fontSize:13,boxShadow:`inset 0 1px 0 rgba(255,255,255,0.03)`},tt={background:`linear-gradient(135deg, rgba(24, 63, 133, 0.42), rgba(35, 85, 176, 0.28))`,color:`#fff`,border:`1px solid ${y.palette.background.shellBorder}`,borderRadius:12,padding:`9px 12px`,cursor:`pointer`,fontWeight:700,fontSize:12,display:`inline-flex`,alignItems:`center`,justifyContent:`center`,boxShadow:`0 8px 22px ${y.palette.background.shellGlow}`},nt={...tt,background:`rgba(255, 255, 255, 0.03)`,border:`1px solid rgba(255, 255, 255, 0.08)`,color:`#c6d4e3`,fontWeight:600},rt={textAlign:`left`,padding:12,background:`rgba(88, 166, 255, 0.08)`,border:`1px solid rgba(88, 166, 255, 0.12)`,borderRadius:10,cursor:`pointer`},it={borderRadius:16,border:`1px solid rgba(255, 255, 255, 0.06)`,background:`rgba(255, 255, 255, 0.02)`,padding:14},at={color:`#8ea4be`,fontSize:12,padding:10},ot={display:`grid`,gridTemplateColumns:`repeat(auto-fit, minmax(220px, 1fr))`,gap:10,maxHeight:186,overflowY:`auto`},st={padding:24,color:`#8ea4be`,fontSize:12},ct={height:`90px`,display:`flex`,alignItems:`center`,padding:`0 18px`,color:`#8ea4be`,fontSize:12,borderTop:`1px solid rgba(88, 166, 255, 0.2)`,background:`rgba(1, 4, 9, 0.88)`},lt={background:`rgba(255, 255, 255, 0.04)`,color:`#cfe3ff`,padding:`6px 10px`,borderRadius:999,fontSize:12,border:`1px solid rgba(127, 208, 255, 0.12)`};export{$e as GraphWorkspace}; \ No newline at end of file diff --git a/semantica/static/assets/ImportExportWorkspace-CYQpATgz.js b/semantica/static/assets/ImportExportWorkspace-BU8nK4nT.js similarity index 98% rename from semantica/static/assets/ImportExportWorkspace-CYQpATgz.js rename to semantica/static/assets/ImportExportWorkspace-BU8nK4nT.js index dce76f29..a3f1462d 100644 --- a/semantica/static/assets/ImportExportWorkspace-CYQpATgz.js +++ b/semantica/static/assets/ImportExportWorkspace-BU8nK4nT.js @@ -1,4 +1,4 @@ -import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{T as t,a as n}from"./query-vendor-Cbp9LWgA.js";import{a as r,i,n as a,r as o,t as s}from"./es-BveUcJeu.js";import{n as c}from"./index-BVBOQ8an.js";var l=c(`circle-alert`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]]),u=c(`download`,[[`path`,{d:`M12 15V3`,key:`m9g1x1`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}],[`path`,{d:`m7 10 5 5 5-5`,key:`brsn70`}]]),d=c(`file-braces`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1`,key:`1oajmo`}],[`path`,{d:`M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1`,key:`mpwhp6`}]]),f=e(t(),1),p=n(),m=` +import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{T as t,a as n}from"./query-vendor-Cbp9LWgA.js";import{a as r,i,n as a,r as o,t as s}from"./es-CS4MDIhr.js";import{n as c}from"./index-DDOaKEbH.js";var l=c(`circle-alert`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]]),u=c(`download`,[[`path`,{d:`M12 15V3`,key:`m9g1x1`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}],[`path`,{d:`m7 10 5 5 5-5`,key:`brsn70`}]]),d=c(`file-braces`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1`,key:`1oajmo`}],[`path`,{d:`M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1`,key:`mpwhp6`}]]),f=e(t(),1),p=n(),m=` .glass-panel { background: linear-gradient(135deg, rgba(13,17,23,0.75), rgba(22,27,34,0.6)); backdrop-filter: blur(16px) saturate(1.2); diff --git a/semantica/static/assets/LineageDiagram-DQTOL97h.js b/semantica/static/assets/LineageDiagram-BcIhRlOg.js similarity index 99% rename from semantica/static/assets/LineageDiagram-DQTOL97h.js rename to semantica/static/assets/LineageDiagram-BcIhRlOg.js index a930d330..7c813955 100644 --- a/semantica/static/assets/LineageDiagram-DQTOL97h.js +++ b/semantica/static/assets/LineageDiagram-BcIhRlOg.js @@ -1,4 +1,4 @@ -import{i as e,t}from"./rolldown-runtime-B1FJdls4.js";import{T as n,a as r}from"./query-vendor-Cbp9LWgA.js";import{i}from"./index-BVBOQ8an.js";import{t as a}from"./shim-CnYKr5zR.js";var o=e(n(),1),s=r();function c(e){if(typeof e==`string`||typeof e==`number`)return``+e;let t=``;if(Array.isArray(e))for(let n=0,r;n{}};function u(){for(var e=0,t=arguments.length,n={},r;e=0&&(n=e.slice(r+1),e=e.slice(0,r)),e&&!t.hasOwnProperty(e))throw Error(`unknown type: `+e);return{type:e,name:n}})}d.prototype=u.prototype={constructor:d,on:function(e,t){var n=this._,r=f(e+``,n),i,a=-1,o=r.length;if(arguments.length<2){for(;++a0)for(var n=Array(i),r=0,i,a;r=0&&(t=e.slice(0,n))!==`xmlns`&&(e=e.slice(n+1)),h.hasOwnProperty(t)?{space:h[t],local:e}:e}function _(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===`http://www.w3.org/1999/xhtml`&&t.documentElement.namespaceURI===`http://www.w3.org/1999/xhtml`?t.createElement(e):t.createElementNS(n,e)}}function v(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function y(e){var t=g(e);return(t.local?v:_)(t)}function b(){}function x(e){return e==null?b:function(){return this.querySelector(e)}}function S(e){typeof e!=`function`&&(e=x(e));for(var t=this._groups,n=t.length,r=Array(n),i=0;i=v&&(v=_+1);!(b=g[v])&&++v=0;)(o=r[i])&&(a&&o.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(o,a),a=o);return this}function oe(e){e||=se;function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}for(var n=this._groups,r=n.length,i=Array(r),a=0;at?1:e>=t?0:NaN}function ce(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function le(){return Array.from(this)}function ue(){for(var e=this._groups,t=0,n=e.length;t1?this.each((t==null?Se:typeof t==`function`?we:Ce)(e,t,n??``)):Ee(this.node(),e)}function Ee(e,t){return e.style.getPropertyValue(t)||xe(e).getComputedStyle(e,null).getPropertyValue(t)}function De(e){return function(){delete this[e]}}function Oe(e,t){return function(){this[e]=t}}function ke(e,t){return function(){var n=t.apply(this,arguments);n==null?delete this[e]:this[e]=n}}function Ae(e,t){return arguments.length>1?this.each((t==null?De:typeof t==`function`?ke:Oe)(e,t)):this.node()[e]}function je(e){return e.trim().split(/^|\s+/)}function Me(e){return e.classList||new Ne(e)}function Ne(e){this._node=e,this._names=je(e.getAttribute(`class`)||``)}Ne.prototype={add:function(e){this._names.indexOf(e)<0&&(this._names.push(e),this._node.setAttribute(`class`,this._names.join(` `)))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute(`class`,this._names.join(` `)))},contains:function(e){return this._names.indexOf(e)>=0}};function Pe(e,t){for(var n=Me(e),r=-1,i=t.length;++r=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}function lt(e){return function(){var t=this.__on;if(t){for(var n=0,r=-1,i=t.length,a;n()=>e;function Ot(e,{sourceEvent:t,subject:n,target:r,identifier:i,active:a,x:o,y:s,dx:c,dy:l,dispatch:u}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:n,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},identifier:{value:i,enumerable:!0,configurable:!0},active:{value:a,enumerable:!0,configurable:!0},x:{value:o,enumerable:!0,configurable:!0},y:{value:s,enumerable:!0,configurable:!0},dx:{value:c,enumerable:!0,configurable:!0},dy:{value:l,enumerable:!0,configurable:!0},_:{value:u}})}Ot.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function kt(e){return!e.ctrlKey&&!e.button}function At(){return this.parentNode}function jt(e,t){return t??{x:e.x,y:e.y}}function Mt(){return navigator.maxTouchPoints||`ontouchstart`in this}function Nt(){var e=kt,t=At,n=jt,r=Mt,i={},a=u(`start`,`drag`,`end`),o=0,s,c,l,d,f=0;function p(e){e.on(`mousedown.drag`,m).filter(r).on(`touchstart.drag`,_).on(`touchmove.drag`,v,xt).on(`touchend.drag touchcancel.drag`,y).style(`touch-action`,`none`).style(`-webkit-tap-highlight-color`,`rgba(0,0,0,0)`)}function m(n,r){if(!(d||!e.call(this,n,r))){var i=b(this,t.call(this,n,r),n,r,`mouse`);i&&(q(n.view).on(`mousemove.drag`,h,St).on(`mouseup.drag`,g,St),Tt(n.view),Ct(n),l=!1,s=n.clientX,c=n.clientY,i(`start`,n))}}function h(e){if(wt(e),!l){var t=e.clientX-s,n=e.clientY-c;l=t*t+n*n>f}i.mouse(`drag`,e)}function g(e){q(e.view).on(`mousemove.drag mouseup.drag`,null),Et(e.view,l),wt(e),i.mouse(`end`,e)}function _(n,r){if(e.call(this,n,r)){var i=n.changedTouches,a=t.call(this,n,r),o=i.length,s,c;for(s=0;s>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?nn(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?nn(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=Ut.exec(e))?new Y(t[1],t[2],t[3],1):(t=Wt.exec(e))?new Y(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=Gt.exec(e))?nn(t[1],t[2],t[3],t[4]):(t=Kt.exec(e))?nn(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=qt.exec(e))?fn(t[1],t[2]/100,t[3]/100,1):(t=Jt.exec(e))?fn(t[1],t[2]/100,t[3]/100,t[4]):Yt.hasOwnProperty(e)?tn(Yt[e]):e===`transparent`?new Y(NaN,NaN,NaN,0):null}function tn(e){return new Y(e>>16&255,e>>8&255,e&255,1)}function nn(e,t,n,r){return r<=0&&(e=t=n=NaN),new Y(e,t,n,r)}function rn(e){return e instanceof It||(e=en(e)),e?(e=e.rgb(),new Y(e.r,e.g,e.b,e.opacity)):new Y}function an(e,t,n,r){return arguments.length===1?rn(e):new Y(e,t,n,r??1)}function Y(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}Pt(Y,an,Ft(It,{brighter(e){return e=e==null?Rt:Rt**+e,new Y(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Lt:Lt**+e,new Y(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new Y(un(this.r),un(this.g),un(this.b),ln(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:on,formatHex:on,formatHex8:sn,formatRgb:cn,toString:cn}));function on(){return`#${dn(this.r)}${dn(this.g)}${dn(this.b)}`}function sn(){return`#${dn(this.r)}${dn(this.g)}${dn(this.b)}${dn((isNaN(this.opacity)?1:this.opacity)*255)}`}function cn(){let e=ln(this.opacity);return`${e===1?`rgb(`:`rgba(`}${un(this.r)}, ${un(this.g)}, ${un(this.b)}${e===1?`)`:`, ${e})`}`}function ln(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function un(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function dn(e){return e=un(e),(e<16?`0`:``)+e.toString(16)}function fn(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new hn(e,t,n,r)}function pn(e){if(e instanceof hn)return new hn(e.h,e.s,e.l,e.opacity);if(e instanceof It||(e=en(e)),!e)return new hn;if(e instanceof hn)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,i=Math.min(t,n,r),a=Math.max(t,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(o=t===a?(n-r)/s+(n0&&c<1?0:o,new hn(o,s,c,e.opacity)}function mn(e,t,n,r){return arguments.length===1?pn(e):new hn(e,t,n,r??1)}function hn(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}Pt(hn,mn,Ft(It,{brighter(e){return e=e==null?Rt:Rt**+e,new hn(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Lt:Lt**+e,new hn(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,i=2*n-r;return new Y(vn(e>=240?e-240:e+120,i,r),vn(e,i,r),vn(e<120?e+240:e-120,i,r),this.opacity)},clamp(){return new hn(gn(this.h),_n(this.s),_n(this.l),ln(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let e=ln(this.opacity);return`${e===1?`hsl(`:`hsla(`}${gn(this.h)}, ${_n(this.s)*100}%, ${_n(this.l)*100}%${e===1?`)`:`, ${e})`}`}}));function gn(e){return e=(e||0)%360,e<0?e+360:e}function _n(e){return Math.max(0,Math.min(1,e||0))}function vn(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}var yn=e=>()=>e;function bn(e,t){return function(n){return e+n*t}}function xn(e,t,n){return e**=+n,t=t**+n-e,n=1/n,function(r){return(e+r*t)**+n}}function Sn(e){return(e=+e)==1?Cn:function(t,n){return n-t?xn(t,n,e):yn(isNaN(t)?n:t)}}function Cn(e,t){var n=t-e;return n?bn(e,n):yn(isNaN(e)?t:e)}var wn=(function e(t){var n=Sn(t);function r(e,t){var r=n((e=an(e)).r,(t=an(t)).r),i=n(e.g,t.g),a=n(e.b,t.b),o=Cn(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=i(t),e.b=a(t),e.opacity=o(t),e+``}}return r.gamma=e,r})(1);function Tn(e,t){t||=[];var n=e?Math.min(t.length,e.length):0,r=t.slice(),i;return function(a){for(i=0;in&&(a=t.slice(n,a),s[o]?s[o]+=a:s[++o]=a),(r=r[0])===(i=i[0])?s[o]?s[o]+=i:s[++o]=i:(s[++o]=null,c.push({i:o,x:kn(r,i)})),n=Mn.lastIndex;return n180?t+=360:t-e>180&&(e+=360),a.push({i:n.push(i(n)+`rotate(`,null,r)-2,x:kn(e,t)}))}function s(e,t,n,a){e===t?t&&n.push(i(n)+`skewX(`+t+r):a.push({i:n.push(i(n)+`skewX(`,null,r)-2,x:kn(e,t)})}function c(e,t,n,r,a,o){if(e!==n||t!==r){var s=a.push(i(a)+`scale(`,null,`,`,null,`)`);o.push({i:s-4,x:kn(e,n)},{i:s-2,x:kn(t,r)})}else (n!==1||r!==1)&&a.push(i(a)+`scale(`+n+`,`+r+`)`)}return function(t,n){var r=[],i=[];return t=e(t),n=e(n),a(t.translateX,t.translateY,n.translateX,n.translateY,r,i),o(t.rotate,n.rotate,r,i),s(t.skewX,n.skewX,r,i),c(t.scaleX,t.scaleY,n.scaleX,n.scaleY,r,i),t=n=null,function(e){for(var t=-1,n=i.length,a;++t=0&&e._call.call(void 0,t),e=e._next;--Zn}function pr(){ir=(rr=or.now())+ar,Zn=Qn=0;try{fr()}finally{Zn=0,hr(),ir=0}}function mr(){var e=or.now(),t=e-rr;t>er&&(ar-=t,rr=e)}function hr(){for(var e,t=tr,n,r=1/0;t;)t._call?(r>t._time&&(r=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:tr=n);nr=e,gr(r)}function gr(e){Zn||(Qn&&=clearTimeout(Qn),e-ir>24?(e<1/0&&(Qn=setTimeout(pr,e-or.now()-ar)),$n&&=clearInterval($n)):($n||=(rr=or.now(),setInterval(mr,er)),Zn=1,sr(pr)))}function _r(e,t,n){var r=new ur;return t=t==null?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}var vr=u(`start`,`end`,`cancel`,`interrupt`),yr=[];function br(e,t,n,r,i,a){var o=e.__transition;if(!o)e.__transition={};else if(n in o)return;wr(e,n,{name:t,index:r,group:i,on:vr,tween:yr,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:0})}function xr(e,t){var n=Cr(e,t);if(n.state>0)throw Error(`too late; already scheduled`);return n}function Sr(e,t){var n=Cr(e,t);if(n.state>3)throw Error(`too late; already running`);return n}function Cr(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw Error(`transition not found`);return n}function wr(e,t,n){var r=e.__transition,i;r[t]=n,n.timer=dr(a,0,n.time);function a(e){n.state=1,n.timer.restart(o,n.delay,n.time),n.delay<=e&&o(e-n.delay)}function o(a){var l,u,d,f;if(n.state!==1)return c();for(l in r)if(f=r[l],f.name===n.name){if(f.state===3)return _r(o);f.state===4?(f.state=6,f.timer.stop(),f.on.call(`interrupt`,e,e.__data__,f.index,f.group),delete r[l]):+l2&&r.state<5,r.state=6,r.timer.stop(),r.on.call(i?`interrupt`:`cancel`,e,e.__data__,r.index,r.group),delete n[o]}a&&delete e.__transition}}function Er(e){return this.each(function(){Tr(this,e)})}function Dr(e,t){var n,r;return function(){var i=Sr(this,e),a=i.tween;if(a!==n){r=n=a;for(var o=0,s=r.length;o=0&&(e=e.slice(0,t)),!e||e===`start`})}function ri(e,t,n){var r,i,a=ni(t)?xr:Sr;return function(){var o=a(this,e),s=o.on;s!==r&&(i=(r=s).copy()).on(t,n),o.on=i}}function ii(e,t){var n=this._id;return arguments.length<2?Cr(this.node(),n).on.on(e):this.each(ri(n,e,t))}function ai(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}function oi(){return this.on(`end.remove`,ai(this._id))}function si(e){var t=this._name,n=this._id;typeof e!=`function`&&(e=x(e));for(var r=this._groups,i=r.length,a=Array(i),o=0;o()=>e;function Ri(e,{sourceEvent:t,target:n,transform:r,dispatch:i}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},transform:{value:r,enumerable:!0,configurable:!0},_:{value:i}})}function zi(e,t,n){this.k=e,this.x=t,this.y=n}zi.prototype={constructor:zi,scale:function(e){return e===1?this:new zi(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new zi(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return`translate(`+this.x+`,`+this.y+`) scale(`+this.k+`)`}};var Bi=new zi(1,0,0);Vi.prototype=zi.prototype;function Vi(e){for(;!e.__zoom;)if(!(e=e.parentNode))return Bi;return e.__zoom}function Hi(e){e.stopImmediatePropagation()}function Ui(e){e.preventDefault(),e.stopImmediatePropagation()}function Wi(e){return(!e.ctrlKey||e.type===`wheel`)&&!e.button}function Gi(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute(`viewBox`)?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function Ki(){return this.__zoom||Bi}function qi(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function Ji(){return navigator.maxTouchPoints||`ontouchstart`in this}function Yi(e,t,n){var r=e.invertX(t[0][0])-n[0][0],i=e.invertX(t[1][0])-n[1][0],a=e.invertY(t[0][1])-n[0][1],o=e.invertY(t[1][1])-n[1][1];return e.translate(i>r?(r+i)/2:Math.min(0,r)||Math.max(0,i),o>a?(a+o)/2:Math.min(0,a)||Math.max(0,o))}function Xi(){var e=Wi,t=Gi,n=Yi,r=qi,i=Ji,a=[0,1/0],o=[[-1/0,-1/0],[1/0,1/0]],s=250,c=Xn,l=u(`start`,`zoom`,`end`),d,f,p,m=500,h=150,g=0,_=10;function v(e){e.property(`__zoom`,Ki).on(`wheel.zoom`,T,{passive:!1}).on(`mousedown.zoom`,E).on(`dblclick.zoom`,D).filter(i).on(`touchstart.zoom`,O).on(`touchmove.zoom`,k).on(`touchend.zoom touchcancel.zoom`,A).style(`-webkit-tap-highlight-color`,`rgba(0,0,0,0)`)}v.transform=function(e,t,n,r){var i=e.selection?e.selection():e;i.property(`__zoom`,Ki),e===i?i.interrupt().each(function(){C(this,arguments).event(r).start().zoom(null,typeof t==`function`?t.apply(this,arguments):t).end()}):S(e,t,n,r)},v.scaleBy=function(e,t,n,r){v.scaleTo(e,function(){return this.__zoom.k*(typeof t==`function`?t.apply(this,arguments):t)},n,r)},v.scaleTo=function(e,r,i,a){v.transform(e,function(){var e=t.apply(this,arguments),a=this.__zoom,s=i==null?x(e):typeof i==`function`?i.apply(this,arguments):i,c=a.invert(s),l=typeof r==`function`?r.apply(this,arguments):r;return n(b(y(a,l),s,c),e,o)},i,a)},v.translateBy=function(e,r,i,a){v.transform(e,function(){return n(this.__zoom.translate(typeof r==`function`?r.apply(this,arguments):r,typeof i==`function`?i.apply(this,arguments):i),t.apply(this,arguments),o)},null,a)},v.translateTo=function(e,r,i,a,s){v.transform(e,function(){var e=t.apply(this,arguments),s=this.__zoom,c=a==null?x(e):typeof a==`function`?a.apply(this,arguments):a;return n(Bi.translate(c[0],c[1]).scale(s.k).translate(typeof r==`function`?-r.apply(this,arguments):-r,typeof i==`function`?-i.apply(this,arguments):-i),e,o)},a,s)};function y(e,t){return t=Math.max(a[0],Math.min(a[1],t)),t===e.k?e:new zi(t,e.x,e.y)}function b(e,t,n){var r=t[0]-n[0]*e.k,i=t[1]-n[1]*e.k;return r===e.x&&i===e.y?e:new zi(e.k,r,i)}function x(e){return[(+e[0][0]+ +e[1][0])/2,(+e[0][1]+ +e[1][1])/2]}function S(e,n,r,i){e.on(`start.zoom`,function(){C(this,arguments).event(i).start()}).on(`interrupt.zoom end.zoom`,function(){C(this,arguments).event(i).end()}).tween(`zoom`,function(){var e=this,a=arguments,o=C(e,a).event(i),s=t.apply(e,a),l=r==null?x(s):typeof r==`function`?r.apply(e,a):r,u=Math.max(s[1][0]-s[0][0],s[1][1]-s[0][1]),d=e.__zoom,f=typeof n==`function`?n.apply(e,a):n,p=c(d.invert(l).concat(u/d.k),f.invert(l).concat(u/f.k));return function(e){if(e===1)e=f;else{var t=p(e),n=u/t[2];e=new zi(n,l[0]-t[0]*n,l[1]-t[1]*n)}o.zoom(null,e)}})}function C(e,t,n){return!n&&e.__zooming||new w(e,t)}function w(e,n){this.that=e,this.args=n,this.active=0,this.sourceEvent=null,this.extent=t.apply(e,n),this.taps=0}w.prototype={event:function(e){return e&&(this.sourceEvent=e),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit(`start`)),this},zoom:function(e,t){return this.mouse&&e!==`mouse`&&(this.mouse[1]=t.invert(this.mouse[0])),this.touch0&&e!==`touch`&&(this.touch0[1]=t.invert(this.touch0[0])),this.touch1&&e!==`touch`&&(this.touch1[1]=t.invert(this.touch1[0])),this.that.__zoom=t,this.emit(`zoom`),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit(`end`)),this},emit:function(e){var t=q(this.that).datum();l.call(e,this.that,new Ri(e,{sourceEvent:this.sourceEvent,target:v,type:e,transform:this.that.__zoom,dispatch:l}),t)}};function T(t,...i){if(!e.apply(this,arguments))return;var s=C(this,i).event(t),c=this.__zoom,l=Math.max(a[0],Math.min(a[1],c.k*2**r.apply(this,arguments))),u=J(t);if(s.wheel)(s.mouse[0][0]!==u[0]||s.mouse[0][1]!==u[1])&&(s.mouse[1]=c.invert(s.mouse[0]=u)),clearTimeout(s.wheel);else if(c.k===l)return;else s.mouse=[u,c.invert(u)],Tr(this),s.start();Ui(t),s.wheel=setTimeout(d,h),s.zoom(`mouse`,n(b(y(c,l),s.mouse[0],s.mouse[1]),s.extent,o));function d(){s.wheel=null,s.end()}}function E(t,...r){if(p||!e.apply(this,arguments))return;var i=t.currentTarget,a=C(this,r,!0).event(t),s=q(t.view).on(`mousemove.zoom`,d,!0).on(`mouseup.zoom`,f,!0),c=J(t,i),l=t.clientX,u=t.clientY;Tt(t.view),Hi(t),a.mouse=[c,this.__zoom.invert(c)],Tr(this),a.start();function d(e){if(Ui(e),!a.moved){var t=e.clientX-l,r=e.clientY-u;a.moved=t*t+r*r>g}a.event(e).zoom(`mouse`,n(b(a.that.__zoom,a.mouse[0]=J(e,i),a.mouse[1]),a.extent,o))}function f(e){s.on(`mousemove.zoom mouseup.zoom`,null),Et(e.view,a.moved),Ui(e),a.event(e).end()}}function D(r,...i){if(e.apply(this,arguments)){var a=this.__zoom,c=J(r.changedTouches?r.changedTouches[0]:r,this),l=a.invert(c),u=a.k*(r.shiftKey?.5:2),d=n(b(y(a,u),c,l),t.apply(this,i),o);Ui(r),s>0?q(this).transition().duration(s).call(S,d,c,r):q(this).call(v.transform,d,c,r)}}function O(t,...n){if(e.apply(this,arguments)){var r=t.touches,i=r.length,a=C(this,n,t.changedTouches.length===i).event(t),o,s,c,l;for(Hi(t),s=0;s`[React Flow]: Seems like you have not used zustand provider as an ancestor. Help: https://reactflow.dev/error#001`,error002:()=>`It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.`,error003:e=>`Node type "${e}" not found. Using fallback type "default".`,error004:()=>`The React Flow parent container needs a width and a height to render the graph.`,error005:()=>`Only child nodes can use a parent extent.`,error006:()=>`Can't create edge. An edge needs a source and a target.`,error007:e=>`The old edge with id=${e} does not exist.`,error009:e=>`Marker type "${e}" doesn't exist.`,error008:(e,{id:t,sourceHandle:n,targetHandle:r})=>`Couldn't create edge for ${e} handle id: "${e===`source`?n:r}", edge id: ${t}.`,error010:()=>`Handle: No node id found. Make sure to only use a Handle inside a custom Node.`,error011:e=>`Edge type "${e}" not found. Using fallback type "default".`,error012:e=>`Node with id "${e}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(e=`react`)=>`It seems that you haven't loaded the styles. Please import '@xyflow/${e}/dist/style.css' or base.css to make sure everything is working properly.`,error014:()=>`useNodeConnections: No node ID found. Call useNodeConnections inside a custom Node or provide a node ID.`,error015:()=>`It seems that you are trying to drag a node that is not initialized. Please use onNodesChange as explained in the docs.`},Qi=[[-1/0,-1/0],[1/0,1/0]],$i=[`Enter`,` `,`Escape`],ea={"node.a11yDescription.default":`Press enter or space to select a node. Press delete to remove it and escape to cancel.`,"node.a11yDescription.keyboardDisabled":`Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.`,"node.a11yDescription.ariaLiveMessage":({direction:e,x:t,y:n})=>`Moved selected node ${e}. New position, x: ${t}, y: ${n}`,"edge.a11yDescription.default":`Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.`,"controls.ariaLabel":`Control Panel`,"controls.zoomIn.ariaLabel":`Zoom In`,"controls.zoomOut.ariaLabel":`Zoom Out`,"controls.fitView.ariaLabel":`Fit View`,"controls.interactive.ariaLabel":`Toggle Interactivity`,"minimap.ariaLabel":`Mini Map`,"handle.ariaLabel":`Handle`},ta;(function(e){e.Strict=`strict`,e.Loose=`loose`})(ta||={});var na;(function(e){e.Free=`free`,e.Vertical=`vertical`,e.Horizontal=`horizontal`})(na||={});var ra;(function(e){e.Partial=`partial`,e.Full=`full`})(ra||={});var ia={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null},aa;(function(e){e.Bezier=`default`,e.Straight=`straight`,e.Step=`step`,e.SmoothStep=`smoothstep`,e.SimpleBezier=`simplebezier`})(aa||={});var oa;(function(e){e.Arrow=`arrow`,e.ArrowClosed=`arrowclosed`})(oa||={});var X;(function(e){e.Left=`left`,e.Top=`top`,e.Right=`right`,e.Bottom=`bottom`})(X||={});var sa={[X.Left]:X.Right,[X.Right]:X.Left,[X.Top]:X.Bottom,[X.Bottom]:X.Top};function ca(e){return e===null?null:e?`valid`:`invalid`}var la=e=>`id`in e&&`source`in e&&`target`in e,ua=e=>`id`in e&&`position`in e&&!(`source`in e)&&!(`target`in e),da=e=>`id`in e&&`internals`in e&&!(`source`in e)&&!(`target`in e),fa=(e,t=[0,0])=>{let{width:n,height:r}=Ga(e),i=e.origin??t,a=n*i[0],o=r*i[1];return{x:e.position.x-a,y:e.position.y-o}},pa=(e,t={nodeOrigin:[0,0]})=>e.length===0?{x:0,y:0,width:0,height:0}:Oa(e.reduce((e,n)=>{let r=typeof n==`string`,i=!t.nodeLookup&&!r?n:void 0;return t.nodeLookup&&(i=r?t.nodeLookup.get(n):da(n)?n:t.nodeLookup.get(n.id)),Ea(e,i?Aa(i,t.nodeOrigin):{x:0,y:0,x2:0,y2:0})},{x:1/0,y:1/0,x2:-1/0,y2:-1/0})),ma=(e,t={})=>{let n={x:1/0,y:1/0,x2:-1/0,y2:-1/0},r=!1;return e.forEach(e=>{(t.filter===void 0||t.filter(e))&&(n=Ea(n,Aa(e)),r=!0)}),r?Oa(n):{x:0,y:0,width:0,height:0}},ha=(e,t,[n,r,i]=[0,0,1],a=!1,o=!1)=>{let s={...La(t,[n,r,i]),width:t.width/i,height:t.height/i},c=[];for(let t of e.values()){let{measured:e,selectable:n=!0,hidden:r=!1}=t;if(o&&!n||r)continue;let i=e.width??t.width??t.initialWidth??null,l=e.height??t.height??t.initialHeight??null,u=Ma(s,ka(t)),d=(i??0)*(l??0),f=a&&u>0;(!t.internals.handleBounds||f||u>=d||t.dragging)&&c.push(t)}return c},ga=(e,t)=>{let n=new Set;return e.forEach(e=>{n.add(e.id)}),t.filter(e=>n.has(e.source)||n.has(e.target))};function _a(e,t){let n=new Map,r=t?.nodes?new Set(t.nodes.map(e=>e.id)):null;return e.forEach(e=>{e.measured.width&&e.measured.height&&(t?.includeHiddenNodes||!e.hidden)&&(!r||r.has(e.id))&&n.set(e.id,e)}),n}async function va({nodes:e,width:t,height:n,panZoom:r,minZoom:i,maxZoom:a},o){if(e.size===0)return Promise.resolve(!0);let s=Ha(ma(_a(e,o)),t,n,o?.minZoom??i,o?.maxZoom??a,o?.padding??.1);return await r.setViewport(s,{duration:o?.duration,ease:o?.ease,interpolate:o?.interpolate}),Promise.resolve(!0)}function ya({nodeId:e,nextPosition:t,nodeLookup:n,nodeOrigin:r=[0,0],nodeExtent:i,onError:a}){let o=n.get(e),s=o.parentId?n.get(o.parentId):void 0,{x:c,y:l}=s?s.internals.positionAbsolute:{x:0,y:0},u=o.origin??r,d=o.extent||i;if(o.extent===`parent`&&!o.expandParent)if(!s)a?.(`005`,Zi.error005());else{let e=s.measured.width,t=s.measured.height;e&&t&&(d=[[c,l],[c+e,l+t]])}else s&&Wa(o.extent)&&(d=[[o.extent[0][0]+c,o.extent[0][1]+l],[o.extent[1][0]+c,o.extent[1][1]+l]]);let f=Wa(d)?Sa(t,d,o.measured):t;return(o.measured.width===void 0||o.measured.height===void 0)&&a?.(`015`,Zi.error015()),{position:{x:f.x-c+(o.measured.width??0)*u[0],y:f.y-l+(o.measured.height??0)*u[1]},positionAbsolute:f}}async function ba({nodesToRemove:e=[],edgesToRemove:t=[],nodes:n,edges:r,onBeforeDelete:i}){let a=new Set(e.map(e=>e.id)),o=[];for(let e of n){if(e.deletable===!1)continue;let t=a.has(e.id),n=!t&&e.parentId&&o.find(t=>t.id===e.parentId);(t||n)&&o.push(e)}let s=new Set(t.map(e=>e.id)),c=r.filter(e=>e.deletable!==!1),l=ga(o,c);for(let e of c)s.has(e.id)&&!l.find(t=>t.id===e.id)&&l.push(e);if(!i)return{edges:l,nodes:o};let u=await i({nodes:o,edges:l});return typeof u==`boolean`?u?{edges:l,nodes:o}:{edges:[],nodes:[]}:u}var xa=(e,t=0,n=1)=>Math.min(Math.max(e,t),n),Sa=(e={x:0,y:0},t,n)=>({x:xa(e.x,t[0][0],t[1][0]-(n?.width??0)),y:xa(e.y,t[0][1],t[1][1]-(n?.height??0))});function Ca(e,t,n){let{width:r,height:i}=Ga(n),{x:a,y:o}=n.internals.positionAbsolute;return Sa(e,[[a,o],[a+r,o+i]],t)}var wa=(e,t,n)=>en?-xa(Math.abs(e-n),1,t)/t:0,Ta=(e,t,n=15,r=40)=>[wa(e.x,r,t.width-r)*n,wa(e.y,r,t.height-r)*n],Ea=(e,t)=>({x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x2,t.x2),y2:Math.max(e.y2,t.y2)}),Da=({x:e,y:t,width:n,height:r})=>({x:e,y:t,x2:e+n,y2:t+r}),Oa=({x:e,y:t,x2:n,y2:r})=>({x:e,y:t,width:n-e,height:r-t}),ka=(e,t=[0,0])=>{let{x:n,y:r}=da(e)?e.internals.positionAbsolute:fa(e,t);return{x:n,y:r,width:e.measured?.width??e.width??e.initialWidth??0,height:e.measured?.height??e.height??e.initialHeight??0}},Aa=(e,t=[0,0])=>{let{x:n,y:r}=da(e)?e.internals.positionAbsolute:fa(e,t);return{x:n,y:r,x2:n+(e.measured?.width??e.width??e.initialWidth??0),y2:r+(e.measured?.height??e.height??e.initialHeight??0)}},ja=(e,t)=>Oa(Ea(Da(e),Da(t))),Ma=(e,t)=>{let n=Math.max(0,Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x)),r=Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y));return Math.ceil(n*r)},Na=e=>Pa(e.width)&&Pa(e.height)&&Pa(e.x)&&Pa(e.y),Pa=e=>!isNaN(e)&&isFinite(e),Fa=(e,t)=>{},Ia=(e,t=[1,1])=>({x:t[0]*Math.round(e.x/t[0]),y:t[1]*Math.round(e.y/t[1])}),La=({x:e,y:t},[n,r,i],a=!1,o=[1,1])=>{let s={x:(e-n)/i,y:(t-r)/i};return a?Ia(s,o):s},Ra=({x:e,y:t},[n,r,i])=>({x:e*i+n,y:t*i+r});function za(e,t){if(typeof e==`number`)return Math.floor((t-t/(1+e))*.5);if(typeof e==`string`&&e.endsWith(`px`)){let t=parseFloat(e);if(!Number.isNaN(t))return Math.floor(t)}if(typeof e==`string`&&e.endsWith(`%`)){let n=parseFloat(e);if(!Number.isNaN(n))return Math.floor(t*n*.01)}return console.error(`[React Flow] The padding value "${e}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function Ba(e,t,n){if(typeof e==`string`||typeof e==`number`){let r=za(e,n),i=za(e,t);return{top:r,right:i,bottom:r,left:i,x:i*2,y:r*2}}if(typeof e==`object`){let r=za(e.top??e.y??0,n),i=za(e.bottom??e.y??0,n),a=za(e.left??e.x??0,t),o=za(e.right??e.x??0,t);return{top:r,right:o,bottom:i,left:a,x:a+o,y:r+i}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function Va(e,t,n,r,i,a){let{x:o,y:s}=Ra(e,[t,n,r]),{x:c,y:l}=Ra({x:e.x+e.width,y:e.y+e.height},[t,n,r]),u=i-c,d=a-l;return{left:Math.floor(o),top:Math.floor(s),right:Math.floor(u),bottom:Math.floor(d)}}var Ha=(e,t,n,r,i,a)=>{let o=Ba(a,t,n),s=(t-o.x)/e.width,c=(n-o.y)/e.height,l=xa(Math.min(s,c),r,i),u=e.x+e.width/2,d=e.y+e.height/2,f=t/2-u*l,p=n/2-d*l,m=Va(e,f,p,l,t,n),h={left:Math.min(m.left-o.left,0),top:Math.min(m.top-o.top,0),right:Math.min(m.right-o.right,0),bottom:Math.min(m.bottom-o.bottom,0)};return{x:f-h.left+h.right,y:p-h.top+h.bottom,zoom:l}},Ua=()=>typeof navigator<`u`&&navigator?.userAgent?.indexOf(`Mac`)>=0;function Wa(e){return e!=null&&e!==`parent`}function Ga(e){return{width:e.measured?.width??e.width??e.initialWidth??0,height:e.measured?.height??e.height??e.initialHeight??0}}function Ka(e){return(e.measured?.width??e.width??e.initialWidth)!==void 0&&(e.measured?.height??e.height??e.initialHeight)!==void 0}function qa(e,t={width:0,height:0},n,r,i){let a={...e},o=r.get(n);if(o){let e=o.origin||i;a.x+=o.internals.positionAbsolute.x-(t.width??0)*e[0],a.y+=o.internals.positionAbsolute.y-(t.height??0)*e[1]}return a}function Ja(e,t){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}function Ya(){let e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}function Xa(e){return{...ea,...e||{}}}function Za(e,{snapGrid:t=[0,0],snapToGrid:n=!1,transform:r,containerBounds:i}){let{x:a,y:o}=ro(e),s=La({x:a-(i?.left??0),y:o-(i?.top??0)},r),{x:c,y:l}=n?Ia(s,t):s;return{xSnapped:c,ySnapped:l,...s}}var Qa=e=>({width:e.offsetWidth,height:e.offsetHeight}),$a=e=>e?.getRootNode?.()||window?.document,eo=[`INPUT`,`SELECT`,`TEXTAREA`];function to(e){let t=e.composedPath?.()?.[0]||e.target;return t?.nodeType===1?eo.includes(t.nodeName)||t.hasAttribute(`contenteditable`)||!!t.closest(`.nokey`):!1}var no=e=>`clientX`in e,ro=(e,t)=>{let n=no(e),r=n?e.clientX:e.touches?.[0].clientX,i=n?e.clientY:e.touches?.[0].clientY;return{x:r-(t?.left??0),y:i-(t?.top??0)}},io=(e,t,n,r,i)=>{let a=t.querySelectorAll(`.${e}`);return!a||!a.length?null:Array.from(a).map(t=>{let a=t.getBoundingClientRect();return{id:t.getAttribute(`data-handleid`),type:e,nodeId:i,position:t.getAttribute(`data-handlepos`),x:(a.left-n.left)/r,y:(a.top-n.top)/r,...Qa(t)}})};function ao({sourceX:e,sourceY:t,targetX:n,targetY:r,sourceControlX:i,sourceControlY:a,targetControlX:o,targetControlY:s}){let c=e*.125+i*.375+o*.375+n*.125,l=t*.125+a*.375+s*.375+r*.125;return[c,l,Math.abs(c-e),Math.abs(l-t)]}function oo(e,t){return e>=0?.5*e:t*25*Math.sqrt(-e)}function so({pos:e,x1:t,y1:n,x2:r,y2:i,c:a}){switch(e){case X.Left:return[t-oo(t-r,a),n];case X.Right:return[t+oo(r-t,a),n];case X.Top:return[t,n-oo(n-i,a)];case X.Bottom:return[t,n+oo(i-n,a)]}}function co({sourceX:e,sourceY:t,sourcePosition:n=X.Bottom,targetX:r,targetY:i,targetPosition:a=X.Top,curvature:o=.25}){let[s,c]=so({pos:n,x1:e,y1:t,x2:r,y2:i,c:o}),[l,u]=so({pos:a,x1:r,y1:i,x2:e,y2:t,c:o}),[d,f,p,m]=ao({sourceX:e,sourceY:t,targetX:r,targetY:i,sourceControlX:s,sourceControlY:c,targetControlX:l,targetControlY:u});return[`M${e},${t} C${s},${c} ${l},${u} ${r},${i}`,d,f,p,m]}function lo({sourceX:e,sourceY:t,targetX:n,targetY:r}){let i=Math.abs(n-e)/2,a=n0}var po=({source:e,sourceHandle:t,target:n,targetHandle:r})=>`xy-edge__${e}${t||``}-${n}${r||``}`,mo=(e,t)=>t.some(t=>t.source===e.source&&t.target===e.target&&(t.sourceHandle===e.sourceHandle||!t.sourceHandle&&!e.sourceHandle)&&(t.targetHandle===e.targetHandle||!t.targetHandle&&!e.targetHandle)),ho=(e,t,n={})=>{if(!e.source||!e.target)return Zi.error006(),t;let r=n.getEdgeId||po,i;return i=la(e)?{...e}:{...e,id:r(e)},mo(i,t)?t:(i.sourceHandle===null&&delete i.sourceHandle,i.targetHandle===null&&delete i.targetHandle,t.concat(i))};function go({sourceX:e,sourceY:t,targetX:n,targetY:r}){let[i,a,o,s]=lo({sourceX:e,sourceY:t,targetX:n,targetY:r});return[`M ${e},${t}L ${n},${r}`,i,a,o,s]}var _o={[X.Left]:{x:-1,y:0},[X.Right]:{x:1,y:0},[X.Top]:{x:0,y:-1},[X.Bottom]:{x:0,y:1}},vo=({source:e,sourcePosition:t=X.Bottom,target:n})=>t===X.Left||t===X.Right?e.xMath.sqrt((t.x-e.x)**2+(t.y-e.y)**2);function bo({source:e,sourcePosition:t=X.Bottom,target:n,targetPosition:r=X.Top,center:i,offset:a,stepPosition:o}){let s=_o[t],c=_o[r],l={x:e.x+s.x*a,y:e.y+s.y*a},u={x:n.x+c.x*a,y:n.y+c.y*a},d=vo({source:l,sourcePosition:t,target:u}),f=d.x===0?`y`:`x`,p=d[f],m=[],h,g,_={x:0,y:0},v={x:0,y:0},[,,y,b]=lo({sourceX:e.x,sourceY:e.y,targetX:n.x,targetY:n.y});if(s[f]*c[f]===-1){f===`x`?(h=i.x??l.x+(u.x-l.x)*o,g=i.y??(l.y+u.y)/2):(h=i.x??(l.x+u.x)/2,g=i.y??l.y+(u.y-l.y)*o);let e=[{x:h,y:l.y},{x:h,y:u.y}],t=[{x:l.x,y:g},{x:u.x,y:g}];m=s[f]===p?f===`x`?e:t:f===`x`?t:e}else{let i=[{x:l.x,y:u.y}],o=[{x:u.x,y:l.y}];if(m=f===`x`?s.x===p?o:i:s.y===p?i:o,t===r){let t=Math.abs(e[f]-n[f]);if(t<=a){let r=Math.min(a-1,a-t);s[f]===p?_[f]=(l[f]>e[f]?-1:1)*r:v[f]=(u[f]>n[f]?-1:1)*r}}if(t!==r){let e=f===`x`?`y`:`x`,t=s[f]===c[e],n=l[e]>u[e],r=l[e]=Math.max(Math.abs(d.y-m[0].y),Math.abs(y.y-m[0].y))?(h=(d.x+y.x)/2,g=m[0].y):(h=m[0].x,g=(d.y+y.y)/2)}let x={x:l.x+_.x,y:l.y+_.y},S={x:u.x+v.x,y:u.y+v.y};return[[e,...x.x!==m[0].x||x.y!==m[0].y?[x]:[],...m,...S.x!==m[m.length-1].x||S.y!==m[m.length-1].y?[S]:[],n],h,g,y,b]}function xo(e,t,n,r){let i=Math.min(yo(e,t)/2,yo(t,n)/2,r),{x:a,y:o}=t;if(e.x===a&&a===n.x||e.y===o&&o===n.y)return`L${a} ${o}`;if(e.y===o){let t=e.xe.id===t):e[0])||null}function Oo(e,t){return e?typeof e==`string`?e:`${t?`${t}__`:``}${Object.keys(e).sort().map(t=>`${t}=${e[t]}`).join(`&`)}`:``}function ko(e,{id:t,defaultColor:n,defaultMarkerStart:r,defaultMarkerEnd:i}){let a=new Set;return e.reduce((e,o)=>([o.markerStart||r,o.markerEnd||i].forEach(r=>{if(r&&typeof r==`object`){let i=Oo(r,t);a.has(i)||(e.push({id:i,color:r.color||n,...r}),a.add(i))}}),e),[]).sort((e,t)=>e.id.localeCompare(t.id))}var Ao=1e3,jo=10,Mo={nodeOrigin:[0,0],nodeExtent:Qi,elevateNodesOnSelect:!0,zIndexMode:`basic`,defaults:{}},No={...Mo,checkEquality:!0};function Po(e,t){let n={...e};for(let e in t)t[e]!==void 0&&(n[e]=t[e]);return n}function Fo(e,t,n){let r=Po(Mo,n);for(let n of e.values())if(n.parentId)Bo(n,e,t,r);else{let e=Sa(fa(n,r.nodeOrigin),Wa(n.extent)?n.extent:r.nodeExtent,Ga(n));n.internals.positionAbsolute=e}}function Io(e,t){if(!e.handles)return e.measured?t?.internals.handleBounds:void 0;let n=[],r=[];for(let t of e.handles){let i={id:t.id,width:t.width??1,height:t.height??1,nodeId:e.id,x:t.x,y:t.y,position:t.position,type:t.type};t.type===`source`?n.push(i):t.type===`target`&&r.push(i)}return{source:n,target:r}}function Lo(e){return e===`manual`}function Ro(e,t,n,r={}){let i=Po(No,r),a={i:0},o=new Map(t),s=i?.elevateNodesOnSelect&&!Lo(i.zIndexMode)?Ao:0,c=e.length>0,l=!1;t.clear(),n.clear();for(let u of e){let e=o.get(u.id);if(i.checkEquality&&u===e?.internals.userNode)t.set(u.id,e);else{let n=Sa(fa(u,i.nodeOrigin),Wa(u.extent)?u.extent:i.nodeExtent,Ga(u));e={...i.defaults,...u,measured:{width:u.measured?.width,height:u.measured?.height},internals:{positionAbsolute:n,handleBounds:Io(u,e),z:Vo(u,s,i.zIndexMode),userNode:u}},t.set(u.id,e)}(e.measured===void 0||e.measured.width===void 0||e.measured.height===void 0)&&!e.hidden&&(c=!1),u.parentId&&Bo(e,t,n,r,a),l||=u.selected??!1}return{nodesInitialized:c,hasSelectedNodes:l}}function zo(e,t){if(!e.parentId)return;let n=t.get(e.parentId);n?n.set(e.id,e):t.set(e.parentId,new Map([[e.id,e]]))}function Bo(e,t,n,r,i){let{elevateNodesOnSelect:a,nodeOrigin:o,nodeExtent:s,zIndexMode:c}=Po(Mo,r),l=e.parentId,u=t.get(l);if(!u){console.warn(`Parent node ${l} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}zo(e,n),i&&!u.parentId&&u.internals.rootParentIndex===void 0&&c===`auto`&&(u.internals.rootParentIndex=++i.i,u.internals.z=u.internals.z+i.i*jo),i&&u.internals.rootParentIndex!==void 0&&(i.i=u.internals.rootParentIndex);let{x:d,y:f,z:p}=Ho(e,u,o,s,a&&!Lo(c)?Ao:0,c),{positionAbsolute:m}=e.internals,h=d!==m.x||f!==m.y;(h||p!==e.internals.z)&&t.set(e.id,{...e,internals:{...e.internals,positionAbsolute:h?{x:d,y:f}:m,z:p}})}function Vo(e,t,n){let r=Pa(e.zIndex)?e.zIndex:0;return Lo(n)?r:r+(e.selected?t:0)}function Ho(e,t,n,r,i,a){let{x:o,y:s}=t.internals.positionAbsolute,c=Ga(e),l=fa(e,n),u=Wa(e.extent)?Sa(l,e.extent,c):l,d=Sa({x:o+u.x,y:s+u.y},r,c);e.extent===`parent`&&(d=Ca(d,c,t));let f=Vo(e,i,a),p=t.internals.z??0;return{x:d.x,y:d.y,z:p>=f?p+1:f}}function Uo(e,t,n,r=[0,0]){let i=[],a=new Map;for(let n of e){let e=t.get(n.parentId);if(!e)continue;let r=ja(a.get(n.parentId)?.expandedRect??ka(e),n.rect);a.set(n.parentId,{expandedRect:r,parent:e})}return a.size>0&&a.forEach(({expandedRect:t,parent:a},o)=>{let s=a.internals.positionAbsolute,c=Ga(a),l=a.origin??r,u=t.x0||d>0||m||h)&&(i.push({id:o,type:`position`,position:{x:a.position.x-u+m,y:a.position.y-d+h}}),n.get(o)?.forEach(t=>{e.some(e=>e.id===t.id)||i.push({id:t.id,type:`position`,position:{x:t.position.x+u,y:t.position.y+d}})})),(c.width0){let e=Uo(f,t,n,i);l.push(...e)}return{changes:l,updatedInternals:c}}async function Go({delta:e,panZoom:t,transform:n,translateExtent:r,width:i,height:a}){if(!t||!e.x&&!e.y)return Promise.resolve(!1);let o=await t.setViewportConstrained({x:n[0]+e.x,y:n[1]+e.y,zoom:n[2]},[[0,0],[i,a]],r),s=!!o&&(o.x!==n[0]||o.y!==n[1]||o.k!==n[2]);return Promise.resolve(s)}function Ko(e,t,n,r,i,a){let o=i,s=r.get(o)||new Map;r.set(o,s.set(n,t)),o=`${i}-${e}`;let c=r.get(o)||new Map;if(r.set(o,c.set(n,t)),a){o=`${i}-${e}-${a}`;let s=r.get(o)||new Map;r.set(o,s.set(n,t))}}function qo(e,t,n){e.clear(),t.clear();for(let r of n){let{source:n,target:i,sourceHandle:a=null,targetHandle:o=null}=r,s={edgeId:r.id,source:n,target:i,sourceHandle:a,targetHandle:o},c=`${n}-${a}--${i}-${o}`;Ko(`source`,s,`${i}-${o}--${n}-${a}`,e,n,a),Ko(`target`,s,c,e,i,o),t.set(r.id,r)}}function Jo(e,t){if(!e.parentId)return!1;let n=t.get(e.parentId);return n?n.selected?!0:Jo(n,t):!1}function Yo(e,t,n){let r=e;do{if(r?.matches?.(t))return!0;if(r===n)return!1;r=r?.parentElement}while(r);return!1}function Xo(e,t,n,r){let i=new Map;for(let[a,o]of e)if((o.selected||o.id===r)&&(!o.parentId||!Jo(o,e))&&(o.draggable||t&&o.draggable===void 0)){let t=e.get(a);t&&i.set(a,{id:a,position:t.position||{x:0,y:0},distance:{x:n.x-t.internals.positionAbsolute.x,y:n.y-t.internals.positionAbsolute.y},extent:t.extent,parentId:t.parentId,origin:t.origin,expandParent:t.expandParent,internals:{positionAbsolute:t.internals.positionAbsolute||{x:0,y:0}},measured:{width:t.measured.width??0,height:t.measured.height??0}})}return i}function Zo({nodeId:e,dragItems:t,nodeLookup:n,dragging:r=!0}){let i=[];for(let[e,a]of t){let t=n.get(e)?.internals.userNode;t&&i.push({...t,position:a.position,dragging:r})}if(!e)return[i[0],i];let a=n.get(e)?.internals.userNode;return[a?{...a,position:t.get(e)?.position||a.position,dragging:r}:i[0],i]}function Qo({dragItems:e,snapGrid:t,x:n,y:r}){let i=e.values().next().value;if(!i)return null;let a={x:n-i.distance.x,y:r-i.distance.y},o=Ia(a,t);return{x:o.x-a.x,y:o.y-a.y}}function $o({onNodeMouseDown:e,getStoreItems:t,onDragStart:n,onDrag:r,onDragStop:i}){let a={x:null,y:null},o=0,s=new Map,c=!1,l={x:0,y:0},u=null,d=!1,f=null,p=!1,m=!1,h=null;function g({noDragClassName:g,handleSelector:_,domNode:v,isSelectable:y,nodeId:b,nodeClickDistance:x=0}){f=q(v);function S({x:e,y:n}){let{nodeLookup:i,nodeExtent:o,snapGrid:c,snapToGrid:l,nodeOrigin:u,onNodeDrag:d,onSelectionDrag:f,onError:p,updateNodePositions:g}=t();a={x:e,y:n};let _=!1,v=s.size>1,y=v&&o?Da(ma(s)):null,x=v&&l?Qo({dragItems:s,snapGrid:c,x:e,y:n}):null;for(let[t,r]of s){if(!i.has(t))continue;let a={x:e-r.distance.x,y:n-r.distance.y};l&&(a=x?{x:Math.round(a.x+x.x),y:Math.round(a.y+x.y)}:Ia(a,c));let s=null;if(v&&o&&!r.extent&&y){let{positionAbsolute:e}=r.internals,t=e.x-y.x+o[0][0],n=e.x+r.measured.width-y.x2+o[1][0],i=e.y-y.y+o[0][1],a=e.y+r.measured.height-y.y2+o[1][1];s=[[t,i],[n,a]]}let{position:d,positionAbsolute:f}=ya({nodeId:t,nextPosition:a,nodeLookup:i,nodeExtent:s||o,nodeOrigin:u,onError:p});_=_||r.position.x!==d.x||r.position.y!==d.y,r.position=d,r.internals.positionAbsolute=f}if(m||=_,_&&(g(s,!0),h&&(r||d||!b&&f))){let[e,t]=Zo({nodeId:b,dragItems:s,nodeLookup:i});r?.(h,s,e,t),d?.(h,e,t),b||f?.(h,t)}}async function C(){if(!u)return;let{transform:e,panBy:n,autoPanSpeed:r,autoPanOnNodeDrag:i}=t();if(!i){c=!1,cancelAnimationFrame(o);return}let[s,d]=Ta(l,u,r);(s!==0||d!==0)&&(a.x=(a.x??0)-s/e[2],a.y=(a.y??0)-d/e[2],await n({x:s,y:d})&&S(a)),o=requestAnimationFrame(C)}function w(r){let{nodeLookup:i,multiSelectionActive:o,nodesDraggable:c,transform:l,snapGrid:f,snapToGrid:p,selectNodesOnDrag:m,onNodeDragStart:h,onSelectionDragStart:g,unselectNodesAndEdges:_}=t();d=!0,(!m||!y)&&!o&&b&&(i.get(b)?.selected||_()),y&&m&&b&&e?.(b);let v=Za(r.sourceEvent,{transform:l,snapGrid:f,snapToGrid:p,containerBounds:u});if(a=v,s=Xo(i,c,v,b),s.size>0&&(n||h||!b&&g)){let[e,t]=Zo({nodeId:b,dragItems:s,nodeLookup:i});n?.(r.sourceEvent,s,e,t),h?.(r.sourceEvent,e,t),b||g?.(r.sourceEvent,t)}}let T=Nt().clickDistance(x).on(`start`,e=>{let{domNode:n,nodeDragThreshold:r,transform:i,snapGrid:o,snapToGrid:s}=t();u=n?.getBoundingClientRect()||null,p=!1,m=!1,h=e.sourceEvent,r===0&&w(e),a=Za(e.sourceEvent,{transform:i,snapGrid:o,snapToGrid:s,containerBounds:u}),l=ro(e.sourceEvent,u)}).on(`drag`,e=>{let{autoPanOnNodeDrag:n,transform:r,snapGrid:i,snapToGrid:o,nodeDragThreshold:f,nodeLookup:m}=t(),g=Za(e.sourceEvent,{transform:r,snapGrid:i,snapToGrid:o,containerBounds:u});if(h=e.sourceEvent,(e.sourceEvent.type===`touchmove`&&e.sourceEvent.touches.length>1||b&&!m.has(b))&&(p=!0),!p){if(!c&&n&&d&&(c=!0,C()),!d){let t=ro(e.sourceEvent,u),n=t.x-l.x,r=t.y-l.y;Math.sqrt(n*n+r*r)>f&&w(e)}(a.x!==g.xSnapped||a.y!==g.ySnapped)&&s&&d&&(l=ro(e.sourceEvent,u),S(g))}}).on(`end`,e=>{if(!(!d||p)&&(c=!1,d=!1,cancelAnimationFrame(o),s.size>0)){let{nodeLookup:n,updateNodePositions:r,onNodeDragStop:a,onSelectionDragStop:o}=t();if(m&&=(r(s,!1),!1),i||a||!b&&o){let[t,r]=Zo({nodeId:b,dragItems:s,nodeLookup:n,dragging:!1});i?.(e.sourceEvent,s,t,r),a?.(e.sourceEvent,t,r),b||o?.(e.sourceEvent,r)}}}).filter(e=>{let t=e.target;return!e.button&&(!g||!Yo(t,`.${g}`,v))&&(!_||Yo(t,_,v))});f.call(T)}function _(){f?.on(`.drag`,null)}return{update:g,destroy:_}}function es(e,t,n){let r=[],i={x:e.x-n,y:e.y-n,width:n*2,height:n*2};for(let e of t.values())Ma(i,ka(e))>0&&r.push(e);return r}var ts=250;function ns(e,t,n,r){let i=[],a=1/0,o=es(e,n,t+ts);for(let n of o){let o=[...n.internals.handleBounds?.source??[],...n.internals.handleBounds?.target??[]];for(let s of o){if(r.nodeId===s.nodeId&&r.type===s.type&&r.id===s.id)continue;let{x:o,y:c}=Eo(n,s,s.position,!0),l=Math.sqrt((o-e.x)**2+(c-e.y)**2);l>t||(l1){let e=r.type===`source`?`target`:`source`;return i.find(t=>t.type===e)??i[0]}return i[0]}function rs(e,t,n,r,i,a=!1){let o=r.get(e);if(!o)return null;let s=i===`strict`?o.internals.handleBounds?.[t]:[...o.internals.handleBounds?.source??[],...o.internals.handleBounds?.target??[]],c=(n?s?.find(e=>e.id===n):s?.[0])??null;return c&&a?{...c,...Eo(o,c,c.position,!0)}:c}function is(e,t){return e||(t?.classList.contains(`target`)?`target`:t?.classList.contains(`source`)?`source`:null)}function as(e,t){let n=null;return t?n=!0:e&&!t&&(n=!1),n}var os=()=>!0;function ss(e,{connectionMode:t,connectionRadius:n,handleId:r,nodeId:i,edgeUpdaterType:a,isTarget:o,domNode:s,nodeLookup:c,lib:l,autoPanOnConnect:u,flowId:d,panBy:f,cancelConnection:p,onConnectStart:m,onConnect:h,onConnectEnd:g,isValidConnection:_=os,onReconnectEnd:v,updateConnection:y,getTransform:b,getFromHandle:x,autoPanSpeed:S,dragThreshold:C=1,handleDomNode:w}){let T=$a(e.target),E=0,D,{x:O,y:k}=ro(e),A=is(a,w),j=s?.getBoundingClientRect(),M=!1;if(!j||!A)return;let N=rs(i,A,r,c,t);if(!N)return;let P=ro(e,j),F=!1,I=null,L=!1,R=null;function z(){if(!u||!j)return;let[e,t]=Ta(P,j,S);f({x:e,y:t}),E=requestAnimationFrame(z)}let B={...N,nodeId:i,type:A,position:N.position},V=c.get(i),H={inProgress:!0,isValid:null,from:Eo(V,B,X.Left,!0),fromHandle:B,fromPosition:B.position,fromNode:V,to:P,toHandle:null,toPosition:sa[B.position],toNode:null,pointer:P};function U(){M=!0,y(H),m?.(e,{nodeId:i,handleId:r,handleType:A})}C===0&&U();function W(e){if(!M){let{x:t,y:n}=ro(e),r=t-O,i=n-k;if(!(r*r+i*i>C*C))return;U()}if(!x()||!B){G(e);return}let a=b();P=ro(e,j),D=ns(La(P,a,!1,[1,1]),n,c,B),F||=(z(),!0);let s=cs(e,{handle:D,connectionMode:t,fromNodeId:i,fromHandleId:r,fromType:o?`target`:`source`,isValidConnection:_,doc:T,lib:l,flowId:d,nodeLookup:c});R=s.handleDomNode,I=s.connection,L=as(!!D,s.isValid);let u=c.get(i),f=u?Eo(u,B,X.Left,!0):H.from,p={...H,from:f,isValid:L,to:s.toHandle&&L?Ra({x:s.toHandle.x,y:s.toHandle.y},a):P,toHandle:s.toHandle,toPosition:L&&s.toHandle?s.toHandle.position:sa[B.position],toNode:s.toHandle?c.get(s.toHandle.nodeId):null,pointer:P};y(p),H=p}function G(e){if(!(`touches`in e&&e.touches.length>0)){if(M){(D||R)&&I&&L&&h?.(I);let{inProgress:t,...n}=H,r={...n,toPosition:H.toHandle?H.toPosition:null};g?.(e,r),a&&v?.(e,r)}p(),cancelAnimationFrame(E),F=!1,L=!1,I=null,R=null,T.removeEventListener(`mousemove`,W),T.removeEventListener(`mouseup`,G),T.removeEventListener(`touchmove`,W),T.removeEventListener(`touchend`,G)}}T.addEventListener(`mousemove`,W),T.addEventListener(`mouseup`,G),T.addEventListener(`touchmove`,W),T.addEventListener(`touchend`,G)}function cs(e,{handle:t,connectionMode:n,fromNodeId:r,fromHandleId:i,fromType:a,doc:o,lib:s,flowId:c,isValidConnection:l=os,nodeLookup:u}){let d=a===`target`,f=t?o.querySelector(`.${s}-flow__handle[data-id="${c}-${t?.nodeId}-${t?.id}-${t?.type}"]`):null,{x:p,y:m}=ro(e),h=o.elementFromPoint(p,m),g=h?.classList.contains(`${s}-flow__handle`)?h:f,_={handleDomNode:g,isValid:!1,connection:null,toHandle:null};if(g){let e=is(void 0,g),t=g.getAttribute(`data-nodeid`),a=g.getAttribute(`data-handleid`),o=g.classList.contains(`connectable`),s=g.classList.contains(`connectableend`);if(!t||!e)return _;let c={source:d?t:r,sourceHandle:d?a:i,target:d?r:t,targetHandle:d?i:a};_.connection=c,_.isValid=o&&s&&(n===ta.Strict?d&&e===`source`||!d&&e===`target`:t!==r||a!==i)&&l(c),_.toHandle=rs(t,e,a,u,n,!0)}return _}var ls={onPointerDown:ss,isValid:cs};function us({domNode:e,panZoom:t,getTransform:n,getViewScale:r}){let i=q(e);function a({translateExtent:e,width:a,height:o,zoomStep:s=1,pannable:c=!0,zoomable:l=!0,inversePan:u=!1}){let d=e=>{if(e.sourceEvent.type!==`wheel`||!t)return;let r=n(),i=e.sourceEvent.ctrlKey&&Ua()?10:1,a=-e.sourceEvent.deltaY*(e.sourceEvent.deltaMode===1?.05:e.sourceEvent.deltaMode?1:.002)*s,o=r[2]*2**(a*i);t.scaleTo(o)},f=[0,0],p=Xi().on(`start`,e=>{(e.sourceEvent.type===`mousedown`||e.sourceEvent.type===`touchstart`)&&(f=[e.sourceEvent.clientX??e.sourceEvent.touches[0].clientX,e.sourceEvent.clientY??e.sourceEvent.touches[0].clientY])}).on(`zoom`,c?i=>{let s=n();if(i.sourceEvent.type!==`mousemove`&&i.sourceEvent.type!==`touchmove`||!t)return;let c=[i.sourceEvent.clientX??i.sourceEvent.touches[0].clientX,i.sourceEvent.clientY??i.sourceEvent.touches[0].clientY],l=[c[0]-f[0],c[1]-f[1]];f=c;let d=r()*Math.max(s[2],Math.log(s[2]))*(u?-1:1),p={x:s[0]-l[0]*d,y:s[1]-l[1]*d},m=[[0,0],[a,o]];t.setViewportConstrained({x:p.x,y:p.y,zoom:s[2]},m,e)}:null).on(`zoom.wheel`,l?d:null);i.call(p,{})}function o(){i.on(`zoom`,null)}return{update:a,destroy:o,pointer:J}}var ds=e=>({x:e.x,y:e.y,zoom:e.k}),fs=({x:e,y:t,zoom:n})=>Bi.translate(e,t).scale(n),ps=(e,t)=>e.target.closest(`.${t}`),ms=(e,t)=>t===2&&Array.isArray(e)&&e.includes(2),hs=e=>((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2,gs=(e,t=0,n=hs,r=()=>{})=>{let i=typeof t==`number`&&t>0;return i||r(),i?e.transition().duration(t).ease(n).on(`end`,r):e},_s=e=>{let t=e.ctrlKey&&Ua()?10:1;return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*t};function vs({zoomPanValues:e,noWheelClassName:t,d3Selection:n,d3Zoom:r,panOnScrollMode:i,panOnScrollSpeed:a,zoomOnPinch:o,onPanZoomStart:s,onPanZoom:c,onPanZoomEnd:l}){return u=>{if(ps(u,t))return u.ctrlKey&&u.preventDefault(),!1;u.preventDefault(),u.stopImmediatePropagation();let d=n.property(`__zoom`).k||1;if(u.ctrlKey&&o){let e=J(u),t=d*2**_s(u);r.scaleTo(n,t,e,u);return}let f=u.deltaMode===1?20:1,p=i===na.Vertical?0:u.deltaX*f,m=i===na.Horizontal?0:u.deltaY*f;!Ua()&&u.shiftKey&&i!==na.Vertical&&(p=u.deltaY*f,m=0),r.translateBy(n,-(p/d)*a,-(m/d)*a,{internal:!0});let h=ds(n.property(`__zoom`));clearTimeout(e.panScrollTimeout),e.isPanScrolling?(c?.(u,h),e.panScrollTimeout=setTimeout(()=>{l?.(u,h),e.isPanScrolling=!1},150)):(e.isPanScrolling=!0,s?.(u,h))}}function ys({noWheelClassName:e,preventScrolling:t,d3ZoomHandler:n}){return function(r,i){let a=r.type===`wheel`,o=!t&&a&&!r.ctrlKey,s=ps(r,e);if(r.ctrlKey&&a&&s&&r.preventDefault(),o||s)return null;r.preventDefault(),n.call(this,r,i)}}function bs({zoomPanValues:e,onDraggingChange:t,onPanZoomStart:n}){return r=>{if(r.sourceEvent?.internal)return;let i=ds(r.transform);e.mouseButton=r.sourceEvent?.button||0,e.isZoomingOrPanning=!0,e.prevViewport=i,r.sourceEvent?.type===`mousedown`&&t(!0),n&&n?.(r.sourceEvent,i)}}function xs({zoomPanValues:e,panOnDrag:t,onPaneContextMenu:n,onTransformChange:r,onPanZoom:i}){return a=>{e.usedRightMouseButton=!!(n&&ms(t,e.mouseButton??0)),a.sourceEvent?.sync||r([a.transform.x,a.transform.y,a.transform.k]),i&&!a.sourceEvent?.internal&&i?.(a.sourceEvent,ds(a.transform))}}function Ss({zoomPanValues:e,panOnDrag:t,panOnScroll:n,onDraggingChange:r,onPanZoomEnd:i,onPaneContextMenu:a}){return o=>{if(!o.sourceEvent?.internal&&(e.isZoomingOrPanning=!1,a&&ms(t,e.mouseButton??0)&&!e.usedRightMouseButton&&o.sourceEvent&&a(o.sourceEvent),e.usedRightMouseButton=!1,r(!1),i)){let t=ds(o.transform);e.prevViewport=t,clearTimeout(e.timerId),e.timerId=setTimeout(()=>{i?.(o.sourceEvent,t)},n?150:0)}}}function Cs({zoomActivationKeyPressed:e,zoomOnScroll:t,zoomOnPinch:n,panOnDrag:r,panOnScroll:i,zoomOnDoubleClick:a,userSelectionActive:o,noWheelClassName:s,noPanClassName:c,lib:l,connectionInProgress:u}){return d=>{let f=e||t,p=n&&d.ctrlKey,m=d.type===`wheel`;if(d.button===1&&d.type===`mousedown`&&(ps(d,`${l}-flow__node`)||ps(d,`${l}-flow__edge`)))return!0;if(!r&&!f&&!i&&!a&&!n||o||u&&!m||ps(d,s)&&m||ps(d,c)&&(!m||i&&m&&!e)||!n&&d.ctrlKey&&m)return!1;if(!n&&d.type===`touchstart`&&d.touches?.length>1)return d.preventDefault(),!1;if(!f&&!i&&!p&&m||!r&&(d.type===`mousedown`||d.type===`touchstart`)||Array.isArray(r)&&!r.includes(d.button)&&d.type===`mousedown`)return!1;let h=Array.isArray(r)&&r.includes(d.button)||!d.button||d.button<=1;return(!d.ctrlKey||m)&&h}}function ws({domNode:e,minZoom:t,maxZoom:n,translateExtent:r,viewport:i,onPanZoom:a,onPanZoomStart:o,onPanZoomEnd:s,onDraggingChange:c}){let l={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{x:0,y:0,zoom:0},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},u=e.getBoundingClientRect(),d=Xi().scaleExtent([t,n]).translateExtent(r),f=q(e).call(d);v({x:i.x,y:i.y,zoom:xa(i.zoom,t,n)},[[0,0],[u.width,u.height]],r);let p=f.on(`wheel.zoom`),m=f.on(`dblclick.zoom`);d.wheelDelta(_s);function h(e,t){return f?new Promise(n=>{d?.interpolate(t?.interpolate===`linear`?In:Xn).transform(gs(f,t?.duration,t?.ease,()=>n(!0)),e)}):Promise.resolve(!1)}function g({noWheelClassName:e,noPanClassName:t,onPaneContextMenu:n,userSelectionActive:r,panOnScroll:i,panOnDrag:u,panOnScrollMode:h,panOnScrollSpeed:g,preventScrolling:v,zoomOnPinch:y,zoomOnScroll:b,zoomOnDoubleClick:x,zoomActivationKeyPressed:S,lib:C,onTransformChange:w,connectionInProgress:T,paneClickDistance:E,selectionOnDrag:D}){r&&!l.isZoomingOrPanning&&_();let O=i&&!S&&!r;d.clickDistance(D?1/0:!Pa(E)||E<0?0:E);let k=O?vs({zoomPanValues:l,noWheelClassName:e,d3Selection:f,d3Zoom:d,panOnScrollMode:h,panOnScrollSpeed:g,zoomOnPinch:y,onPanZoomStart:o,onPanZoom:a,onPanZoomEnd:s}):ys({noWheelClassName:e,preventScrolling:v,d3ZoomHandler:p});if(f.on(`wheel.zoom`,k,{passive:!1}),!r){let e=bs({zoomPanValues:l,onDraggingChange:c,onPanZoomStart:o});d.on(`start`,e);let t=xs({zoomPanValues:l,panOnDrag:u,onPaneContextMenu:!!n,onPanZoom:a,onTransformChange:w});d.on(`zoom`,t);let r=Ss({zoomPanValues:l,panOnDrag:u,panOnScroll:i,onPaneContextMenu:n,onPanZoomEnd:s,onDraggingChange:c});d.on(`end`,r)}let A=Cs({zoomActivationKeyPressed:S,panOnDrag:u,zoomOnScroll:b,panOnScroll:i,zoomOnDoubleClick:x,zoomOnPinch:y,userSelectionActive:r,noPanClassName:t,noWheelClassName:e,lib:C,connectionInProgress:T});d.filter(A),x?f.on(`dblclick.zoom`,m):f.on(`dblclick.zoom`,null)}function _(){d.on(`zoom`,null)}async function v(e,t,n){let r=fs(e),i=d?.constrain()(r,t,n);return i&&await h(i),new Promise(e=>e(i))}async function y(e,t){let n=fs(e);return await h(n,t),new Promise(e=>e(n))}function b(e){if(f){let t=fs(e),n=f.property(`__zoom`);(n.k!==e.zoom||n.x!==e.x||n.y!==e.y)&&d?.transform(f,t,null,{sync:!0})}}function x(){let e=f?Vi(f.node()):{x:0,y:0,k:1};return{x:e.x,y:e.y,zoom:e.k}}function S(e,t){return f?new Promise(n=>{d?.interpolate(t?.interpolate===`linear`?In:Xn).scaleTo(gs(f,t?.duration,t?.ease,()=>n(!0)),e)}):Promise.resolve(!1)}function C(e,t){return f?new Promise(n=>{d?.interpolate(t?.interpolate===`linear`?In:Xn).scaleBy(gs(f,t?.duration,t?.ease,()=>n(!0)),e)}):Promise.resolve(!1)}function w(e){d?.scaleExtent(e)}function T(e){d?.translateExtent(e)}function E(e){let t=!Pa(e)||e<0?0:e;d?.clickDistance(t)}return{update:g,destroy:_,setViewport:y,setViewportConstrained:v,getViewport:x,scaleTo:S,scaleBy:C,setScaleExtent:w,setTranslateExtent:T,syncViewport:b,setClickDistance:E}}var Ts;(function(e){e.Line=`line`,e.Handle=`handle`})(Ts||={});function Es({width:e,prevWidth:t,height:n,prevHeight:r,affectsX:i,affectsY:a}){let o=e-t,s=n-r,c=[o>0?1:o<0?-1:0,s>0?1:s<0?-1:0];return o&&i&&(c[0]*=-1),s&&a&&(c[1]*=-1),c}function Ds(e){return{isHorizontal:e.includes(`right`)||e.includes(`left`),isVertical:e.includes(`bottom`)||e.includes(`top`),affectsX:e.includes(`left`),affectsY:e.includes(`top`)}}function Os(e,t){return Math.max(0,t-e)}function ks(e,t){return Math.max(0,e-t)}function As(e,t,n){return Math.max(0,t-e,e-n)}function js(e,t){return e?!t:t}function Ms(e,t,n,r,i,a,o,s){let{affectsX:c,affectsY:l}=t,{isHorizontal:u,isVertical:d}=t,f=u&&d,{xSnapped:p,ySnapped:m}=n,{minWidth:h,maxWidth:g,minHeight:_,maxHeight:v}=r,{x:y,y:b,width:x,height:S,aspectRatio:C}=e,w=Math.floor(u?p-e.pointerX:0),T=Math.floor(d?m-e.pointerY:0),E=x+(c?-w:w),D=S+(l?-T:T),O=-a[0]*x,k=-a[1]*S,A=As(E,h,g),j=As(D,_,v);if(o){let e=0,t=0;c&&w<0?e=Os(y+w+O,o[0][0]):!c&&w>0&&(e=ks(y+E+O,o[1][0])),l&&T<0?t=Os(b+T+k,o[0][1]):!l&&T>0&&(t=ks(b+D+k,o[1][1])),A=Math.max(A,e),j=Math.max(j,t)}if(s){let e=0,t=0;c&&w>0?e=ks(y+w,s[0][0]):!c&&w<0&&(e=Os(y+E,s[1][0])),l&&T>0?t=ks(b+T,s[0][1]):!l&&T<0&&(t=Os(b+D,s[1][1])),A=Math.max(A,e),j=Math.max(j,t)}if(i){if(u){let e=As(E/C,_,v)*C;if(A=Math.max(A,e),o){let e=0;e=!c&&!l||c&&!l&&f?ks(b+k+E/C,o[1][1])*C:Os(b+k+(c?w:-w)/C,o[0][1])*C,A=Math.max(A,e)}if(s){let e=0;e=!c&&!l||c&&!l&&f?Os(b+E/C,s[1][1])*C:ks(b+(c?w:-w)/C,s[0][1])*C,A=Math.max(A,e)}}if(d){let e=As(D*C,h,g)/C;if(j=Math.max(j,e),o){let e=0;e=!c&&!l||l&&!c&&f?ks(y+D*C+O,o[1][0])/C:Os(y+(l?T:-T)*C+O,o[0][0])/C,j=Math.max(j,e)}if(s){let e=0;e=!c&&!l||l&&!c&&f?Os(y+D*C,s[1][0])/C:ks(y+(l?T:-T)*C,s[0][0])/C,j=Math.max(j,e)}}}T+=T<0?j:-j,w+=w<0?A:-A,i&&(f?E>D*C?T=(js(c,l)?-w:w)/C:w=(js(c,l)?-T:T)*C:u?(T=w/C,l=c):(w=T*C,c=l));let M=c?y+w:y,N=l?b+T:b;return{width:x+(c?-w:w),height:S+(l?-T:T),x:a[0]*w*(c?-1:1)+M,y:a[1]*T*(l?-1:1)+N}}var Ns={width:0,height:0,x:0,y:0},Ps={...Ns,pointerX:0,pointerY:0,aspectRatio:1};function Fs(e){return[[0,0],[e.measured.width,e.measured.height]]}function Is(e,t,n){let r=t.position.x+e.position.x,i=t.position.y+e.position.y,a=e.measured.width??0,o=e.measured.height??0,s=n[0]*a,c=n[1]*o;return[[r-s,i-c],[r+a-s,i+o-c]]}function Ls({domNode:e,nodeId:t,getStoreItems:n,onChange:r,onEnd:i}){let a=q(e),o={controlDirection:Ds(`bottom-right`),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function s({controlPosition:e,boundaries:s,keepAspectRatio:c,resizeDirection:l,onResizeStart:u,onResize:d,onResizeEnd:f,shouldResize:p}){let m={...Ns},h={...Ps};o={boundaries:s,resizeDirection:l,keepAspectRatio:c,controlDirection:Ds(e)};let g,_=null,v=[],y,b,x,S=!1,C=Nt().on(`start`,e=>{let{nodeLookup:r,transform:i,snapGrid:a,snapToGrid:o,nodeOrigin:s,paneDomNode:c}=n();if(g=r.get(t),!g)return;_=c?.getBoundingClientRect()??null;let{xSnapped:l,ySnapped:d}=Za(e.sourceEvent,{transform:i,snapGrid:a,snapToGrid:o,containerBounds:_});m={width:g.measured.width??0,height:g.measured.height??0,x:g.position.x??0,y:g.position.y??0},h={...m,pointerX:l,pointerY:d,aspectRatio:m.width/m.height},y=void 0,g.parentId&&(g.extent===`parent`||g.expandParent)&&(y=r.get(g.parentId),b=y&&g.extent===`parent`?Fs(y):void 0),v=[],x=void 0;for(let[e,n]of r)if(n.parentId===t&&(v.push({id:e,position:{...n.position},extent:n.extent}),n.extent===`parent`||n.expandParent)){let e=Is(n,g,n.origin??s);x=x?[[Math.min(e[0][0],x[0][0]),Math.min(e[0][1],x[0][1])],[Math.max(e[1][0],x[1][0]),Math.max(e[1][1],x[1][1])]]:e}u?.(e,{...m})}).on(`drag`,e=>{let{transform:t,snapGrid:i,snapToGrid:a,nodeOrigin:s}=n(),c=Za(e.sourceEvent,{transform:t,snapGrid:i,snapToGrid:a,containerBounds:_}),l=[];if(!g)return;let{x:u,y:f,width:C,height:w}=m,T={},E=g.origin??s,{width:D,height:O,x:k,y:A}=Ms(h,o.controlDirection,c,o.boundaries,o.keepAspectRatio,E,b,x),j=D!==C,M=O!==w,N=k!==u&&j,P=A!==f&&M;if(!N&&!P&&!j&&!M)return;if((N||P||E[0]===1||E[1]===1)&&(T.x=N?k:m.x,T.y=P?A:m.y,m.x=T.x,m.y=T.y,v.length>0)){let e=k-u,t=A-f;for(let n of v)n.position={x:n.position.x-e+E[0]*(D-C),y:n.position.y-t+E[1]*(O-w)},l.push(n)}if((j||M)&&(T.width=j&&(!o.resizeDirection||o.resizeDirection===`horizontal`)?D:m.width,T.height=M&&(!o.resizeDirection||o.resizeDirection===`vertical`)?O:m.height,m.width=T.width,m.height=T.height),y&&g.expandParent){let e=E[0]*(T.width??0);T.x&&T.x{S&&=(f?.(e,{...m}),i?.({...m}),!1)});a.call(C)}function c(){a.on(`.drag`,null)}return{update:s,destroy:c}}var Rs=t((e=>{var t=n(),r=a();function i(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var o=typeof Object.is==`function`?Object.is:i,s=r.useSyncExternalStore,c=t.useRef,l=t.useEffect,u=t.useMemo,d=t.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,i){var a=c(null);if(a.current===null){var f={hasValue:!1,value:null};a.current=f}else f=a.current;a=u(function(){function e(e){if(!a){if(a=!0,s=e,e=r(e),i!==void 0&&f.hasValue){var t=f.value;if(i(t,e))return c=t}return c=e}if(t=c,o(s,e))return t;var n=r(e);return i!==void 0&&i(t,n)?(s=e,t):(s=e,c=n)}var a=!1,s,c,l=n===void 0?null:n;return[function(){return e(t())},l===null?void 0:function(){return e(l())}]},[t,n,r,i]);var p=s(e,a[0],a[1]);return l(function(){f.hasValue=!0,f.value=p},[p]),d(p),p}})),zs=e(t(((e,t)=>{t.exports=Rs()}))(),1),Bs=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e)),destroy:()=>{n.clear()}},o=t=e(r,i,a);return a},Vs=e=>e?Bs(e):Bs,{useDebugValue:Hs}=o.default,{useSyncExternalStoreWithSelector:Us}=zs.default,Ws=e=>e;function Gs(e,t=Ws,n){let r=Us(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,n);return Hs(r),r}var Ks=(e,t)=>{let n=Vs(e),r=(e,r=t)=>Gs(n,e,r);return Object.assign(r,n),r},qs=(e,t)=>e?Ks(e,t):Ks;function Z(e,t){if(Object.is(e,t))return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[n,r]of e)if(!Object.is(r,t.get(n)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}let n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;for(let r of n)if(!Object.prototype.hasOwnProperty.call(t,r)||!Object.is(e[r],t[r]))return!1;return!0}i();var Js=(0,o.createContext)(null),Ys=Js.Provider,Xs=Zi.error001();function Q(e,t){let n=(0,o.useContext)(Js);if(n===null)throw Error(Xs);return Gs(n,e,t)}function $(){let e=(0,o.useContext)(Js);if(e===null)throw Error(Xs);return(0,o.useMemo)(()=>({getState:e.getState,setState:e.setState,subscribe:e.subscribe}),[e])}var Zs={display:`none`},Qs={position:`absolute`,width:1,height:1,margin:-1,border:0,padding:0,overflow:`hidden`,clip:`rect(0px, 0px, 0px, 0px)`,clipPath:`inset(100%)`},$s=`react-flow__node-desc`,ec=`react-flow__edge-desc`,tc=`react-flow__aria-live`,nc=e=>e.ariaLiveMessage,rc=e=>e.ariaLabelConfig;function ic({rfId:e}){let t=Q(nc);return(0,s.jsx)(`div`,{id:`${tc}-${e}`,"aria-live":`assertive`,"aria-atomic":`true`,style:Qs,children:t})}function ac({rfId:e,disableKeyboardA11y:t}){let n=Q(rc);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(`div`,{id:`${$s}-${e}`,style:Zs,children:t?n[`node.a11yDescription.default`]:n[`node.a11yDescription.keyboardDisabled`]}),(0,s.jsx)(`div`,{id:`${ec}-${e}`,style:Zs,children:n[`edge.a11yDescription.default`]}),!t&&(0,s.jsx)(ic,{rfId:e})]})}var oc=(0,o.forwardRef)(({position:e=`top-left`,children:t,className:n,style:r,...i},a)=>(0,s.jsx)(`div`,{className:c([`react-flow__panel`,n,...`${e}`.split(`-`)]),style:r,ref:a,...i,children:t}));oc.displayName=`Panel`;function sc({proOptions:e,position:t=`bottom-right`}){return e?.hideAttribution?null:(0,s.jsx)(oc,{position:t,className:`react-flow__attribution`,"data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: https://pro.reactflow.dev`,children:(0,s.jsx)(`a`,{href:`https://reactflow.dev`,target:`_blank`,rel:`noopener noreferrer`,"aria-label":`React Flow attribution`,children:`React Flow`})})}var cc=e=>{let t=[],n=[];for(let[,n]of e.nodeLookup)n.selected&&t.push(n.internals.userNode);for(let[,t]of e.edgeLookup)t.selected&&n.push(t);return{selectedNodes:t,selectedEdges:n}},lc=e=>e.id;function uc(e,t){return Z(e.selectedNodes.map(lc),t.selectedNodes.map(lc))&&Z(e.selectedEdges.map(lc),t.selectedEdges.map(lc))}function dc({onSelectionChange:e}){let t=$(),{selectedNodes:n,selectedEdges:r}=Q(cc,uc);return(0,o.useEffect)(()=>{let i={nodes:n,edges:r};e?.(i),t.getState().onSelectionChangeHandlers.forEach(e=>e(i))},[n,r,e]),null}var fc=e=>!!e.onSelectionChangeHandlers;function pc({onSelectionChange:e}){let t=Q(fc);return e||t?(0,s.jsx)(dc,{onSelectionChange:e}):null}var mc=typeof window<`u`?o.useLayoutEffect:o.useEffect,hc=[0,0],gc={x:0,y:0,zoom:1},_c=[...`nodes.edges.defaultNodes.defaultEdges.onConnect.onConnectStart.onConnectEnd.onClickConnectStart.onClickConnectEnd.nodesDraggable.autoPanOnNodeFocus.nodesConnectable.nodesFocusable.edgesFocusable.edgesReconnectable.elevateNodesOnSelect.elevateEdgesOnSelect.minZoom.maxZoom.nodeExtent.onNodesChange.onEdgesChange.elementsSelectable.connectionMode.snapGrid.snapToGrid.translateExtent.connectOnClick.defaultEdgeOptions.fitView.fitViewOptions.onNodesDelete.onEdgesDelete.onDelete.onNodeDrag.onNodeDragStart.onNodeDragStop.onSelectionDrag.onSelectionDragStart.onSelectionDragStop.onMoveStart.onMove.onMoveEnd.noPanClassName.nodeOrigin.autoPanOnConnect.autoPanOnNodeDrag.onError.connectionRadius.isValidConnection.selectNodesOnDrag.nodeDragThreshold.connectionDragThreshold.onBeforeDelete.debug.autoPanSpeed.ariaLabelConfig.zIndexMode`.split(`.`),`rfId`],vc=e=>({setNodes:e.setNodes,setEdges:e.setEdges,setMinZoom:e.setMinZoom,setMaxZoom:e.setMaxZoom,setTranslateExtent:e.setTranslateExtent,setNodeExtent:e.setNodeExtent,reset:e.reset,setDefaultNodesAndEdges:e.setDefaultNodesAndEdges}),yc={translateExtent:Qi,nodeOrigin:hc,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:`nopan`,rfId:`1`};function bc(e){let{setNodes:t,setEdges:n,setMinZoom:r,setMaxZoom:i,setTranslateExtent:a,setNodeExtent:s,reset:c,setDefaultNodesAndEdges:l}=Q(vc,Z),u=$();mc(()=>(l(e.defaultNodes,e.defaultEdges),()=>{d.current=yc,c()}),[]);let d=(0,o.useRef)(yc);return mc(()=>{for(let o of _c){let c=e[o];c!==d.current[o]&&e[o]!==void 0&&(o===`nodes`?t(c):o===`edges`?n(c):o===`minZoom`?r(c):o===`maxZoom`?i(c):o===`translateExtent`?a(c):o===`nodeExtent`?s(c):o===`ariaLabelConfig`?u.setState({ariaLabelConfig:Xa(c)}):o===`fitView`?u.setState({fitViewQueued:c}):o===`fitViewOptions`?u.setState({fitViewOptions:c}):u.setState({[o]:c}))}d.current=e},_c.map(t=>e[t])),null}function xc(){return typeof window>`u`||!window.matchMedia?null:window.matchMedia(`(prefers-color-scheme: dark)`)}function Sc(e){let[t,n]=(0,o.useState)(e===`system`?null:e);return(0,o.useEffect)(()=>{if(e!==`system`){n(e);return}let t=xc(),r=()=>n(t?.matches?`dark`:`light`);return r(),t?.addEventListener(`change`,r),()=>{t?.removeEventListener(`change`,r)}},[e]),t===null?xc()?.matches?`dark`:`light`:t}var Cc=typeof document<`u`?document:null;function wc(e=null,t={target:Cc,actInsideInputWithModifier:!0}){let[n,r]=(0,o.useState)(!1),i=(0,o.useRef)(!1),a=(0,o.useRef)(new Set([])),[s,c]=(0,o.useMemo)(()=>{if(e!==null){let t=(Array.isArray(e)?e:[e]).filter(e=>typeof e==`string`).map(e=>e.replace(`+`,` +import{i as e,t}from"./rolldown-runtime-B1FJdls4.js";import{T as n,a as r}from"./query-vendor-Cbp9LWgA.js";import{i}from"./index-DDOaKEbH.js";import{t as a}from"./shim-CnYKr5zR.js";var o=e(n(),1),s=r();function c(e){if(typeof e==`string`||typeof e==`number`)return``+e;let t=``;if(Array.isArray(e))for(let n=0,r;n{}};function u(){for(var e=0,t=arguments.length,n={},r;e=0&&(n=e.slice(r+1),e=e.slice(0,r)),e&&!t.hasOwnProperty(e))throw Error(`unknown type: `+e);return{type:e,name:n}})}d.prototype=u.prototype={constructor:d,on:function(e,t){var n=this._,r=f(e+``,n),i,a=-1,o=r.length;if(arguments.length<2){for(;++a0)for(var n=Array(i),r=0,i,a;r=0&&(t=e.slice(0,n))!==`xmlns`&&(e=e.slice(n+1)),h.hasOwnProperty(t)?{space:h[t],local:e}:e}function _(e){return function(){var t=this.ownerDocument,n=this.namespaceURI;return n===`http://www.w3.org/1999/xhtml`&&t.documentElement.namespaceURI===`http://www.w3.org/1999/xhtml`?t.createElement(e):t.createElementNS(n,e)}}function v(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function y(e){var t=g(e);return(t.local?v:_)(t)}function b(){}function x(e){return e==null?b:function(){return this.querySelector(e)}}function S(e){typeof e!=`function`&&(e=x(e));for(var t=this._groups,n=t.length,r=Array(n),i=0;i=v&&(v=_+1);!(b=g[v])&&++v=0;)(o=r[i])&&(a&&o.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(o,a),a=o);return this}function oe(e){e||=se;function t(t,n){return t&&n?e(t.__data__,n.__data__):!t-!n}for(var n=this._groups,r=n.length,i=Array(r),a=0;at?1:e>=t?0:NaN}function ce(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function le(){return Array.from(this)}function ue(){for(var e=this._groups,t=0,n=e.length;t1?this.each((t==null?Se:typeof t==`function`?we:Ce)(e,t,n??``)):Ee(this.node(),e)}function Ee(e,t){return e.style.getPropertyValue(t)||xe(e).getComputedStyle(e,null).getPropertyValue(t)}function De(e){return function(){delete this[e]}}function Oe(e,t){return function(){this[e]=t}}function ke(e,t){return function(){var n=t.apply(this,arguments);n==null?delete this[e]:this[e]=n}}function Ae(e,t){return arguments.length>1?this.each((t==null?De:typeof t==`function`?ke:Oe)(e,t)):this.node()[e]}function je(e){return e.trim().split(/^|\s+/)}function Me(e){return e.classList||new Ne(e)}function Ne(e){this._node=e,this._names=je(e.getAttribute(`class`)||``)}Ne.prototype={add:function(e){this._names.indexOf(e)<0&&(this._names.push(e),this._node.setAttribute(`class`,this._names.join(` `)))},remove:function(e){var t=this._names.indexOf(e);t>=0&&(this._names.splice(t,1),this._node.setAttribute(`class`,this._names.join(` `)))},contains:function(e){return this._names.indexOf(e)>=0}};function Pe(e,t){for(var n=Me(e),r=-1,i=t.length;++r=0&&(t=e.slice(n+1),e=e.slice(0,n)),{type:e,name:t}})}function lt(e){return function(){var t=this.__on;if(t){for(var n=0,r=-1,i=t.length,a;n()=>e;function Ot(e,{sourceEvent:t,subject:n,target:r,identifier:i,active:a,x:o,y:s,dx:c,dy:l,dispatch:u}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},subject:{value:n,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},identifier:{value:i,enumerable:!0,configurable:!0},active:{value:a,enumerable:!0,configurable:!0},x:{value:o,enumerable:!0,configurable:!0},y:{value:s,enumerable:!0,configurable:!0},dx:{value:c,enumerable:!0,configurable:!0},dy:{value:l,enumerable:!0,configurable:!0},_:{value:u}})}Ot.prototype.on=function(){var e=this._.on.apply(this._,arguments);return e===this._?this:e};function kt(e){return!e.ctrlKey&&!e.button}function At(){return this.parentNode}function jt(e,t){return t??{x:e.x,y:e.y}}function Mt(){return navigator.maxTouchPoints||`ontouchstart`in this}function Nt(){var e=kt,t=At,n=jt,r=Mt,i={},a=u(`start`,`drag`,`end`),o=0,s,c,l,d,f=0;function p(e){e.on(`mousedown.drag`,m).filter(r).on(`touchstart.drag`,_).on(`touchmove.drag`,v,xt).on(`touchend.drag touchcancel.drag`,y).style(`touch-action`,`none`).style(`-webkit-tap-highlight-color`,`rgba(0,0,0,0)`)}function m(n,r){if(!(d||!e.call(this,n,r))){var i=b(this,t.call(this,n,r),n,r,`mouse`);i&&(q(n.view).on(`mousemove.drag`,h,St).on(`mouseup.drag`,g,St),Tt(n.view),Ct(n),l=!1,s=n.clientX,c=n.clientY,i(`start`,n))}}function h(e){if(wt(e),!l){var t=e.clientX-s,n=e.clientY-c;l=t*t+n*n>f}i.mouse(`drag`,e)}function g(e){q(e.view).on(`mousemove.drag mouseup.drag`,null),Et(e.view,l),wt(e),i.mouse(`end`,e)}function _(n,r){if(e.call(this,n,r)){var i=n.changedTouches,a=t.call(this,n,r),o=i.length,s,c;for(s=0;s>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?nn(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?nn(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=Ut.exec(e))?new Y(t[1],t[2],t[3],1):(t=Wt.exec(e))?new Y(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=Gt.exec(e))?nn(t[1],t[2],t[3],t[4]):(t=Kt.exec(e))?nn(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=qt.exec(e))?fn(t[1],t[2]/100,t[3]/100,1):(t=Jt.exec(e))?fn(t[1],t[2]/100,t[3]/100,t[4]):Yt.hasOwnProperty(e)?tn(Yt[e]):e===`transparent`?new Y(NaN,NaN,NaN,0):null}function tn(e){return new Y(e>>16&255,e>>8&255,e&255,1)}function nn(e,t,n,r){return r<=0&&(e=t=n=NaN),new Y(e,t,n,r)}function rn(e){return e instanceof It||(e=en(e)),e?(e=e.rgb(),new Y(e.r,e.g,e.b,e.opacity)):new Y}function an(e,t,n,r){return arguments.length===1?rn(e):new Y(e,t,n,r??1)}function Y(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}Pt(Y,an,Ft(It,{brighter(e){return e=e==null?Rt:Rt**+e,new Y(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?Lt:Lt**+e,new Y(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new Y(un(this.r),un(this.g),un(this.b),ln(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:on,formatHex:on,formatHex8:sn,formatRgb:cn,toString:cn}));function on(){return`#${dn(this.r)}${dn(this.g)}${dn(this.b)}`}function sn(){return`#${dn(this.r)}${dn(this.g)}${dn(this.b)}${dn((isNaN(this.opacity)?1:this.opacity)*255)}`}function cn(){let e=ln(this.opacity);return`${e===1?`rgb(`:`rgba(`}${un(this.r)}, ${un(this.g)}, ${un(this.b)}${e===1?`)`:`, ${e})`}`}function ln(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function un(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function dn(e){return e=un(e),(e<16?`0`:``)+e.toString(16)}function fn(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new hn(e,t,n,r)}function pn(e){if(e instanceof hn)return new hn(e.h,e.s,e.l,e.opacity);if(e instanceof It||(e=en(e)),!e)return new hn;if(e instanceof hn)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,i=Math.min(t,n,r),a=Math.max(t,n,r),o=NaN,s=a-i,c=(a+i)/2;return s?(o=t===a?(n-r)/s+(n0&&c<1?0:o,new hn(o,s,c,e.opacity)}function mn(e,t,n,r){return arguments.length===1?pn(e):new hn(e,t,n,r??1)}function hn(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}Pt(hn,mn,Ft(It,{brighter(e){return e=e==null?Rt:Rt**+e,new hn(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?Lt:Lt**+e,new hn(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,i=2*n-r;return new Y(vn(e>=240?e-240:e+120,i,r),vn(e,i,r),vn(e<120?e+240:e-120,i,r),this.opacity)},clamp(){return new hn(gn(this.h),_n(this.s),_n(this.l),ln(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let e=ln(this.opacity);return`${e===1?`hsl(`:`hsla(`}${gn(this.h)}, ${_n(this.s)*100}%, ${_n(this.l)*100}%${e===1?`)`:`, ${e})`}`}}));function gn(e){return e=(e||0)%360,e<0?e+360:e}function _n(e){return Math.max(0,Math.min(1,e||0))}function vn(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}var yn=e=>()=>e;function bn(e,t){return function(n){return e+n*t}}function xn(e,t,n){return e**=+n,t=t**+n-e,n=1/n,function(r){return(e+r*t)**+n}}function Sn(e){return(e=+e)==1?Cn:function(t,n){return n-t?xn(t,n,e):yn(isNaN(t)?n:t)}}function Cn(e,t){var n=t-e;return n?bn(e,n):yn(isNaN(e)?t:e)}var wn=(function e(t){var n=Sn(t);function r(e,t){var r=n((e=an(e)).r,(t=an(t)).r),i=n(e.g,t.g),a=n(e.b,t.b),o=Cn(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=i(t),e.b=a(t),e.opacity=o(t),e+``}}return r.gamma=e,r})(1);function Tn(e,t){t||=[];var n=e?Math.min(t.length,e.length):0,r=t.slice(),i;return function(a){for(i=0;in&&(a=t.slice(n,a),s[o]?s[o]+=a:s[++o]=a),(r=r[0])===(i=i[0])?s[o]?s[o]+=i:s[++o]=i:(s[++o]=null,c.push({i:o,x:kn(r,i)})),n=Mn.lastIndex;return n180?t+=360:t-e>180&&(e+=360),a.push({i:n.push(i(n)+`rotate(`,null,r)-2,x:kn(e,t)}))}function s(e,t,n,a){e===t?t&&n.push(i(n)+`skewX(`+t+r):a.push({i:n.push(i(n)+`skewX(`,null,r)-2,x:kn(e,t)})}function c(e,t,n,r,a,o){if(e!==n||t!==r){var s=a.push(i(a)+`scale(`,null,`,`,null,`)`);o.push({i:s-4,x:kn(e,n)},{i:s-2,x:kn(t,r)})}else (n!==1||r!==1)&&a.push(i(a)+`scale(`+n+`,`+r+`)`)}return function(t,n){var r=[],i=[];return t=e(t),n=e(n),a(t.translateX,t.translateY,n.translateX,n.translateY,r,i),o(t.rotate,n.rotate,r,i),s(t.skewX,n.skewX,r,i),c(t.scaleX,t.scaleY,n.scaleX,n.scaleY,r,i),t=n=null,function(e){for(var t=-1,n=i.length,a;++t=0&&e._call.call(void 0,t),e=e._next;--Zn}function pr(){ir=(rr=or.now())+ar,Zn=Qn=0;try{fr()}finally{Zn=0,hr(),ir=0}}function mr(){var e=or.now(),t=e-rr;t>er&&(ar-=t,rr=e)}function hr(){for(var e,t=tr,n,r=1/0;t;)t._call?(r>t._time&&(r=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:tr=n);nr=e,gr(r)}function gr(e){Zn||(Qn&&=clearTimeout(Qn),e-ir>24?(e<1/0&&(Qn=setTimeout(pr,e-or.now()-ar)),$n&&=clearInterval($n)):($n||=(rr=or.now(),setInterval(mr,er)),Zn=1,sr(pr)))}function _r(e,t,n){var r=new ur;return t=t==null?0:+t,r.restart(n=>{r.stop(),e(n+t)},t,n),r}var vr=u(`start`,`end`,`cancel`,`interrupt`),yr=[];function br(e,t,n,r,i,a){var o=e.__transition;if(!o)e.__transition={};else if(n in o)return;wr(e,n,{name:t,index:r,group:i,on:vr,tween:yr,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:0})}function xr(e,t){var n=Cr(e,t);if(n.state>0)throw Error(`too late; already scheduled`);return n}function Sr(e,t){var n=Cr(e,t);if(n.state>3)throw Error(`too late; already running`);return n}function Cr(e,t){var n=e.__transition;if(!n||!(n=n[t]))throw Error(`transition not found`);return n}function wr(e,t,n){var r=e.__transition,i;r[t]=n,n.timer=dr(a,0,n.time);function a(e){n.state=1,n.timer.restart(o,n.delay,n.time),n.delay<=e&&o(e-n.delay)}function o(a){var l,u,d,f;if(n.state!==1)return c();for(l in r)if(f=r[l],f.name===n.name){if(f.state===3)return _r(o);f.state===4?(f.state=6,f.timer.stop(),f.on.call(`interrupt`,e,e.__data__,f.index,f.group),delete r[l]):+l2&&r.state<5,r.state=6,r.timer.stop(),r.on.call(i?`interrupt`:`cancel`,e,e.__data__,r.index,r.group),delete n[o]}a&&delete e.__transition}}function Er(e){return this.each(function(){Tr(this,e)})}function Dr(e,t){var n,r;return function(){var i=Sr(this,e),a=i.tween;if(a!==n){r=n=a;for(var o=0,s=r.length;o=0&&(e=e.slice(0,t)),!e||e===`start`})}function ri(e,t,n){var r,i,a=ni(t)?xr:Sr;return function(){var o=a(this,e),s=o.on;s!==r&&(i=(r=s).copy()).on(t,n),o.on=i}}function ii(e,t){var n=this._id;return arguments.length<2?Cr(this.node(),n).on.on(e):this.each(ri(n,e,t))}function ai(e){return function(){var t=this.parentNode;for(var n in this.__transition)if(+n!==e)return;t&&t.removeChild(this)}}function oi(){return this.on(`end.remove`,ai(this._id))}function si(e){var t=this._name,n=this._id;typeof e!=`function`&&(e=x(e));for(var r=this._groups,i=r.length,a=Array(i),o=0;o()=>e;function Ri(e,{sourceEvent:t,target:n,transform:r,dispatch:i}){Object.defineProperties(this,{type:{value:e,enumerable:!0,configurable:!0},sourceEvent:{value:t,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},transform:{value:r,enumerable:!0,configurable:!0},_:{value:i}})}function zi(e,t,n){this.k=e,this.x=t,this.y=n}zi.prototype={constructor:zi,scale:function(e){return e===1?this:new zi(this.k*e,this.x,this.y)},translate:function(e,t){return e===0&t===0?this:new zi(this.k,this.x+this.k*e,this.y+this.k*t)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return`translate(`+this.x+`,`+this.y+`) scale(`+this.k+`)`}};var Bi=new zi(1,0,0);Vi.prototype=zi.prototype;function Vi(e){for(;!e.__zoom;)if(!(e=e.parentNode))return Bi;return e.__zoom}function Hi(e){e.stopImmediatePropagation()}function Ui(e){e.preventDefault(),e.stopImmediatePropagation()}function Wi(e){return(!e.ctrlKey||e.type===`wheel`)&&!e.button}function Gi(){var e=this;return e instanceof SVGElement?(e=e.ownerSVGElement||e,e.hasAttribute(`viewBox`)?(e=e.viewBox.baseVal,[[e.x,e.y],[e.x+e.width,e.y+e.height]]):[[0,0],[e.width.baseVal.value,e.height.baseVal.value]]):[[0,0],[e.clientWidth,e.clientHeight]]}function Ki(){return this.__zoom||Bi}function qi(e){return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*(e.ctrlKey?10:1)}function Ji(){return navigator.maxTouchPoints||`ontouchstart`in this}function Yi(e,t,n){var r=e.invertX(t[0][0])-n[0][0],i=e.invertX(t[1][0])-n[1][0],a=e.invertY(t[0][1])-n[0][1],o=e.invertY(t[1][1])-n[1][1];return e.translate(i>r?(r+i)/2:Math.min(0,r)||Math.max(0,i),o>a?(a+o)/2:Math.min(0,a)||Math.max(0,o))}function Xi(){var e=Wi,t=Gi,n=Yi,r=qi,i=Ji,a=[0,1/0],o=[[-1/0,-1/0],[1/0,1/0]],s=250,c=Xn,l=u(`start`,`zoom`,`end`),d,f,p,m=500,h=150,g=0,_=10;function v(e){e.property(`__zoom`,Ki).on(`wheel.zoom`,T,{passive:!1}).on(`mousedown.zoom`,E).on(`dblclick.zoom`,D).filter(i).on(`touchstart.zoom`,O).on(`touchmove.zoom`,k).on(`touchend.zoom touchcancel.zoom`,A).style(`-webkit-tap-highlight-color`,`rgba(0,0,0,0)`)}v.transform=function(e,t,n,r){var i=e.selection?e.selection():e;i.property(`__zoom`,Ki),e===i?i.interrupt().each(function(){C(this,arguments).event(r).start().zoom(null,typeof t==`function`?t.apply(this,arguments):t).end()}):S(e,t,n,r)},v.scaleBy=function(e,t,n,r){v.scaleTo(e,function(){return this.__zoom.k*(typeof t==`function`?t.apply(this,arguments):t)},n,r)},v.scaleTo=function(e,r,i,a){v.transform(e,function(){var e=t.apply(this,arguments),a=this.__zoom,s=i==null?x(e):typeof i==`function`?i.apply(this,arguments):i,c=a.invert(s),l=typeof r==`function`?r.apply(this,arguments):r;return n(b(y(a,l),s,c),e,o)},i,a)},v.translateBy=function(e,r,i,a){v.transform(e,function(){return n(this.__zoom.translate(typeof r==`function`?r.apply(this,arguments):r,typeof i==`function`?i.apply(this,arguments):i),t.apply(this,arguments),o)},null,a)},v.translateTo=function(e,r,i,a,s){v.transform(e,function(){var e=t.apply(this,arguments),s=this.__zoom,c=a==null?x(e):typeof a==`function`?a.apply(this,arguments):a;return n(Bi.translate(c[0],c[1]).scale(s.k).translate(typeof r==`function`?-r.apply(this,arguments):-r,typeof i==`function`?-i.apply(this,arguments):-i),e,o)},a,s)};function y(e,t){return t=Math.max(a[0],Math.min(a[1],t)),t===e.k?e:new zi(t,e.x,e.y)}function b(e,t,n){var r=t[0]-n[0]*e.k,i=t[1]-n[1]*e.k;return r===e.x&&i===e.y?e:new zi(e.k,r,i)}function x(e){return[(+e[0][0]+ +e[1][0])/2,(+e[0][1]+ +e[1][1])/2]}function S(e,n,r,i){e.on(`start.zoom`,function(){C(this,arguments).event(i).start()}).on(`interrupt.zoom end.zoom`,function(){C(this,arguments).event(i).end()}).tween(`zoom`,function(){var e=this,a=arguments,o=C(e,a).event(i),s=t.apply(e,a),l=r==null?x(s):typeof r==`function`?r.apply(e,a):r,u=Math.max(s[1][0]-s[0][0],s[1][1]-s[0][1]),d=e.__zoom,f=typeof n==`function`?n.apply(e,a):n,p=c(d.invert(l).concat(u/d.k),f.invert(l).concat(u/f.k));return function(e){if(e===1)e=f;else{var t=p(e),n=u/t[2];e=new zi(n,l[0]-t[0]*n,l[1]-t[1]*n)}o.zoom(null,e)}})}function C(e,t,n){return!n&&e.__zooming||new w(e,t)}function w(e,n){this.that=e,this.args=n,this.active=0,this.sourceEvent=null,this.extent=t.apply(e,n),this.taps=0}w.prototype={event:function(e){return e&&(this.sourceEvent=e),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit(`start`)),this},zoom:function(e,t){return this.mouse&&e!==`mouse`&&(this.mouse[1]=t.invert(this.mouse[0])),this.touch0&&e!==`touch`&&(this.touch0[1]=t.invert(this.touch0[0])),this.touch1&&e!==`touch`&&(this.touch1[1]=t.invert(this.touch1[0])),this.that.__zoom=t,this.emit(`zoom`),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit(`end`)),this},emit:function(e){var t=q(this.that).datum();l.call(e,this.that,new Ri(e,{sourceEvent:this.sourceEvent,target:v,type:e,transform:this.that.__zoom,dispatch:l}),t)}};function T(t,...i){if(!e.apply(this,arguments))return;var s=C(this,i).event(t),c=this.__zoom,l=Math.max(a[0],Math.min(a[1],c.k*2**r.apply(this,arguments))),u=J(t);if(s.wheel)(s.mouse[0][0]!==u[0]||s.mouse[0][1]!==u[1])&&(s.mouse[1]=c.invert(s.mouse[0]=u)),clearTimeout(s.wheel);else if(c.k===l)return;else s.mouse=[u,c.invert(u)],Tr(this),s.start();Ui(t),s.wheel=setTimeout(d,h),s.zoom(`mouse`,n(b(y(c,l),s.mouse[0],s.mouse[1]),s.extent,o));function d(){s.wheel=null,s.end()}}function E(t,...r){if(p||!e.apply(this,arguments))return;var i=t.currentTarget,a=C(this,r,!0).event(t),s=q(t.view).on(`mousemove.zoom`,d,!0).on(`mouseup.zoom`,f,!0),c=J(t,i),l=t.clientX,u=t.clientY;Tt(t.view),Hi(t),a.mouse=[c,this.__zoom.invert(c)],Tr(this),a.start();function d(e){if(Ui(e),!a.moved){var t=e.clientX-l,r=e.clientY-u;a.moved=t*t+r*r>g}a.event(e).zoom(`mouse`,n(b(a.that.__zoom,a.mouse[0]=J(e,i),a.mouse[1]),a.extent,o))}function f(e){s.on(`mousemove.zoom mouseup.zoom`,null),Et(e.view,a.moved),Ui(e),a.event(e).end()}}function D(r,...i){if(e.apply(this,arguments)){var a=this.__zoom,c=J(r.changedTouches?r.changedTouches[0]:r,this),l=a.invert(c),u=a.k*(r.shiftKey?.5:2),d=n(b(y(a,u),c,l),t.apply(this,i),o);Ui(r),s>0?q(this).transition().duration(s).call(S,d,c,r):q(this).call(v.transform,d,c,r)}}function O(t,...n){if(e.apply(this,arguments)){var r=t.touches,i=r.length,a=C(this,n,t.changedTouches.length===i).event(t),o,s,c,l;for(Hi(t),s=0;s`[React Flow]: Seems like you have not used zustand provider as an ancestor. Help: https://reactflow.dev/error#001`,error002:()=>`It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.`,error003:e=>`Node type "${e}" not found. Using fallback type "default".`,error004:()=>`The React Flow parent container needs a width and a height to render the graph.`,error005:()=>`Only child nodes can use a parent extent.`,error006:()=>`Can't create edge. An edge needs a source and a target.`,error007:e=>`The old edge with id=${e} does not exist.`,error009:e=>`Marker type "${e}" doesn't exist.`,error008:(e,{id:t,sourceHandle:n,targetHandle:r})=>`Couldn't create edge for ${e} handle id: "${e===`source`?n:r}", edge id: ${t}.`,error010:()=>`Handle: No node id found. Make sure to only use a Handle inside a custom Node.`,error011:e=>`Edge type "${e}" not found. Using fallback type "default".`,error012:e=>`Node with id "${e}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(e=`react`)=>`It seems that you haven't loaded the styles. Please import '@xyflow/${e}/dist/style.css' or base.css to make sure everything is working properly.`,error014:()=>`useNodeConnections: No node ID found. Call useNodeConnections inside a custom Node or provide a node ID.`,error015:()=>`It seems that you are trying to drag a node that is not initialized. Please use onNodesChange as explained in the docs.`},Qi=[[-1/0,-1/0],[1/0,1/0]],$i=[`Enter`,` `,`Escape`],ea={"node.a11yDescription.default":`Press enter or space to select a node. Press delete to remove it and escape to cancel.`,"node.a11yDescription.keyboardDisabled":`Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.`,"node.a11yDescription.ariaLiveMessage":({direction:e,x:t,y:n})=>`Moved selected node ${e}. New position, x: ${t}, y: ${n}`,"edge.a11yDescription.default":`Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.`,"controls.ariaLabel":`Control Panel`,"controls.zoomIn.ariaLabel":`Zoom In`,"controls.zoomOut.ariaLabel":`Zoom Out`,"controls.fitView.ariaLabel":`Fit View`,"controls.interactive.ariaLabel":`Toggle Interactivity`,"minimap.ariaLabel":`Mini Map`,"handle.ariaLabel":`Handle`},ta;(function(e){e.Strict=`strict`,e.Loose=`loose`})(ta||={});var na;(function(e){e.Free=`free`,e.Vertical=`vertical`,e.Horizontal=`horizontal`})(na||={});var ra;(function(e){e.Partial=`partial`,e.Full=`full`})(ra||={});var ia={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null},aa;(function(e){e.Bezier=`default`,e.Straight=`straight`,e.Step=`step`,e.SmoothStep=`smoothstep`,e.SimpleBezier=`simplebezier`})(aa||={});var oa;(function(e){e.Arrow=`arrow`,e.ArrowClosed=`arrowclosed`})(oa||={});var X;(function(e){e.Left=`left`,e.Top=`top`,e.Right=`right`,e.Bottom=`bottom`})(X||={});var sa={[X.Left]:X.Right,[X.Right]:X.Left,[X.Top]:X.Bottom,[X.Bottom]:X.Top};function ca(e){return e===null?null:e?`valid`:`invalid`}var la=e=>`id`in e&&`source`in e&&`target`in e,ua=e=>`id`in e&&`position`in e&&!(`source`in e)&&!(`target`in e),da=e=>`id`in e&&`internals`in e&&!(`source`in e)&&!(`target`in e),fa=(e,t=[0,0])=>{let{width:n,height:r}=Ga(e),i=e.origin??t,a=n*i[0],o=r*i[1];return{x:e.position.x-a,y:e.position.y-o}},pa=(e,t={nodeOrigin:[0,0]})=>e.length===0?{x:0,y:0,width:0,height:0}:Oa(e.reduce((e,n)=>{let r=typeof n==`string`,i=!t.nodeLookup&&!r?n:void 0;return t.nodeLookup&&(i=r?t.nodeLookup.get(n):da(n)?n:t.nodeLookup.get(n.id)),Ea(e,i?Aa(i,t.nodeOrigin):{x:0,y:0,x2:0,y2:0})},{x:1/0,y:1/0,x2:-1/0,y2:-1/0})),ma=(e,t={})=>{let n={x:1/0,y:1/0,x2:-1/0,y2:-1/0},r=!1;return e.forEach(e=>{(t.filter===void 0||t.filter(e))&&(n=Ea(n,Aa(e)),r=!0)}),r?Oa(n):{x:0,y:0,width:0,height:0}},ha=(e,t,[n,r,i]=[0,0,1],a=!1,o=!1)=>{let s={...La(t,[n,r,i]),width:t.width/i,height:t.height/i},c=[];for(let t of e.values()){let{measured:e,selectable:n=!0,hidden:r=!1}=t;if(o&&!n||r)continue;let i=e.width??t.width??t.initialWidth??null,l=e.height??t.height??t.initialHeight??null,u=Ma(s,ka(t)),d=(i??0)*(l??0),f=a&&u>0;(!t.internals.handleBounds||f||u>=d||t.dragging)&&c.push(t)}return c},ga=(e,t)=>{let n=new Set;return e.forEach(e=>{n.add(e.id)}),t.filter(e=>n.has(e.source)||n.has(e.target))};function _a(e,t){let n=new Map,r=t?.nodes?new Set(t.nodes.map(e=>e.id)):null;return e.forEach(e=>{e.measured.width&&e.measured.height&&(t?.includeHiddenNodes||!e.hidden)&&(!r||r.has(e.id))&&n.set(e.id,e)}),n}async function va({nodes:e,width:t,height:n,panZoom:r,minZoom:i,maxZoom:a},o){if(e.size===0)return Promise.resolve(!0);let s=Ha(ma(_a(e,o)),t,n,o?.minZoom??i,o?.maxZoom??a,o?.padding??.1);return await r.setViewport(s,{duration:o?.duration,ease:o?.ease,interpolate:o?.interpolate}),Promise.resolve(!0)}function ya({nodeId:e,nextPosition:t,nodeLookup:n,nodeOrigin:r=[0,0],nodeExtent:i,onError:a}){let o=n.get(e),s=o.parentId?n.get(o.parentId):void 0,{x:c,y:l}=s?s.internals.positionAbsolute:{x:0,y:0},u=o.origin??r,d=o.extent||i;if(o.extent===`parent`&&!o.expandParent)if(!s)a?.(`005`,Zi.error005());else{let e=s.measured.width,t=s.measured.height;e&&t&&(d=[[c,l],[c+e,l+t]])}else s&&Wa(o.extent)&&(d=[[o.extent[0][0]+c,o.extent[0][1]+l],[o.extent[1][0]+c,o.extent[1][1]+l]]);let f=Wa(d)?Sa(t,d,o.measured):t;return(o.measured.width===void 0||o.measured.height===void 0)&&a?.(`015`,Zi.error015()),{position:{x:f.x-c+(o.measured.width??0)*u[0],y:f.y-l+(o.measured.height??0)*u[1]},positionAbsolute:f}}async function ba({nodesToRemove:e=[],edgesToRemove:t=[],nodes:n,edges:r,onBeforeDelete:i}){let a=new Set(e.map(e=>e.id)),o=[];for(let e of n){if(e.deletable===!1)continue;let t=a.has(e.id),n=!t&&e.parentId&&o.find(t=>t.id===e.parentId);(t||n)&&o.push(e)}let s=new Set(t.map(e=>e.id)),c=r.filter(e=>e.deletable!==!1),l=ga(o,c);for(let e of c)s.has(e.id)&&!l.find(t=>t.id===e.id)&&l.push(e);if(!i)return{edges:l,nodes:o};let u=await i({nodes:o,edges:l});return typeof u==`boolean`?u?{edges:l,nodes:o}:{edges:[],nodes:[]}:u}var xa=(e,t=0,n=1)=>Math.min(Math.max(e,t),n),Sa=(e={x:0,y:0},t,n)=>({x:xa(e.x,t[0][0],t[1][0]-(n?.width??0)),y:xa(e.y,t[0][1],t[1][1]-(n?.height??0))});function Ca(e,t,n){let{width:r,height:i}=Ga(n),{x:a,y:o}=n.internals.positionAbsolute;return Sa(e,[[a,o],[a+r,o+i]],t)}var wa=(e,t,n)=>en?-xa(Math.abs(e-n),1,t)/t:0,Ta=(e,t,n=15,r=40)=>[wa(e.x,r,t.width-r)*n,wa(e.y,r,t.height-r)*n],Ea=(e,t)=>({x:Math.min(e.x,t.x),y:Math.min(e.y,t.y),x2:Math.max(e.x2,t.x2),y2:Math.max(e.y2,t.y2)}),Da=({x:e,y:t,width:n,height:r})=>({x:e,y:t,x2:e+n,y2:t+r}),Oa=({x:e,y:t,x2:n,y2:r})=>({x:e,y:t,width:n-e,height:r-t}),ka=(e,t=[0,0])=>{let{x:n,y:r}=da(e)?e.internals.positionAbsolute:fa(e,t);return{x:n,y:r,width:e.measured?.width??e.width??e.initialWidth??0,height:e.measured?.height??e.height??e.initialHeight??0}},Aa=(e,t=[0,0])=>{let{x:n,y:r}=da(e)?e.internals.positionAbsolute:fa(e,t);return{x:n,y:r,x2:n+(e.measured?.width??e.width??e.initialWidth??0),y2:r+(e.measured?.height??e.height??e.initialHeight??0)}},ja=(e,t)=>Oa(Ea(Da(e),Da(t))),Ma=(e,t)=>{let n=Math.max(0,Math.min(e.x+e.width,t.x+t.width)-Math.max(e.x,t.x)),r=Math.max(0,Math.min(e.y+e.height,t.y+t.height)-Math.max(e.y,t.y));return Math.ceil(n*r)},Na=e=>Pa(e.width)&&Pa(e.height)&&Pa(e.x)&&Pa(e.y),Pa=e=>!isNaN(e)&&isFinite(e),Fa=(e,t)=>{},Ia=(e,t=[1,1])=>({x:t[0]*Math.round(e.x/t[0]),y:t[1]*Math.round(e.y/t[1])}),La=({x:e,y:t},[n,r,i],a=!1,o=[1,1])=>{let s={x:(e-n)/i,y:(t-r)/i};return a?Ia(s,o):s},Ra=({x:e,y:t},[n,r,i])=>({x:e*i+n,y:t*i+r});function za(e,t){if(typeof e==`number`)return Math.floor((t-t/(1+e))*.5);if(typeof e==`string`&&e.endsWith(`px`)){let t=parseFloat(e);if(!Number.isNaN(t))return Math.floor(t)}if(typeof e==`string`&&e.endsWith(`%`)){let n=parseFloat(e);if(!Number.isNaN(n))return Math.floor(t*n*.01)}return console.error(`[React Flow] The padding value "${e}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function Ba(e,t,n){if(typeof e==`string`||typeof e==`number`){let r=za(e,n),i=za(e,t);return{top:r,right:i,bottom:r,left:i,x:i*2,y:r*2}}if(typeof e==`object`){let r=za(e.top??e.y??0,n),i=za(e.bottom??e.y??0,n),a=za(e.left??e.x??0,t),o=za(e.right??e.x??0,t);return{top:r,right:o,bottom:i,left:a,x:a+o,y:r+i}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function Va(e,t,n,r,i,a){let{x:o,y:s}=Ra(e,[t,n,r]),{x:c,y:l}=Ra({x:e.x+e.width,y:e.y+e.height},[t,n,r]),u=i-c,d=a-l;return{left:Math.floor(o),top:Math.floor(s),right:Math.floor(u),bottom:Math.floor(d)}}var Ha=(e,t,n,r,i,a)=>{let o=Ba(a,t,n),s=(t-o.x)/e.width,c=(n-o.y)/e.height,l=xa(Math.min(s,c),r,i),u=e.x+e.width/2,d=e.y+e.height/2,f=t/2-u*l,p=n/2-d*l,m=Va(e,f,p,l,t,n),h={left:Math.min(m.left-o.left,0),top:Math.min(m.top-o.top,0),right:Math.min(m.right-o.right,0),bottom:Math.min(m.bottom-o.bottom,0)};return{x:f-h.left+h.right,y:p-h.top+h.bottom,zoom:l}},Ua=()=>typeof navigator<`u`&&navigator?.userAgent?.indexOf(`Mac`)>=0;function Wa(e){return e!=null&&e!==`parent`}function Ga(e){return{width:e.measured?.width??e.width??e.initialWidth??0,height:e.measured?.height??e.height??e.initialHeight??0}}function Ka(e){return(e.measured?.width??e.width??e.initialWidth)!==void 0&&(e.measured?.height??e.height??e.initialHeight)!==void 0}function qa(e,t={width:0,height:0},n,r,i){let a={...e},o=r.get(n);if(o){let e=o.origin||i;a.x+=o.internals.positionAbsolute.x-(t.width??0)*e[0],a.y+=o.internals.positionAbsolute.y-(t.height??0)*e[1]}return a}function Ja(e,t){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}function Ya(){let e,t;return{promise:new Promise((n,r)=>{e=n,t=r}),resolve:e,reject:t}}function Xa(e){return{...ea,...e||{}}}function Za(e,{snapGrid:t=[0,0],snapToGrid:n=!1,transform:r,containerBounds:i}){let{x:a,y:o}=ro(e),s=La({x:a-(i?.left??0),y:o-(i?.top??0)},r),{x:c,y:l}=n?Ia(s,t):s;return{xSnapped:c,ySnapped:l,...s}}var Qa=e=>({width:e.offsetWidth,height:e.offsetHeight}),$a=e=>e?.getRootNode?.()||window?.document,eo=[`INPUT`,`SELECT`,`TEXTAREA`];function to(e){let t=e.composedPath?.()?.[0]||e.target;return t?.nodeType===1?eo.includes(t.nodeName)||t.hasAttribute(`contenteditable`)||!!t.closest(`.nokey`):!1}var no=e=>`clientX`in e,ro=(e,t)=>{let n=no(e),r=n?e.clientX:e.touches?.[0].clientX,i=n?e.clientY:e.touches?.[0].clientY;return{x:r-(t?.left??0),y:i-(t?.top??0)}},io=(e,t,n,r,i)=>{let a=t.querySelectorAll(`.${e}`);return!a||!a.length?null:Array.from(a).map(t=>{let a=t.getBoundingClientRect();return{id:t.getAttribute(`data-handleid`),type:e,nodeId:i,position:t.getAttribute(`data-handlepos`),x:(a.left-n.left)/r,y:(a.top-n.top)/r,...Qa(t)}})};function ao({sourceX:e,sourceY:t,targetX:n,targetY:r,sourceControlX:i,sourceControlY:a,targetControlX:o,targetControlY:s}){let c=e*.125+i*.375+o*.375+n*.125,l=t*.125+a*.375+s*.375+r*.125;return[c,l,Math.abs(c-e),Math.abs(l-t)]}function oo(e,t){return e>=0?.5*e:t*25*Math.sqrt(-e)}function so({pos:e,x1:t,y1:n,x2:r,y2:i,c:a}){switch(e){case X.Left:return[t-oo(t-r,a),n];case X.Right:return[t+oo(r-t,a),n];case X.Top:return[t,n-oo(n-i,a)];case X.Bottom:return[t,n+oo(i-n,a)]}}function co({sourceX:e,sourceY:t,sourcePosition:n=X.Bottom,targetX:r,targetY:i,targetPosition:a=X.Top,curvature:o=.25}){let[s,c]=so({pos:n,x1:e,y1:t,x2:r,y2:i,c:o}),[l,u]=so({pos:a,x1:r,y1:i,x2:e,y2:t,c:o}),[d,f,p,m]=ao({sourceX:e,sourceY:t,targetX:r,targetY:i,sourceControlX:s,sourceControlY:c,targetControlX:l,targetControlY:u});return[`M${e},${t} C${s},${c} ${l},${u} ${r},${i}`,d,f,p,m]}function lo({sourceX:e,sourceY:t,targetX:n,targetY:r}){let i=Math.abs(n-e)/2,a=n0}var po=({source:e,sourceHandle:t,target:n,targetHandle:r})=>`xy-edge__${e}${t||``}-${n}${r||``}`,mo=(e,t)=>t.some(t=>t.source===e.source&&t.target===e.target&&(t.sourceHandle===e.sourceHandle||!t.sourceHandle&&!e.sourceHandle)&&(t.targetHandle===e.targetHandle||!t.targetHandle&&!e.targetHandle)),ho=(e,t,n={})=>{if(!e.source||!e.target)return Zi.error006(),t;let r=n.getEdgeId||po,i;return i=la(e)?{...e}:{...e,id:r(e)},mo(i,t)?t:(i.sourceHandle===null&&delete i.sourceHandle,i.targetHandle===null&&delete i.targetHandle,t.concat(i))};function go({sourceX:e,sourceY:t,targetX:n,targetY:r}){let[i,a,o,s]=lo({sourceX:e,sourceY:t,targetX:n,targetY:r});return[`M ${e},${t}L ${n},${r}`,i,a,o,s]}var _o={[X.Left]:{x:-1,y:0},[X.Right]:{x:1,y:0},[X.Top]:{x:0,y:-1},[X.Bottom]:{x:0,y:1}},vo=({source:e,sourcePosition:t=X.Bottom,target:n})=>t===X.Left||t===X.Right?e.xMath.sqrt((t.x-e.x)**2+(t.y-e.y)**2);function bo({source:e,sourcePosition:t=X.Bottom,target:n,targetPosition:r=X.Top,center:i,offset:a,stepPosition:o}){let s=_o[t],c=_o[r],l={x:e.x+s.x*a,y:e.y+s.y*a},u={x:n.x+c.x*a,y:n.y+c.y*a},d=vo({source:l,sourcePosition:t,target:u}),f=d.x===0?`y`:`x`,p=d[f],m=[],h,g,_={x:0,y:0},v={x:0,y:0},[,,y,b]=lo({sourceX:e.x,sourceY:e.y,targetX:n.x,targetY:n.y});if(s[f]*c[f]===-1){f===`x`?(h=i.x??l.x+(u.x-l.x)*o,g=i.y??(l.y+u.y)/2):(h=i.x??(l.x+u.x)/2,g=i.y??l.y+(u.y-l.y)*o);let e=[{x:h,y:l.y},{x:h,y:u.y}],t=[{x:l.x,y:g},{x:u.x,y:g}];m=s[f]===p?f===`x`?e:t:f===`x`?t:e}else{let i=[{x:l.x,y:u.y}],o=[{x:u.x,y:l.y}];if(m=f===`x`?s.x===p?o:i:s.y===p?i:o,t===r){let t=Math.abs(e[f]-n[f]);if(t<=a){let r=Math.min(a-1,a-t);s[f]===p?_[f]=(l[f]>e[f]?-1:1)*r:v[f]=(u[f]>n[f]?-1:1)*r}}if(t!==r){let e=f===`x`?`y`:`x`,t=s[f]===c[e],n=l[e]>u[e],r=l[e]=Math.max(Math.abs(d.y-m[0].y),Math.abs(y.y-m[0].y))?(h=(d.x+y.x)/2,g=m[0].y):(h=m[0].x,g=(d.y+y.y)/2)}let x={x:l.x+_.x,y:l.y+_.y},S={x:u.x+v.x,y:u.y+v.y};return[[e,...x.x!==m[0].x||x.y!==m[0].y?[x]:[],...m,...S.x!==m[m.length-1].x||S.y!==m[m.length-1].y?[S]:[],n],h,g,y,b]}function xo(e,t,n,r){let i=Math.min(yo(e,t)/2,yo(t,n)/2,r),{x:a,y:o}=t;if(e.x===a&&a===n.x||e.y===o&&o===n.y)return`L${a} ${o}`;if(e.y===o){let t=e.xe.id===t):e[0])||null}function Oo(e,t){return e?typeof e==`string`?e:`${t?`${t}__`:``}${Object.keys(e).sort().map(t=>`${t}=${e[t]}`).join(`&`)}`:``}function ko(e,{id:t,defaultColor:n,defaultMarkerStart:r,defaultMarkerEnd:i}){let a=new Set;return e.reduce((e,o)=>([o.markerStart||r,o.markerEnd||i].forEach(r=>{if(r&&typeof r==`object`){let i=Oo(r,t);a.has(i)||(e.push({id:i,color:r.color||n,...r}),a.add(i))}}),e),[]).sort((e,t)=>e.id.localeCompare(t.id))}var Ao=1e3,jo=10,Mo={nodeOrigin:[0,0],nodeExtent:Qi,elevateNodesOnSelect:!0,zIndexMode:`basic`,defaults:{}},No={...Mo,checkEquality:!0};function Po(e,t){let n={...e};for(let e in t)t[e]!==void 0&&(n[e]=t[e]);return n}function Fo(e,t,n){let r=Po(Mo,n);for(let n of e.values())if(n.parentId)Bo(n,e,t,r);else{let e=Sa(fa(n,r.nodeOrigin),Wa(n.extent)?n.extent:r.nodeExtent,Ga(n));n.internals.positionAbsolute=e}}function Io(e,t){if(!e.handles)return e.measured?t?.internals.handleBounds:void 0;let n=[],r=[];for(let t of e.handles){let i={id:t.id,width:t.width??1,height:t.height??1,nodeId:e.id,x:t.x,y:t.y,position:t.position,type:t.type};t.type===`source`?n.push(i):t.type===`target`&&r.push(i)}return{source:n,target:r}}function Lo(e){return e===`manual`}function Ro(e,t,n,r={}){let i=Po(No,r),a={i:0},o=new Map(t),s=i?.elevateNodesOnSelect&&!Lo(i.zIndexMode)?Ao:0,c=e.length>0,l=!1;t.clear(),n.clear();for(let u of e){let e=o.get(u.id);if(i.checkEquality&&u===e?.internals.userNode)t.set(u.id,e);else{let n=Sa(fa(u,i.nodeOrigin),Wa(u.extent)?u.extent:i.nodeExtent,Ga(u));e={...i.defaults,...u,measured:{width:u.measured?.width,height:u.measured?.height},internals:{positionAbsolute:n,handleBounds:Io(u,e),z:Vo(u,s,i.zIndexMode),userNode:u}},t.set(u.id,e)}(e.measured===void 0||e.measured.width===void 0||e.measured.height===void 0)&&!e.hidden&&(c=!1),u.parentId&&Bo(e,t,n,r,a),l||=u.selected??!1}return{nodesInitialized:c,hasSelectedNodes:l}}function zo(e,t){if(!e.parentId)return;let n=t.get(e.parentId);n?n.set(e.id,e):t.set(e.parentId,new Map([[e.id,e]]))}function Bo(e,t,n,r,i){let{elevateNodesOnSelect:a,nodeOrigin:o,nodeExtent:s,zIndexMode:c}=Po(Mo,r),l=e.parentId,u=t.get(l);if(!u){console.warn(`Parent node ${l} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}zo(e,n),i&&!u.parentId&&u.internals.rootParentIndex===void 0&&c===`auto`&&(u.internals.rootParentIndex=++i.i,u.internals.z=u.internals.z+i.i*jo),i&&u.internals.rootParentIndex!==void 0&&(i.i=u.internals.rootParentIndex);let{x:d,y:f,z:p}=Ho(e,u,o,s,a&&!Lo(c)?Ao:0,c),{positionAbsolute:m}=e.internals,h=d!==m.x||f!==m.y;(h||p!==e.internals.z)&&t.set(e.id,{...e,internals:{...e.internals,positionAbsolute:h?{x:d,y:f}:m,z:p}})}function Vo(e,t,n){let r=Pa(e.zIndex)?e.zIndex:0;return Lo(n)?r:r+(e.selected?t:0)}function Ho(e,t,n,r,i,a){let{x:o,y:s}=t.internals.positionAbsolute,c=Ga(e),l=fa(e,n),u=Wa(e.extent)?Sa(l,e.extent,c):l,d=Sa({x:o+u.x,y:s+u.y},r,c);e.extent===`parent`&&(d=Ca(d,c,t));let f=Vo(e,i,a),p=t.internals.z??0;return{x:d.x,y:d.y,z:p>=f?p+1:f}}function Uo(e,t,n,r=[0,0]){let i=[],a=new Map;for(let n of e){let e=t.get(n.parentId);if(!e)continue;let r=ja(a.get(n.parentId)?.expandedRect??ka(e),n.rect);a.set(n.parentId,{expandedRect:r,parent:e})}return a.size>0&&a.forEach(({expandedRect:t,parent:a},o)=>{let s=a.internals.positionAbsolute,c=Ga(a),l=a.origin??r,u=t.x0||d>0||m||h)&&(i.push({id:o,type:`position`,position:{x:a.position.x-u+m,y:a.position.y-d+h}}),n.get(o)?.forEach(t=>{e.some(e=>e.id===t.id)||i.push({id:t.id,type:`position`,position:{x:t.position.x+u,y:t.position.y+d}})})),(c.width0){let e=Uo(f,t,n,i);l.push(...e)}return{changes:l,updatedInternals:c}}async function Go({delta:e,panZoom:t,transform:n,translateExtent:r,width:i,height:a}){if(!t||!e.x&&!e.y)return Promise.resolve(!1);let o=await t.setViewportConstrained({x:n[0]+e.x,y:n[1]+e.y,zoom:n[2]},[[0,0],[i,a]],r),s=!!o&&(o.x!==n[0]||o.y!==n[1]||o.k!==n[2]);return Promise.resolve(s)}function Ko(e,t,n,r,i,a){let o=i,s=r.get(o)||new Map;r.set(o,s.set(n,t)),o=`${i}-${e}`;let c=r.get(o)||new Map;if(r.set(o,c.set(n,t)),a){o=`${i}-${e}-${a}`;let s=r.get(o)||new Map;r.set(o,s.set(n,t))}}function qo(e,t,n){e.clear(),t.clear();for(let r of n){let{source:n,target:i,sourceHandle:a=null,targetHandle:o=null}=r,s={edgeId:r.id,source:n,target:i,sourceHandle:a,targetHandle:o},c=`${n}-${a}--${i}-${o}`;Ko(`source`,s,`${i}-${o}--${n}-${a}`,e,n,a),Ko(`target`,s,c,e,i,o),t.set(r.id,r)}}function Jo(e,t){if(!e.parentId)return!1;let n=t.get(e.parentId);return n?n.selected?!0:Jo(n,t):!1}function Yo(e,t,n){let r=e;do{if(r?.matches?.(t))return!0;if(r===n)return!1;r=r?.parentElement}while(r);return!1}function Xo(e,t,n,r){let i=new Map;for(let[a,o]of e)if((o.selected||o.id===r)&&(!o.parentId||!Jo(o,e))&&(o.draggable||t&&o.draggable===void 0)){let t=e.get(a);t&&i.set(a,{id:a,position:t.position||{x:0,y:0},distance:{x:n.x-t.internals.positionAbsolute.x,y:n.y-t.internals.positionAbsolute.y},extent:t.extent,parentId:t.parentId,origin:t.origin,expandParent:t.expandParent,internals:{positionAbsolute:t.internals.positionAbsolute||{x:0,y:0}},measured:{width:t.measured.width??0,height:t.measured.height??0}})}return i}function Zo({nodeId:e,dragItems:t,nodeLookup:n,dragging:r=!0}){let i=[];for(let[e,a]of t){let t=n.get(e)?.internals.userNode;t&&i.push({...t,position:a.position,dragging:r})}if(!e)return[i[0],i];let a=n.get(e)?.internals.userNode;return[a?{...a,position:t.get(e)?.position||a.position,dragging:r}:i[0],i]}function Qo({dragItems:e,snapGrid:t,x:n,y:r}){let i=e.values().next().value;if(!i)return null;let a={x:n-i.distance.x,y:r-i.distance.y},o=Ia(a,t);return{x:o.x-a.x,y:o.y-a.y}}function $o({onNodeMouseDown:e,getStoreItems:t,onDragStart:n,onDrag:r,onDragStop:i}){let a={x:null,y:null},o=0,s=new Map,c=!1,l={x:0,y:0},u=null,d=!1,f=null,p=!1,m=!1,h=null;function g({noDragClassName:g,handleSelector:_,domNode:v,isSelectable:y,nodeId:b,nodeClickDistance:x=0}){f=q(v);function S({x:e,y:n}){let{nodeLookup:i,nodeExtent:o,snapGrid:c,snapToGrid:l,nodeOrigin:u,onNodeDrag:d,onSelectionDrag:f,onError:p,updateNodePositions:g}=t();a={x:e,y:n};let _=!1,v=s.size>1,y=v&&o?Da(ma(s)):null,x=v&&l?Qo({dragItems:s,snapGrid:c,x:e,y:n}):null;for(let[t,r]of s){if(!i.has(t))continue;let a={x:e-r.distance.x,y:n-r.distance.y};l&&(a=x?{x:Math.round(a.x+x.x),y:Math.round(a.y+x.y)}:Ia(a,c));let s=null;if(v&&o&&!r.extent&&y){let{positionAbsolute:e}=r.internals,t=e.x-y.x+o[0][0],n=e.x+r.measured.width-y.x2+o[1][0],i=e.y-y.y+o[0][1],a=e.y+r.measured.height-y.y2+o[1][1];s=[[t,i],[n,a]]}let{position:d,positionAbsolute:f}=ya({nodeId:t,nextPosition:a,nodeLookup:i,nodeExtent:s||o,nodeOrigin:u,onError:p});_=_||r.position.x!==d.x||r.position.y!==d.y,r.position=d,r.internals.positionAbsolute=f}if(m||=_,_&&(g(s,!0),h&&(r||d||!b&&f))){let[e,t]=Zo({nodeId:b,dragItems:s,nodeLookup:i});r?.(h,s,e,t),d?.(h,e,t),b||f?.(h,t)}}async function C(){if(!u)return;let{transform:e,panBy:n,autoPanSpeed:r,autoPanOnNodeDrag:i}=t();if(!i){c=!1,cancelAnimationFrame(o);return}let[s,d]=Ta(l,u,r);(s!==0||d!==0)&&(a.x=(a.x??0)-s/e[2],a.y=(a.y??0)-d/e[2],await n({x:s,y:d})&&S(a)),o=requestAnimationFrame(C)}function w(r){let{nodeLookup:i,multiSelectionActive:o,nodesDraggable:c,transform:l,snapGrid:f,snapToGrid:p,selectNodesOnDrag:m,onNodeDragStart:h,onSelectionDragStart:g,unselectNodesAndEdges:_}=t();d=!0,(!m||!y)&&!o&&b&&(i.get(b)?.selected||_()),y&&m&&b&&e?.(b);let v=Za(r.sourceEvent,{transform:l,snapGrid:f,snapToGrid:p,containerBounds:u});if(a=v,s=Xo(i,c,v,b),s.size>0&&(n||h||!b&&g)){let[e,t]=Zo({nodeId:b,dragItems:s,nodeLookup:i});n?.(r.sourceEvent,s,e,t),h?.(r.sourceEvent,e,t),b||g?.(r.sourceEvent,t)}}let T=Nt().clickDistance(x).on(`start`,e=>{let{domNode:n,nodeDragThreshold:r,transform:i,snapGrid:o,snapToGrid:s}=t();u=n?.getBoundingClientRect()||null,p=!1,m=!1,h=e.sourceEvent,r===0&&w(e),a=Za(e.sourceEvent,{transform:i,snapGrid:o,snapToGrid:s,containerBounds:u}),l=ro(e.sourceEvent,u)}).on(`drag`,e=>{let{autoPanOnNodeDrag:n,transform:r,snapGrid:i,snapToGrid:o,nodeDragThreshold:f,nodeLookup:m}=t(),g=Za(e.sourceEvent,{transform:r,snapGrid:i,snapToGrid:o,containerBounds:u});if(h=e.sourceEvent,(e.sourceEvent.type===`touchmove`&&e.sourceEvent.touches.length>1||b&&!m.has(b))&&(p=!0),!p){if(!c&&n&&d&&(c=!0,C()),!d){let t=ro(e.sourceEvent,u),n=t.x-l.x,r=t.y-l.y;Math.sqrt(n*n+r*r)>f&&w(e)}(a.x!==g.xSnapped||a.y!==g.ySnapped)&&s&&d&&(l=ro(e.sourceEvent,u),S(g))}}).on(`end`,e=>{if(!(!d||p)&&(c=!1,d=!1,cancelAnimationFrame(o),s.size>0)){let{nodeLookup:n,updateNodePositions:r,onNodeDragStop:a,onSelectionDragStop:o}=t();if(m&&=(r(s,!1),!1),i||a||!b&&o){let[t,r]=Zo({nodeId:b,dragItems:s,nodeLookup:n,dragging:!1});i?.(e.sourceEvent,s,t,r),a?.(e.sourceEvent,t,r),b||o?.(e.sourceEvent,r)}}}).filter(e=>{let t=e.target;return!e.button&&(!g||!Yo(t,`.${g}`,v))&&(!_||Yo(t,_,v))});f.call(T)}function _(){f?.on(`.drag`,null)}return{update:g,destroy:_}}function es(e,t,n){let r=[],i={x:e.x-n,y:e.y-n,width:n*2,height:n*2};for(let e of t.values())Ma(i,ka(e))>0&&r.push(e);return r}var ts=250;function ns(e,t,n,r){let i=[],a=1/0,o=es(e,n,t+ts);for(let n of o){let o=[...n.internals.handleBounds?.source??[],...n.internals.handleBounds?.target??[]];for(let s of o){if(r.nodeId===s.nodeId&&r.type===s.type&&r.id===s.id)continue;let{x:o,y:c}=Eo(n,s,s.position,!0),l=Math.sqrt((o-e.x)**2+(c-e.y)**2);l>t||(l1){let e=r.type===`source`?`target`:`source`;return i.find(t=>t.type===e)??i[0]}return i[0]}function rs(e,t,n,r,i,a=!1){let o=r.get(e);if(!o)return null;let s=i===`strict`?o.internals.handleBounds?.[t]:[...o.internals.handleBounds?.source??[],...o.internals.handleBounds?.target??[]],c=(n?s?.find(e=>e.id===n):s?.[0])??null;return c&&a?{...c,...Eo(o,c,c.position,!0)}:c}function is(e,t){return e||(t?.classList.contains(`target`)?`target`:t?.classList.contains(`source`)?`source`:null)}function as(e,t){let n=null;return t?n=!0:e&&!t&&(n=!1),n}var os=()=>!0;function ss(e,{connectionMode:t,connectionRadius:n,handleId:r,nodeId:i,edgeUpdaterType:a,isTarget:o,domNode:s,nodeLookup:c,lib:l,autoPanOnConnect:u,flowId:d,panBy:f,cancelConnection:p,onConnectStart:m,onConnect:h,onConnectEnd:g,isValidConnection:_=os,onReconnectEnd:v,updateConnection:y,getTransform:b,getFromHandle:x,autoPanSpeed:S,dragThreshold:C=1,handleDomNode:w}){let T=$a(e.target),E=0,D,{x:O,y:k}=ro(e),A=is(a,w),j=s?.getBoundingClientRect(),M=!1;if(!j||!A)return;let N=rs(i,A,r,c,t);if(!N)return;let P=ro(e,j),F=!1,I=null,L=!1,R=null;function z(){if(!u||!j)return;let[e,t]=Ta(P,j,S);f({x:e,y:t}),E=requestAnimationFrame(z)}let B={...N,nodeId:i,type:A,position:N.position},V=c.get(i),H={inProgress:!0,isValid:null,from:Eo(V,B,X.Left,!0),fromHandle:B,fromPosition:B.position,fromNode:V,to:P,toHandle:null,toPosition:sa[B.position],toNode:null,pointer:P};function U(){M=!0,y(H),m?.(e,{nodeId:i,handleId:r,handleType:A})}C===0&&U();function W(e){if(!M){let{x:t,y:n}=ro(e),r=t-O,i=n-k;if(!(r*r+i*i>C*C))return;U()}if(!x()||!B){G(e);return}let a=b();P=ro(e,j),D=ns(La(P,a,!1,[1,1]),n,c,B),F||=(z(),!0);let s=cs(e,{handle:D,connectionMode:t,fromNodeId:i,fromHandleId:r,fromType:o?`target`:`source`,isValidConnection:_,doc:T,lib:l,flowId:d,nodeLookup:c});R=s.handleDomNode,I=s.connection,L=as(!!D,s.isValid);let u=c.get(i),f=u?Eo(u,B,X.Left,!0):H.from,p={...H,from:f,isValid:L,to:s.toHandle&&L?Ra({x:s.toHandle.x,y:s.toHandle.y},a):P,toHandle:s.toHandle,toPosition:L&&s.toHandle?s.toHandle.position:sa[B.position],toNode:s.toHandle?c.get(s.toHandle.nodeId):null,pointer:P};y(p),H=p}function G(e){if(!(`touches`in e&&e.touches.length>0)){if(M){(D||R)&&I&&L&&h?.(I);let{inProgress:t,...n}=H,r={...n,toPosition:H.toHandle?H.toPosition:null};g?.(e,r),a&&v?.(e,r)}p(),cancelAnimationFrame(E),F=!1,L=!1,I=null,R=null,T.removeEventListener(`mousemove`,W),T.removeEventListener(`mouseup`,G),T.removeEventListener(`touchmove`,W),T.removeEventListener(`touchend`,G)}}T.addEventListener(`mousemove`,W),T.addEventListener(`mouseup`,G),T.addEventListener(`touchmove`,W),T.addEventListener(`touchend`,G)}function cs(e,{handle:t,connectionMode:n,fromNodeId:r,fromHandleId:i,fromType:a,doc:o,lib:s,flowId:c,isValidConnection:l=os,nodeLookup:u}){let d=a===`target`,f=t?o.querySelector(`.${s}-flow__handle[data-id="${c}-${t?.nodeId}-${t?.id}-${t?.type}"]`):null,{x:p,y:m}=ro(e),h=o.elementFromPoint(p,m),g=h?.classList.contains(`${s}-flow__handle`)?h:f,_={handleDomNode:g,isValid:!1,connection:null,toHandle:null};if(g){let e=is(void 0,g),t=g.getAttribute(`data-nodeid`),a=g.getAttribute(`data-handleid`),o=g.classList.contains(`connectable`),s=g.classList.contains(`connectableend`);if(!t||!e)return _;let c={source:d?t:r,sourceHandle:d?a:i,target:d?r:t,targetHandle:d?i:a};_.connection=c,_.isValid=o&&s&&(n===ta.Strict?d&&e===`source`||!d&&e===`target`:t!==r||a!==i)&&l(c),_.toHandle=rs(t,e,a,u,n,!0)}return _}var ls={onPointerDown:ss,isValid:cs};function us({domNode:e,panZoom:t,getTransform:n,getViewScale:r}){let i=q(e);function a({translateExtent:e,width:a,height:o,zoomStep:s=1,pannable:c=!0,zoomable:l=!0,inversePan:u=!1}){let d=e=>{if(e.sourceEvent.type!==`wheel`||!t)return;let r=n(),i=e.sourceEvent.ctrlKey&&Ua()?10:1,a=-e.sourceEvent.deltaY*(e.sourceEvent.deltaMode===1?.05:e.sourceEvent.deltaMode?1:.002)*s,o=r[2]*2**(a*i);t.scaleTo(o)},f=[0,0],p=Xi().on(`start`,e=>{(e.sourceEvent.type===`mousedown`||e.sourceEvent.type===`touchstart`)&&(f=[e.sourceEvent.clientX??e.sourceEvent.touches[0].clientX,e.sourceEvent.clientY??e.sourceEvent.touches[0].clientY])}).on(`zoom`,c?i=>{let s=n();if(i.sourceEvent.type!==`mousemove`&&i.sourceEvent.type!==`touchmove`||!t)return;let c=[i.sourceEvent.clientX??i.sourceEvent.touches[0].clientX,i.sourceEvent.clientY??i.sourceEvent.touches[0].clientY],l=[c[0]-f[0],c[1]-f[1]];f=c;let d=r()*Math.max(s[2],Math.log(s[2]))*(u?-1:1),p={x:s[0]-l[0]*d,y:s[1]-l[1]*d},m=[[0,0],[a,o]];t.setViewportConstrained({x:p.x,y:p.y,zoom:s[2]},m,e)}:null).on(`zoom.wheel`,l?d:null);i.call(p,{})}function o(){i.on(`zoom`,null)}return{update:a,destroy:o,pointer:J}}var ds=e=>({x:e.x,y:e.y,zoom:e.k}),fs=({x:e,y:t,zoom:n})=>Bi.translate(e,t).scale(n),ps=(e,t)=>e.target.closest(`.${t}`),ms=(e,t)=>t===2&&Array.isArray(e)&&e.includes(2),hs=e=>((e*=2)<=1?e*e*e:(e-=2)*e*e+2)/2,gs=(e,t=0,n=hs,r=()=>{})=>{let i=typeof t==`number`&&t>0;return i||r(),i?e.transition().duration(t).ease(n).on(`end`,r):e},_s=e=>{let t=e.ctrlKey&&Ua()?10:1;return-e.deltaY*(e.deltaMode===1?.05:e.deltaMode?1:.002)*t};function vs({zoomPanValues:e,noWheelClassName:t,d3Selection:n,d3Zoom:r,panOnScrollMode:i,panOnScrollSpeed:a,zoomOnPinch:o,onPanZoomStart:s,onPanZoom:c,onPanZoomEnd:l}){return u=>{if(ps(u,t))return u.ctrlKey&&u.preventDefault(),!1;u.preventDefault(),u.stopImmediatePropagation();let d=n.property(`__zoom`).k||1;if(u.ctrlKey&&o){let e=J(u),t=d*2**_s(u);r.scaleTo(n,t,e,u);return}let f=u.deltaMode===1?20:1,p=i===na.Vertical?0:u.deltaX*f,m=i===na.Horizontal?0:u.deltaY*f;!Ua()&&u.shiftKey&&i!==na.Vertical&&(p=u.deltaY*f,m=0),r.translateBy(n,-(p/d)*a,-(m/d)*a,{internal:!0});let h=ds(n.property(`__zoom`));clearTimeout(e.panScrollTimeout),e.isPanScrolling?(c?.(u,h),e.panScrollTimeout=setTimeout(()=>{l?.(u,h),e.isPanScrolling=!1},150)):(e.isPanScrolling=!0,s?.(u,h))}}function ys({noWheelClassName:e,preventScrolling:t,d3ZoomHandler:n}){return function(r,i){let a=r.type===`wheel`,o=!t&&a&&!r.ctrlKey,s=ps(r,e);if(r.ctrlKey&&a&&s&&r.preventDefault(),o||s)return null;r.preventDefault(),n.call(this,r,i)}}function bs({zoomPanValues:e,onDraggingChange:t,onPanZoomStart:n}){return r=>{if(r.sourceEvent?.internal)return;let i=ds(r.transform);e.mouseButton=r.sourceEvent?.button||0,e.isZoomingOrPanning=!0,e.prevViewport=i,r.sourceEvent?.type===`mousedown`&&t(!0),n&&n?.(r.sourceEvent,i)}}function xs({zoomPanValues:e,panOnDrag:t,onPaneContextMenu:n,onTransformChange:r,onPanZoom:i}){return a=>{e.usedRightMouseButton=!!(n&&ms(t,e.mouseButton??0)),a.sourceEvent?.sync||r([a.transform.x,a.transform.y,a.transform.k]),i&&!a.sourceEvent?.internal&&i?.(a.sourceEvent,ds(a.transform))}}function Ss({zoomPanValues:e,panOnDrag:t,panOnScroll:n,onDraggingChange:r,onPanZoomEnd:i,onPaneContextMenu:a}){return o=>{if(!o.sourceEvent?.internal&&(e.isZoomingOrPanning=!1,a&&ms(t,e.mouseButton??0)&&!e.usedRightMouseButton&&o.sourceEvent&&a(o.sourceEvent),e.usedRightMouseButton=!1,r(!1),i)){let t=ds(o.transform);e.prevViewport=t,clearTimeout(e.timerId),e.timerId=setTimeout(()=>{i?.(o.sourceEvent,t)},n?150:0)}}}function Cs({zoomActivationKeyPressed:e,zoomOnScroll:t,zoomOnPinch:n,panOnDrag:r,panOnScroll:i,zoomOnDoubleClick:a,userSelectionActive:o,noWheelClassName:s,noPanClassName:c,lib:l,connectionInProgress:u}){return d=>{let f=e||t,p=n&&d.ctrlKey,m=d.type===`wheel`;if(d.button===1&&d.type===`mousedown`&&(ps(d,`${l}-flow__node`)||ps(d,`${l}-flow__edge`)))return!0;if(!r&&!f&&!i&&!a&&!n||o||u&&!m||ps(d,s)&&m||ps(d,c)&&(!m||i&&m&&!e)||!n&&d.ctrlKey&&m)return!1;if(!n&&d.type===`touchstart`&&d.touches?.length>1)return d.preventDefault(),!1;if(!f&&!i&&!p&&m||!r&&(d.type===`mousedown`||d.type===`touchstart`)||Array.isArray(r)&&!r.includes(d.button)&&d.type===`mousedown`)return!1;let h=Array.isArray(r)&&r.includes(d.button)||!d.button||d.button<=1;return(!d.ctrlKey||m)&&h}}function ws({domNode:e,minZoom:t,maxZoom:n,translateExtent:r,viewport:i,onPanZoom:a,onPanZoomStart:o,onPanZoomEnd:s,onDraggingChange:c}){let l={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{x:0,y:0,zoom:0},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},u=e.getBoundingClientRect(),d=Xi().scaleExtent([t,n]).translateExtent(r),f=q(e).call(d);v({x:i.x,y:i.y,zoom:xa(i.zoom,t,n)},[[0,0],[u.width,u.height]],r);let p=f.on(`wheel.zoom`),m=f.on(`dblclick.zoom`);d.wheelDelta(_s);function h(e,t){return f?new Promise(n=>{d?.interpolate(t?.interpolate===`linear`?In:Xn).transform(gs(f,t?.duration,t?.ease,()=>n(!0)),e)}):Promise.resolve(!1)}function g({noWheelClassName:e,noPanClassName:t,onPaneContextMenu:n,userSelectionActive:r,panOnScroll:i,panOnDrag:u,panOnScrollMode:h,panOnScrollSpeed:g,preventScrolling:v,zoomOnPinch:y,zoomOnScroll:b,zoomOnDoubleClick:x,zoomActivationKeyPressed:S,lib:C,onTransformChange:w,connectionInProgress:T,paneClickDistance:E,selectionOnDrag:D}){r&&!l.isZoomingOrPanning&&_();let O=i&&!S&&!r;d.clickDistance(D?1/0:!Pa(E)||E<0?0:E);let k=O?vs({zoomPanValues:l,noWheelClassName:e,d3Selection:f,d3Zoom:d,panOnScrollMode:h,panOnScrollSpeed:g,zoomOnPinch:y,onPanZoomStart:o,onPanZoom:a,onPanZoomEnd:s}):ys({noWheelClassName:e,preventScrolling:v,d3ZoomHandler:p});if(f.on(`wheel.zoom`,k,{passive:!1}),!r){let e=bs({zoomPanValues:l,onDraggingChange:c,onPanZoomStart:o});d.on(`start`,e);let t=xs({zoomPanValues:l,panOnDrag:u,onPaneContextMenu:!!n,onPanZoom:a,onTransformChange:w});d.on(`zoom`,t);let r=Ss({zoomPanValues:l,panOnDrag:u,panOnScroll:i,onPaneContextMenu:n,onPanZoomEnd:s,onDraggingChange:c});d.on(`end`,r)}let A=Cs({zoomActivationKeyPressed:S,panOnDrag:u,zoomOnScroll:b,panOnScroll:i,zoomOnDoubleClick:x,zoomOnPinch:y,userSelectionActive:r,noPanClassName:t,noWheelClassName:e,lib:C,connectionInProgress:T});d.filter(A),x?f.on(`dblclick.zoom`,m):f.on(`dblclick.zoom`,null)}function _(){d.on(`zoom`,null)}async function v(e,t,n){let r=fs(e),i=d?.constrain()(r,t,n);return i&&await h(i),new Promise(e=>e(i))}async function y(e,t){let n=fs(e);return await h(n,t),new Promise(e=>e(n))}function b(e){if(f){let t=fs(e),n=f.property(`__zoom`);(n.k!==e.zoom||n.x!==e.x||n.y!==e.y)&&d?.transform(f,t,null,{sync:!0})}}function x(){let e=f?Vi(f.node()):{x:0,y:0,k:1};return{x:e.x,y:e.y,zoom:e.k}}function S(e,t){return f?new Promise(n=>{d?.interpolate(t?.interpolate===`linear`?In:Xn).scaleTo(gs(f,t?.duration,t?.ease,()=>n(!0)),e)}):Promise.resolve(!1)}function C(e,t){return f?new Promise(n=>{d?.interpolate(t?.interpolate===`linear`?In:Xn).scaleBy(gs(f,t?.duration,t?.ease,()=>n(!0)),e)}):Promise.resolve(!1)}function w(e){d?.scaleExtent(e)}function T(e){d?.translateExtent(e)}function E(e){let t=!Pa(e)||e<0?0:e;d?.clickDistance(t)}return{update:g,destroy:_,setViewport:y,setViewportConstrained:v,getViewport:x,scaleTo:S,scaleBy:C,setScaleExtent:w,setTranslateExtent:T,syncViewport:b,setClickDistance:E}}var Ts;(function(e){e.Line=`line`,e.Handle=`handle`})(Ts||={});function Es({width:e,prevWidth:t,height:n,prevHeight:r,affectsX:i,affectsY:a}){let o=e-t,s=n-r,c=[o>0?1:o<0?-1:0,s>0?1:s<0?-1:0];return o&&i&&(c[0]*=-1),s&&a&&(c[1]*=-1),c}function Ds(e){return{isHorizontal:e.includes(`right`)||e.includes(`left`),isVertical:e.includes(`bottom`)||e.includes(`top`),affectsX:e.includes(`left`),affectsY:e.includes(`top`)}}function Os(e,t){return Math.max(0,t-e)}function ks(e,t){return Math.max(0,e-t)}function As(e,t,n){return Math.max(0,t-e,e-n)}function js(e,t){return e?!t:t}function Ms(e,t,n,r,i,a,o,s){let{affectsX:c,affectsY:l}=t,{isHorizontal:u,isVertical:d}=t,f=u&&d,{xSnapped:p,ySnapped:m}=n,{minWidth:h,maxWidth:g,minHeight:_,maxHeight:v}=r,{x:y,y:b,width:x,height:S,aspectRatio:C}=e,w=Math.floor(u?p-e.pointerX:0),T=Math.floor(d?m-e.pointerY:0),E=x+(c?-w:w),D=S+(l?-T:T),O=-a[0]*x,k=-a[1]*S,A=As(E,h,g),j=As(D,_,v);if(o){let e=0,t=0;c&&w<0?e=Os(y+w+O,o[0][0]):!c&&w>0&&(e=ks(y+E+O,o[1][0])),l&&T<0?t=Os(b+T+k,o[0][1]):!l&&T>0&&(t=ks(b+D+k,o[1][1])),A=Math.max(A,e),j=Math.max(j,t)}if(s){let e=0,t=0;c&&w>0?e=ks(y+w,s[0][0]):!c&&w<0&&(e=Os(y+E,s[1][0])),l&&T>0?t=ks(b+T,s[0][1]):!l&&T<0&&(t=Os(b+D,s[1][1])),A=Math.max(A,e),j=Math.max(j,t)}if(i){if(u){let e=As(E/C,_,v)*C;if(A=Math.max(A,e),o){let e=0;e=!c&&!l||c&&!l&&f?ks(b+k+E/C,o[1][1])*C:Os(b+k+(c?w:-w)/C,o[0][1])*C,A=Math.max(A,e)}if(s){let e=0;e=!c&&!l||c&&!l&&f?Os(b+E/C,s[1][1])*C:ks(b+(c?w:-w)/C,s[0][1])*C,A=Math.max(A,e)}}if(d){let e=As(D*C,h,g)/C;if(j=Math.max(j,e),o){let e=0;e=!c&&!l||l&&!c&&f?ks(y+D*C+O,o[1][0])/C:Os(y+(l?T:-T)*C+O,o[0][0])/C,j=Math.max(j,e)}if(s){let e=0;e=!c&&!l||l&&!c&&f?Os(y+D*C,s[1][0])/C:ks(y+(l?T:-T)*C,s[0][0])/C,j=Math.max(j,e)}}}T+=T<0?j:-j,w+=w<0?A:-A,i&&(f?E>D*C?T=(js(c,l)?-w:w)/C:w=(js(c,l)?-T:T)*C:u?(T=w/C,l=c):(w=T*C,c=l));let M=c?y+w:y,N=l?b+T:b;return{width:x+(c?-w:w),height:S+(l?-T:T),x:a[0]*w*(c?-1:1)+M,y:a[1]*T*(l?-1:1)+N}}var Ns={width:0,height:0,x:0,y:0},Ps={...Ns,pointerX:0,pointerY:0,aspectRatio:1};function Fs(e){return[[0,0],[e.measured.width,e.measured.height]]}function Is(e,t,n){let r=t.position.x+e.position.x,i=t.position.y+e.position.y,a=e.measured.width??0,o=e.measured.height??0,s=n[0]*a,c=n[1]*o;return[[r-s,i-c],[r+a-s,i+o-c]]}function Ls({domNode:e,nodeId:t,getStoreItems:n,onChange:r,onEnd:i}){let a=q(e),o={controlDirection:Ds(`bottom-right`),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function s({controlPosition:e,boundaries:s,keepAspectRatio:c,resizeDirection:l,onResizeStart:u,onResize:d,onResizeEnd:f,shouldResize:p}){let m={...Ns},h={...Ps};o={boundaries:s,resizeDirection:l,keepAspectRatio:c,controlDirection:Ds(e)};let g,_=null,v=[],y,b,x,S=!1,C=Nt().on(`start`,e=>{let{nodeLookup:r,transform:i,snapGrid:a,snapToGrid:o,nodeOrigin:s,paneDomNode:c}=n();if(g=r.get(t),!g)return;_=c?.getBoundingClientRect()??null;let{xSnapped:l,ySnapped:d}=Za(e.sourceEvent,{transform:i,snapGrid:a,snapToGrid:o,containerBounds:_});m={width:g.measured.width??0,height:g.measured.height??0,x:g.position.x??0,y:g.position.y??0},h={...m,pointerX:l,pointerY:d,aspectRatio:m.width/m.height},y=void 0,g.parentId&&(g.extent===`parent`||g.expandParent)&&(y=r.get(g.parentId),b=y&&g.extent===`parent`?Fs(y):void 0),v=[],x=void 0;for(let[e,n]of r)if(n.parentId===t&&(v.push({id:e,position:{...n.position},extent:n.extent}),n.extent===`parent`||n.expandParent)){let e=Is(n,g,n.origin??s);x=x?[[Math.min(e[0][0],x[0][0]),Math.min(e[0][1],x[0][1])],[Math.max(e[1][0],x[1][0]),Math.max(e[1][1],x[1][1])]]:e}u?.(e,{...m})}).on(`drag`,e=>{let{transform:t,snapGrid:i,snapToGrid:a,nodeOrigin:s}=n(),c=Za(e.sourceEvent,{transform:t,snapGrid:i,snapToGrid:a,containerBounds:_}),l=[];if(!g)return;let{x:u,y:f,width:C,height:w}=m,T={},E=g.origin??s,{width:D,height:O,x:k,y:A}=Ms(h,o.controlDirection,c,o.boundaries,o.keepAspectRatio,E,b,x),j=D!==C,M=O!==w,N=k!==u&&j,P=A!==f&&M;if(!N&&!P&&!j&&!M)return;if((N||P||E[0]===1||E[1]===1)&&(T.x=N?k:m.x,T.y=P?A:m.y,m.x=T.x,m.y=T.y,v.length>0)){let e=k-u,t=A-f;for(let n of v)n.position={x:n.position.x-e+E[0]*(D-C),y:n.position.y-t+E[1]*(O-w)},l.push(n)}if((j||M)&&(T.width=j&&(!o.resizeDirection||o.resizeDirection===`horizontal`)?D:m.width,T.height=M&&(!o.resizeDirection||o.resizeDirection===`vertical`)?O:m.height,m.width=T.width,m.height=T.height),y&&g.expandParent){let e=E[0]*(T.width??0);T.x&&T.x{S&&=(f?.(e,{...m}),i?.({...m}),!1)});a.call(C)}function c(){a.on(`.drag`,null)}return{update:s,destroy:c}}var Rs=t((e=>{var t=n(),r=a();function i(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var o=typeof Object.is==`function`?Object.is:i,s=r.useSyncExternalStore,c=t.useRef,l=t.useEffect,u=t.useMemo,d=t.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,i){var a=c(null);if(a.current===null){var f={hasValue:!1,value:null};a.current=f}else f=a.current;a=u(function(){function e(e){if(!a){if(a=!0,s=e,e=r(e),i!==void 0&&f.hasValue){var t=f.value;if(i(t,e))return c=t}return c=e}if(t=c,o(s,e))return t;var n=r(e);return i!==void 0&&i(t,n)?(s=e,t):(s=e,c=n)}var a=!1,s,c,l=n===void 0?null:n;return[function(){return e(t())},l===null?void 0:function(){return e(l())}]},[t,n,r,i]);var p=s(e,a[0],a[1]);return l(function(){f.hasValue=!0,f.value=p},[p]),d(p),p}})),zs=e(t(((e,t)=>{t.exports=Rs()}))(),1),Bs=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e)),destroy:()=>{n.clear()}},o=t=e(r,i,a);return a},Vs=e=>e?Bs(e):Bs,{useDebugValue:Hs}=o.default,{useSyncExternalStoreWithSelector:Us}=zs.default,Ws=e=>e;function Gs(e,t=Ws,n){let r=Us(e.subscribe,e.getState,e.getServerState||e.getInitialState,t,n);return Hs(r),r}var Ks=(e,t)=>{let n=Vs(e),r=(e,r=t)=>Gs(n,e,r);return Object.assign(r,n),r},qs=(e,t)=>e?Ks(e,t):Ks;function Z(e,t){if(Object.is(e,t))return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[n,r]of e)if(!Object.is(r,t.get(n)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}let n=Object.keys(e);if(n.length!==Object.keys(t).length)return!1;for(let r of n)if(!Object.prototype.hasOwnProperty.call(t,r)||!Object.is(e[r],t[r]))return!1;return!0}i();var Js=(0,o.createContext)(null),Ys=Js.Provider,Xs=Zi.error001();function Q(e,t){let n=(0,o.useContext)(Js);if(n===null)throw Error(Xs);return Gs(n,e,t)}function $(){let e=(0,o.useContext)(Js);if(e===null)throw Error(Xs);return(0,o.useMemo)(()=>({getState:e.getState,setState:e.setState,subscribe:e.subscribe}),[e])}var Zs={display:`none`},Qs={position:`absolute`,width:1,height:1,margin:-1,border:0,padding:0,overflow:`hidden`,clip:`rect(0px, 0px, 0px, 0px)`,clipPath:`inset(100%)`},$s=`react-flow__node-desc`,ec=`react-flow__edge-desc`,tc=`react-flow__aria-live`,nc=e=>e.ariaLiveMessage,rc=e=>e.ariaLabelConfig;function ic({rfId:e}){let t=Q(nc);return(0,s.jsx)(`div`,{id:`${tc}-${e}`,"aria-live":`assertive`,"aria-atomic":`true`,style:Qs,children:t})}function ac({rfId:e,disableKeyboardA11y:t}){let n=Q(rc);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(`div`,{id:`${$s}-${e}`,style:Zs,children:t?n[`node.a11yDescription.default`]:n[`node.a11yDescription.keyboardDisabled`]}),(0,s.jsx)(`div`,{id:`${ec}-${e}`,style:Zs,children:n[`edge.a11yDescription.default`]}),!t&&(0,s.jsx)(ic,{rfId:e})]})}var oc=(0,o.forwardRef)(({position:e=`top-left`,children:t,className:n,style:r,...i},a)=>(0,s.jsx)(`div`,{className:c([`react-flow__panel`,n,...`${e}`.split(`-`)]),style:r,ref:a,...i,children:t}));oc.displayName=`Panel`;function sc({proOptions:e,position:t=`bottom-right`}){return e?.hideAttribution?null:(0,s.jsx)(oc,{position:t,className:`react-flow__attribution`,"data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: https://pro.reactflow.dev`,children:(0,s.jsx)(`a`,{href:`https://reactflow.dev`,target:`_blank`,rel:`noopener noreferrer`,"aria-label":`React Flow attribution`,children:`React Flow`})})}var cc=e=>{let t=[],n=[];for(let[,n]of e.nodeLookup)n.selected&&t.push(n.internals.userNode);for(let[,t]of e.edgeLookup)t.selected&&n.push(t);return{selectedNodes:t,selectedEdges:n}},lc=e=>e.id;function uc(e,t){return Z(e.selectedNodes.map(lc),t.selectedNodes.map(lc))&&Z(e.selectedEdges.map(lc),t.selectedEdges.map(lc))}function dc({onSelectionChange:e}){let t=$(),{selectedNodes:n,selectedEdges:r}=Q(cc,uc);return(0,o.useEffect)(()=>{let i={nodes:n,edges:r};e?.(i),t.getState().onSelectionChangeHandlers.forEach(e=>e(i))},[n,r,e]),null}var fc=e=>!!e.onSelectionChangeHandlers;function pc({onSelectionChange:e}){let t=Q(fc);return e||t?(0,s.jsx)(dc,{onSelectionChange:e}):null}var mc=typeof window<`u`?o.useLayoutEffect:o.useEffect,hc=[0,0],gc={x:0,y:0,zoom:1},_c=[...`nodes.edges.defaultNodes.defaultEdges.onConnect.onConnectStart.onConnectEnd.onClickConnectStart.onClickConnectEnd.nodesDraggable.autoPanOnNodeFocus.nodesConnectable.nodesFocusable.edgesFocusable.edgesReconnectable.elevateNodesOnSelect.elevateEdgesOnSelect.minZoom.maxZoom.nodeExtent.onNodesChange.onEdgesChange.elementsSelectable.connectionMode.snapGrid.snapToGrid.translateExtent.connectOnClick.defaultEdgeOptions.fitView.fitViewOptions.onNodesDelete.onEdgesDelete.onDelete.onNodeDrag.onNodeDragStart.onNodeDragStop.onSelectionDrag.onSelectionDragStart.onSelectionDragStop.onMoveStart.onMove.onMoveEnd.noPanClassName.nodeOrigin.autoPanOnConnect.autoPanOnNodeDrag.onError.connectionRadius.isValidConnection.selectNodesOnDrag.nodeDragThreshold.connectionDragThreshold.onBeforeDelete.debug.autoPanSpeed.ariaLabelConfig.zIndexMode`.split(`.`),`rfId`],vc=e=>({setNodes:e.setNodes,setEdges:e.setEdges,setMinZoom:e.setMinZoom,setMaxZoom:e.setMaxZoom,setTranslateExtent:e.setTranslateExtent,setNodeExtent:e.setNodeExtent,reset:e.reset,setDefaultNodesAndEdges:e.setDefaultNodesAndEdges}),yc={translateExtent:Qi,nodeOrigin:hc,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:`nopan`,rfId:`1`};function bc(e){let{setNodes:t,setEdges:n,setMinZoom:r,setMaxZoom:i,setTranslateExtent:a,setNodeExtent:s,reset:c,setDefaultNodesAndEdges:l}=Q(vc,Z),u=$();mc(()=>(l(e.defaultNodes,e.defaultEdges),()=>{d.current=yc,c()}),[]);let d=(0,o.useRef)(yc);return mc(()=>{for(let o of _c){let c=e[o];c!==d.current[o]&&e[o]!==void 0&&(o===`nodes`?t(c):o===`edges`?n(c):o===`minZoom`?r(c):o===`maxZoom`?i(c):o===`translateExtent`?a(c):o===`nodeExtent`?s(c):o===`ariaLabelConfig`?u.setState({ariaLabelConfig:Xa(c)}):o===`fitView`?u.setState({fitViewQueued:c}):o===`fitViewOptions`?u.setState({fitViewOptions:c}):u.setState({[o]:c}))}d.current=e},_c.map(t=>e[t])),null}function xc(){return typeof window>`u`||!window.matchMedia?null:window.matchMedia(`(prefers-color-scheme: dark)`)}function Sc(e){let[t,n]=(0,o.useState)(e===`system`?null:e);return(0,o.useEffect)(()=>{if(e!==`system`){n(e);return}let t=xc(),r=()=>n(t?.matches?`dark`:`light`);return r(),t?.addEventListener(`change`,r),()=>{t?.removeEventListener(`change`,r)}},[e]),t===null?xc()?.matches?`dark`:`light`:t}var Cc=typeof document<`u`?document:null;function wc(e=null,t={target:Cc,actInsideInputWithModifier:!0}){let[n,r]=(0,o.useState)(!1),i=(0,o.useRef)(!1),a=(0,o.useRef)(new Set([])),[s,c]=(0,o.useMemo)(()=>{if(e!==null){let t=(Array.isArray(e)?e:[e]).filter(e=>typeof e==`string`).map(e=>e.replace(`+`,` `).replace(` `,` diff --git a/semantica/static/assets/TimelinePanel-YrOmsTlw.js b/semantica/static/assets/TimelinePanel-DZ8Z1JsZ.js similarity index 98% rename from semantica/static/assets/TimelinePanel-YrOmsTlw.js rename to semantica/static/assets/TimelinePanel-DZ8Z1JsZ.js index 8b59967e..0bd5131b 100644 --- a/semantica/static/assets/TimelinePanel-YrOmsTlw.js +++ b/semantica/static/assets/TimelinePanel-DZ8Z1JsZ.js @@ -1,4 +1,4 @@ -import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{T as t,a as n}from"./query-vendor-Cbp9LWgA.js";import{r}from"./index-BVBOQ8an.js";import{n as ee,t as te}from"./timeline-vendor-DxuOyw5t.js";var ne=r(),i=e(t(),1),a=n(),o=new Date(`1970-01-01T00:00:00Z`),re=new Date(`2030-01-01T00:00:00Z`),s=`playhead`,ie=500,ae=6,oe=` +import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{T as t,a as n}from"./query-vendor-Cbp9LWgA.js";import{r}from"./index-DDOaKEbH.js";import{n as ee,t as te}from"./timeline-vendor-DxuOyw5t.js";var ne=r(),i=e(t(),1),a=n(),o=new Date(`1970-01-01T00:00:00Z`),re=new Date(`2030-01-01T00:00:00Z`),s=`playhead`,ie=500,ae=6,oe=` .sem-timeline-wrap .vis-timeline { border: none !important; background: transparent !important; overflow: visible !important; } .sem-timeline-wrap .vis-panel.vis-background, .sem-timeline-wrap .vis-panel.vis-center { background: transparent !important; } .sem-timeline-wrap .vis-panel { border-color: rgba(88, 166, 255, 0.15) !important; } diff --git a/semantica/static/assets/VocabularyWorkspace-Xth7XSJd.js b/semantica/static/assets/VocabularyWorkspace-BonIpRiP.js similarity index 99% rename from semantica/static/assets/VocabularyWorkspace-Xth7XSJd.js rename to semantica/static/assets/VocabularyWorkspace-BonIpRiP.js index 0b6793ab..eb4c2575 100644 --- a/semantica/static/assets/VocabularyWorkspace-Xth7XSJd.js +++ b/semantica/static/assets/VocabularyWorkspace-BonIpRiP.js @@ -1,4 +1,4 @@ -import{i as e,n as t,t as n}from"./rolldown-runtime-B1FJdls4.js";import{T as r,a as i,i as a,n as o,t as s}from"./query-vendor-Cbp9LWgA.js";import{a as c,i as l,n as u,r as d,t as f}from"./es-BveUcJeu.js";import{n as p,r as m}from"./index-BVBOQ8an.js";import{t as h}from"./shim-CnYKr5zR.js";var g=p(`chevron-down`,[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]),_=p(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),v=p(`folder`,[[`path`,{d:`M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z`,key:`1kt360`}]]),y=e(r()),b=m(),x=async()=>{let e=await fetch(`/api/vocabulary/schemes`);if(!e.ok)throw Error(`Failed to fetch vocabularies`);return e.json()},S=async e=>{let t=await fetch(`/api/vocabulary/hierarchy?scheme=${encodeURIComponent(e)}`);if(!t.ok)throw Error(`Failed to fetch hierarchy`);return t.json()},C=async e=>{let t=new FormData;t.append(`file`,e);let n=await fetch(`/api/vocabulary/import`,{method:`POST`,body:t});if(!n.ok)throw Error(`Failed to import vocabulary`);return n.json()},w=()=>{let e=(0,b.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`vocabularies`],queryFn:x},e[0]=t):t=e[0],o(t)},T=e=>{let t=(0,b.c)(7),n,r;t[0]===e?(n=t[1],r=t[2]):(n=[`hierarchy`,e],r=()=>S(e),t[0]=e,t[1]=n,t[2]=r);let i=!!e,a;return t[3]!==n||t[4]!==r||t[5]!==i?(a={queryKey:n,queryFn:r,enabled:i},t[3]=n,t[4]=r,t[5]=i,t[6]=a):a=t[6],o(a)},E=()=>{let e=(0,b.c)(2),t=a(),n;return e[0]===t?n=e[1]:(n={mutationFn:C,onSuccess:()=>{t.invalidateQueries({queryKey:[`vocabularies`]})}},e[0]=t,e[1]=n),s(n)},D=(0,y.createContext)(null);function O(){let e=(0,y.useContext)(D);if(e===null)throw Error(`No Tree Api Provided`);return e}var k=(0,y.createContext)(null);function ee(){let e=(0,y.useContext)(k);if(e===null)throw Error(`Provide a NodesContext`);return e}var te=(0,y.createContext)(null);function ne(){let e=(0,y.useContext)(te);if(e===null)throw Error(`Provide a DnDContext`);return e}var re=(0,y.createContext)(0);function ie(){(0,y.useContext)(re)}var ae=t({access:()=>A,bound:()=>oe,dfs:()=>pe,focusNextElement:()=>he,focusPrevElement:()=>ge,getInsertIndex:()=>we,getInsertParentId:()=>Te,identify:()=>j,identifyNull:()=>be,indexOf:()=>de,isClosed:()=>ce,isDescendant:()=>ue,isItem:()=>se,isOpenWithEmptyChildren:()=>le,mergeRefs:()=>xe,noop:()=>fe,safeRun:()=>Se,waitFor:()=>Ce,walk:()=>me});function oe(e,t,n){return Math.max(Math.min(e,n),t)}function se(e){return e&&e.isLeaf}function ce(e){return e&&e.isInternal&&!e.isOpen}function le(e){return e&&e.isOpen&&!e.children?.length}var ue=(e,t)=>{let n=e;for(;n;){if(n.id===t.id)return!0;n=n.parent}return!1},de=e=>{if(!e.parent)throw Error(`Node does not have a parent`);return e.parent.children.findIndex(t=>t.id===e.id)};function fe(){}function pe(e,t){if(!e)return null;if(e.id===t)return e;if(e.children)for(let n of e.children){let e=pe(n,t);if(e)return e}return null}function me(e,t){if(t(e),e.children)for(let n of e.children)me(n,t)}function he(e){let t=ye(e),n;for(let r=0;r=0?e[t-1]:e[e.length-1]}function ye(e){return Array.from(document.querySelectorAll(`button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled]), details:not([disabled]), summary:not(:disabled)`)).filter(t=>t===e||!e.contains(t))}function A(e,t){return typeof t==`boolean`?t:typeof t==`string`?e[t]:t(e)}function be(e){return e===null?null:j(e)}function j(e){return typeof e==`string`?e:e.id}function xe(...e){return t=>{e.forEach(e=>{typeof e==`function`?e(t):e!=null&&(e.current=t)})}}function Se(e,...t){if(e)return e(...t)}function Ce(e){return new Promise((t,n)=>{let r=0;function i(){r+=1,r===100&&n(),e()?t():setTimeout(i,10)}i()})}function we(e){let t=e.focusedNode;return t?t.isOpen?0:t.parent?t.childIndex+1:0:e.root.children?.length??0}function Te(e){let t=e.focusedNode;return t?t.isOpen?t.id:t.parent&&!t.parent.isRoot?t.parent.id:null:null}var M=i(),Ee={display:`flex`,alignItems:`center`,zIndex:1},De={flex:1,height:`2px`,background:`#4B91E2`,borderRadius:`1px`},Oe={width:`4px`,height:`4px`,boxShadow:`0 0 0 3px #4B91E2`,borderRadius:`50%`},ke=y.memo(function({top:e,left:t,indent:n}){let r={position:`absolute`,pointerEvents:`none`,top:e-2+`px`,left:t+`px`,right:n+`px`};return(0,M.jsxs)(`div`,{style:Object.assign(Object.assign({},Ee),r),children:[(0,M.jsx)(`div`,{style:Object.assign({},Oe)}),(0,M.jsx)(`div`,{style:Object.assign({},De)})]})});function Ae({node:e,attrs:t,innerRef:n,children:r}){return(0,M.jsx)(`div`,Object.assign({},t,{ref:n,onFocus:e=>e.stopPropagation(),onClick:e.handleClick,children:r}))}function je(e){return(0,M.jsxs)(`div`,{ref:e.dragHandle,style:e.style,children:[(0,M.jsx)(`span`,{onClick:t=>{t.stopPropagation(),e.node.toggle()},children:e.node.isLeaf?`🌳`:e.node.isOpen?`🗁`:`🗀`}),` `,e.node.isEditing?(0,M.jsx)(Ne,Object.assign({},e)):(0,M.jsx)(Me,Object.assign({},e))]})}function Me(e){return(0,M.jsx)(M.Fragment,{children:(0,M.jsx)(`span`,{children:e.node.data.name})})}function Ne({node:e}){let t=(0,y.useRef)();return(0,y.useEffect)(()=>{var e,n;(e=t.current)==null||e.focus(),(n=t.current)==null||n.select()},[]),(0,M.jsx)(`input`,{ref:t,defaultValue:e.data.name,onBlur:()=>e.reset(),onKeyDown:n=>{n.key===`Escape`&&e.reset(),n.key===`Enter`&&e.submit(t.current?.value||``)}})}function Pe(e){return{type:`EDIT`,id:e}}function Fe(e={id:null},t){return t.type===`EDIT`?Object.assign(Object.assign({},e),{id:t.id}):e}function N(e){return{type:`FOCUS`,id:e}}function Ie(){return{type:`TREE_BLUR`}}function Le(e={id:null,treeFocused:!1},t){return t.type===`FOCUS`?Object.assign(Object.assign({},e),{id:t.id,treeFocused:!0}):t.type===`TREE_BLUR`?Object.assign(Object.assign({},e),{treeFocused:!1}):e}var Re=class e{constructor(e){this.handleClick=e=>{e.metaKey&&!this.tree.props.disableMultiSelection?this.isSelected?this.deselect():this.selectMulti():e.shiftKey&&!this.tree.props.disableMultiSelection?this.selectContiguous():(this.select(),this.activate())},this.tree=e.tree,this.id=e.id,this.data=e.data,this.level=e.level,this.children=e.children,this.parent=e.parent,this.isDraggable=e.isDraggable,this.rowIndex=e.rowIndex}get isRoot(){return this.id===ze}get isLeaf(){return!Array.isArray(this.children)}get isInternal(){return!this.isLeaf}get isOpen(){return this.isLeaf?!1:this.tree.isOpen(this.id)}get isClosed(){return this.isLeaf?!1:!this.tree.isOpen(this.id)}get isEditable(){return this.tree.isEditable(this.data)}get isEditing(){return this.tree.editingId===this.id}get isSelected(){return this.tree.isSelected(this.id)}get isOnlySelection(){return this.isSelected&&this.tree.hasOneSelection}get isSelectedStart(){return this.isSelected&&!this.prev?.isSelected}get isSelectedEnd(){return this.isSelected&&!this.next?.isSelected}get isFocused(){return this.tree.isFocused(this.id)}get isDragging(){return this.tree.isDragging(this.id)}get willReceiveDrop(){return this.tree.willReceiveDrop(this.id)}get state(){return{isClosed:this.isClosed,isDragging:this.isDragging,isEditing:this.isEditing,isFocused:this.isFocused,isInternal:this.isInternal,isLeaf:this.isLeaf,isOpen:this.isOpen,isSelected:this.isSelected,isSelectedEnd:this.isSelectedEnd,isSelectedStart:this.isSelectedStart,willReceiveDrop:this.willReceiveDrop}}get childIndex(){return this.parent&&this.parent.children?this.parent.children.findIndex(e=>e.id===this.id):-1}get next(){return this.rowIndex===null?null:this.tree.at(this.rowIndex+1)}get prev(){return this.rowIndex===null?null:this.tree.at(this.rowIndex-1)}get nextSibling(){let e=this.childIndex;return this.parent?.children[e+1]??null}isAncestorOf(e){if(!e)return!1;let t=e;for(;t;){if(t.id===this.id)return!0;t=t.parent}return!1}select(){this.tree.select(this)}deselect(){this.tree.deselect(this)}selectMulti(){this.tree.selectMulti(this)}selectContiguous(){this.tree.selectContiguous(this)}activate(){this.tree.activate(this)}focus(){this.tree.focus(this)}toggle(){this.tree.toggle(this)}open(){this.tree.open(this)}openParents(){this.tree.openParents(this)}close(){this.tree.close(this)}submit(e){this.tree.submit(this,e)}reset(){this.tree.reset()}clone(){return new e(Object.assign({},this))}edit(){return this.tree.edit(this)}},ze=`__REACT_ARBORIST_INTERNAL_ROOT__`;function Be(e){function t(n,r,i){let a=new Re({tree:e,data:n,level:r,parent:i,id:e.accessId(n),children:null,isDraggable:e.isDraggable(n),rowIndex:null}),o=e.accessChildren(n);return o&&(a.children=o.map(e=>t(e,r+1,a))),a}let n=new Re({tree:e,id:ze,data:{id:ze},level:-1,parent:null,children:null,isDraggable:!0,rowIndex:null});return n.children=(e.props.data??[]).map(e=>t(e,0,n)),n}var Ve={open(e,t){return{type:`VISIBILITY_OPEN`,id:e,filtered:t}},close(e,t){return{type:`VISIBILITY_CLOSE`,id:e,filtered:t}},toggle(e,t){return{type:`VISIBILITY_TOGGLE`,id:e,filtered:t}},clear(e){return{type:`VISIBILITY_CLEAR`,filtered:e}}};function He(e={},t){if(t.type===`VISIBILITY_OPEN`)return Object.assign(Object.assign({},e),{[t.id]:!0});if(t.type===`VISIBILITY_CLOSE`)return Object.assign(Object.assign({},e),{[t.id]:!1});if(t.type===`VISIBILITY_TOGGLE`){let n=e[t.id];return Object.assign(Object.assign({},e),{[t.id]:!n})}else if(t.type===`VISIBILITY_CLEAR`)return{};else return e}function Ue(e={filtered:{},unfiltered:{}},t){return t.type.startsWith(`VISIBILITY`)?t.filtered?Object.assign(Object.assign({},e),{filtered:He(e.filtered,t)}):Object.assign(Object.assign({},e),{unfiltered:He(e.unfiltered,t)}):e}var P=e=>({nodes:{open:{filtered:{},unfiltered:e?.initialOpenState??{}},focus:{id:null,treeFocused:!1},edit:{id:null},drag:{id:null,selectedIds:[],destinationParentId:null,destinationIndex:null},selection:{ids:new Set,anchor:null,mostRecent:null}},dnd:{cursor:{type:`none`},dragId:null,dragIds:[],parentId:null,index:-1}}),F={clear:()=>({type:`SELECTION_CLEAR`}),only:e=>({type:`SELECTION_ONLY`,id:j(e)}),add:e=>({type:`SELECTION_ADD`,ids:(Array.isArray(e)?e:[e]).map(j)}),remove:e=>({type:`SELECTION_REMOVE`,ids:(Array.isArray(e)?e:[e]).map(j)}),set:e=>Object.assign({type:`SELECTION_SET`},e),mostRecent:e=>({type:`SELECTION_MOST_RECENT`,id:e===null?null:j(e)}),anchor:e=>({type:`SELECTION_ANCHOR`,id:e===null?null:j(e)})};function We(e=P().nodes.selection,t){let n=e.ids;switch(t.type){case`SELECTION_CLEAR`:return Object.assign(Object.assign({},e),{ids:new Set});case`SELECTION_ONLY`:return Object.assign(Object.assign({},e),{ids:new Set([t.id])});case`SELECTION_ADD`:return t.ids.length===0?e:(t.ids.forEach(e=>n.add(e)),Object.assign(Object.assign({},e),{ids:new Set(n)}));case`SELECTION_REMOVE`:return t.ids.length===0?e:(t.ids.forEach(e=>n.delete(e)),Object.assign(Object.assign({},e),{ids:new Set(n)}));case`SELECTION_SET`:return Object.assign(Object.assign({},e),{ids:t.ids,mostRecent:t.mostRecent,anchor:t.anchor});case`SELECTION_MOST_RECENT`:return Object.assign(Object.assign({},e),{mostRecent:t.id});case`SELECTION_ANCHOR`:return Object.assign(Object.assign({},e),{anchor:t.id});default:return e}}var I={cursor(e){return{type:`DND_CURSOR`,cursor:e}},dragStart(e,t){return{type:`DND_DRAG_START`,id:e,dragIds:t}},dragEnd(){return{type:`DND_DRAG_END`}},hovering(e,t){return{type:`DND_HOVERING`,parentId:e,index:t}}};function Ge(e=P().dnd,t){switch(t.type){case`DND_CURSOR`:return Object.assign(Object.assign({},e),{cursor:t.cursor});case`DND_DRAG_START`:return Object.assign(Object.assign({},e),{dragId:t.id,dragIds:t.dragIds});case`DND_DRAG_END`:return P().dnd;case`DND_HOVERING`:return Object.assign(Object.assign({},e),{parentId:t.parentId,index:t.index});default:return e}}var Ke={position:`fixed`,pointerEvents:`none`,zIndex:100,left:0,top:0,width:`100%`,height:`100%`},qe=e=>{if(!e)return{display:`none`};let{x:t,y:n}=e;return{transform:`translate(${t}px, ${n}px)`}},Je=e=>{if(!e)return{display:`none`};let{x:t,y:n}=e;return{transform:`translate(${t+10}px, ${n+10}px)`}};function Ye({offset:e,mouse:t,id:n,dragIds:r,isDragging:i}){return(0,M.jsxs)(Xe,{isDragging:i,children:[(0,M.jsx)(Ze,{offset:e,children:(0,M.jsx)($e,{id:n,dragIds:r})}),(0,M.jsx)(Qe,{mouse:t,count:r.length})]})}var Xe=(0,y.memo)(function(e){return e.isDragging?(0,M.jsx)(`div`,{style:Ke,children:e.children}):null});function Ze(e){return(0,M.jsx)(`div`,{className:`row preview`,style:qe(e.offset),children:e.children})}function Qe(e){let{count:t,mouse:n}=e;return t>1?(0,M.jsx)(`div`,{className:`selected-count`,style:Je(n),children:t}):null}var $e=(0,y.memo)(function(e){let t=O(),n=t.get(e.id);return n?(0,M.jsx)(t.renderNode,{preview:!0,node:n,style:{paddingLeft:n.level*t.indent,opacity:.2,background:`transparent`},tree:t}):null});function et(){return et=Object.assign?Object.assign.bind():function(e){for(var t=1;t=t?e.call(null):i.id=requestAnimationFrame(r)}var i={id:requestAnimationFrame(r)};return i}var dt=-1;function ft(e){if(e===void 0&&(e=!1),dt===-1||e){var t=document.createElement(`div`),n=t.style;n.width=`50px`,n.height=`50px`,n.overflow=`scroll`,document.body.appendChild(t),dt=t.offsetWidth-t.clientWidth,document.body.removeChild(t)}return dt}var pt=null;function mt(e){if(e===void 0&&(e=!1),pt===null||e){var t=document.createElement(`div`),n=t.style;n.width=`50px`,n.height=`50px`,n.overflow=`scroll`,n.direction=`rtl`;var r=document.createElement(`div`),i=r.style;return i.width=`100px`,i.height=`100px`,t.appendChild(r),document.body.appendChild(t),t.scrollLeft>0?pt=`positive-descending`:(t.scrollLeft=1,pt=t.scrollLeft===0?`negative`:`positive-ascending`),document.body.removeChild(t),pt}return pt}var ht=150,gt=function(e,t){return e};function _t(e){var t,n=e.getItemOffset,r=e.getEstimatedTotalSize,i=e.getItemSize,a=e.getOffsetForIndexAndAlignment,o=e.getStartIndexForOffset,s=e.getStopIndexForStartIndex,c=e.initInstanceProps,l=e.shouldResetStyleCacheOnItemSizeChange,u=e.validateProps;return t=function(e){rt(t,e);function t(t){var r=e.call(this,t)||this;return r._instanceProps=c(r.props,tt(r)),r._outerRef=void 0,r._resetIsScrollingTimeoutId=null,r.state={instance:tt(r),isScrolling:!1,scrollDirection:`forward`,scrollOffset:typeof r.props.initialScrollOffset==`number`?r.props.initialScrollOffset:0,scrollUpdateWasRequested:!1},r._callOnItemsRendered=void 0,r._callOnItemsRendered=st(function(e,t,n,i){return r.props.onItemsRendered({overscanStartIndex:e,overscanStopIndex:t,visibleStartIndex:n,visibleStopIndex:i})}),r._callOnScroll=void 0,r._callOnScroll=st(function(e,t,n){return r.props.onScroll({scrollDirection:e,scrollOffset:t,scrollUpdateWasRequested:n})}),r._getItemStyle=void 0,r._getItemStyle=function(e){var t=r.props,a=t.direction,o=t.itemSize,s=t.layout,c=r._getItemStyleCache(l&&o,l&&s,l&&a),u;if(c.hasOwnProperty(e))u=c[e];else{var d=n(r.props,e,r._instanceProps),f=i(r.props,e,r._instanceProps),p=a===`horizontal`||s===`horizontal`,m=a===`rtl`,h=p?d:0;c[e]=u={position:`absolute`,left:m?void 0:h,right:m?h:void 0,top:p?0:d,height:p?`100%`:f,width:p?f:`100%`}}return u},r._getItemStyleCache=void 0,r._getItemStyleCache=st(function(e,t,n){return{}}),r._onScrollHorizontal=function(e){var t=e.currentTarget,n=t.clientWidth,i=t.scrollLeft,a=t.scrollWidth;r.setState(function(e){if(e.scrollOffset===i)return null;var t=r.props.direction,o=i;if(t===`rtl`)switch(mt()){case`negative`:o=-i;break;case`positive-descending`:o=a-n-i;break}return o=Math.max(0,Math.min(o,a-n)),{isScrolling:!0,scrollDirection:e.scrollOffsetc.clientWidth?ft():0:c.scrollHeight>c.clientHeight?ft():0}this.scrollTo(a(this.props,e,t,o,this._instanceProps,s))},d.componentDidMount=function(){var e=this.props,t=e.direction,n=e.initialScrollOffset,r=e.layout;if(typeof n==`number`&&this._outerRef!=null){var i=this._outerRef;t===`horizontal`||r===`horizontal`?i.scrollLeft=n:i.scrollTop=n}this._callPropsCallbacks()},d.componentDidUpdate=function(){var e=this.props,t=e.direction,n=e.layout,r=this.state,i=r.scrollOffset;if(r.scrollUpdateWasRequested&&this._outerRef!=null){var a=this._outerRef;if(t===`horizontal`||n===`horizontal`)if(t===`rtl`)switch(mt()){case`negative`:a.scrollLeft=-i;break;case`positive-ascending`:a.scrollLeft=i;break;default:var o=a.clientWidth;a.scrollLeft=a.scrollWidth-o-i;break}else a.scrollLeft=i;else a.scrollTop=i}this._callPropsCallbacks()},d.componentWillUnmount=function(){this._resetIsScrollingTimeoutId!==null&<(this._resetIsScrollingTimeoutId)},d.render=function(){var e=this.props,t=e.children,n=e.className,i=e.direction,a=e.height,o=e.innerRef,s=e.innerElementType,c=e.innerTagName,l=e.itemCount,u=e.itemData,d=e.itemKey,f=d===void 0?gt:d,p=e.layout,m=e.outerElementType,h=e.outerTagName,g=e.style,_=e.useIsScrolling,v=e.width,b=this.state.isScrolling,x=i===`horizontal`||p===`horizontal`,S=x?this._onScrollHorizontal:this._onScrollVertical,C=this._getRangeToRender(),w=C[0],T=C[1],E=[];if(l>0)for(var D=w;D<=T;D++)E.push((0,y.createElement)(t,{data:u,key:f(D,u),index:D,isScrolling:_?b:void 0,style:this._getItemStyle(D)}));var O=r(this.props,this._instanceProps);return(0,y.createElement)(m||h||`div`,{className:n,onScroll:S,ref:this._outerRefSetter,style:et({position:`relative`,height:a,width:v,overflow:`auto`,WebkitOverflowScrolling:`touch`,willChange:`transform`,direction:i},g)},(0,y.createElement)(s||c||`div`,{children:E,ref:o,style:{height:x?`100%`:O,pointerEvents:b?`none`:void 0,width:x?O:`100%`}}))},d._callPropsCallbacks=function(){if(typeof this.props.onItemsRendered==`function`&&this.props.itemCount>0){var e=this._getRangeToRender(),t=e[0],n=e[1],r=e[2],i=e[3];this._callOnItemsRendered(t,n,r,i)}if(typeof this.props.onScroll==`function`){var a=this.state,o=a.scrollDirection,s=a.scrollOffset,c=a.scrollUpdateWasRequested;this._callOnScroll(o,s,c)}},d._getRangeToRender=function(){var e=this.props,t=e.itemCount,n=e.overscanCount,r=this.state,i=r.isScrolling,a=r.scrollDirection,c=r.scrollOffset;if(t===0)return[0,0,0,0];var l=o(this.props,c,this._instanceProps),u=s(this.props,l,c,this._instanceProps),d=!i||a===`backward`?Math.max(1,n):1,f=!i||a===`forward`?Math.max(1,n):1;return[Math.max(0,l-d),Math.max(0,Math.min(t-1,u+f)),l,u]},t}(y.PureComponent),t.defaultProps={direction:`ltr`,itemData:void 0,layout:`vertical`,overscanCount:2,useIsScrolling:!1},t}var vt=function(e,t){e.children,e.direction,e.height,e.layout,e.innerTagName,e.outerTagName,e.width,t.instance},yt=_t({getItemOffset:function(e,t){return t*e.itemSize},getItemSize:function(e,t){return e.itemSize},getEstimatedTotalSize:function(e){var t=e.itemCount;return e.itemSize*t},getOffsetForIndexAndAlignment:function(e,t,n,r,i,a){var o=e.direction,s=e.height,c=e.itemCount,l=e.itemSize,u=e.layout,d=e.width,f=o===`horizontal`||u===`horizontal`?d:s,p=Math.max(0,c*l-f),m=Math.min(p,t*l),h=Math.max(0,t*l-f+l+a);switch(n===`smart`&&(n=r>=h-f&&r<=m+f?`auto`:`center`),n){case`start`:return m;case`end`:return h;case`center`:var g=Math.round(h+(m-h)/2);return gp+Math.floor(f/2)?p:g;default:return r>=h&&r<=m?r:r{e.currentTarget===e.target&&i.deselectAll()},children:[(0,M.jsx)(Ct,{}),n]}))}),Ct=()=>{let e=O();return(0,M.jsx)(`div`,{style:{height:e.visibleNodes.length*e.rowHeight,width:`100%`,position:`absolute`,left:`0`,right:`0`},children:(0,M.jsx)(bt,{})})},wt=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols==`function`)for(var i=0,r=Object.getOwnPropertySymbols(e);i-1})}var Bt={type:Dt,payload:{clientOffset:null,sourceClientOffset:null}};function Vt(e){return function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{publishSource:!0},r=n.publishSource,i=r===void 0?!0:r,a=n.clientOffset,o=n.getSourceClientOffset,s=e.getMonitor(),c=e.getRegistry();e.dispatch(Nt(a)),Ht(t,s,c);var l=Gt(t,s);if(l===null){e.dispatch(Bt);return}var u=null;if(a){if(!o)throw Error(`getSourceClientOffset must be defined`);Ut(o),u=o(l)}e.dispatch(Nt(a,u));var d=c.getSource(l).beginDrag(s,l);if(d!=null)return Wt(d),c.pinSource(l),{type:Ot,payload:{itemType:c.getSourceType(l),item:d,sourceId:l,clientOffset:a||null,sourceClientOffset:u||null,isSourcePublic:!!i}}}}function Ht(e,t,n){R(!t.isDragging(),`Cannot call beginDrag while dragging.`),e.forEach(function(e){R(n.getSource(e),`Expected sourceIds to be registered.`)})}function Ut(e){R(typeof e==`function`,`When clientOffset is provided, getSourceClientOffset must be a function.`)}function Wt(e){R(Lt(e),`Item must be an object.`)}function Gt(e,t){for(var n=null,r=e.length-1;r>=0;r--)if(t.canDragSource(e[r])){n=e[r];break}return n}function Kt(e){return function(){if(e.getMonitor().isDragging())return{type:kt}}}function qt(e,t){return t===null?e===null:Array.isArray(e)?e.some(function(e){return e===t}):e===t}function Jt(e){return function(t){var n=(arguments.length>1&&arguments[1]!==void 0?arguments[1]:{}).clientOffset;Yt(t);var r=t.slice(0),i=e.getMonitor(),a=e.getRegistry();return Xt(r,i,a),Zt(r,a,i.getItemType()),Qt(r,i,a),{type:At,payload:{targetIds:r,clientOffset:n||null}}}}function Yt(e){R(Array.isArray(e),`Expected targetIds to be an array.`)}function Xt(e,t,n){R(t.isDragging(),`Cannot call hover while not dragging.`),R(!t.didDrop(),`Cannot call hover after drop.`);for(var r=0;r=0;r--){var i=e[r];qt(t.getTargetType(i),n)||e.splice(r,1)}}function Qt(e,t,n){e.forEach(function(e){n.getTarget(e).hover(t,e)})}function $t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function en(e){for(var t=1;t0&&arguments[0]!==void 0?arguments[0]:{},n=e.getMonitor(),r=e.getRegistry();rn(n),sn(n).forEach(function(i,a){var o=an(i,a,r,n),s={type:jt,payload:{dropResult:en(en({},t),o)}};e.dispatch(s)})}}function rn(e){R(e.isDragging(),`Cannot call drop while not dragging.`),R(!e.didDrop(),`Cannot call drop twice during one drag operation.`)}function an(e,t,n,r){var i=n.getTarget(e),a=i?i.drop(r,e):void 0;return on(a),a===void 0&&(a=t===0?{}:r.getDropResult()),a}function on(e){R(e===void 0||Lt(e),`Drop result must either be an object or undefined.`)}function sn(e){var t=e.getTargetIds().filter(e.canDropOnTarget,e);return t.reverse(),t}function cn(e){return function(){var t=e.getMonitor(),n=e.getRegistry();ln(t);var r=t.getSourceId();return r!=null&&(n.getSource(r,!0).endDrag(t,r),n.unpinSource()),{type:Mt}}}function ln(e){R(e.isDragging(),`Cannot call endDrag while not dragging.`)}function un(e){return{beginDrag:Vt(e),publishDragSource:Kt(e),hover:Jt(e),drop:nn(e),endDrag:cn(e)}}function dn(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)}function fn(e,t){for(var n=0;n0;r.backend&&(e&&!r.isSetUp?(r.backend.setup(),r.isSetUp=!0):!e&&r.isSetUp&&(r.backend.teardown(),r.isSetUp=!1))}),this.store=t,this.monitor=n,t.subscribe(this.handleRefCountChange)}return pn(e,[{key:`receiveBackend`,value:function(e){this.backend=e}},{key:`getMonitor`,value:function(){return this.monitor}},{key:`getBackend`,value:function(){return this.backend}},{key:`getRegistry`,value:function(){return this.monitor.registry}},{key:`getActions`,value:function(){var e=this,t=this.store.dispatch;function n(n){return function(){var r=[...arguments],i=n.apply(e,r);i!==void 0&&t(i)}}var r=un(this);return Object.keys(r).reduce(function(e,t){var i=r[t];return e[t]=n(i),e},{})}},{key:`dispatch`,value:function(e){this.store.dispatch(e)}}]),e}();function B(e){return`Minified Redux error #`+e+`; visit https://redux.js.org/Errors?code=`+e+` for the full message or use the non-minified dev environment for full errors. `}var hn=(function(){return typeof Symbol==`function`&&Symbol.observable||`@@observable`})(),gn=function(){return Math.random().toString(36).substring(7).split(``).join(`.`)},_n={INIT:`@@redux/INIT`+gn(),REPLACE:`@@redux/REPLACE`+gn(),PROBE_UNKNOWN_ACTION:function(){return`@@redux/PROBE_UNKNOWN_ACTION`+gn()}};function vn(e){if(typeof e!=`object`||!e)return!1;for(var t=e;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function yn(e,t,n){var r;if(typeof t==`function`&&typeof n==`function`||typeof n==`function`&&typeof arguments[3]==`function`)throw Error(B(0));if(typeof t==`function`&&n===void 0&&(n=t,t=void 0),n!==void 0){if(typeof n!=`function`)throw Error(B(1));return n(yn)(e,t)}if(typeof e!=`function`)throw Error(B(2));var i=e,a=t,o=[],s=o,c=!1;function l(){s===o&&(s=o.slice())}function u(){if(c)throw Error(B(3));return a}function d(e){if(typeof e!=`function`)throw Error(B(4));if(c)throw Error(B(5));var t=!0;return l(),s.push(e),function(){if(t){if(c)throw Error(B(6));t=!1,l();var n=s.indexOf(e);s.splice(n,1),o=null}}}function f(e){if(!vn(e))throw Error(B(7));if(e.type===void 0)throw Error(B(8));if(c)throw Error(B(9));try{c=!0,a=i(a,e)}finally{c=!1}for(var t=o=s,n=0;n2&&arguments[2]!==void 0?arguments[2]:bn;if(e.length!==t.length)return!1;for(var r=0;r0&&arguments[0]!==void 0?arguments[0]:En,t=arguments.length>1?arguments[1]:void 0,n=t.payload;switch(t.type){case Dt:case Ot:return{initialSourceClientOffset:n.sourceClientOffset,initialClientOffset:n.clientOffset,clientOffset:n.clientOffset};case At:return xn(e.clientOffset,n.clientOffset)?e:wn(wn({},e),{},{clientOffset:n.clientOffset});case Mt:case jt:return En;default:return e}}var On=`dnd-core/ADD_SOURCE`,kn=`dnd-core/ADD_TARGET`,An=`dnd-core/REMOVE_SOURCE`,jn=`dnd-core/REMOVE_TARGET`;function Mn(e){return{type:On,payload:{sourceId:e}}}function Nn(e){return{type:kn,payload:{targetId:e}}}function Pn(e){return{type:An,payload:{sourceId:e}}}function Fn(e){return{type:jn,payload:{targetId:e}}}function In(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function V(e){for(var t=1;t0&&arguments[0]!==void 0?arguments[0]:Rn,t=arguments.length>1?arguments[1]:void 0,n=t.payload;switch(t.type){case Ot:return V(V({},e),{},{itemType:n.itemType,item:n.item,sourceId:n.sourceId,isSourcePublic:n.isSourcePublic,dropResult:null,didDrop:!1});case kt:return V(V({},e),{},{isSourcePublic:!0});case At:return V(V({},e),{},{targetIds:n.targetIds});case jn:return e.targetIds.indexOf(n.targetId)===-1?e:V(V({},e),{},{targetIds:It(e.targetIds,n.targetId)});case jt:return V(V({},e),{},{dropResult:n.dropResult,didDrop:!0,targetIds:[]});case Mt:return V(V({},e),{},{itemType:null,item:null,sourceId:null,dropResult:null,didDrop:!1,isSourcePublic:null,targetIds:[]});default:return e}}function Bn(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0;switch((arguments.length>1?arguments[1]:void 0).type){case On:case kn:return e+1;case An:case jn:return e-1;default:return e}}var Vn=[],Hn=[];Vn.__IS_NONE__=!0,Hn.__IS_ALL__=!0;function Un(e,t){return e===Vn?!1:e===Hn||t===void 0?!0:zt(t,e).length>0}function Wn(){arguments.length>0&&arguments[0]!==void 0&&arguments[0];var e=arguments.length>1?arguments[1]:void 0;switch(e.type){case At:break;case On:case kn:case jn:case An:return Vn;case Ot:case kt:case Mt:case jt:default:return Hn}var t=e.payload,n=t.targetIds,r=n===void 0?[]:n,i=t.prevTargetIds,a=i===void 0?[]:i,o=Rt(r,a);if(!(o.length>0||!Sn(r,a)))return Vn;var s=a[a.length-1],c=r[r.length-1];return s!==c&&(s&&o.push(s),c&&o.push(c)),o}function Gn(){return(arguments.length>0&&arguments[0]!==void 0?arguments[0]:0)+1}function Kn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function qn(e){for(var t=1;t0&&arguments[0]!==void 0?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;return{dirtyHandlerIds:Wn(e.dirtyHandlerIds,{type:t.type,payload:qn(qn({},t.payload),{},{prevTargetIds:Ft(e,`dragOperation.targetIds`,[])})}),dragOffset:Dn(e.dragOffset,t),refCount:Bn(e.refCount,t),dragOperation:zn(e.dragOperation,t),stateId:Gn(e.stateId)}}function Xn(e,t){return{x:e.x+t.x,y:e.y+t.y}}function Zn(e,t){return{x:e.x-t.x,y:e.y-t.y}}function Qn(e){var t=e.clientOffset,n=e.initialClientOffset,r=e.initialSourceClientOffset;return!t||!n||!r?null:Zn(Xn(t,r),n)}function $n(e){var t=e.clientOffset,n=e.initialClientOffset;return!t||!n?null:Zn(t,n)}function er(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)}function tr(e,t){for(var n=0;n1&&arguments[1]!==void 0?arguments[1]:{handlerIds:void 0}).handlerIds;R(typeof e==`function`,`listener must be a function.`),R(n===void 0||Array.isArray(n),`handlerIds, when specified, must be an array of strings.`);var r=this.store.getState().stateId;return this.store.subscribe(function(){var i=t.store.getState(),a=i.stateId;try{a===r||a===r+1&&!Un(i.dirtyHandlerIds,n)||e()}finally{r=a}})}},{key:`subscribeToOffsetChange`,value:function(e){var t=this;R(typeof e==`function`,`listener must be a function.`);var n=this.store.getState().dragOffset;return this.store.subscribe(function(){var r=t.store.getState().dragOffset;r!==n&&(n=r,e())})}},{key:`canDragSource`,value:function(e){if(!e)return!1;var t=this.registry.getSource(e);return R(t,`Expected to find a valid source. sourceId=${e}`),this.isDragging()?!1:t.canDrag(this,e)}},{key:`canDropOnTarget`,value:function(e){if(!e)return!1;var t=this.registry.getTarget(e);return R(t,`Expected to find a valid target. targetId=${e}`),!this.isDragging()||this.didDrop()?!1:qt(this.registry.getTargetType(e),this.getItemType())&&t.canDrop(this,e)}},{key:`isDragging`,value:function(){return!!this.getItemType()}},{key:`isDraggingSource`,value:function(e){if(!e)return!1;var t=this.registry.getSource(e,!0);return R(t,`Expected to find a valid source. sourceId=${e}`),!this.isDragging()||!this.isSourcePublic()||this.registry.getSourceType(e)!==this.getItemType()?!1:t.isDragging(this,e)}},{key:`isOverTarget`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{shallow:!1};if(!e)return!1;var n=t.shallow;if(!this.isDragging())return!1;var r=this.registry.getTargetType(e),i=this.getItemType();if(i&&!qt(r,i))return!1;var a=this.getTargetIds();if(!a.length)return!1;var o=a.indexOf(e);return n?o===a.length-1:o>-1}},{key:`getItemType`,value:function(){return this.store.getState().dragOperation.itemType}},{key:`getItem`,value:function(){return this.store.getState().dragOperation.item}},{key:`getSourceId`,value:function(){return this.store.getState().dragOperation.sourceId}},{key:`getTargetIds`,value:function(){return this.store.getState().dragOperation.targetIds}},{key:`getDropResult`,value:function(){return this.store.getState().dragOperation.dropResult}},{key:`didDrop`,value:function(){return this.store.getState().dragOperation.didDrop}},{key:`isSourcePublic`,value:function(){return!!this.store.getState().dragOperation.isSourcePublic}},{key:`getInitialClientOffset`,value:function(){return this.store.getState().dragOffset.initialClientOffset}},{key:`getInitialSourceClientOffset`,value:function(){return this.store.getState().dragOffset.initialSourceClientOffset}},{key:`getClientOffset`,value:function(){return this.store.getState().dragOffset.clientOffset}},{key:`getSourceClientOffset`,value:function(){return Qn(this.store.getState().dragOffset)}},{key:`getDifferenceFromInitialOffset`,value:function(){return $n(this.store.getState().dragOffset)}}]),e}(),ar=0;function or(){return ar++}function sr(e){"@babel/helpers - typeof";return sr=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},sr(e)}function cr(e){R(typeof e.canDrag==`function`,`Expected canDrag to be a function.`),R(typeof e.beginDrag==`function`,`Expected beginDrag to be a function.`),R(typeof e.endDrag==`function`,`Expected endDrag to be a function.`)}function lr(e){R(typeof e.canDrop==`function`,`Expected canDrop to be a function.`),R(typeof e.hover==`function`,`Expected hover to be a function.`),R(typeof e.drop==`function`,`Expected beginDrag to be a function.`)}function ur(e,t){if(t&&Array.isArray(e)){e.forEach(function(e){return ur(e,!1)});return}R(typeof e==`string`||sr(e)===`symbol`,t?`Type can only be a string, a symbol, or an array of either.`:`Type can only be a string or a symbol.`)}var dr=typeof global<`u`?global:self,fr=dr.MutationObserver||dr.WebKitMutationObserver;function pr(e){return function(){let t=setTimeout(r,0),n=setInterval(r,50);function r(){clearTimeout(t),clearInterval(n),e()}}}function mr(e){let t=1,n=new fr(e),r=document.createTextNode(``);return n.observe(r,{characterData:!0}),function(){t=-t,r.data=t}}var hr=typeof fr==`function`?mr:pr,gr=class{enqueueTask(e){let{queue:t,requestFlush:n}=this;t.length||(n(),this.flushing=!0),t[t.length]=e}constructor(){this.queue=[],this.pendingErrors=[],this.flushing=!1,this.index=0,this.capacity=1024,this.flush=()=>{let{queue:e}=this;for(;this.indexthis.capacity){for(let t=0,n=e.length-this.index;t{this.pendingErrors.push(e),this.requestErrorThrow()},this.requestFlush=hr(this.flush),this.requestErrorThrow=pr(()=>{if(this.pendingErrors.length)throw this.pendingErrors.shift()})}},_r=class{call(){try{this.task&&this.task()}catch(e){this.onError(e)}finally{this.task=null,this.release(this)}}constructor(e,t){this.onError=e,this.release=t,this.task=null}},vr=class{create(e){let t=this.freeTasks,n=t.length?t.pop():new _r(this.onError,e=>t[t.length]=e);return n.task=e,n}constructor(e){this.onError=e,this.freeTasks=[]}},yr=new gr,br=new vr(yr.registerPendingError);function xr(e){yr.enqueueTask(br.create(e))}function Sr(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)}function Cr(e,t){for(var n=0;n{let e=await fetch(`/api/vocabulary/schemes`);if(!e.ok)throw Error(`Failed to fetch vocabularies`);return e.json()},S=async e=>{let t=await fetch(`/api/vocabulary/hierarchy?scheme=${encodeURIComponent(e)}`);if(!t.ok)throw Error(`Failed to fetch hierarchy`);return t.json()},C=async e=>{let t=new FormData;t.append(`file`,e);let n=await fetch(`/api/vocabulary/import`,{method:`POST`,body:t});if(!n.ok)throw Error(`Failed to import vocabulary`);return n.json()},w=()=>{let e=(0,b.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={queryKey:[`vocabularies`],queryFn:x},e[0]=t):t=e[0],o(t)},T=e=>{let t=(0,b.c)(7),n,r;t[0]===e?(n=t[1],r=t[2]):(n=[`hierarchy`,e],r=()=>S(e),t[0]=e,t[1]=n,t[2]=r);let i=!!e,a;return t[3]!==n||t[4]!==r||t[5]!==i?(a={queryKey:n,queryFn:r,enabled:i},t[3]=n,t[4]=r,t[5]=i,t[6]=a):a=t[6],o(a)},E=()=>{let e=(0,b.c)(2),t=a(),n;return e[0]===t?n=e[1]:(n={mutationFn:C,onSuccess:()=>{t.invalidateQueries({queryKey:[`vocabularies`]})}},e[0]=t,e[1]=n),s(n)},D=(0,y.createContext)(null);function O(){let e=(0,y.useContext)(D);if(e===null)throw Error(`No Tree Api Provided`);return e}var k=(0,y.createContext)(null);function ee(){let e=(0,y.useContext)(k);if(e===null)throw Error(`Provide a NodesContext`);return e}var te=(0,y.createContext)(null);function ne(){let e=(0,y.useContext)(te);if(e===null)throw Error(`Provide a DnDContext`);return e}var re=(0,y.createContext)(0);function ie(){(0,y.useContext)(re)}var ae=t({access:()=>A,bound:()=>oe,dfs:()=>pe,focusNextElement:()=>he,focusPrevElement:()=>ge,getInsertIndex:()=>we,getInsertParentId:()=>Te,identify:()=>j,identifyNull:()=>be,indexOf:()=>de,isClosed:()=>ce,isDescendant:()=>ue,isItem:()=>se,isOpenWithEmptyChildren:()=>le,mergeRefs:()=>xe,noop:()=>fe,safeRun:()=>Se,waitFor:()=>Ce,walk:()=>me});function oe(e,t,n){return Math.max(Math.min(e,n),t)}function se(e){return e&&e.isLeaf}function ce(e){return e&&e.isInternal&&!e.isOpen}function le(e){return e&&e.isOpen&&!e.children?.length}var ue=(e,t)=>{let n=e;for(;n;){if(n.id===t.id)return!0;n=n.parent}return!1},de=e=>{if(!e.parent)throw Error(`Node does not have a parent`);return e.parent.children.findIndex(t=>t.id===e.id)};function fe(){}function pe(e,t){if(!e)return null;if(e.id===t)return e;if(e.children)for(let n of e.children){let e=pe(n,t);if(e)return e}return null}function me(e,t){if(t(e),e.children)for(let n of e.children)me(n,t)}function he(e){let t=ye(e),n;for(let r=0;r=0?e[t-1]:e[e.length-1]}function ye(e){return Array.from(document.querySelectorAll(`button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled]), details:not([disabled]), summary:not(:disabled)`)).filter(t=>t===e||!e.contains(t))}function A(e,t){return typeof t==`boolean`?t:typeof t==`string`?e[t]:t(e)}function be(e){return e===null?null:j(e)}function j(e){return typeof e==`string`?e:e.id}function xe(...e){return t=>{e.forEach(e=>{typeof e==`function`?e(t):e!=null&&(e.current=t)})}}function Se(e,...t){if(e)return e(...t)}function Ce(e){return new Promise((t,n)=>{let r=0;function i(){r+=1,r===100&&n(),e()?t():setTimeout(i,10)}i()})}function we(e){let t=e.focusedNode;return t?t.isOpen?0:t.parent?t.childIndex+1:0:e.root.children?.length??0}function Te(e){let t=e.focusedNode;return t?t.isOpen?t.id:t.parent&&!t.parent.isRoot?t.parent.id:null:null}var M=i(),Ee={display:`flex`,alignItems:`center`,zIndex:1},De={flex:1,height:`2px`,background:`#4B91E2`,borderRadius:`1px`},Oe={width:`4px`,height:`4px`,boxShadow:`0 0 0 3px #4B91E2`,borderRadius:`50%`},ke=y.memo(function({top:e,left:t,indent:n}){let r={position:`absolute`,pointerEvents:`none`,top:e-2+`px`,left:t+`px`,right:n+`px`};return(0,M.jsxs)(`div`,{style:Object.assign(Object.assign({},Ee),r),children:[(0,M.jsx)(`div`,{style:Object.assign({},Oe)}),(0,M.jsx)(`div`,{style:Object.assign({},De)})]})});function Ae({node:e,attrs:t,innerRef:n,children:r}){return(0,M.jsx)(`div`,Object.assign({},t,{ref:n,onFocus:e=>e.stopPropagation(),onClick:e.handleClick,children:r}))}function je(e){return(0,M.jsxs)(`div`,{ref:e.dragHandle,style:e.style,children:[(0,M.jsx)(`span`,{onClick:t=>{t.stopPropagation(),e.node.toggle()},children:e.node.isLeaf?`🌳`:e.node.isOpen?`🗁`:`🗀`}),` `,e.node.isEditing?(0,M.jsx)(Ne,Object.assign({},e)):(0,M.jsx)(Me,Object.assign({},e))]})}function Me(e){return(0,M.jsx)(M.Fragment,{children:(0,M.jsx)(`span`,{children:e.node.data.name})})}function Ne({node:e}){let t=(0,y.useRef)();return(0,y.useEffect)(()=>{var e,n;(e=t.current)==null||e.focus(),(n=t.current)==null||n.select()},[]),(0,M.jsx)(`input`,{ref:t,defaultValue:e.data.name,onBlur:()=>e.reset(),onKeyDown:n=>{n.key===`Escape`&&e.reset(),n.key===`Enter`&&e.submit(t.current?.value||``)}})}function Pe(e){return{type:`EDIT`,id:e}}function Fe(e={id:null},t){return t.type===`EDIT`?Object.assign(Object.assign({},e),{id:t.id}):e}function N(e){return{type:`FOCUS`,id:e}}function Ie(){return{type:`TREE_BLUR`}}function Le(e={id:null,treeFocused:!1},t){return t.type===`FOCUS`?Object.assign(Object.assign({},e),{id:t.id,treeFocused:!0}):t.type===`TREE_BLUR`?Object.assign(Object.assign({},e),{treeFocused:!1}):e}var Re=class e{constructor(e){this.handleClick=e=>{e.metaKey&&!this.tree.props.disableMultiSelection?this.isSelected?this.deselect():this.selectMulti():e.shiftKey&&!this.tree.props.disableMultiSelection?this.selectContiguous():(this.select(),this.activate())},this.tree=e.tree,this.id=e.id,this.data=e.data,this.level=e.level,this.children=e.children,this.parent=e.parent,this.isDraggable=e.isDraggable,this.rowIndex=e.rowIndex}get isRoot(){return this.id===ze}get isLeaf(){return!Array.isArray(this.children)}get isInternal(){return!this.isLeaf}get isOpen(){return this.isLeaf?!1:this.tree.isOpen(this.id)}get isClosed(){return this.isLeaf?!1:!this.tree.isOpen(this.id)}get isEditable(){return this.tree.isEditable(this.data)}get isEditing(){return this.tree.editingId===this.id}get isSelected(){return this.tree.isSelected(this.id)}get isOnlySelection(){return this.isSelected&&this.tree.hasOneSelection}get isSelectedStart(){return this.isSelected&&!this.prev?.isSelected}get isSelectedEnd(){return this.isSelected&&!this.next?.isSelected}get isFocused(){return this.tree.isFocused(this.id)}get isDragging(){return this.tree.isDragging(this.id)}get willReceiveDrop(){return this.tree.willReceiveDrop(this.id)}get state(){return{isClosed:this.isClosed,isDragging:this.isDragging,isEditing:this.isEditing,isFocused:this.isFocused,isInternal:this.isInternal,isLeaf:this.isLeaf,isOpen:this.isOpen,isSelected:this.isSelected,isSelectedEnd:this.isSelectedEnd,isSelectedStart:this.isSelectedStart,willReceiveDrop:this.willReceiveDrop}}get childIndex(){return this.parent&&this.parent.children?this.parent.children.findIndex(e=>e.id===this.id):-1}get next(){return this.rowIndex===null?null:this.tree.at(this.rowIndex+1)}get prev(){return this.rowIndex===null?null:this.tree.at(this.rowIndex-1)}get nextSibling(){let e=this.childIndex;return this.parent?.children[e+1]??null}isAncestorOf(e){if(!e)return!1;let t=e;for(;t;){if(t.id===this.id)return!0;t=t.parent}return!1}select(){this.tree.select(this)}deselect(){this.tree.deselect(this)}selectMulti(){this.tree.selectMulti(this)}selectContiguous(){this.tree.selectContiguous(this)}activate(){this.tree.activate(this)}focus(){this.tree.focus(this)}toggle(){this.tree.toggle(this)}open(){this.tree.open(this)}openParents(){this.tree.openParents(this)}close(){this.tree.close(this)}submit(e){this.tree.submit(this,e)}reset(){this.tree.reset()}clone(){return new e(Object.assign({},this))}edit(){return this.tree.edit(this)}},ze=`__REACT_ARBORIST_INTERNAL_ROOT__`;function Be(e){function t(n,r,i){let a=new Re({tree:e,data:n,level:r,parent:i,id:e.accessId(n),children:null,isDraggable:e.isDraggable(n),rowIndex:null}),o=e.accessChildren(n);return o&&(a.children=o.map(e=>t(e,r+1,a))),a}let n=new Re({tree:e,id:ze,data:{id:ze},level:-1,parent:null,children:null,isDraggable:!0,rowIndex:null});return n.children=(e.props.data??[]).map(e=>t(e,0,n)),n}var Ve={open(e,t){return{type:`VISIBILITY_OPEN`,id:e,filtered:t}},close(e,t){return{type:`VISIBILITY_CLOSE`,id:e,filtered:t}},toggle(e,t){return{type:`VISIBILITY_TOGGLE`,id:e,filtered:t}},clear(e){return{type:`VISIBILITY_CLEAR`,filtered:e}}};function He(e={},t){if(t.type===`VISIBILITY_OPEN`)return Object.assign(Object.assign({},e),{[t.id]:!0});if(t.type===`VISIBILITY_CLOSE`)return Object.assign(Object.assign({},e),{[t.id]:!1});if(t.type===`VISIBILITY_TOGGLE`){let n=e[t.id];return Object.assign(Object.assign({},e),{[t.id]:!n})}else if(t.type===`VISIBILITY_CLEAR`)return{};else return e}function Ue(e={filtered:{},unfiltered:{}},t){return t.type.startsWith(`VISIBILITY`)?t.filtered?Object.assign(Object.assign({},e),{filtered:He(e.filtered,t)}):Object.assign(Object.assign({},e),{unfiltered:He(e.unfiltered,t)}):e}var P=e=>({nodes:{open:{filtered:{},unfiltered:e?.initialOpenState??{}},focus:{id:null,treeFocused:!1},edit:{id:null},drag:{id:null,selectedIds:[],destinationParentId:null,destinationIndex:null},selection:{ids:new Set,anchor:null,mostRecent:null}},dnd:{cursor:{type:`none`},dragId:null,dragIds:[],parentId:null,index:-1}}),F={clear:()=>({type:`SELECTION_CLEAR`}),only:e=>({type:`SELECTION_ONLY`,id:j(e)}),add:e=>({type:`SELECTION_ADD`,ids:(Array.isArray(e)?e:[e]).map(j)}),remove:e=>({type:`SELECTION_REMOVE`,ids:(Array.isArray(e)?e:[e]).map(j)}),set:e=>Object.assign({type:`SELECTION_SET`},e),mostRecent:e=>({type:`SELECTION_MOST_RECENT`,id:e===null?null:j(e)}),anchor:e=>({type:`SELECTION_ANCHOR`,id:e===null?null:j(e)})};function We(e=P().nodes.selection,t){let n=e.ids;switch(t.type){case`SELECTION_CLEAR`:return Object.assign(Object.assign({},e),{ids:new Set});case`SELECTION_ONLY`:return Object.assign(Object.assign({},e),{ids:new Set([t.id])});case`SELECTION_ADD`:return t.ids.length===0?e:(t.ids.forEach(e=>n.add(e)),Object.assign(Object.assign({},e),{ids:new Set(n)}));case`SELECTION_REMOVE`:return t.ids.length===0?e:(t.ids.forEach(e=>n.delete(e)),Object.assign(Object.assign({},e),{ids:new Set(n)}));case`SELECTION_SET`:return Object.assign(Object.assign({},e),{ids:t.ids,mostRecent:t.mostRecent,anchor:t.anchor});case`SELECTION_MOST_RECENT`:return Object.assign(Object.assign({},e),{mostRecent:t.id});case`SELECTION_ANCHOR`:return Object.assign(Object.assign({},e),{anchor:t.id});default:return e}}var I={cursor(e){return{type:`DND_CURSOR`,cursor:e}},dragStart(e,t){return{type:`DND_DRAG_START`,id:e,dragIds:t}},dragEnd(){return{type:`DND_DRAG_END`}},hovering(e,t){return{type:`DND_HOVERING`,parentId:e,index:t}}};function Ge(e=P().dnd,t){switch(t.type){case`DND_CURSOR`:return Object.assign(Object.assign({},e),{cursor:t.cursor});case`DND_DRAG_START`:return Object.assign(Object.assign({},e),{dragId:t.id,dragIds:t.dragIds});case`DND_DRAG_END`:return P().dnd;case`DND_HOVERING`:return Object.assign(Object.assign({},e),{parentId:t.parentId,index:t.index});default:return e}}var Ke={position:`fixed`,pointerEvents:`none`,zIndex:100,left:0,top:0,width:`100%`,height:`100%`},qe=e=>{if(!e)return{display:`none`};let{x:t,y:n}=e;return{transform:`translate(${t}px, ${n}px)`}},Je=e=>{if(!e)return{display:`none`};let{x:t,y:n}=e;return{transform:`translate(${t+10}px, ${n+10}px)`}};function Ye({offset:e,mouse:t,id:n,dragIds:r,isDragging:i}){return(0,M.jsxs)(Xe,{isDragging:i,children:[(0,M.jsx)(Ze,{offset:e,children:(0,M.jsx)($e,{id:n,dragIds:r})}),(0,M.jsx)(Qe,{mouse:t,count:r.length})]})}var Xe=(0,y.memo)(function(e){return e.isDragging?(0,M.jsx)(`div`,{style:Ke,children:e.children}):null});function Ze(e){return(0,M.jsx)(`div`,{className:`row preview`,style:qe(e.offset),children:e.children})}function Qe(e){let{count:t,mouse:n}=e;return t>1?(0,M.jsx)(`div`,{className:`selected-count`,style:Je(n),children:t}):null}var $e=(0,y.memo)(function(e){let t=O(),n=t.get(e.id);return n?(0,M.jsx)(t.renderNode,{preview:!0,node:n,style:{paddingLeft:n.level*t.indent,opacity:.2,background:`transparent`},tree:t}):null});function et(){return et=Object.assign?Object.assign.bind():function(e){for(var t=1;t=t?e.call(null):i.id=requestAnimationFrame(r)}var i={id:requestAnimationFrame(r)};return i}var dt=-1;function ft(e){if(e===void 0&&(e=!1),dt===-1||e){var t=document.createElement(`div`),n=t.style;n.width=`50px`,n.height=`50px`,n.overflow=`scroll`,document.body.appendChild(t),dt=t.offsetWidth-t.clientWidth,document.body.removeChild(t)}return dt}var pt=null;function mt(e){if(e===void 0&&(e=!1),pt===null||e){var t=document.createElement(`div`),n=t.style;n.width=`50px`,n.height=`50px`,n.overflow=`scroll`,n.direction=`rtl`;var r=document.createElement(`div`),i=r.style;return i.width=`100px`,i.height=`100px`,t.appendChild(r),document.body.appendChild(t),t.scrollLeft>0?pt=`positive-descending`:(t.scrollLeft=1,pt=t.scrollLeft===0?`negative`:`positive-ascending`),document.body.removeChild(t),pt}return pt}var ht=150,gt=function(e,t){return e};function _t(e){var t,n=e.getItemOffset,r=e.getEstimatedTotalSize,i=e.getItemSize,a=e.getOffsetForIndexAndAlignment,o=e.getStartIndexForOffset,s=e.getStopIndexForStartIndex,c=e.initInstanceProps,l=e.shouldResetStyleCacheOnItemSizeChange,u=e.validateProps;return t=function(e){rt(t,e);function t(t){var r=e.call(this,t)||this;return r._instanceProps=c(r.props,tt(r)),r._outerRef=void 0,r._resetIsScrollingTimeoutId=null,r.state={instance:tt(r),isScrolling:!1,scrollDirection:`forward`,scrollOffset:typeof r.props.initialScrollOffset==`number`?r.props.initialScrollOffset:0,scrollUpdateWasRequested:!1},r._callOnItemsRendered=void 0,r._callOnItemsRendered=st(function(e,t,n,i){return r.props.onItemsRendered({overscanStartIndex:e,overscanStopIndex:t,visibleStartIndex:n,visibleStopIndex:i})}),r._callOnScroll=void 0,r._callOnScroll=st(function(e,t,n){return r.props.onScroll({scrollDirection:e,scrollOffset:t,scrollUpdateWasRequested:n})}),r._getItemStyle=void 0,r._getItemStyle=function(e){var t=r.props,a=t.direction,o=t.itemSize,s=t.layout,c=r._getItemStyleCache(l&&o,l&&s,l&&a),u;if(c.hasOwnProperty(e))u=c[e];else{var d=n(r.props,e,r._instanceProps),f=i(r.props,e,r._instanceProps),p=a===`horizontal`||s===`horizontal`,m=a===`rtl`,h=p?d:0;c[e]=u={position:`absolute`,left:m?void 0:h,right:m?h:void 0,top:p?0:d,height:p?`100%`:f,width:p?f:`100%`}}return u},r._getItemStyleCache=void 0,r._getItemStyleCache=st(function(e,t,n){return{}}),r._onScrollHorizontal=function(e){var t=e.currentTarget,n=t.clientWidth,i=t.scrollLeft,a=t.scrollWidth;r.setState(function(e){if(e.scrollOffset===i)return null;var t=r.props.direction,o=i;if(t===`rtl`)switch(mt()){case`negative`:o=-i;break;case`positive-descending`:o=a-n-i;break}return o=Math.max(0,Math.min(o,a-n)),{isScrolling:!0,scrollDirection:e.scrollOffsetc.clientWidth?ft():0:c.scrollHeight>c.clientHeight?ft():0}this.scrollTo(a(this.props,e,t,o,this._instanceProps,s))},d.componentDidMount=function(){var e=this.props,t=e.direction,n=e.initialScrollOffset,r=e.layout;if(typeof n==`number`&&this._outerRef!=null){var i=this._outerRef;t===`horizontal`||r===`horizontal`?i.scrollLeft=n:i.scrollTop=n}this._callPropsCallbacks()},d.componentDidUpdate=function(){var e=this.props,t=e.direction,n=e.layout,r=this.state,i=r.scrollOffset;if(r.scrollUpdateWasRequested&&this._outerRef!=null){var a=this._outerRef;if(t===`horizontal`||n===`horizontal`)if(t===`rtl`)switch(mt()){case`negative`:a.scrollLeft=-i;break;case`positive-ascending`:a.scrollLeft=i;break;default:var o=a.clientWidth;a.scrollLeft=a.scrollWidth-o-i;break}else a.scrollLeft=i;else a.scrollTop=i}this._callPropsCallbacks()},d.componentWillUnmount=function(){this._resetIsScrollingTimeoutId!==null&<(this._resetIsScrollingTimeoutId)},d.render=function(){var e=this.props,t=e.children,n=e.className,i=e.direction,a=e.height,o=e.innerRef,s=e.innerElementType,c=e.innerTagName,l=e.itemCount,u=e.itemData,d=e.itemKey,f=d===void 0?gt:d,p=e.layout,m=e.outerElementType,h=e.outerTagName,g=e.style,_=e.useIsScrolling,v=e.width,b=this.state.isScrolling,x=i===`horizontal`||p===`horizontal`,S=x?this._onScrollHorizontal:this._onScrollVertical,C=this._getRangeToRender(),w=C[0],T=C[1],E=[];if(l>0)for(var D=w;D<=T;D++)E.push((0,y.createElement)(t,{data:u,key:f(D,u),index:D,isScrolling:_?b:void 0,style:this._getItemStyle(D)}));var O=r(this.props,this._instanceProps);return(0,y.createElement)(m||h||`div`,{className:n,onScroll:S,ref:this._outerRefSetter,style:et({position:`relative`,height:a,width:v,overflow:`auto`,WebkitOverflowScrolling:`touch`,willChange:`transform`,direction:i},g)},(0,y.createElement)(s||c||`div`,{children:E,ref:o,style:{height:x?`100%`:O,pointerEvents:b?`none`:void 0,width:x?O:`100%`}}))},d._callPropsCallbacks=function(){if(typeof this.props.onItemsRendered==`function`&&this.props.itemCount>0){var e=this._getRangeToRender(),t=e[0],n=e[1],r=e[2],i=e[3];this._callOnItemsRendered(t,n,r,i)}if(typeof this.props.onScroll==`function`){var a=this.state,o=a.scrollDirection,s=a.scrollOffset,c=a.scrollUpdateWasRequested;this._callOnScroll(o,s,c)}},d._getRangeToRender=function(){var e=this.props,t=e.itemCount,n=e.overscanCount,r=this.state,i=r.isScrolling,a=r.scrollDirection,c=r.scrollOffset;if(t===0)return[0,0,0,0];var l=o(this.props,c,this._instanceProps),u=s(this.props,l,c,this._instanceProps),d=!i||a===`backward`?Math.max(1,n):1,f=!i||a===`forward`?Math.max(1,n):1;return[Math.max(0,l-d),Math.max(0,Math.min(t-1,u+f)),l,u]},t}(y.PureComponent),t.defaultProps={direction:`ltr`,itemData:void 0,layout:`vertical`,overscanCount:2,useIsScrolling:!1},t}var vt=function(e,t){e.children,e.direction,e.height,e.layout,e.innerTagName,e.outerTagName,e.width,t.instance},yt=_t({getItemOffset:function(e,t){return t*e.itemSize},getItemSize:function(e,t){return e.itemSize},getEstimatedTotalSize:function(e){var t=e.itemCount;return e.itemSize*t},getOffsetForIndexAndAlignment:function(e,t,n,r,i,a){var o=e.direction,s=e.height,c=e.itemCount,l=e.itemSize,u=e.layout,d=e.width,f=o===`horizontal`||u===`horizontal`?d:s,p=Math.max(0,c*l-f),m=Math.min(p,t*l),h=Math.max(0,t*l-f+l+a);switch(n===`smart`&&(n=r>=h-f&&r<=m+f?`auto`:`center`),n){case`start`:return m;case`end`:return h;case`center`:var g=Math.round(h+(m-h)/2);return gp+Math.floor(f/2)?p:g;default:return r>=h&&r<=m?r:r{e.currentTarget===e.target&&i.deselectAll()},children:[(0,M.jsx)(Ct,{}),n]}))}),Ct=()=>{let e=O();return(0,M.jsx)(`div`,{style:{height:e.visibleNodes.length*e.rowHeight,width:`100%`,position:`absolute`,left:`0`,right:`0`},children:(0,M.jsx)(bt,{})})},wt=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols==`function`)for(var i=0,r=Object.getOwnPropertySymbols(e);i-1})}var Bt={type:Dt,payload:{clientOffset:null,sourceClientOffset:null}};function Vt(e){return function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{publishSource:!0},r=n.publishSource,i=r===void 0?!0:r,a=n.clientOffset,o=n.getSourceClientOffset,s=e.getMonitor(),c=e.getRegistry();e.dispatch(Nt(a)),Ht(t,s,c);var l=Gt(t,s);if(l===null){e.dispatch(Bt);return}var u=null;if(a){if(!o)throw Error(`getSourceClientOffset must be defined`);Ut(o),u=o(l)}e.dispatch(Nt(a,u));var d=c.getSource(l).beginDrag(s,l);if(d!=null)return Wt(d),c.pinSource(l),{type:Ot,payload:{itemType:c.getSourceType(l),item:d,sourceId:l,clientOffset:a||null,sourceClientOffset:u||null,isSourcePublic:!!i}}}}function Ht(e,t,n){R(!t.isDragging(),`Cannot call beginDrag while dragging.`),e.forEach(function(e){R(n.getSource(e),`Expected sourceIds to be registered.`)})}function Ut(e){R(typeof e==`function`,`When clientOffset is provided, getSourceClientOffset must be a function.`)}function Wt(e){R(Lt(e),`Item must be an object.`)}function Gt(e,t){for(var n=null,r=e.length-1;r>=0;r--)if(t.canDragSource(e[r])){n=e[r];break}return n}function Kt(e){return function(){if(e.getMonitor().isDragging())return{type:kt}}}function qt(e,t){return t===null?e===null:Array.isArray(e)?e.some(function(e){return e===t}):e===t}function Jt(e){return function(t){var n=(arguments.length>1&&arguments[1]!==void 0?arguments[1]:{}).clientOffset;Yt(t);var r=t.slice(0),i=e.getMonitor(),a=e.getRegistry();return Xt(r,i,a),Zt(r,a,i.getItemType()),Qt(r,i,a),{type:At,payload:{targetIds:r,clientOffset:n||null}}}}function Yt(e){R(Array.isArray(e),`Expected targetIds to be an array.`)}function Xt(e,t,n){R(t.isDragging(),`Cannot call hover while not dragging.`),R(!t.didDrop(),`Cannot call hover after drop.`);for(var r=0;r=0;r--){var i=e[r];qt(t.getTargetType(i),n)||e.splice(r,1)}}function Qt(e,t,n){e.forEach(function(e){n.getTarget(e).hover(t,e)})}function $t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function en(e){for(var t=1;t0&&arguments[0]!==void 0?arguments[0]:{},n=e.getMonitor(),r=e.getRegistry();rn(n),sn(n).forEach(function(i,a){var o=an(i,a,r,n),s={type:jt,payload:{dropResult:en(en({},t),o)}};e.dispatch(s)})}}function rn(e){R(e.isDragging(),`Cannot call drop while not dragging.`),R(!e.didDrop(),`Cannot call drop twice during one drag operation.`)}function an(e,t,n,r){var i=n.getTarget(e),a=i?i.drop(r,e):void 0;return on(a),a===void 0&&(a=t===0?{}:r.getDropResult()),a}function on(e){R(e===void 0||Lt(e),`Drop result must either be an object or undefined.`)}function sn(e){var t=e.getTargetIds().filter(e.canDropOnTarget,e);return t.reverse(),t}function cn(e){return function(){var t=e.getMonitor(),n=e.getRegistry();ln(t);var r=t.getSourceId();return r!=null&&(n.getSource(r,!0).endDrag(t,r),n.unpinSource()),{type:Mt}}}function ln(e){R(e.isDragging(),`Cannot call endDrag while not dragging.`)}function un(e){return{beginDrag:Vt(e),publishDragSource:Kt(e),hover:Jt(e),drop:nn(e),endDrag:cn(e)}}function dn(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)}function fn(e,t){for(var n=0;n0;r.backend&&(e&&!r.isSetUp?(r.backend.setup(),r.isSetUp=!0):!e&&r.isSetUp&&(r.backend.teardown(),r.isSetUp=!1))}),this.store=t,this.monitor=n,t.subscribe(this.handleRefCountChange)}return pn(e,[{key:`receiveBackend`,value:function(e){this.backend=e}},{key:`getMonitor`,value:function(){return this.monitor}},{key:`getBackend`,value:function(){return this.backend}},{key:`getRegistry`,value:function(){return this.monitor.registry}},{key:`getActions`,value:function(){var e=this,t=this.store.dispatch;function n(n){return function(){var r=[...arguments],i=n.apply(e,r);i!==void 0&&t(i)}}var r=un(this);return Object.keys(r).reduce(function(e,t){var i=r[t];return e[t]=n(i),e},{})}},{key:`dispatch`,value:function(e){this.store.dispatch(e)}}]),e}();function B(e){return`Minified Redux error #`+e+`; visit https://redux.js.org/Errors?code=`+e+` for the full message or use the non-minified dev environment for full errors. `}var hn=(function(){return typeof Symbol==`function`&&Symbol.observable||`@@observable`})(),gn=function(){return Math.random().toString(36).substring(7).split(``).join(`.`)},_n={INIT:`@@redux/INIT`+gn(),REPLACE:`@@redux/REPLACE`+gn(),PROBE_UNKNOWN_ACTION:function(){return`@@redux/PROBE_UNKNOWN_ACTION`+gn()}};function vn(e){if(typeof e!=`object`||!e)return!1;for(var t=e;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function yn(e,t,n){var r;if(typeof t==`function`&&typeof n==`function`||typeof n==`function`&&typeof arguments[3]==`function`)throw Error(B(0));if(typeof t==`function`&&n===void 0&&(n=t,t=void 0),n!==void 0){if(typeof n!=`function`)throw Error(B(1));return n(yn)(e,t)}if(typeof e!=`function`)throw Error(B(2));var i=e,a=t,o=[],s=o,c=!1;function l(){s===o&&(s=o.slice())}function u(){if(c)throw Error(B(3));return a}function d(e){if(typeof e!=`function`)throw Error(B(4));if(c)throw Error(B(5));var t=!0;return l(),s.push(e),function(){if(t){if(c)throw Error(B(6));t=!1,l();var n=s.indexOf(e);s.splice(n,1),o=null}}}function f(e){if(!vn(e))throw Error(B(7));if(e.type===void 0)throw Error(B(8));if(c)throw Error(B(9));try{c=!0,a=i(a,e)}finally{c=!1}for(var t=o=s,n=0;n2&&arguments[2]!==void 0?arguments[2]:bn;if(e.length!==t.length)return!1;for(var r=0;r0&&arguments[0]!==void 0?arguments[0]:En,t=arguments.length>1?arguments[1]:void 0,n=t.payload;switch(t.type){case Dt:case Ot:return{initialSourceClientOffset:n.sourceClientOffset,initialClientOffset:n.clientOffset,clientOffset:n.clientOffset};case At:return xn(e.clientOffset,n.clientOffset)?e:wn(wn({},e),{},{clientOffset:n.clientOffset});case Mt:case jt:return En;default:return e}}var On=`dnd-core/ADD_SOURCE`,kn=`dnd-core/ADD_TARGET`,An=`dnd-core/REMOVE_SOURCE`,jn=`dnd-core/REMOVE_TARGET`;function Mn(e){return{type:On,payload:{sourceId:e}}}function Nn(e){return{type:kn,payload:{targetId:e}}}function Pn(e){return{type:An,payload:{sourceId:e}}}function Fn(e){return{type:jn,payload:{targetId:e}}}function In(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function V(e){for(var t=1;t0&&arguments[0]!==void 0?arguments[0]:Rn,t=arguments.length>1?arguments[1]:void 0,n=t.payload;switch(t.type){case Ot:return V(V({},e),{},{itemType:n.itemType,item:n.item,sourceId:n.sourceId,isSourcePublic:n.isSourcePublic,dropResult:null,didDrop:!1});case kt:return V(V({},e),{},{isSourcePublic:!0});case At:return V(V({},e),{},{targetIds:n.targetIds});case jn:return e.targetIds.indexOf(n.targetId)===-1?e:V(V({},e),{},{targetIds:It(e.targetIds,n.targetId)});case jt:return V(V({},e),{},{dropResult:n.dropResult,didDrop:!0,targetIds:[]});case Mt:return V(V({},e),{},{itemType:null,item:null,sourceId:null,dropResult:null,didDrop:!1,isSourcePublic:null,targetIds:[]});default:return e}}function Bn(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0;switch((arguments.length>1?arguments[1]:void 0).type){case On:case kn:return e+1;case An:case jn:return e-1;default:return e}}var Vn=[],Hn=[];Vn.__IS_NONE__=!0,Hn.__IS_ALL__=!0;function Un(e,t){return e===Vn?!1:e===Hn||t===void 0?!0:zt(t,e).length>0}function Wn(){arguments.length>0&&arguments[0]!==void 0&&arguments[0];var e=arguments.length>1?arguments[1]:void 0;switch(e.type){case At:break;case On:case kn:case jn:case An:return Vn;case Ot:case kt:case Mt:case jt:default:return Hn}var t=e.payload,n=t.targetIds,r=n===void 0?[]:n,i=t.prevTargetIds,a=i===void 0?[]:i,o=Rt(r,a);if(!(o.length>0||!Sn(r,a)))return Vn;var s=a[a.length-1],c=r[r.length-1];return s!==c&&(s&&o.push(s),c&&o.push(c)),o}function Gn(){return(arguments.length>0&&arguments[0]!==void 0?arguments[0]:0)+1}function Kn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function qn(e){for(var t=1;t0&&arguments[0]!==void 0?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;return{dirtyHandlerIds:Wn(e.dirtyHandlerIds,{type:t.type,payload:qn(qn({},t.payload),{},{prevTargetIds:Ft(e,`dragOperation.targetIds`,[])})}),dragOffset:Dn(e.dragOffset,t),refCount:Bn(e.refCount,t),dragOperation:zn(e.dragOperation,t),stateId:Gn(e.stateId)}}function Xn(e,t){return{x:e.x+t.x,y:e.y+t.y}}function Zn(e,t){return{x:e.x-t.x,y:e.y-t.y}}function Qn(e){var t=e.clientOffset,n=e.initialClientOffset,r=e.initialSourceClientOffset;return!t||!n||!r?null:Zn(Xn(t,r),n)}function $n(e){var t=e.clientOffset,n=e.initialClientOffset;return!t||!n?null:Zn(t,n)}function er(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)}function tr(e,t){for(var n=0;n1&&arguments[1]!==void 0?arguments[1]:{handlerIds:void 0}).handlerIds;R(typeof e==`function`,`listener must be a function.`),R(n===void 0||Array.isArray(n),`handlerIds, when specified, must be an array of strings.`);var r=this.store.getState().stateId;return this.store.subscribe(function(){var i=t.store.getState(),a=i.stateId;try{a===r||a===r+1&&!Un(i.dirtyHandlerIds,n)||e()}finally{r=a}})}},{key:`subscribeToOffsetChange`,value:function(e){var t=this;R(typeof e==`function`,`listener must be a function.`);var n=this.store.getState().dragOffset;return this.store.subscribe(function(){var r=t.store.getState().dragOffset;r!==n&&(n=r,e())})}},{key:`canDragSource`,value:function(e){if(!e)return!1;var t=this.registry.getSource(e);return R(t,`Expected to find a valid source. sourceId=${e}`),this.isDragging()?!1:t.canDrag(this,e)}},{key:`canDropOnTarget`,value:function(e){if(!e)return!1;var t=this.registry.getTarget(e);return R(t,`Expected to find a valid target. targetId=${e}`),!this.isDragging()||this.didDrop()?!1:qt(this.registry.getTargetType(e),this.getItemType())&&t.canDrop(this,e)}},{key:`isDragging`,value:function(){return!!this.getItemType()}},{key:`isDraggingSource`,value:function(e){if(!e)return!1;var t=this.registry.getSource(e,!0);return R(t,`Expected to find a valid source. sourceId=${e}`),!this.isDragging()||!this.isSourcePublic()||this.registry.getSourceType(e)!==this.getItemType()?!1:t.isDragging(this,e)}},{key:`isOverTarget`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{shallow:!1};if(!e)return!1;var n=t.shallow;if(!this.isDragging())return!1;var r=this.registry.getTargetType(e),i=this.getItemType();if(i&&!qt(r,i))return!1;var a=this.getTargetIds();if(!a.length)return!1;var o=a.indexOf(e);return n?o===a.length-1:o>-1}},{key:`getItemType`,value:function(){return this.store.getState().dragOperation.itemType}},{key:`getItem`,value:function(){return this.store.getState().dragOperation.item}},{key:`getSourceId`,value:function(){return this.store.getState().dragOperation.sourceId}},{key:`getTargetIds`,value:function(){return this.store.getState().dragOperation.targetIds}},{key:`getDropResult`,value:function(){return this.store.getState().dragOperation.dropResult}},{key:`didDrop`,value:function(){return this.store.getState().dragOperation.didDrop}},{key:`isSourcePublic`,value:function(){return!!this.store.getState().dragOperation.isSourcePublic}},{key:`getInitialClientOffset`,value:function(){return this.store.getState().dragOffset.initialClientOffset}},{key:`getInitialSourceClientOffset`,value:function(){return this.store.getState().dragOffset.initialSourceClientOffset}},{key:`getClientOffset`,value:function(){return this.store.getState().dragOffset.clientOffset}},{key:`getSourceClientOffset`,value:function(){return Qn(this.store.getState().dragOffset)}},{key:`getDifferenceFromInitialOffset`,value:function(){return $n(this.store.getState().dragOffset)}}]),e}(),ar=0;function or(){return ar++}function sr(e){"@babel/helpers - typeof";return sr=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},sr(e)}function cr(e){R(typeof e.canDrag==`function`,`Expected canDrag to be a function.`),R(typeof e.beginDrag==`function`,`Expected beginDrag to be a function.`),R(typeof e.endDrag==`function`,`Expected endDrag to be a function.`)}function lr(e){R(typeof e.canDrop==`function`,`Expected canDrop to be a function.`),R(typeof e.hover==`function`,`Expected hover to be a function.`),R(typeof e.drop==`function`,`Expected beginDrag to be a function.`)}function ur(e,t){if(t&&Array.isArray(e)){e.forEach(function(e){return ur(e,!1)});return}R(typeof e==`string`||sr(e)===`symbol`,t?`Type can only be a string, a symbol, or an array of either.`:`Type can only be a string or a symbol.`)}var dr=typeof global<`u`?global:self,fr=dr.MutationObserver||dr.WebKitMutationObserver;function pr(e){return function(){let t=setTimeout(r,0),n=setInterval(r,50);function r(){clearTimeout(t),clearInterval(n),e()}}}function mr(e){let t=1,n=new fr(e),r=document.createTextNode(``);return n.observe(r,{characterData:!0}),function(){t=-t,r.data=t}}var hr=typeof fr==`function`?mr:pr,gr=class{enqueueTask(e){let{queue:t,requestFlush:n}=this;t.length||(n(),this.flushing=!0),t[t.length]=e}constructor(){this.queue=[],this.pendingErrors=[],this.flushing=!1,this.index=0,this.capacity=1024,this.flush=()=>{let{queue:e}=this;for(;this.indexthis.capacity){for(let t=0,n=e.length-this.index;t{this.pendingErrors.push(e),this.requestErrorThrow()},this.requestFlush=hr(this.flush),this.requestErrorThrow=pr(()=>{if(this.pendingErrors.length)throw this.pendingErrors.shift()})}},_r=class{call(){try{this.task&&this.task()}catch(e){this.onError(e)}finally{this.task=null,this.release(this)}}constructor(e,t){this.onError=e,this.release=t,this.task=null}},vr=class{create(e){let t=this.freeTasks,n=t.length?t.pop():new _r(this.onError,e=>t[t.length]=e);return n.task=e,n}constructor(e){this.onError=e,this.freeTasks=[]}},yr=new gr,br=new vr(yr.registerPendingError);function xr(e){yr.enqueueTask(br.create(e))}function Sr(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)}function Cr(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=Array(t);n1&&arguments[1]!==void 0?arguments[1]:!1;return R(this.isSourceId(e),`Expected a valid source ID.`),t&&e===this.pinnedSourceId?this.pinnedSource:this.dragSources.get(e)}},{key:`getTarget`,value:function(e){return R(this.isTargetId(e),`Expected a valid target ID.`),this.dropTargets.get(e)}},{key:`getSourceType`,value:function(e){return R(this.isSourceId(e),`Expected a valid source ID.`),this.types.get(e)}},{key:`getTargetType`,value:function(e){return R(this.isTargetId(e),`Expected a valid target ID.`),this.types.get(e)}},{key:`isSourceId`,value:function(e){return Mr(e)===L.SOURCE}},{key:`isTargetId`,value:function(e){return Mr(e)===L.TARGET}},{key:`removeSource`,value:function(e){var t=this;R(this.getSource(e),`Expected an existing source.`),this.store.dispatch(Pn(e)),xr(function(){t.dragSources.delete(e),t.types.delete(e)})}},{key:`removeTarget`,value:function(e){R(this.getTarget(e),`Expected an existing target.`),this.store.dispatch(Fn(e)),this.dropTargets.delete(e),this.types.delete(e)}},{key:`pinSource`,value:function(e){var t=this.getSource(e);R(t,`Expected an existing source.`),this.pinnedSourceId=e,this.pinnedSource=t}},{key:`unpinSource`,value:function(){R(this.pinnedSource,`No source is pinned at the time.`),this.pinnedSourceId=null,this.pinnedSource=null}},{key:`addHandler`,value:function(e,t,n){var r=jr(e);return this.types.set(r,t),e===L.SOURCE?this.dragSources.set(r,n):e===L.TARGET&&this.dropTargets.set(r,n),r}}]),e}();function Fr(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:void 0,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},r=Ir(arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1),i=new mn(r,new ir(r,new Pr(r))),a=e(i,t,n);return i.receiveBackend(a),i}function Ir(e){var t=typeof window<`u`&&window.__REDUX_DEVTOOLS_EXTENSION__;return yn(Yn,e&&t&&t({name:`dnd-core`,instanceId:`dnd-core`}))}var Lr=[`children`];function Rr(e,t){return Ur(e)||Hr(e,t)||Br(e,t)||zr()}function zr(){throw TypeError(`Invalid attempt to destructure non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Br(e,t){if(e){if(typeof e==`string`)return Vr(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);if(n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`)return Array.from(e);if(n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Vr(e,t)}}function Vr(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=0)&&Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}function Gr(e,t){if(e==null)return{};var n={},r=Object.keys(e),i,a;for(a=0;a=0)&&(n[i]=e[i]);return n}var Kr=0,qr=Symbol.for(`__REACT_DND_CONTEXT_INSTANCE__`),Jr=(0,y.memo)(function(e){var t=e.children,n=Rr(Yr(Wr(e,Lr)),2),r=n[0],i=n[1];return(0,y.useEffect)(function(){if(i){var e=Zr();return++Kr,function(){--Kr===0&&(e[qr]=null)}}},[]),(0,M.jsx)(Et.Provider,Object.assign({value:r},{children:t}),void 0)});function Yr(e){return`manager`in e?[{dragDropManager:e.manager},!1]:[Xr(e.backend,e.context,e.options,e.debugMode),!e.context]}function Xr(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Zr(),n=arguments.length>2?arguments[2]:void 0,r=arguments.length>3?arguments[3]:void 0,i=t;return i[qr]||(i[qr]={dragDropManager:Fr(e,t,n,r)}),i[qr]}function Zr(){return typeof global<`u`?global:window}function Qr(e,t){if(!(e instanceof t))throw TypeError(`Cannot call a class as a function`)}function $r(e,t){for(var n=0;n, or turn it into a drag source or a drop target itself.`)}}function fi(e){return function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:null,n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;if(!(0,y.isValidElement)(t)){var r=t;return e(r,n),r}var i=t;return di(i),hi(i,n?function(t){return e(t,n)}:e)}}function pi(e){var t={};return Object.keys(e).forEach(function(n){var r=e[n];if(n.endsWith(`Ref`))t[n]=e[n];else{var i=fi(r);t[n]=function(){return i}}}),t}function mi(e,t){typeof e==`function`?e(t):e.current=t}function hi(e,t){var n=e.ref;return R(typeof n!=`string`,`Cannot connect React DnD to an element with an existing string ref. Please convert it to use a callback ref instead, or wrap it into a or
. Read more: https://reactjs.org/docs/refs-and-the-dom.html#callback-refs`),n?(0,y.cloneElement)(e,{ref:function(e){mi(n,e),mi(t,e)}}):(0,y.cloneElement)(e,{ref:t})}function gi(e){"@babel/helpers - typeof";return gi=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},gi(e)}function _i(e){return e!==null&&gi(e)===`object`&&Object.prototype.hasOwnProperty.call(e,`current`)}function vi(e,t,n,r){var i=n?n.call(r,e,t):void 0;if(i!==void 0)return!!i;if(e===t)return!0;if(typeof e!=`object`||!e||typeof t!=`object`||!t)return!1;var a=Object.keys(e),o=Object.keys(t);if(a.length!==o.length)return!1;for(var s=Object.prototype.hasOwnProperty.bind(t),c=0;ce.length)&&(t=e.length);for(var n=0,r=Array(t);n{t.exports=`SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED`})),l=t(((e,t)=>{var n=c();function r(){}function i(){}i.resetWarningCache=r,t.exports=function(){function e(e,t,r,i,a,o){if(o!==n){var s=Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name=`Invariant Violation`,s}}e.isRequired=e;function t(){return e}var a={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:r};return a.PropTypes=a,a}})),u=t(((e,t)=>{t.exports=l()()}));function d(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})}var f=new Map([[`1km`,`application/vnd.1000minds.decision-model+xml`],[`3dml`,`text/vnd.in3d.3dml`],[`3ds`,`image/x-3ds`],[`3g2`,`video/3gpp2`],[`3gp`,`video/3gp`],[`3gpp`,`video/3gpp`],[`3mf`,`model/3mf`],[`7z`,`application/x-7z-compressed`],[`7zip`,`application/x-7z-compressed`],[`123`,`application/vnd.lotus-1-2-3`],[`aab`,`application/x-authorware-bin`],[`aac`,`audio/x-acc`],[`aam`,`application/x-authorware-map`],[`aas`,`application/x-authorware-seg`],[`abw`,`application/x-abiword`],[`ac`,`application/vnd.nokia.n-gage.ac+xml`],[`ac3`,`audio/ac3`],[`acc`,`application/vnd.americandynamics.acc`],[`ace`,`application/x-ace-compressed`],[`acu`,`application/vnd.acucobol`],[`acutc`,`application/vnd.acucorp`],[`adp`,`audio/adpcm`],[`aep`,`application/vnd.audiograph`],[`afm`,`application/x-font-type1`],[`afp`,`application/vnd.ibm.modcap`],[`ahead`,`application/vnd.ahead.space`],[`ai`,`application/pdf`],[`aif`,`audio/x-aiff`],[`aifc`,`audio/x-aiff`],[`aiff`,`audio/x-aiff`],[`air`,`application/vnd.adobe.air-application-installer-package+zip`],[`ait`,`application/vnd.dvb.ait`],[`ami`,`application/vnd.amiga.ami`],[`amr`,`audio/amr`],[`apk`,`application/vnd.android.package-archive`],[`apng`,`image/apng`],[`appcache`,`text/cache-manifest`],[`application`,`application/x-ms-application`],[`apr`,`application/vnd.lotus-approach`],[`arc`,`application/x-freearc`],[`arj`,`application/x-arj`],[`asc`,`application/pgp-signature`],[`asf`,`video/x-ms-asf`],[`asm`,`text/x-asm`],[`aso`,`application/vnd.accpac.simply.aso`],[`asx`,`video/x-ms-asf`],[`atc`,`application/vnd.acucorp`],[`atom`,`application/atom+xml`],[`atomcat`,`application/atomcat+xml`],[`atomdeleted`,`application/atomdeleted+xml`],[`atomsvc`,`application/atomsvc+xml`],[`atx`,`application/vnd.antix.game-component`],[`au`,`audio/x-au`],[`avi`,`video/x-msvideo`],[`avif`,`image/avif`],[`aw`,`application/applixware`],[`azf`,`application/vnd.airzip.filesecure.azf`],[`azs`,`application/vnd.airzip.filesecure.azs`],[`azv`,`image/vnd.airzip.accelerator.azv`],[`azw`,`application/vnd.amazon.ebook`],[`b16`,`image/vnd.pco.b16`],[`bat`,`application/x-msdownload`],[`bcpio`,`application/x-bcpio`],[`bdf`,`application/x-font-bdf`],[`bdm`,`application/vnd.syncml.dm+wbxml`],[`bdoc`,`application/x-bdoc`],[`bed`,`application/vnd.realvnc.bed`],[`bh2`,`application/vnd.fujitsu.oasysprs`],[`bin`,`application/octet-stream`],[`blb`,`application/x-blorb`],[`blorb`,`application/x-blorb`],[`bmi`,`application/vnd.bmi`],[`bmml`,`application/vnd.balsamiq.bmml+xml`],[`bmp`,`image/bmp`],[`book`,`application/vnd.framemaker`],[`box`,`application/vnd.previewsystems.box`],[`boz`,`application/x-bzip2`],[`bpk`,`application/octet-stream`],[`bpmn`,`application/octet-stream`],[`bsp`,`model/vnd.valve.source.compiled-map`],[`btif`,`image/prs.btif`],[`buffer`,`application/octet-stream`],[`bz`,`application/x-bzip`],[`bz2`,`application/x-bzip2`],[`c`,`text/x-c`],[`c4d`,`application/vnd.clonk.c4group`],[`c4f`,`application/vnd.clonk.c4group`],[`c4g`,`application/vnd.clonk.c4group`],[`c4p`,`application/vnd.clonk.c4group`],[`c4u`,`application/vnd.clonk.c4group`],[`c11amc`,`application/vnd.cluetrust.cartomobile-config`],[`c11amz`,`application/vnd.cluetrust.cartomobile-config-pkg`],[`cab`,`application/vnd.ms-cab-compressed`],[`caf`,`audio/x-caf`],[`cap`,`application/vnd.tcpdump.pcap`],[`car`,`application/vnd.curl.car`],[`cat`,`application/vnd.ms-pki.seccat`],[`cb7`,`application/x-cbr`],[`cba`,`application/x-cbr`],[`cbr`,`application/x-cbr`],[`cbt`,`application/x-cbr`],[`cbz`,`application/x-cbr`],[`cc`,`text/x-c`],[`cco`,`application/x-cocoa`],[`cct`,`application/x-director`],[`ccxml`,`application/ccxml+xml`],[`cdbcmsg`,`application/vnd.contact.cmsg`],[`cda`,`application/x-cdf`],[`cdf`,`application/x-netcdf`],[`cdfx`,`application/cdfx+xml`],[`cdkey`,`application/vnd.mediastation.cdkey`],[`cdmia`,`application/cdmi-capability`],[`cdmic`,`application/cdmi-container`],[`cdmid`,`application/cdmi-domain`],[`cdmio`,`application/cdmi-object`],[`cdmiq`,`application/cdmi-queue`],[`cdr`,`application/cdr`],[`cdx`,`chemical/x-cdx`],[`cdxml`,`application/vnd.chemdraw+xml`],[`cdy`,`application/vnd.cinderella`],[`cer`,`application/pkix-cert`],[`cfs`,`application/x-cfs-compressed`],[`cgm`,`image/cgm`],[`chat`,`application/x-chat`],[`chm`,`application/vnd.ms-htmlhelp`],[`chrt`,`application/vnd.kde.kchart`],[`cif`,`chemical/x-cif`],[`cii`,`application/vnd.anser-web-certificate-issue-initiation`],[`cil`,`application/vnd.ms-artgalry`],[`cjs`,`application/node`],[`cla`,`application/vnd.claymore`],[`class`,`application/octet-stream`],[`clkk`,`application/vnd.crick.clicker.keyboard`],[`clkp`,`application/vnd.crick.clicker.palette`],[`clkt`,`application/vnd.crick.clicker.template`],[`clkw`,`application/vnd.crick.clicker.wordbank`],[`clkx`,`application/vnd.crick.clicker`],[`clp`,`application/x-msclip`],[`cmc`,`application/vnd.cosmocaller`],[`cmdf`,`chemical/x-cmdf`],[`cml`,`chemical/x-cml`],[`cmp`,`application/vnd.yellowriver-custom-menu`],[`cmx`,`image/x-cmx`],[`cod`,`application/vnd.rim.cod`],[`coffee`,`text/coffeescript`],[`com`,`application/x-msdownload`],[`conf`,`text/plain`],[`cpio`,`application/x-cpio`],[`cpp`,`text/x-c`],[`cpt`,`application/mac-compactpro`],[`crd`,`application/x-mscardfile`],[`crl`,`application/pkix-crl`],[`crt`,`application/x-x509-ca-cert`],[`crx`,`application/x-chrome-extension`],[`cryptonote`,`application/vnd.rig.cryptonote`],[`csh`,`application/x-csh`],[`csl`,`application/vnd.citationstyles.style+xml`],[`csml`,`chemical/x-csml`],[`csp`,`application/vnd.commonspace`],[`csr`,`application/octet-stream`],[`css`,`text/css`],[`cst`,`application/x-director`],[`csv`,`text/csv`],[`cu`,`application/cu-seeme`],[`curl`,`text/vnd.curl`],[`cww`,`application/prs.cww`],[`cxt`,`application/x-director`],[`cxx`,`text/x-c`],[`dae`,`model/vnd.collada+xml`],[`daf`,`application/vnd.mobius.daf`],[`dart`,`application/vnd.dart`],[`dataless`,`application/vnd.fdsn.seed`],[`davmount`,`application/davmount+xml`],[`dbf`,`application/vnd.dbf`],[`dbk`,`application/docbook+xml`],[`dcr`,`application/x-director`],[`dcurl`,`text/vnd.curl.dcurl`],[`dd2`,`application/vnd.oma.dd2+xml`],[`ddd`,`application/vnd.fujixerox.ddd`],[`ddf`,`application/vnd.syncml.dmddf+xml`],[`dds`,`image/vnd.ms-dds`],[`deb`,`application/x-debian-package`],[`def`,`text/plain`],[`deploy`,`application/octet-stream`],[`der`,`application/x-x509-ca-cert`],[`dfac`,`application/vnd.dreamfactory`],[`dgc`,`application/x-dgc-compressed`],[`dic`,`text/x-c`],[`dir`,`application/x-director`],[`dis`,`application/vnd.mobius.dis`],[`disposition-notification`,`message/disposition-notification`],[`dist`,`application/octet-stream`],[`distz`,`application/octet-stream`],[`djv`,`image/vnd.djvu`],[`djvu`,`image/vnd.djvu`],[`dll`,`application/octet-stream`],[`dmg`,`application/x-apple-diskimage`],[`dmn`,`application/octet-stream`],[`dmp`,`application/vnd.tcpdump.pcap`],[`dms`,`application/octet-stream`],[`dna`,`application/vnd.dna`],[`doc`,`application/msword`],[`docm`,`application/vnd.ms-word.template.macroEnabled.12`],[`docx`,`application/vnd.openxmlformats-officedocument.wordprocessingml.document`],[`dot`,`application/msword`],[`dotm`,`application/vnd.ms-word.template.macroEnabled.12`],[`dotx`,`application/vnd.openxmlformats-officedocument.wordprocessingml.template`],[`dp`,`application/vnd.osgi.dp`],[`dpg`,`application/vnd.dpgraph`],[`dra`,`audio/vnd.dra`],[`drle`,`image/dicom-rle`],[`dsc`,`text/prs.lines.tag`],[`dssc`,`application/dssc+der`],[`dtb`,`application/x-dtbook+xml`],[`dtd`,`application/xml-dtd`],[`dts`,`audio/vnd.dts`],[`dtshd`,`audio/vnd.dts.hd`],[`dump`,`application/octet-stream`],[`dvb`,`video/vnd.dvb.file`],[`dvi`,`application/x-dvi`],[`dwd`,`application/atsc-dwd+xml`],[`dwf`,`model/vnd.dwf`],[`dwg`,`image/vnd.dwg`],[`dxf`,`image/vnd.dxf`],[`dxp`,`application/vnd.spotfire.dxp`],[`dxr`,`application/x-director`],[`ear`,`application/java-archive`],[`ecelp4800`,`audio/vnd.nuera.ecelp4800`],[`ecelp7470`,`audio/vnd.nuera.ecelp7470`],[`ecelp9600`,`audio/vnd.nuera.ecelp9600`],[`ecma`,`application/ecmascript`],[`edm`,`application/vnd.novadigm.edm`],[`edx`,`application/vnd.novadigm.edx`],[`efif`,`application/vnd.picsel`],[`ei6`,`application/vnd.pg.osasli`],[`elc`,`application/octet-stream`],[`emf`,`image/emf`],[`eml`,`message/rfc822`],[`emma`,`application/emma+xml`],[`emotionml`,`application/emotionml+xml`],[`emz`,`application/x-msmetafile`],[`eol`,`audio/vnd.digital-winds`],[`eot`,`application/vnd.ms-fontobject`],[`eps`,`application/postscript`],[`epub`,`application/epub+zip`],[`es`,`application/ecmascript`],[`es3`,`application/vnd.eszigno3+xml`],[`esa`,`application/vnd.osgi.subsystem`],[`esf`,`application/vnd.epson.esf`],[`et3`,`application/vnd.eszigno3+xml`],[`etx`,`text/x-setext`],[`eva`,`application/x-eva`],[`evy`,`application/x-envoy`],[`exe`,`application/octet-stream`],[`exi`,`application/exi`],[`exp`,`application/express`],[`exr`,`image/aces`],[`ext`,`application/vnd.novadigm.ext`],[`ez`,`application/andrew-inset`],[`ez2`,`application/vnd.ezpix-album`],[`ez3`,`application/vnd.ezpix-package`],[`f`,`text/x-fortran`],[`f4v`,`video/mp4`],[`f77`,`text/x-fortran`],[`f90`,`text/x-fortran`],[`fbs`,`image/vnd.fastbidsheet`],[`fcdt`,`application/vnd.adobe.formscentral.fcdt`],[`fcs`,`application/vnd.isac.fcs`],[`fdf`,`application/vnd.fdf`],[`fdt`,`application/fdt+xml`],[`fe_launch`,`application/vnd.denovo.fcselayout-link`],[`fg5`,`application/vnd.fujitsu.oasysgp`],[`fgd`,`application/x-director`],[`fh`,`image/x-freehand`],[`fh4`,`image/x-freehand`],[`fh5`,`image/x-freehand`],[`fh7`,`image/x-freehand`],[`fhc`,`image/x-freehand`],[`fig`,`application/x-xfig`],[`fits`,`image/fits`],[`flac`,`audio/x-flac`],[`fli`,`video/x-fli`],[`flo`,`application/vnd.micrografx.flo`],[`flv`,`video/x-flv`],[`flw`,`application/vnd.kde.kivio`],[`flx`,`text/vnd.fmi.flexstor`],[`fly`,`text/vnd.fly`],[`fm`,`application/vnd.framemaker`],[`fnc`,`application/vnd.frogans.fnc`],[`fo`,`application/vnd.software602.filler.form+xml`],[`for`,`text/x-fortran`],[`fpx`,`image/vnd.fpx`],[`frame`,`application/vnd.framemaker`],[`fsc`,`application/vnd.fsc.weblaunch`],[`fst`,`image/vnd.fst`],[`ftc`,`application/vnd.fluxtime.clip`],[`fti`,`application/vnd.anser-web-funds-transfer-initiation`],[`fvt`,`video/vnd.fvt`],[`fxp`,`application/vnd.adobe.fxp`],[`fxpl`,`application/vnd.adobe.fxp`],[`fzs`,`application/vnd.fuzzysheet`],[`g2w`,`application/vnd.geoplan`],[`g3`,`image/g3fax`],[`g3w`,`application/vnd.geospace`],[`gac`,`application/vnd.groove-account`],[`gam`,`application/x-tads`],[`gbr`,`application/rpki-ghostbusters`],[`gca`,`application/x-gca-compressed`],[`gdl`,`model/vnd.gdl`],[`gdoc`,`application/vnd.google-apps.document`],[`geo`,`application/vnd.dynageo`],[`geojson`,`application/geo+json`],[`gex`,`application/vnd.geometry-explorer`],[`ggb`,`application/vnd.geogebra.file`],[`ggt`,`application/vnd.geogebra.tool`],[`ghf`,`application/vnd.groove-help`],[`gif`,`image/gif`],[`gim`,`application/vnd.groove-identity-message`],[`glb`,`model/gltf-binary`],[`gltf`,`model/gltf+json`],[`gml`,`application/gml+xml`],[`gmx`,`application/vnd.gmx`],[`gnumeric`,`application/x-gnumeric`],[`gpg`,`application/gpg-keys`],[`gph`,`application/vnd.flographit`],[`gpx`,`application/gpx+xml`],[`gqf`,`application/vnd.grafeq`],[`gqs`,`application/vnd.grafeq`],[`gram`,`application/srgs`],[`gramps`,`application/x-gramps-xml`],[`gre`,`application/vnd.geometry-explorer`],[`grv`,`application/vnd.groove-injector`],[`grxml`,`application/srgs+xml`],[`gsf`,`application/x-font-ghostscript`],[`gsheet`,`application/vnd.google-apps.spreadsheet`],[`gslides`,`application/vnd.google-apps.presentation`],[`gtar`,`application/x-gtar`],[`gtm`,`application/vnd.groove-tool-message`],[`gtw`,`model/vnd.gtw`],[`gv`,`text/vnd.graphviz`],[`gxf`,`application/gxf`],[`gxt`,`application/vnd.geonext`],[`gz`,`application/gzip`],[`gzip`,`application/gzip`],[`h`,`text/x-c`],[`h261`,`video/h261`],[`h263`,`video/h263`],[`h264`,`video/h264`],[`hal`,`application/vnd.hal+xml`],[`hbci`,`application/vnd.hbci`],[`hbs`,`text/x-handlebars-template`],[`hdd`,`application/x-virtualbox-hdd`],[`hdf`,`application/x-hdf`],[`heic`,`image/heic`],[`heics`,`image/heic-sequence`],[`heif`,`image/heif`],[`heifs`,`image/heif-sequence`],[`hej2`,`image/hej2k`],[`held`,`application/atsc-held+xml`],[`hh`,`text/x-c`],[`hjson`,`application/hjson`],[`hlp`,`application/winhlp`],[`hpgl`,`application/vnd.hp-hpgl`],[`hpid`,`application/vnd.hp-hpid`],[`hps`,`application/vnd.hp-hps`],[`hqx`,`application/mac-binhex40`],[`hsj2`,`image/hsj2`],[`htc`,`text/x-component`],[`htke`,`application/vnd.kenameaapp`],[`htm`,`text/html`],[`html`,`text/html`],[`hvd`,`application/vnd.yamaha.hv-dic`],[`hvp`,`application/vnd.yamaha.hv-voice`],[`hvs`,`application/vnd.yamaha.hv-script`],[`i2g`,`application/vnd.intergeo`],[`icc`,`application/vnd.iccprofile`],[`ice`,`x-conference/x-cooltalk`],[`icm`,`application/vnd.iccprofile`],[`ico`,`image/x-icon`],[`ics`,`text/calendar`],[`ief`,`image/ief`],[`ifb`,`text/calendar`],[`ifm`,`application/vnd.shana.informed.formdata`],[`iges`,`model/iges`],[`igl`,`application/vnd.igloader`],[`igm`,`application/vnd.insors.igm`],[`igs`,`model/iges`],[`igx`,`application/vnd.micrografx.igx`],[`iif`,`application/vnd.shana.informed.interchange`],[`img`,`application/octet-stream`],[`imp`,`application/vnd.accpac.simply.imp`],[`ims`,`application/vnd.ms-ims`],[`in`,`text/plain`],[`ini`,`text/plain`],[`ink`,`application/inkml+xml`],[`inkml`,`application/inkml+xml`],[`install`,`application/x-install-instructions`],[`iota`,`application/vnd.astraea-software.iota`],[`ipfix`,`application/ipfix`],[`ipk`,`application/vnd.shana.informed.package`],[`irm`,`application/vnd.ibm.rights-management`],[`irp`,`application/vnd.irepository.package+xml`],[`iso`,`application/x-iso9660-image`],[`itp`,`application/vnd.shana.informed.formtemplate`],[`its`,`application/its+xml`],[`ivp`,`application/vnd.immervision-ivp`],[`ivu`,`application/vnd.immervision-ivu`],[`jad`,`text/vnd.sun.j2me.app-descriptor`],[`jade`,`text/jade`],[`jam`,`application/vnd.jam`],[`jar`,`application/java-archive`],[`jardiff`,`application/x-java-archive-diff`],[`java`,`text/x-java-source`],[`jhc`,`image/jphc`],[`jisp`,`application/vnd.jisp`],[`jls`,`image/jls`],[`jlt`,`application/vnd.hp-jlyt`],[`jng`,`image/x-jng`],[`jnlp`,`application/x-java-jnlp-file`],[`joda`,`application/vnd.joost.joda-archive`],[`jp2`,`image/jp2`],[`jpe`,`image/jpeg`],[`jpeg`,`image/jpeg`],[`jpf`,`image/jpx`],[`jpg`,`image/jpeg`],[`jpg2`,`image/jp2`],[`jpgm`,`video/jpm`],[`jpgv`,`video/jpeg`],[`jph`,`image/jph`],[`jpm`,`video/jpm`],[`jpx`,`image/jpx`],[`js`,`application/javascript`],[`json`,`application/json`],[`json5`,`application/json5`],[`jsonld`,`application/ld+json`],[`jsonl`,`application/jsonl`],[`jsonml`,`application/jsonml+json`],[`jsx`,`text/jsx`],[`jxr`,`image/jxr`],[`jxra`,`image/jxra`],[`jxrs`,`image/jxrs`],[`jxs`,`image/jxs`],[`jxsc`,`image/jxsc`],[`jxsi`,`image/jxsi`],[`jxss`,`image/jxss`],[`kar`,`audio/midi`],[`karbon`,`application/vnd.kde.karbon`],[`kdb`,`application/octet-stream`],[`kdbx`,`application/x-keepass2`],[`key`,`application/x-iwork-keynote-sffkey`],[`kfo`,`application/vnd.kde.kformula`],[`kia`,`application/vnd.kidspiration`],[`kml`,`application/vnd.google-earth.kml+xml`],[`kmz`,`application/vnd.google-earth.kmz`],[`kne`,`application/vnd.kinar`],[`knp`,`application/vnd.kinar`],[`kon`,`application/vnd.kde.kontour`],[`kpr`,`application/vnd.kde.kpresenter`],[`kpt`,`application/vnd.kde.kpresenter`],[`kpxx`,`application/vnd.ds-keypoint`],[`ksp`,`application/vnd.kde.kspread`],[`ktr`,`application/vnd.kahootz`],[`ktx`,`image/ktx`],[`ktx2`,`image/ktx2`],[`ktz`,`application/vnd.kahootz`],[`kwd`,`application/vnd.kde.kword`],[`kwt`,`application/vnd.kde.kword`],[`lasxml`,`application/vnd.las.las+xml`],[`latex`,`application/x-latex`],[`lbd`,`application/vnd.llamagraphics.life-balance.desktop`],[`lbe`,`application/vnd.llamagraphics.life-balance.exchange+xml`],[`les`,`application/vnd.hhe.lesson-player`],[`less`,`text/less`],[`lgr`,`application/lgr+xml`],[`lha`,`application/octet-stream`],[`link66`,`application/vnd.route66.link66+xml`],[`list`,`text/plain`],[`list3820`,`application/vnd.ibm.modcap`],[`listafp`,`application/vnd.ibm.modcap`],[`litcoffee`,`text/coffeescript`],[`lnk`,`application/x-ms-shortcut`],[`log`,`text/plain`],[`lostxml`,`application/lost+xml`],[`lrf`,`application/octet-stream`],[`lrm`,`application/vnd.ms-lrm`],[`ltf`,`application/vnd.frogans.ltf`],[`lua`,`text/x-lua`],[`luac`,`application/x-lua-bytecode`],[`lvp`,`audio/vnd.lucent.voice`],[`lwp`,`application/vnd.lotus-wordpro`],[`lzh`,`application/octet-stream`],[`m1v`,`video/mpeg`],[`m2a`,`audio/mpeg`],[`m2v`,`video/mpeg`],[`m3a`,`audio/mpeg`],[`m3u`,`text/plain`],[`m3u8`,`application/vnd.apple.mpegurl`],[`m4a`,`audio/x-m4a`],[`m4p`,`application/mp4`],[`m4s`,`video/iso.segment`],[`m4u`,`application/vnd.mpegurl`],[`m4v`,`video/x-m4v`],[`m13`,`application/x-msmediaview`],[`m14`,`application/x-msmediaview`],[`m21`,`application/mp21`],[`ma`,`application/mathematica`],[`mads`,`application/mads+xml`],[`maei`,`application/mmt-aei+xml`],[`mag`,`application/vnd.ecowin.chart`],[`maker`,`application/vnd.framemaker`],[`man`,`text/troff`],[`manifest`,`text/cache-manifest`],[`map`,`application/json`],[`mar`,`application/octet-stream`],[`markdown`,`text/markdown`],[`mathml`,`application/mathml+xml`],[`mb`,`application/mathematica`],[`mbk`,`application/vnd.mobius.mbk`],[`mbox`,`application/mbox`],[`mc1`,`application/vnd.medcalcdata`],[`mcd`,`application/vnd.mcd`],[`mcurl`,`text/vnd.curl.mcurl`],[`md`,`text/markdown`],[`mdb`,`application/x-msaccess`],[`mdi`,`image/vnd.ms-modi`],[`mdx`,`text/mdx`],[`me`,`text/troff`],[`mesh`,`model/mesh`],[`meta4`,`application/metalink4+xml`],[`metalink`,`application/metalink+xml`],[`mets`,`application/mets+xml`],[`mfm`,`application/vnd.mfmp`],[`mft`,`application/rpki-manifest`],[`mgp`,`application/vnd.osgeo.mapguide.package`],[`mgz`,`application/vnd.proteus.magazine`],[`mid`,`audio/midi`],[`midi`,`audio/midi`],[`mie`,`application/x-mie`],[`mif`,`application/vnd.mif`],[`mime`,`message/rfc822`],[`mj2`,`video/mj2`],[`mjp2`,`video/mj2`],[`mjs`,`application/javascript`],[`mk3d`,`video/x-matroska`],[`mka`,`audio/x-matroska`],[`mkd`,`text/x-markdown`],[`mks`,`video/x-matroska`],[`mkv`,`video/x-matroska`],[`mlp`,`application/vnd.dolby.mlp`],[`mmd`,`application/vnd.chipnuts.karaoke-mmd`],[`mmf`,`application/vnd.smaf`],[`mml`,`text/mathml`],[`mmr`,`image/vnd.fujixerox.edmics-mmr`],[`mng`,`video/x-mng`],[`mny`,`application/x-msmoney`],[`mobi`,`application/x-mobipocket-ebook`],[`mods`,`application/mods+xml`],[`mov`,`video/quicktime`],[`movie`,`video/x-sgi-movie`],[`mp2`,`audio/mpeg`],[`mp2a`,`audio/mpeg`],[`mp3`,`audio/mpeg`],[`mp4`,`video/mp4`],[`mp4a`,`audio/mp4`],[`mp4s`,`application/mp4`],[`mp4v`,`video/mp4`],[`mp21`,`application/mp21`],[`mpc`,`application/vnd.mophun.certificate`],[`mpd`,`application/dash+xml`],[`mpe`,`video/mpeg`],[`mpeg`,`video/mpeg`],[`mpg`,`video/mpeg`],[`mpg4`,`video/mp4`],[`mpga`,`audio/mpeg`],[`mpkg`,`application/vnd.apple.installer+xml`],[`mpm`,`application/vnd.blueice.multipass`],[`mpn`,`application/vnd.mophun.application`],[`mpp`,`application/vnd.ms-project`],[`mpt`,`application/vnd.ms-project`],[`mpy`,`application/vnd.ibm.minipay`],[`mqy`,`application/vnd.mobius.mqy`],[`mrc`,`application/marc`],[`mrcx`,`application/marcxml+xml`],[`ms`,`text/troff`],[`mscml`,`application/mediaservercontrol+xml`],[`mseed`,`application/vnd.fdsn.mseed`],[`mseq`,`application/vnd.mseq`],[`msf`,`application/vnd.epson.msf`],[`msg`,`application/vnd.ms-outlook`],[`msh`,`model/mesh`],[`msi`,`application/x-msdownload`],[`msl`,`application/vnd.mobius.msl`],[`msm`,`application/octet-stream`],[`msp`,`application/octet-stream`],[`msty`,`application/vnd.muvee.style`],[`mtl`,`model/mtl`],[`mts`,`model/vnd.mts`],[`mus`,`application/vnd.musician`],[`musd`,`application/mmt-usd+xml`],[`musicxml`,`application/vnd.recordare.musicxml+xml`],[`mvb`,`application/x-msmediaview`],[`mvt`,`application/vnd.mapbox-vector-tile`],[`mwf`,`application/vnd.mfer`],[`mxf`,`application/mxf`],[`mxl`,`application/vnd.recordare.musicxml`],[`mxmf`,`audio/mobile-xmf`],[`mxml`,`application/xv+xml`],[`mxs`,`application/vnd.triscape.mxs`],[`mxu`,`video/vnd.mpegurl`],[`n-gage`,`application/vnd.nokia.n-gage.symbian.install`],[`n3`,`text/n3`],[`nb`,`application/mathematica`],[`nbp`,`application/vnd.wolfram.player`],[`nc`,`application/x-netcdf`],[`ncx`,`application/x-dtbncx+xml`],[`nfo`,`text/x-nfo`],[`ngdat`,`application/vnd.nokia.n-gage.data`],[`nitf`,`application/vnd.nitf`],[`nlu`,`application/vnd.neurolanguage.nlu`],[`nml`,`application/vnd.enliven`],[`nnd`,`application/vnd.noblenet-directory`],[`nns`,`application/vnd.noblenet-sealer`],[`nnw`,`application/vnd.noblenet-web`],[`npx`,`image/vnd.net-fpx`],[`nq`,`application/n-quads`],[`nsc`,`application/x-conference`],[`nsf`,`application/vnd.lotus-notes`],[`nt`,`application/n-triples`],[`ntf`,`application/vnd.nitf`],[`numbers`,`application/x-iwork-numbers-sffnumbers`],[`nzb`,`application/x-nzb`],[`oa2`,`application/vnd.fujitsu.oasys2`],[`oa3`,`application/vnd.fujitsu.oasys3`],[`oas`,`application/vnd.fujitsu.oasys`],[`obd`,`application/x-msbinder`],[`obgx`,`application/vnd.openblox.game+xml`],[`obj`,`model/obj`],[`oda`,`application/oda`],[`odb`,`application/vnd.oasis.opendocument.database`],[`odc`,`application/vnd.oasis.opendocument.chart`],[`odf`,`application/vnd.oasis.opendocument.formula`],[`odft`,`application/vnd.oasis.opendocument.formula-template`],[`odg`,`application/vnd.oasis.opendocument.graphics`],[`odi`,`application/vnd.oasis.opendocument.image`],[`odm`,`application/vnd.oasis.opendocument.text-master`],[`odp`,`application/vnd.oasis.opendocument.presentation`],[`ods`,`application/vnd.oasis.opendocument.spreadsheet`],[`odt`,`application/vnd.oasis.opendocument.text`],[`oga`,`audio/ogg`],[`ogex`,`model/vnd.opengex`],[`ogg`,`audio/ogg`],[`ogv`,`video/ogg`],[`ogx`,`application/ogg`],[`omdoc`,`application/omdoc+xml`],[`onepkg`,`application/onenote`],[`onetmp`,`application/onenote`],[`onetoc`,`application/onenote`],[`onetoc2`,`application/onenote`],[`opf`,`application/oebps-package+xml`],[`opml`,`text/x-opml`],[`oprc`,`application/vnd.palm`],[`opus`,`audio/ogg`],[`org`,`text/x-org`],[`osf`,`application/vnd.yamaha.openscoreformat`],[`osfpvg`,`application/vnd.yamaha.openscoreformat.osfpvg+xml`],[`osm`,`application/vnd.openstreetmap.data+xml`],[`otc`,`application/vnd.oasis.opendocument.chart-template`],[`otf`,`font/otf`],[`otg`,`application/vnd.oasis.opendocument.graphics-template`],[`oth`,`application/vnd.oasis.opendocument.text-web`],[`oti`,`application/vnd.oasis.opendocument.image-template`],[`otp`,`application/vnd.oasis.opendocument.presentation-template`],[`ots`,`application/vnd.oasis.opendocument.spreadsheet-template`],[`ott`,`application/vnd.oasis.opendocument.text-template`],[`ova`,`application/x-virtualbox-ova`],[`ovf`,`application/x-virtualbox-ovf`],[`owl`,`application/rdf+xml`],[`oxps`,`application/oxps`],[`oxt`,`application/vnd.openofficeorg.extension`],[`p`,`text/x-pascal`],[`p7a`,`application/x-pkcs7-signature`],[`p7b`,`application/x-pkcs7-certificates`],[`p7c`,`application/pkcs7-mime`],[`p7m`,`application/pkcs7-mime`],[`p7r`,`application/x-pkcs7-certreqresp`],[`p7s`,`application/pkcs7-signature`],[`p8`,`application/pkcs8`],[`p10`,`application/x-pkcs10`],[`p12`,`application/x-pkcs12`],[`pac`,`application/x-ns-proxy-autoconfig`],[`pages`,`application/x-iwork-pages-sffpages`],[`pas`,`text/x-pascal`],[`paw`,`application/vnd.pawaafile`],[`pbd`,`application/vnd.powerbuilder6`],[`pbm`,`image/x-portable-bitmap`],[`pcap`,`application/vnd.tcpdump.pcap`],[`pcf`,`application/x-font-pcf`],[`pcl`,`application/vnd.hp-pcl`],[`pclxl`,`application/vnd.hp-pclxl`],[`pct`,`image/x-pict`],[`pcurl`,`application/vnd.curl.pcurl`],[`pcx`,`image/x-pcx`],[`pdb`,`application/x-pilot`],[`pde`,`text/x-processing`],[`pdf`,`application/pdf`],[`pem`,`application/x-x509-user-cert`],[`pfa`,`application/x-font-type1`],[`pfb`,`application/x-font-type1`],[`pfm`,`application/x-font-type1`],[`pfr`,`application/font-tdpfr`],[`pfx`,`application/x-pkcs12`],[`pgm`,`image/x-portable-graymap`],[`pgn`,`application/x-chess-pgn`],[`pgp`,`application/pgp`],[`php`,`application/x-httpd-php`],[`php3`,`application/x-httpd-php`],[`php4`,`application/x-httpd-php`],[`phps`,`application/x-httpd-php-source`],[`phtml`,`application/x-httpd-php`],[`pic`,`image/x-pict`],[`pkg`,`application/octet-stream`],[`pki`,`application/pkixcmp`],[`pkipath`,`application/pkix-pkipath`],[`pkpass`,`application/vnd.apple.pkpass`],[`pl`,`application/x-perl`],[`plb`,`application/vnd.3gpp.pic-bw-large`],[`plc`,`application/vnd.mobius.plc`],[`plf`,`application/vnd.pocketlearn`],[`pls`,`application/pls+xml`],[`pm`,`application/x-perl`],[`pml`,`application/vnd.ctc-posml`],[`png`,`image/png`],[`pnm`,`image/x-portable-anymap`],[`portpkg`,`application/vnd.macports.portpkg`],[`pot`,`application/vnd.ms-powerpoint`],[`potm`,`application/vnd.ms-powerpoint.presentation.macroEnabled.12`],[`potx`,`application/vnd.openxmlformats-officedocument.presentationml.template`],[`ppa`,`application/vnd.ms-powerpoint`],[`ppam`,`application/vnd.ms-powerpoint.addin.macroEnabled.12`],[`ppd`,`application/vnd.cups-ppd`],[`ppm`,`image/x-portable-pixmap`],[`pps`,`application/vnd.ms-powerpoint`],[`ppsm`,`application/vnd.ms-powerpoint.slideshow.macroEnabled.12`],[`ppsx`,`application/vnd.openxmlformats-officedocument.presentationml.slideshow`],[`ppt`,`application/powerpoint`],[`pptm`,`application/vnd.ms-powerpoint.presentation.macroEnabled.12`],[`pptx`,`application/vnd.openxmlformats-officedocument.presentationml.presentation`],[`pqa`,`application/vnd.palm`],[`prc`,`application/x-pilot`],[`pre`,`application/vnd.lotus-freelance`],[`prf`,`application/pics-rules`],[`provx`,`application/provenance+xml`],[`ps`,`application/postscript`],[`psb`,`application/vnd.3gpp.pic-bw-small`],[`psd`,`application/x-photoshop`],[`psf`,`application/x-font-linux-psf`],[`pskcxml`,`application/pskc+xml`],[`pti`,`image/prs.pti`],[`ptid`,`application/vnd.pvi.ptid1`],[`pub`,`application/x-mspublisher`],[`pvb`,`application/vnd.3gpp.pic-bw-var`],[`pwn`,`application/vnd.3m.post-it-notes`],[`pya`,`audio/vnd.ms-playready.media.pya`],[`pyv`,`video/vnd.ms-playready.media.pyv`],[`qam`,`application/vnd.epson.quickanime`],[`qbo`,`application/vnd.intu.qbo`],[`qfx`,`application/vnd.intu.qfx`],[`qps`,`application/vnd.publishare-delta-tree`],[`qt`,`video/quicktime`],[`qwd`,`application/vnd.quark.quarkxpress`],[`qwt`,`application/vnd.quark.quarkxpress`],[`qxb`,`application/vnd.quark.quarkxpress`],[`qxd`,`application/vnd.quark.quarkxpress`],[`qxl`,`application/vnd.quark.quarkxpress`],[`qxt`,`application/vnd.quark.quarkxpress`],[`ra`,`audio/x-realaudio`],[`ram`,`audio/x-pn-realaudio`],[`raml`,`application/raml+yaml`],[`rapd`,`application/route-apd+xml`],[`rar`,`application/x-rar`],[`ras`,`image/x-cmu-raster`],[`rcprofile`,`application/vnd.ipunplugged.rcprofile`],[`rdf`,`application/rdf+xml`],[`rdz`,`application/vnd.data-vision.rdz`],[`relo`,`application/p2p-overlay+xml`],[`rep`,`application/vnd.businessobjects`],[`res`,`application/x-dtbresource+xml`],[`rgb`,`image/x-rgb`],[`rif`,`application/reginfo+xml`],[`rip`,`audio/vnd.rip`],[`ris`,`application/x-research-info-systems`],[`rl`,`application/resource-lists+xml`],[`rlc`,`image/vnd.fujixerox.edmics-rlc`],[`rld`,`application/resource-lists-diff+xml`],[`rm`,`audio/x-pn-realaudio`],[`rmi`,`audio/midi`],[`rmp`,`audio/x-pn-realaudio-plugin`],[`rms`,`application/vnd.jcp.javame.midlet-rms`],[`rmvb`,`application/vnd.rn-realmedia-vbr`],[`rnc`,`application/relax-ng-compact-syntax`],[`rng`,`application/xml`],[`roa`,`application/rpki-roa`],[`roff`,`text/troff`],[`rp9`,`application/vnd.cloanto.rp9`],[`rpm`,`audio/x-pn-realaudio-plugin`],[`rpss`,`application/vnd.nokia.radio-presets`],[`rpst`,`application/vnd.nokia.radio-preset`],[`rq`,`application/sparql-query`],[`rs`,`application/rls-services+xml`],[`rsa`,`application/x-pkcs7`],[`rsat`,`application/atsc-rsat+xml`],[`rsd`,`application/rsd+xml`],[`rsheet`,`application/urc-ressheet+xml`],[`rss`,`application/rss+xml`],[`rtf`,`text/rtf`],[`rtx`,`text/richtext`],[`run`,`application/x-makeself`],[`rusd`,`application/route-usd+xml`],[`rv`,`video/vnd.rn-realvideo`],[`s`,`text/x-asm`],[`s3m`,`audio/s3m`],[`saf`,`application/vnd.yamaha.smaf-audio`],[`sass`,`text/x-sass`],[`sbml`,`application/sbml+xml`],[`sc`,`application/vnd.ibm.secure-container`],[`scd`,`application/x-msschedule`],[`scm`,`application/vnd.lotus-screencam`],[`scq`,`application/scvp-cv-request`],[`scs`,`application/scvp-cv-response`],[`scss`,`text/x-scss`],[`scurl`,`text/vnd.curl.scurl`],[`sda`,`application/vnd.stardivision.draw`],[`sdc`,`application/vnd.stardivision.calc`],[`sdd`,`application/vnd.stardivision.impress`],[`sdkd`,`application/vnd.solent.sdkm+xml`],[`sdkm`,`application/vnd.solent.sdkm+xml`],[`sdp`,`application/sdp`],[`sdw`,`application/vnd.stardivision.writer`],[`sea`,`application/octet-stream`],[`see`,`application/vnd.seemail`],[`seed`,`application/vnd.fdsn.seed`],[`sema`,`application/vnd.sema`],[`semd`,`application/vnd.semd`],[`semf`,`application/vnd.semf`],[`senmlx`,`application/senml+xml`],[`sensmlx`,`application/sensml+xml`],[`ser`,`application/java-serialized-object`],[`setpay`,`application/set-payment-initiation`],[`setreg`,`application/set-registration-initiation`],[`sfd-hdstx`,`application/vnd.hydrostatix.sof-data`],[`sfs`,`application/vnd.spotfire.sfs`],[`sfv`,`text/x-sfv`],[`sgi`,`image/sgi`],[`sgl`,`application/vnd.stardivision.writer-global`],[`sgm`,`text/sgml`],[`sgml`,`text/sgml`],[`sh`,`application/x-sh`],[`shar`,`application/x-shar`],[`shex`,`text/shex`],[`shf`,`application/shf+xml`],[`shtml`,`text/html`],[`sid`,`image/x-mrsid-image`],[`sieve`,`application/sieve`],[`sig`,`application/pgp-signature`],[`sil`,`audio/silk`],[`silo`,`model/mesh`],[`sis`,`application/vnd.symbian.install`],[`sisx`,`application/vnd.symbian.install`],[`sit`,`application/x-stuffit`],[`sitx`,`application/x-stuffitx`],[`siv`,`application/sieve`],[`skd`,`application/vnd.koan`],[`skm`,`application/vnd.koan`],[`skp`,`application/vnd.koan`],[`skt`,`application/vnd.koan`],[`sldm`,`application/vnd.ms-powerpoint.slide.macroenabled.12`],[`sldx`,`application/vnd.openxmlformats-officedocument.presentationml.slide`],[`slim`,`text/slim`],[`slm`,`text/slim`],[`sls`,`application/route-s-tsid+xml`],[`slt`,`application/vnd.epson.salt`],[`sm`,`application/vnd.stepmania.stepchart`],[`smf`,`application/vnd.stardivision.math`],[`smi`,`application/smil`],[`smil`,`application/smil`],[`smv`,`video/x-smv`],[`smzip`,`application/vnd.stepmania.package`],[`snd`,`audio/basic`],[`snf`,`application/x-font-snf`],[`so`,`application/octet-stream`],[`spc`,`application/x-pkcs7-certificates`],[`spdx`,`text/spdx`],[`spf`,`application/vnd.yamaha.smaf-phrase`],[`spl`,`application/x-futuresplash`],[`spot`,`text/vnd.in3d.spot`],[`spp`,`application/scvp-vp-response`],[`spq`,`application/scvp-vp-request`],[`spx`,`audio/ogg`],[`sql`,`application/x-sql`],[`src`,`application/x-wais-source`],[`srt`,`application/x-subrip`],[`sru`,`application/sru+xml`],[`srx`,`application/sparql-results+xml`],[`ssdl`,`application/ssdl+xml`],[`sse`,`application/vnd.kodak-descriptor`],[`ssf`,`application/vnd.epson.ssf`],[`ssml`,`application/ssml+xml`],[`sst`,`application/octet-stream`],[`st`,`application/vnd.sailingtracker.track`],[`stc`,`application/vnd.sun.xml.calc.template`],[`std`,`application/vnd.sun.xml.draw.template`],[`stf`,`application/vnd.wt.stf`],[`sti`,`application/vnd.sun.xml.impress.template`],[`stk`,`application/hyperstudio`],[`stl`,`model/stl`],[`stpx`,`model/step+xml`],[`stpxz`,`model/step-xml+zip`],[`stpz`,`model/step+zip`],[`str`,`application/vnd.pg.format`],[`stw`,`application/vnd.sun.xml.writer.template`],[`styl`,`text/stylus`],[`stylus`,`text/stylus`],[`sub`,`text/vnd.dvb.subtitle`],[`sus`,`application/vnd.sus-calendar`],[`susp`,`application/vnd.sus-calendar`],[`sv4cpio`,`application/x-sv4cpio`],[`sv4crc`,`application/x-sv4crc`],[`svc`,`application/vnd.dvb.service`],[`svd`,`application/vnd.svd`],[`svg`,`image/svg+xml`],[`svgz`,`image/svg+xml`],[`swa`,`application/x-director`],[`swf`,`application/x-shockwave-flash`],[`swi`,`application/vnd.aristanetworks.swi`],[`swidtag`,`application/swid+xml`],[`sxc`,`application/vnd.sun.xml.calc`],[`sxd`,`application/vnd.sun.xml.draw`],[`sxg`,`application/vnd.sun.xml.writer.global`],[`sxi`,`application/vnd.sun.xml.impress`],[`sxm`,`application/vnd.sun.xml.math`],[`sxw`,`application/vnd.sun.xml.writer`],[`t`,`text/troff`],[`t3`,`application/x-t3vm-image`],[`t38`,`image/t38`],[`taglet`,`application/vnd.mynfc`],[`tao`,`application/vnd.tao.intent-module-archive`],[`tap`,`image/vnd.tencent.tap`],[`tar`,`application/x-tar`],[`tcap`,`application/vnd.3gpp2.tcap`],[`tcl`,`application/x-tcl`],[`td`,`application/urc-targetdesc+xml`],[`teacher`,`application/vnd.smart.teacher`],[`tei`,`application/tei+xml`],[`teicorpus`,`application/tei+xml`],[`tex`,`application/x-tex`],[`texi`,`application/x-texinfo`],[`texinfo`,`application/x-texinfo`],[`text`,`text/plain`],[`tfi`,`application/thraud+xml`],[`tfm`,`application/x-tex-tfm`],[`tfx`,`image/tiff-fx`],[`tga`,`image/x-tga`],[`tgz`,`application/x-tar`],[`thmx`,`application/vnd.ms-officetheme`],[`tif`,`image/tiff`],[`tiff`,`image/tiff`],[`tk`,`application/x-tcl`],[`tmo`,`application/vnd.tmobile-livetv`],[`toml`,`application/toml`],[`torrent`,`application/x-bittorrent`],[`tpl`,`application/vnd.groove-tool-template`],[`tpt`,`application/vnd.trid.tpt`],[`tr`,`text/troff`],[`tra`,`application/vnd.trueapp`],[`trig`,`application/trig`],[`trm`,`application/x-msterminal`],[`ts`,`video/mp2t`],[`tsd`,`application/timestamped-data`],[`tsv`,`text/tab-separated-values`],[`ttc`,`font/collection`],[`ttf`,`font/ttf`],[`ttl`,`text/turtle`],[`ttml`,`application/ttml+xml`],[`twd`,`application/vnd.simtech-mindmapper`],[`twds`,`application/vnd.simtech-mindmapper`],[`txd`,`application/vnd.genomatix.tuxedo`],[`txf`,`application/vnd.mobius.txf`],[`txt`,`text/plain`],[`u8dsn`,`message/global-delivery-status`],[`u8hdr`,`message/global-headers`],[`u8mdn`,`message/global-disposition-notification`],[`u8msg`,`message/global`],[`u32`,`application/x-authorware-bin`],[`ubj`,`application/ubjson`],[`udeb`,`application/x-debian-package`],[`ufd`,`application/vnd.ufdl`],[`ufdl`,`application/vnd.ufdl`],[`ulx`,`application/x-glulx`],[`umj`,`application/vnd.umajin`],[`unityweb`,`application/vnd.unity`],[`uoml`,`application/vnd.uoml+xml`],[`uri`,`text/uri-list`],[`uris`,`text/uri-list`],[`urls`,`text/uri-list`],[`usdz`,`model/vnd.usdz+zip`],[`ustar`,`application/x-ustar`],[`utz`,`application/vnd.uiq.theme`],[`uu`,`text/x-uuencode`],[`uva`,`audio/vnd.dece.audio`],[`uvd`,`application/vnd.dece.data`],[`uvf`,`application/vnd.dece.data`],[`uvg`,`image/vnd.dece.graphic`],[`uvh`,`video/vnd.dece.hd`],[`uvi`,`image/vnd.dece.graphic`],[`uvm`,`video/vnd.dece.mobile`],[`uvp`,`video/vnd.dece.pd`],[`uvs`,`video/vnd.dece.sd`],[`uvt`,`application/vnd.dece.ttml+xml`],[`uvu`,`video/vnd.uvvu.mp4`],[`uvv`,`video/vnd.dece.video`],[`uvva`,`audio/vnd.dece.audio`],[`uvvd`,`application/vnd.dece.data`],[`uvvf`,`application/vnd.dece.data`],[`uvvg`,`image/vnd.dece.graphic`],[`uvvh`,`video/vnd.dece.hd`],[`uvvi`,`image/vnd.dece.graphic`],[`uvvm`,`video/vnd.dece.mobile`],[`uvvp`,`video/vnd.dece.pd`],[`uvvs`,`video/vnd.dece.sd`],[`uvvt`,`application/vnd.dece.ttml+xml`],[`uvvu`,`video/vnd.uvvu.mp4`],[`uvvv`,`video/vnd.dece.video`],[`uvvx`,`application/vnd.dece.unspecified`],[`uvvz`,`application/vnd.dece.zip`],[`uvx`,`application/vnd.dece.unspecified`],[`uvz`,`application/vnd.dece.zip`],[`vbox`,`application/x-virtualbox-vbox`],[`vbox-extpack`,`application/x-virtualbox-vbox-extpack`],[`vcard`,`text/vcard`],[`vcd`,`application/x-cdlink`],[`vcf`,`text/x-vcard`],[`vcg`,`application/vnd.groove-vcard`],[`vcs`,`text/x-vcalendar`],[`vcx`,`application/vnd.vcx`],[`vdi`,`application/x-virtualbox-vdi`],[`vds`,`model/vnd.sap.vds`],[`vhd`,`application/x-virtualbox-vhd`],[`vis`,`application/vnd.visionary`],[`viv`,`video/vnd.vivo`],[`vlc`,`application/videolan`],[`vmdk`,`application/x-virtualbox-vmdk`],[`vob`,`video/x-ms-vob`],[`vor`,`application/vnd.stardivision.writer`],[`vox`,`application/x-authorware-bin`],[`vrml`,`model/vrml`],[`vsd`,`application/vnd.visio`],[`vsf`,`application/vnd.vsf`],[`vss`,`application/vnd.visio`],[`vst`,`application/vnd.visio`],[`vsw`,`application/vnd.visio`],[`vtf`,`image/vnd.valve.source.texture`],[`vtt`,`text/vtt`],[`vtu`,`model/vnd.vtu`],[`vxml`,`application/voicexml+xml`],[`w3d`,`application/x-director`],[`wad`,`application/x-doom`],[`wadl`,`application/vnd.sun.wadl+xml`],[`war`,`application/java-archive`],[`wasm`,`application/wasm`],[`wav`,`audio/x-wav`],[`wax`,`audio/x-ms-wax`],[`wbmp`,`image/vnd.wap.wbmp`],[`wbs`,`application/vnd.criticaltools.wbs+xml`],[`wbxml`,`application/wbxml`],[`wcm`,`application/vnd.ms-works`],[`wdb`,`application/vnd.ms-works`],[`wdp`,`image/vnd.ms-photo`],[`weba`,`audio/webm`],[`webapp`,`application/x-web-app-manifest+json`],[`webm`,`video/webm`],[`webmanifest`,`application/manifest+json`],[`webp`,`image/webp`],[`wg`,`application/vnd.pmi.widget`],[`wgt`,`application/widget`],[`wks`,`application/vnd.ms-works`],[`wm`,`video/x-ms-wm`],[`wma`,`audio/x-ms-wma`],[`wmd`,`application/x-ms-wmd`],[`wmf`,`image/wmf`],[`wml`,`text/vnd.wap.wml`],[`wmlc`,`application/wmlc`],[`wmls`,`text/vnd.wap.wmlscript`],[`wmlsc`,`application/vnd.wap.wmlscriptc`],[`wmv`,`video/x-ms-wmv`],[`wmx`,`video/x-ms-wmx`],[`wmz`,`application/x-msmetafile`],[`woff`,`font/woff`],[`woff2`,`font/woff2`],[`word`,`application/msword`],[`wpd`,`application/vnd.wordperfect`],[`wpl`,`application/vnd.ms-wpl`],[`wps`,`application/vnd.ms-works`],[`wqd`,`application/vnd.wqd`],[`wri`,`application/x-mswrite`],[`wrl`,`model/vrml`],[`wsc`,`message/vnd.wfa.wsc`],[`wsdl`,`application/wsdl+xml`],[`wspolicy`,`application/wspolicy+xml`],[`wtb`,`application/vnd.webturbo`],[`wvx`,`video/x-ms-wvx`],[`x3d`,`model/x3d+xml`],[`x3db`,`model/x3d+fastinfoset`],[`x3dbz`,`model/x3d+binary`],[`x3dv`,`model/x3d-vrml`],[`x3dvz`,`model/x3d+vrml`],[`x3dz`,`model/x3d+xml`],[`x32`,`application/x-authorware-bin`],[`x_b`,`model/vnd.parasolid.transmit.binary`],[`x_t`,`model/vnd.parasolid.transmit.text`],[`xaml`,`application/xaml+xml`],[`xap`,`application/x-silverlight-app`],[`xar`,`application/vnd.xara`],[`xav`,`application/xcap-att+xml`],[`xbap`,`application/x-ms-xbap`],[`xbd`,`application/vnd.fujixerox.docuworks.binder`],[`xbm`,`image/x-xbitmap`],[`xca`,`application/xcap-caps+xml`],[`xcs`,`application/calendar+xml`],[`xdf`,`application/xcap-diff+xml`],[`xdm`,`application/vnd.syncml.dm+xml`],[`xdp`,`application/vnd.adobe.xdp+xml`],[`xdssc`,`application/dssc+xml`],[`xdw`,`application/vnd.fujixerox.docuworks`],[`xel`,`application/xcap-el+xml`],[`xenc`,`application/xenc+xml`],[`xer`,`application/patch-ops-error+xml`],[`xfdf`,`application/vnd.adobe.xfdf`],[`xfdl`,`application/vnd.xfdl`],[`xht`,`application/xhtml+xml`],[`xhtml`,`application/xhtml+xml`],[`xhvml`,`application/xv+xml`],[`xif`,`image/vnd.xiff`],[`xl`,`application/excel`],[`xla`,`application/vnd.ms-excel`],[`xlam`,`application/vnd.ms-excel.addin.macroEnabled.12`],[`xlc`,`application/vnd.ms-excel`],[`xlf`,`application/xliff+xml`],[`xlm`,`application/vnd.ms-excel`],[`xls`,`application/vnd.ms-excel`],[`xlsb`,`application/vnd.ms-excel.sheet.binary.macroEnabled.12`],[`xlsm`,`application/vnd.ms-excel.sheet.macroEnabled.12`],[`xlsx`,`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`],[`xlt`,`application/vnd.ms-excel`],[`xltm`,`application/vnd.ms-excel.template.macroEnabled.12`],[`xltx`,`application/vnd.openxmlformats-officedocument.spreadsheetml.template`],[`xlw`,`application/vnd.ms-excel`],[`xm`,`audio/xm`],[`xml`,`application/xml`],[`xns`,`application/xcap-ns+xml`],[`xo`,`application/vnd.olpc-sugar`],[`xop`,`application/xop+xml`],[`xpi`,`application/x-xpinstall`],[`xpl`,`application/xproc+xml`],[`xpm`,`image/x-xpixmap`],[`xpr`,`application/vnd.is-xpr`],[`xps`,`application/vnd.ms-xpsdocument`],[`xpw`,`application/vnd.intercon.formnet`],[`xpx`,`application/vnd.intercon.formnet`],[`xsd`,`application/xml`],[`xsl`,`application/xml`],[`xslt`,`application/xslt+xml`],[`xsm`,`application/vnd.syncml+xml`],[`xspf`,`application/xspf+xml`],[`xul`,`application/vnd.mozilla.xul+xml`],[`xvm`,`application/xv+xml`],[`xvml`,`application/xv+xml`],[`xwd`,`image/x-xwindowdump`],[`xyz`,`chemical/x-xyz`],[`xz`,`application/x-xz`],[`yaml`,`text/yaml`],[`yang`,`application/yang`],[`yin`,`application/yin+xml`],[`yml`,`text/yaml`],[`ymp`,`text/x-suse-ymp`],[`z`,`application/x-compress`],[`z1`,`application/x-zmachine`],[`z2`,`application/x-zmachine`],[`z3`,`application/x-zmachine`],[`z4`,`application/x-zmachine`],[`z5`,`application/x-zmachine`],[`z6`,`application/x-zmachine`],[`z7`,`application/x-zmachine`],[`z8`,`application/x-zmachine`],[`zaz`,`application/vnd.zzazz.deck+xml`],[`zip`,`application/zip`],[`zir`,`application/vnd.zul`],[`zirz`,`application/vnd.zul`],[`zmm`,`application/vnd.handheld-entertainment+xml`],[`zsh`,`text/x-scriptzsh`]]);function p(e,t,n){let r=m(e),{webkitRelativePath:i}=e,a=typeof t==`string`?t:typeof i==`string`&&i.length>0?i:`./${e.name}`;return typeof r.path!=`string`&&h(r,`path`,a),n!==void 0&&Object.defineProperty(r,`handle`,{value:n,writable:!1,configurable:!1,enumerable:!0}),h(r,`relativePath`,a),r}function m(e){let{name:t}=e;if(t&&t.lastIndexOf(`.`)!==-1&&!e.type){let n=t.split(`.`).pop().toLowerCase(),r=f.get(n);r&&Object.defineProperty(e,`type`,{value:r,writable:!1,configurable:!1,enumerable:!0})}return e}function h(e,t,n){Object.defineProperty(e,t,{value:n,writable:!1,configurable:!1,enumerable:!0})}var g=[`.DS_Store`,`Thumbs.db`];function ee(e){return d(this,void 0,void 0,function*(){return v(e)&&te(e.dataTransfer)?b(e.dataTransfer,e.type):_(e)?y(e):Array.isArray(e)&&e.every(e=>`getFile`in e&&typeof e.getFile==`function`)?ne(e):[]})}function te(e){return v(e)}function _(e){return v(e)&&v(e.target)}function v(e){return typeof e==`object`&&!!e}function y(e){return S(e.target.files).map(e=>p(e))}function ne(e){return d(this,void 0,void 0,function*(){return(yield Promise.all(e.map(e=>e.getFile()))).map(e=>p(e))})}function b(e,t){return d(this,void 0,void 0,function*(){if(e.items){let n=S(e.items).filter(e=>e.kind===`file`);return t===`drop`?x(w(yield Promise.all(n.map(C)))):n}return x(S(e.files).map(e=>p(e)))})}function x(e){return e.filter(e=>g.indexOf(e.name)===-1)}function S(e){if(e===null)return[];let t=[];for(let n=0;n[...e,...Array.isArray(t)?w(t):[t]],[])}function T(e,t){return d(this,void 0,void 0,function*(){if(globalThis.isSecureContext&&typeof e.getAsFileSystemHandle==`function`){let t=yield e.getAsFileSystemHandle();if(t===null)throw Error(`${e} is not a File`);if(t!==void 0){let e=yield t.getFile();return e.handle=t,p(e)}}let n=e.getAsFile();if(!n)throw Error(`${e} is not a File`);return p(n,t?.fullPath??void 0)})}function E(e){return d(this,void 0,void 0,function*(){return e.isDirectory?D(e):O(e)})}function D(e){let t=e.createReader();return new Promise((e,n)=>{let r=[];function i(){t.readEntries(t=>d(this,void 0,void 0,function*(){if(t.length){let e=Promise.all(t.map(E));r.push(e),i()}else try{e(yield Promise.all(r))}catch(e){n(e)}}),e=>{n(e)})}i()})}function O(e){return d(this,void 0,void 0,function*(){return new Promise((t,n)=>{e.file(n=>{t(p(n,e.fullPath))},e=>{n(e)})})})}var k=e(t((e=>{e.__esModule=!0,e.default=function(e,t){if(e&&t){var n=Array.isArray(t)?t:t.split(`,`);if(n.length===0)return!0;var r=e.name||``,i=(e.type||``).toLowerCase(),a=i.replace(/\/.*$/,``);return n.some(function(e){var t=e.trim().toLowerCase();return t.charAt(0)===`.`?r.toLowerCase().endsWith(t):t.endsWith(`/*`)?a===t.replace(/\/.*$/,``):i===t})}return!0}}))());function A(e){return ie(e)||re(e)||I(e)||j()}function j(){throw TypeError(`Invalid attempt to spread non-iterable instance. +import{i as e,t}from"./rolldown-runtime-B1FJdls4.js";import{T as n}from"./query-vendor-Cbp9LWgA.js";import{n as r}from"./index-DDOaKEbH.js";var i=r(`circle-check`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),a=r(`cloud-upload`,[[`path`,{d:`M12 13v8`,key:`1l5pq0`}],[`path`,{d:`M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242`,key:`1pljnt`}],[`path`,{d:`m8 17 4-4 4 4`,key:`1quai1`}]]),o=r(`file-text`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 9H8`,key:`b1mrlr`}],[`path`,{d:`M16 13H8`,key:`t4e002`}],[`path`,{d:`M16 17H8`,key:`z1uh3a`}]]),s=r(`loader-circle`,[[`path`,{d:`M21 12a9 9 0 1 1-6.219-8.56`,key:`13zald`}]]),c=t(((e,t)=>{t.exports=`SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED`})),l=t(((e,t)=>{var n=c();function r(){}function i(){}i.resetWarningCache=r,t.exports=function(){function e(e,t,r,i,a,o){if(o!==n){var s=Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name=`Invariant Violation`,s}}e.isRequired=e;function t(){return e}var a={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:r};return a.PropTypes=a,a}})),u=t(((e,t)=>{t.exports=l()()}));function d(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})}var f=new Map([[`1km`,`application/vnd.1000minds.decision-model+xml`],[`3dml`,`text/vnd.in3d.3dml`],[`3ds`,`image/x-3ds`],[`3g2`,`video/3gpp2`],[`3gp`,`video/3gp`],[`3gpp`,`video/3gpp`],[`3mf`,`model/3mf`],[`7z`,`application/x-7z-compressed`],[`7zip`,`application/x-7z-compressed`],[`123`,`application/vnd.lotus-1-2-3`],[`aab`,`application/x-authorware-bin`],[`aac`,`audio/x-acc`],[`aam`,`application/x-authorware-map`],[`aas`,`application/x-authorware-seg`],[`abw`,`application/x-abiword`],[`ac`,`application/vnd.nokia.n-gage.ac+xml`],[`ac3`,`audio/ac3`],[`acc`,`application/vnd.americandynamics.acc`],[`ace`,`application/x-ace-compressed`],[`acu`,`application/vnd.acucobol`],[`acutc`,`application/vnd.acucorp`],[`adp`,`audio/adpcm`],[`aep`,`application/vnd.audiograph`],[`afm`,`application/x-font-type1`],[`afp`,`application/vnd.ibm.modcap`],[`ahead`,`application/vnd.ahead.space`],[`ai`,`application/pdf`],[`aif`,`audio/x-aiff`],[`aifc`,`audio/x-aiff`],[`aiff`,`audio/x-aiff`],[`air`,`application/vnd.adobe.air-application-installer-package+zip`],[`ait`,`application/vnd.dvb.ait`],[`ami`,`application/vnd.amiga.ami`],[`amr`,`audio/amr`],[`apk`,`application/vnd.android.package-archive`],[`apng`,`image/apng`],[`appcache`,`text/cache-manifest`],[`application`,`application/x-ms-application`],[`apr`,`application/vnd.lotus-approach`],[`arc`,`application/x-freearc`],[`arj`,`application/x-arj`],[`asc`,`application/pgp-signature`],[`asf`,`video/x-ms-asf`],[`asm`,`text/x-asm`],[`aso`,`application/vnd.accpac.simply.aso`],[`asx`,`video/x-ms-asf`],[`atc`,`application/vnd.acucorp`],[`atom`,`application/atom+xml`],[`atomcat`,`application/atomcat+xml`],[`atomdeleted`,`application/atomdeleted+xml`],[`atomsvc`,`application/atomsvc+xml`],[`atx`,`application/vnd.antix.game-component`],[`au`,`audio/x-au`],[`avi`,`video/x-msvideo`],[`avif`,`image/avif`],[`aw`,`application/applixware`],[`azf`,`application/vnd.airzip.filesecure.azf`],[`azs`,`application/vnd.airzip.filesecure.azs`],[`azv`,`image/vnd.airzip.accelerator.azv`],[`azw`,`application/vnd.amazon.ebook`],[`b16`,`image/vnd.pco.b16`],[`bat`,`application/x-msdownload`],[`bcpio`,`application/x-bcpio`],[`bdf`,`application/x-font-bdf`],[`bdm`,`application/vnd.syncml.dm+wbxml`],[`bdoc`,`application/x-bdoc`],[`bed`,`application/vnd.realvnc.bed`],[`bh2`,`application/vnd.fujitsu.oasysprs`],[`bin`,`application/octet-stream`],[`blb`,`application/x-blorb`],[`blorb`,`application/x-blorb`],[`bmi`,`application/vnd.bmi`],[`bmml`,`application/vnd.balsamiq.bmml+xml`],[`bmp`,`image/bmp`],[`book`,`application/vnd.framemaker`],[`box`,`application/vnd.previewsystems.box`],[`boz`,`application/x-bzip2`],[`bpk`,`application/octet-stream`],[`bpmn`,`application/octet-stream`],[`bsp`,`model/vnd.valve.source.compiled-map`],[`btif`,`image/prs.btif`],[`buffer`,`application/octet-stream`],[`bz`,`application/x-bzip`],[`bz2`,`application/x-bzip2`],[`c`,`text/x-c`],[`c4d`,`application/vnd.clonk.c4group`],[`c4f`,`application/vnd.clonk.c4group`],[`c4g`,`application/vnd.clonk.c4group`],[`c4p`,`application/vnd.clonk.c4group`],[`c4u`,`application/vnd.clonk.c4group`],[`c11amc`,`application/vnd.cluetrust.cartomobile-config`],[`c11amz`,`application/vnd.cluetrust.cartomobile-config-pkg`],[`cab`,`application/vnd.ms-cab-compressed`],[`caf`,`audio/x-caf`],[`cap`,`application/vnd.tcpdump.pcap`],[`car`,`application/vnd.curl.car`],[`cat`,`application/vnd.ms-pki.seccat`],[`cb7`,`application/x-cbr`],[`cba`,`application/x-cbr`],[`cbr`,`application/x-cbr`],[`cbt`,`application/x-cbr`],[`cbz`,`application/x-cbr`],[`cc`,`text/x-c`],[`cco`,`application/x-cocoa`],[`cct`,`application/x-director`],[`ccxml`,`application/ccxml+xml`],[`cdbcmsg`,`application/vnd.contact.cmsg`],[`cda`,`application/x-cdf`],[`cdf`,`application/x-netcdf`],[`cdfx`,`application/cdfx+xml`],[`cdkey`,`application/vnd.mediastation.cdkey`],[`cdmia`,`application/cdmi-capability`],[`cdmic`,`application/cdmi-container`],[`cdmid`,`application/cdmi-domain`],[`cdmio`,`application/cdmi-object`],[`cdmiq`,`application/cdmi-queue`],[`cdr`,`application/cdr`],[`cdx`,`chemical/x-cdx`],[`cdxml`,`application/vnd.chemdraw+xml`],[`cdy`,`application/vnd.cinderella`],[`cer`,`application/pkix-cert`],[`cfs`,`application/x-cfs-compressed`],[`cgm`,`image/cgm`],[`chat`,`application/x-chat`],[`chm`,`application/vnd.ms-htmlhelp`],[`chrt`,`application/vnd.kde.kchart`],[`cif`,`chemical/x-cif`],[`cii`,`application/vnd.anser-web-certificate-issue-initiation`],[`cil`,`application/vnd.ms-artgalry`],[`cjs`,`application/node`],[`cla`,`application/vnd.claymore`],[`class`,`application/octet-stream`],[`clkk`,`application/vnd.crick.clicker.keyboard`],[`clkp`,`application/vnd.crick.clicker.palette`],[`clkt`,`application/vnd.crick.clicker.template`],[`clkw`,`application/vnd.crick.clicker.wordbank`],[`clkx`,`application/vnd.crick.clicker`],[`clp`,`application/x-msclip`],[`cmc`,`application/vnd.cosmocaller`],[`cmdf`,`chemical/x-cmdf`],[`cml`,`chemical/x-cml`],[`cmp`,`application/vnd.yellowriver-custom-menu`],[`cmx`,`image/x-cmx`],[`cod`,`application/vnd.rim.cod`],[`coffee`,`text/coffeescript`],[`com`,`application/x-msdownload`],[`conf`,`text/plain`],[`cpio`,`application/x-cpio`],[`cpp`,`text/x-c`],[`cpt`,`application/mac-compactpro`],[`crd`,`application/x-mscardfile`],[`crl`,`application/pkix-crl`],[`crt`,`application/x-x509-ca-cert`],[`crx`,`application/x-chrome-extension`],[`cryptonote`,`application/vnd.rig.cryptonote`],[`csh`,`application/x-csh`],[`csl`,`application/vnd.citationstyles.style+xml`],[`csml`,`chemical/x-csml`],[`csp`,`application/vnd.commonspace`],[`csr`,`application/octet-stream`],[`css`,`text/css`],[`cst`,`application/x-director`],[`csv`,`text/csv`],[`cu`,`application/cu-seeme`],[`curl`,`text/vnd.curl`],[`cww`,`application/prs.cww`],[`cxt`,`application/x-director`],[`cxx`,`text/x-c`],[`dae`,`model/vnd.collada+xml`],[`daf`,`application/vnd.mobius.daf`],[`dart`,`application/vnd.dart`],[`dataless`,`application/vnd.fdsn.seed`],[`davmount`,`application/davmount+xml`],[`dbf`,`application/vnd.dbf`],[`dbk`,`application/docbook+xml`],[`dcr`,`application/x-director`],[`dcurl`,`text/vnd.curl.dcurl`],[`dd2`,`application/vnd.oma.dd2+xml`],[`ddd`,`application/vnd.fujixerox.ddd`],[`ddf`,`application/vnd.syncml.dmddf+xml`],[`dds`,`image/vnd.ms-dds`],[`deb`,`application/x-debian-package`],[`def`,`text/plain`],[`deploy`,`application/octet-stream`],[`der`,`application/x-x509-ca-cert`],[`dfac`,`application/vnd.dreamfactory`],[`dgc`,`application/x-dgc-compressed`],[`dic`,`text/x-c`],[`dir`,`application/x-director`],[`dis`,`application/vnd.mobius.dis`],[`disposition-notification`,`message/disposition-notification`],[`dist`,`application/octet-stream`],[`distz`,`application/octet-stream`],[`djv`,`image/vnd.djvu`],[`djvu`,`image/vnd.djvu`],[`dll`,`application/octet-stream`],[`dmg`,`application/x-apple-diskimage`],[`dmn`,`application/octet-stream`],[`dmp`,`application/vnd.tcpdump.pcap`],[`dms`,`application/octet-stream`],[`dna`,`application/vnd.dna`],[`doc`,`application/msword`],[`docm`,`application/vnd.ms-word.template.macroEnabled.12`],[`docx`,`application/vnd.openxmlformats-officedocument.wordprocessingml.document`],[`dot`,`application/msword`],[`dotm`,`application/vnd.ms-word.template.macroEnabled.12`],[`dotx`,`application/vnd.openxmlformats-officedocument.wordprocessingml.template`],[`dp`,`application/vnd.osgi.dp`],[`dpg`,`application/vnd.dpgraph`],[`dra`,`audio/vnd.dra`],[`drle`,`image/dicom-rle`],[`dsc`,`text/prs.lines.tag`],[`dssc`,`application/dssc+der`],[`dtb`,`application/x-dtbook+xml`],[`dtd`,`application/xml-dtd`],[`dts`,`audio/vnd.dts`],[`dtshd`,`audio/vnd.dts.hd`],[`dump`,`application/octet-stream`],[`dvb`,`video/vnd.dvb.file`],[`dvi`,`application/x-dvi`],[`dwd`,`application/atsc-dwd+xml`],[`dwf`,`model/vnd.dwf`],[`dwg`,`image/vnd.dwg`],[`dxf`,`image/vnd.dxf`],[`dxp`,`application/vnd.spotfire.dxp`],[`dxr`,`application/x-director`],[`ear`,`application/java-archive`],[`ecelp4800`,`audio/vnd.nuera.ecelp4800`],[`ecelp7470`,`audio/vnd.nuera.ecelp7470`],[`ecelp9600`,`audio/vnd.nuera.ecelp9600`],[`ecma`,`application/ecmascript`],[`edm`,`application/vnd.novadigm.edm`],[`edx`,`application/vnd.novadigm.edx`],[`efif`,`application/vnd.picsel`],[`ei6`,`application/vnd.pg.osasli`],[`elc`,`application/octet-stream`],[`emf`,`image/emf`],[`eml`,`message/rfc822`],[`emma`,`application/emma+xml`],[`emotionml`,`application/emotionml+xml`],[`emz`,`application/x-msmetafile`],[`eol`,`audio/vnd.digital-winds`],[`eot`,`application/vnd.ms-fontobject`],[`eps`,`application/postscript`],[`epub`,`application/epub+zip`],[`es`,`application/ecmascript`],[`es3`,`application/vnd.eszigno3+xml`],[`esa`,`application/vnd.osgi.subsystem`],[`esf`,`application/vnd.epson.esf`],[`et3`,`application/vnd.eszigno3+xml`],[`etx`,`text/x-setext`],[`eva`,`application/x-eva`],[`evy`,`application/x-envoy`],[`exe`,`application/octet-stream`],[`exi`,`application/exi`],[`exp`,`application/express`],[`exr`,`image/aces`],[`ext`,`application/vnd.novadigm.ext`],[`ez`,`application/andrew-inset`],[`ez2`,`application/vnd.ezpix-album`],[`ez3`,`application/vnd.ezpix-package`],[`f`,`text/x-fortran`],[`f4v`,`video/mp4`],[`f77`,`text/x-fortran`],[`f90`,`text/x-fortran`],[`fbs`,`image/vnd.fastbidsheet`],[`fcdt`,`application/vnd.adobe.formscentral.fcdt`],[`fcs`,`application/vnd.isac.fcs`],[`fdf`,`application/vnd.fdf`],[`fdt`,`application/fdt+xml`],[`fe_launch`,`application/vnd.denovo.fcselayout-link`],[`fg5`,`application/vnd.fujitsu.oasysgp`],[`fgd`,`application/x-director`],[`fh`,`image/x-freehand`],[`fh4`,`image/x-freehand`],[`fh5`,`image/x-freehand`],[`fh7`,`image/x-freehand`],[`fhc`,`image/x-freehand`],[`fig`,`application/x-xfig`],[`fits`,`image/fits`],[`flac`,`audio/x-flac`],[`fli`,`video/x-fli`],[`flo`,`application/vnd.micrografx.flo`],[`flv`,`video/x-flv`],[`flw`,`application/vnd.kde.kivio`],[`flx`,`text/vnd.fmi.flexstor`],[`fly`,`text/vnd.fly`],[`fm`,`application/vnd.framemaker`],[`fnc`,`application/vnd.frogans.fnc`],[`fo`,`application/vnd.software602.filler.form+xml`],[`for`,`text/x-fortran`],[`fpx`,`image/vnd.fpx`],[`frame`,`application/vnd.framemaker`],[`fsc`,`application/vnd.fsc.weblaunch`],[`fst`,`image/vnd.fst`],[`ftc`,`application/vnd.fluxtime.clip`],[`fti`,`application/vnd.anser-web-funds-transfer-initiation`],[`fvt`,`video/vnd.fvt`],[`fxp`,`application/vnd.adobe.fxp`],[`fxpl`,`application/vnd.adobe.fxp`],[`fzs`,`application/vnd.fuzzysheet`],[`g2w`,`application/vnd.geoplan`],[`g3`,`image/g3fax`],[`g3w`,`application/vnd.geospace`],[`gac`,`application/vnd.groove-account`],[`gam`,`application/x-tads`],[`gbr`,`application/rpki-ghostbusters`],[`gca`,`application/x-gca-compressed`],[`gdl`,`model/vnd.gdl`],[`gdoc`,`application/vnd.google-apps.document`],[`geo`,`application/vnd.dynageo`],[`geojson`,`application/geo+json`],[`gex`,`application/vnd.geometry-explorer`],[`ggb`,`application/vnd.geogebra.file`],[`ggt`,`application/vnd.geogebra.tool`],[`ghf`,`application/vnd.groove-help`],[`gif`,`image/gif`],[`gim`,`application/vnd.groove-identity-message`],[`glb`,`model/gltf-binary`],[`gltf`,`model/gltf+json`],[`gml`,`application/gml+xml`],[`gmx`,`application/vnd.gmx`],[`gnumeric`,`application/x-gnumeric`],[`gpg`,`application/gpg-keys`],[`gph`,`application/vnd.flographit`],[`gpx`,`application/gpx+xml`],[`gqf`,`application/vnd.grafeq`],[`gqs`,`application/vnd.grafeq`],[`gram`,`application/srgs`],[`gramps`,`application/x-gramps-xml`],[`gre`,`application/vnd.geometry-explorer`],[`grv`,`application/vnd.groove-injector`],[`grxml`,`application/srgs+xml`],[`gsf`,`application/x-font-ghostscript`],[`gsheet`,`application/vnd.google-apps.spreadsheet`],[`gslides`,`application/vnd.google-apps.presentation`],[`gtar`,`application/x-gtar`],[`gtm`,`application/vnd.groove-tool-message`],[`gtw`,`model/vnd.gtw`],[`gv`,`text/vnd.graphviz`],[`gxf`,`application/gxf`],[`gxt`,`application/vnd.geonext`],[`gz`,`application/gzip`],[`gzip`,`application/gzip`],[`h`,`text/x-c`],[`h261`,`video/h261`],[`h263`,`video/h263`],[`h264`,`video/h264`],[`hal`,`application/vnd.hal+xml`],[`hbci`,`application/vnd.hbci`],[`hbs`,`text/x-handlebars-template`],[`hdd`,`application/x-virtualbox-hdd`],[`hdf`,`application/x-hdf`],[`heic`,`image/heic`],[`heics`,`image/heic-sequence`],[`heif`,`image/heif`],[`heifs`,`image/heif-sequence`],[`hej2`,`image/hej2k`],[`held`,`application/atsc-held+xml`],[`hh`,`text/x-c`],[`hjson`,`application/hjson`],[`hlp`,`application/winhlp`],[`hpgl`,`application/vnd.hp-hpgl`],[`hpid`,`application/vnd.hp-hpid`],[`hps`,`application/vnd.hp-hps`],[`hqx`,`application/mac-binhex40`],[`hsj2`,`image/hsj2`],[`htc`,`text/x-component`],[`htke`,`application/vnd.kenameaapp`],[`htm`,`text/html`],[`html`,`text/html`],[`hvd`,`application/vnd.yamaha.hv-dic`],[`hvp`,`application/vnd.yamaha.hv-voice`],[`hvs`,`application/vnd.yamaha.hv-script`],[`i2g`,`application/vnd.intergeo`],[`icc`,`application/vnd.iccprofile`],[`ice`,`x-conference/x-cooltalk`],[`icm`,`application/vnd.iccprofile`],[`ico`,`image/x-icon`],[`ics`,`text/calendar`],[`ief`,`image/ief`],[`ifb`,`text/calendar`],[`ifm`,`application/vnd.shana.informed.formdata`],[`iges`,`model/iges`],[`igl`,`application/vnd.igloader`],[`igm`,`application/vnd.insors.igm`],[`igs`,`model/iges`],[`igx`,`application/vnd.micrografx.igx`],[`iif`,`application/vnd.shana.informed.interchange`],[`img`,`application/octet-stream`],[`imp`,`application/vnd.accpac.simply.imp`],[`ims`,`application/vnd.ms-ims`],[`in`,`text/plain`],[`ini`,`text/plain`],[`ink`,`application/inkml+xml`],[`inkml`,`application/inkml+xml`],[`install`,`application/x-install-instructions`],[`iota`,`application/vnd.astraea-software.iota`],[`ipfix`,`application/ipfix`],[`ipk`,`application/vnd.shana.informed.package`],[`irm`,`application/vnd.ibm.rights-management`],[`irp`,`application/vnd.irepository.package+xml`],[`iso`,`application/x-iso9660-image`],[`itp`,`application/vnd.shana.informed.formtemplate`],[`its`,`application/its+xml`],[`ivp`,`application/vnd.immervision-ivp`],[`ivu`,`application/vnd.immervision-ivu`],[`jad`,`text/vnd.sun.j2me.app-descriptor`],[`jade`,`text/jade`],[`jam`,`application/vnd.jam`],[`jar`,`application/java-archive`],[`jardiff`,`application/x-java-archive-diff`],[`java`,`text/x-java-source`],[`jhc`,`image/jphc`],[`jisp`,`application/vnd.jisp`],[`jls`,`image/jls`],[`jlt`,`application/vnd.hp-jlyt`],[`jng`,`image/x-jng`],[`jnlp`,`application/x-java-jnlp-file`],[`joda`,`application/vnd.joost.joda-archive`],[`jp2`,`image/jp2`],[`jpe`,`image/jpeg`],[`jpeg`,`image/jpeg`],[`jpf`,`image/jpx`],[`jpg`,`image/jpeg`],[`jpg2`,`image/jp2`],[`jpgm`,`video/jpm`],[`jpgv`,`video/jpeg`],[`jph`,`image/jph`],[`jpm`,`video/jpm`],[`jpx`,`image/jpx`],[`js`,`application/javascript`],[`json`,`application/json`],[`json5`,`application/json5`],[`jsonld`,`application/ld+json`],[`jsonl`,`application/jsonl`],[`jsonml`,`application/jsonml+json`],[`jsx`,`text/jsx`],[`jxr`,`image/jxr`],[`jxra`,`image/jxra`],[`jxrs`,`image/jxrs`],[`jxs`,`image/jxs`],[`jxsc`,`image/jxsc`],[`jxsi`,`image/jxsi`],[`jxss`,`image/jxss`],[`kar`,`audio/midi`],[`karbon`,`application/vnd.kde.karbon`],[`kdb`,`application/octet-stream`],[`kdbx`,`application/x-keepass2`],[`key`,`application/x-iwork-keynote-sffkey`],[`kfo`,`application/vnd.kde.kformula`],[`kia`,`application/vnd.kidspiration`],[`kml`,`application/vnd.google-earth.kml+xml`],[`kmz`,`application/vnd.google-earth.kmz`],[`kne`,`application/vnd.kinar`],[`knp`,`application/vnd.kinar`],[`kon`,`application/vnd.kde.kontour`],[`kpr`,`application/vnd.kde.kpresenter`],[`kpt`,`application/vnd.kde.kpresenter`],[`kpxx`,`application/vnd.ds-keypoint`],[`ksp`,`application/vnd.kde.kspread`],[`ktr`,`application/vnd.kahootz`],[`ktx`,`image/ktx`],[`ktx2`,`image/ktx2`],[`ktz`,`application/vnd.kahootz`],[`kwd`,`application/vnd.kde.kword`],[`kwt`,`application/vnd.kde.kword`],[`lasxml`,`application/vnd.las.las+xml`],[`latex`,`application/x-latex`],[`lbd`,`application/vnd.llamagraphics.life-balance.desktop`],[`lbe`,`application/vnd.llamagraphics.life-balance.exchange+xml`],[`les`,`application/vnd.hhe.lesson-player`],[`less`,`text/less`],[`lgr`,`application/lgr+xml`],[`lha`,`application/octet-stream`],[`link66`,`application/vnd.route66.link66+xml`],[`list`,`text/plain`],[`list3820`,`application/vnd.ibm.modcap`],[`listafp`,`application/vnd.ibm.modcap`],[`litcoffee`,`text/coffeescript`],[`lnk`,`application/x-ms-shortcut`],[`log`,`text/plain`],[`lostxml`,`application/lost+xml`],[`lrf`,`application/octet-stream`],[`lrm`,`application/vnd.ms-lrm`],[`ltf`,`application/vnd.frogans.ltf`],[`lua`,`text/x-lua`],[`luac`,`application/x-lua-bytecode`],[`lvp`,`audio/vnd.lucent.voice`],[`lwp`,`application/vnd.lotus-wordpro`],[`lzh`,`application/octet-stream`],[`m1v`,`video/mpeg`],[`m2a`,`audio/mpeg`],[`m2v`,`video/mpeg`],[`m3a`,`audio/mpeg`],[`m3u`,`text/plain`],[`m3u8`,`application/vnd.apple.mpegurl`],[`m4a`,`audio/x-m4a`],[`m4p`,`application/mp4`],[`m4s`,`video/iso.segment`],[`m4u`,`application/vnd.mpegurl`],[`m4v`,`video/x-m4v`],[`m13`,`application/x-msmediaview`],[`m14`,`application/x-msmediaview`],[`m21`,`application/mp21`],[`ma`,`application/mathematica`],[`mads`,`application/mads+xml`],[`maei`,`application/mmt-aei+xml`],[`mag`,`application/vnd.ecowin.chart`],[`maker`,`application/vnd.framemaker`],[`man`,`text/troff`],[`manifest`,`text/cache-manifest`],[`map`,`application/json`],[`mar`,`application/octet-stream`],[`markdown`,`text/markdown`],[`mathml`,`application/mathml+xml`],[`mb`,`application/mathematica`],[`mbk`,`application/vnd.mobius.mbk`],[`mbox`,`application/mbox`],[`mc1`,`application/vnd.medcalcdata`],[`mcd`,`application/vnd.mcd`],[`mcurl`,`text/vnd.curl.mcurl`],[`md`,`text/markdown`],[`mdb`,`application/x-msaccess`],[`mdi`,`image/vnd.ms-modi`],[`mdx`,`text/mdx`],[`me`,`text/troff`],[`mesh`,`model/mesh`],[`meta4`,`application/metalink4+xml`],[`metalink`,`application/metalink+xml`],[`mets`,`application/mets+xml`],[`mfm`,`application/vnd.mfmp`],[`mft`,`application/rpki-manifest`],[`mgp`,`application/vnd.osgeo.mapguide.package`],[`mgz`,`application/vnd.proteus.magazine`],[`mid`,`audio/midi`],[`midi`,`audio/midi`],[`mie`,`application/x-mie`],[`mif`,`application/vnd.mif`],[`mime`,`message/rfc822`],[`mj2`,`video/mj2`],[`mjp2`,`video/mj2`],[`mjs`,`application/javascript`],[`mk3d`,`video/x-matroska`],[`mka`,`audio/x-matroska`],[`mkd`,`text/x-markdown`],[`mks`,`video/x-matroska`],[`mkv`,`video/x-matroska`],[`mlp`,`application/vnd.dolby.mlp`],[`mmd`,`application/vnd.chipnuts.karaoke-mmd`],[`mmf`,`application/vnd.smaf`],[`mml`,`text/mathml`],[`mmr`,`image/vnd.fujixerox.edmics-mmr`],[`mng`,`video/x-mng`],[`mny`,`application/x-msmoney`],[`mobi`,`application/x-mobipocket-ebook`],[`mods`,`application/mods+xml`],[`mov`,`video/quicktime`],[`movie`,`video/x-sgi-movie`],[`mp2`,`audio/mpeg`],[`mp2a`,`audio/mpeg`],[`mp3`,`audio/mpeg`],[`mp4`,`video/mp4`],[`mp4a`,`audio/mp4`],[`mp4s`,`application/mp4`],[`mp4v`,`video/mp4`],[`mp21`,`application/mp21`],[`mpc`,`application/vnd.mophun.certificate`],[`mpd`,`application/dash+xml`],[`mpe`,`video/mpeg`],[`mpeg`,`video/mpeg`],[`mpg`,`video/mpeg`],[`mpg4`,`video/mp4`],[`mpga`,`audio/mpeg`],[`mpkg`,`application/vnd.apple.installer+xml`],[`mpm`,`application/vnd.blueice.multipass`],[`mpn`,`application/vnd.mophun.application`],[`mpp`,`application/vnd.ms-project`],[`mpt`,`application/vnd.ms-project`],[`mpy`,`application/vnd.ibm.minipay`],[`mqy`,`application/vnd.mobius.mqy`],[`mrc`,`application/marc`],[`mrcx`,`application/marcxml+xml`],[`ms`,`text/troff`],[`mscml`,`application/mediaservercontrol+xml`],[`mseed`,`application/vnd.fdsn.mseed`],[`mseq`,`application/vnd.mseq`],[`msf`,`application/vnd.epson.msf`],[`msg`,`application/vnd.ms-outlook`],[`msh`,`model/mesh`],[`msi`,`application/x-msdownload`],[`msl`,`application/vnd.mobius.msl`],[`msm`,`application/octet-stream`],[`msp`,`application/octet-stream`],[`msty`,`application/vnd.muvee.style`],[`mtl`,`model/mtl`],[`mts`,`model/vnd.mts`],[`mus`,`application/vnd.musician`],[`musd`,`application/mmt-usd+xml`],[`musicxml`,`application/vnd.recordare.musicxml+xml`],[`mvb`,`application/x-msmediaview`],[`mvt`,`application/vnd.mapbox-vector-tile`],[`mwf`,`application/vnd.mfer`],[`mxf`,`application/mxf`],[`mxl`,`application/vnd.recordare.musicxml`],[`mxmf`,`audio/mobile-xmf`],[`mxml`,`application/xv+xml`],[`mxs`,`application/vnd.triscape.mxs`],[`mxu`,`video/vnd.mpegurl`],[`n-gage`,`application/vnd.nokia.n-gage.symbian.install`],[`n3`,`text/n3`],[`nb`,`application/mathematica`],[`nbp`,`application/vnd.wolfram.player`],[`nc`,`application/x-netcdf`],[`ncx`,`application/x-dtbncx+xml`],[`nfo`,`text/x-nfo`],[`ngdat`,`application/vnd.nokia.n-gage.data`],[`nitf`,`application/vnd.nitf`],[`nlu`,`application/vnd.neurolanguage.nlu`],[`nml`,`application/vnd.enliven`],[`nnd`,`application/vnd.noblenet-directory`],[`nns`,`application/vnd.noblenet-sealer`],[`nnw`,`application/vnd.noblenet-web`],[`npx`,`image/vnd.net-fpx`],[`nq`,`application/n-quads`],[`nsc`,`application/x-conference`],[`nsf`,`application/vnd.lotus-notes`],[`nt`,`application/n-triples`],[`ntf`,`application/vnd.nitf`],[`numbers`,`application/x-iwork-numbers-sffnumbers`],[`nzb`,`application/x-nzb`],[`oa2`,`application/vnd.fujitsu.oasys2`],[`oa3`,`application/vnd.fujitsu.oasys3`],[`oas`,`application/vnd.fujitsu.oasys`],[`obd`,`application/x-msbinder`],[`obgx`,`application/vnd.openblox.game+xml`],[`obj`,`model/obj`],[`oda`,`application/oda`],[`odb`,`application/vnd.oasis.opendocument.database`],[`odc`,`application/vnd.oasis.opendocument.chart`],[`odf`,`application/vnd.oasis.opendocument.formula`],[`odft`,`application/vnd.oasis.opendocument.formula-template`],[`odg`,`application/vnd.oasis.opendocument.graphics`],[`odi`,`application/vnd.oasis.opendocument.image`],[`odm`,`application/vnd.oasis.opendocument.text-master`],[`odp`,`application/vnd.oasis.opendocument.presentation`],[`ods`,`application/vnd.oasis.opendocument.spreadsheet`],[`odt`,`application/vnd.oasis.opendocument.text`],[`oga`,`audio/ogg`],[`ogex`,`model/vnd.opengex`],[`ogg`,`audio/ogg`],[`ogv`,`video/ogg`],[`ogx`,`application/ogg`],[`omdoc`,`application/omdoc+xml`],[`onepkg`,`application/onenote`],[`onetmp`,`application/onenote`],[`onetoc`,`application/onenote`],[`onetoc2`,`application/onenote`],[`opf`,`application/oebps-package+xml`],[`opml`,`text/x-opml`],[`oprc`,`application/vnd.palm`],[`opus`,`audio/ogg`],[`org`,`text/x-org`],[`osf`,`application/vnd.yamaha.openscoreformat`],[`osfpvg`,`application/vnd.yamaha.openscoreformat.osfpvg+xml`],[`osm`,`application/vnd.openstreetmap.data+xml`],[`otc`,`application/vnd.oasis.opendocument.chart-template`],[`otf`,`font/otf`],[`otg`,`application/vnd.oasis.opendocument.graphics-template`],[`oth`,`application/vnd.oasis.opendocument.text-web`],[`oti`,`application/vnd.oasis.opendocument.image-template`],[`otp`,`application/vnd.oasis.opendocument.presentation-template`],[`ots`,`application/vnd.oasis.opendocument.spreadsheet-template`],[`ott`,`application/vnd.oasis.opendocument.text-template`],[`ova`,`application/x-virtualbox-ova`],[`ovf`,`application/x-virtualbox-ovf`],[`owl`,`application/rdf+xml`],[`oxps`,`application/oxps`],[`oxt`,`application/vnd.openofficeorg.extension`],[`p`,`text/x-pascal`],[`p7a`,`application/x-pkcs7-signature`],[`p7b`,`application/x-pkcs7-certificates`],[`p7c`,`application/pkcs7-mime`],[`p7m`,`application/pkcs7-mime`],[`p7r`,`application/x-pkcs7-certreqresp`],[`p7s`,`application/pkcs7-signature`],[`p8`,`application/pkcs8`],[`p10`,`application/x-pkcs10`],[`p12`,`application/x-pkcs12`],[`pac`,`application/x-ns-proxy-autoconfig`],[`pages`,`application/x-iwork-pages-sffpages`],[`pas`,`text/x-pascal`],[`paw`,`application/vnd.pawaafile`],[`pbd`,`application/vnd.powerbuilder6`],[`pbm`,`image/x-portable-bitmap`],[`pcap`,`application/vnd.tcpdump.pcap`],[`pcf`,`application/x-font-pcf`],[`pcl`,`application/vnd.hp-pcl`],[`pclxl`,`application/vnd.hp-pclxl`],[`pct`,`image/x-pict`],[`pcurl`,`application/vnd.curl.pcurl`],[`pcx`,`image/x-pcx`],[`pdb`,`application/x-pilot`],[`pde`,`text/x-processing`],[`pdf`,`application/pdf`],[`pem`,`application/x-x509-user-cert`],[`pfa`,`application/x-font-type1`],[`pfb`,`application/x-font-type1`],[`pfm`,`application/x-font-type1`],[`pfr`,`application/font-tdpfr`],[`pfx`,`application/x-pkcs12`],[`pgm`,`image/x-portable-graymap`],[`pgn`,`application/x-chess-pgn`],[`pgp`,`application/pgp`],[`php`,`application/x-httpd-php`],[`php3`,`application/x-httpd-php`],[`php4`,`application/x-httpd-php`],[`phps`,`application/x-httpd-php-source`],[`phtml`,`application/x-httpd-php`],[`pic`,`image/x-pict`],[`pkg`,`application/octet-stream`],[`pki`,`application/pkixcmp`],[`pkipath`,`application/pkix-pkipath`],[`pkpass`,`application/vnd.apple.pkpass`],[`pl`,`application/x-perl`],[`plb`,`application/vnd.3gpp.pic-bw-large`],[`plc`,`application/vnd.mobius.plc`],[`plf`,`application/vnd.pocketlearn`],[`pls`,`application/pls+xml`],[`pm`,`application/x-perl`],[`pml`,`application/vnd.ctc-posml`],[`png`,`image/png`],[`pnm`,`image/x-portable-anymap`],[`portpkg`,`application/vnd.macports.portpkg`],[`pot`,`application/vnd.ms-powerpoint`],[`potm`,`application/vnd.ms-powerpoint.presentation.macroEnabled.12`],[`potx`,`application/vnd.openxmlformats-officedocument.presentationml.template`],[`ppa`,`application/vnd.ms-powerpoint`],[`ppam`,`application/vnd.ms-powerpoint.addin.macroEnabled.12`],[`ppd`,`application/vnd.cups-ppd`],[`ppm`,`image/x-portable-pixmap`],[`pps`,`application/vnd.ms-powerpoint`],[`ppsm`,`application/vnd.ms-powerpoint.slideshow.macroEnabled.12`],[`ppsx`,`application/vnd.openxmlformats-officedocument.presentationml.slideshow`],[`ppt`,`application/powerpoint`],[`pptm`,`application/vnd.ms-powerpoint.presentation.macroEnabled.12`],[`pptx`,`application/vnd.openxmlformats-officedocument.presentationml.presentation`],[`pqa`,`application/vnd.palm`],[`prc`,`application/x-pilot`],[`pre`,`application/vnd.lotus-freelance`],[`prf`,`application/pics-rules`],[`provx`,`application/provenance+xml`],[`ps`,`application/postscript`],[`psb`,`application/vnd.3gpp.pic-bw-small`],[`psd`,`application/x-photoshop`],[`psf`,`application/x-font-linux-psf`],[`pskcxml`,`application/pskc+xml`],[`pti`,`image/prs.pti`],[`ptid`,`application/vnd.pvi.ptid1`],[`pub`,`application/x-mspublisher`],[`pvb`,`application/vnd.3gpp.pic-bw-var`],[`pwn`,`application/vnd.3m.post-it-notes`],[`pya`,`audio/vnd.ms-playready.media.pya`],[`pyv`,`video/vnd.ms-playready.media.pyv`],[`qam`,`application/vnd.epson.quickanime`],[`qbo`,`application/vnd.intu.qbo`],[`qfx`,`application/vnd.intu.qfx`],[`qps`,`application/vnd.publishare-delta-tree`],[`qt`,`video/quicktime`],[`qwd`,`application/vnd.quark.quarkxpress`],[`qwt`,`application/vnd.quark.quarkxpress`],[`qxb`,`application/vnd.quark.quarkxpress`],[`qxd`,`application/vnd.quark.quarkxpress`],[`qxl`,`application/vnd.quark.quarkxpress`],[`qxt`,`application/vnd.quark.quarkxpress`],[`ra`,`audio/x-realaudio`],[`ram`,`audio/x-pn-realaudio`],[`raml`,`application/raml+yaml`],[`rapd`,`application/route-apd+xml`],[`rar`,`application/x-rar`],[`ras`,`image/x-cmu-raster`],[`rcprofile`,`application/vnd.ipunplugged.rcprofile`],[`rdf`,`application/rdf+xml`],[`rdz`,`application/vnd.data-vision.rdz`],[`relo`,`application/p2p-overlay+xml`],[`rep`,`application/vnd.businessobjects`],[`res`,`application/x-dtbresource+xml`],[`rgb`,`image/x-rgb`],[`rif`,`application/reginfo+xml`],[`rip`,`audio/vnd.rip`],[`ris`,`application/x-research-info-systems`],[`rl`,`application/resource-lists+xml`],[`rlc`,`image/vnd.fujixerox.edmics-rlc`],[`rld`,`application/resource-lists-diff+xml`],[`rm`,`audio/x-pn-realaudio`],[`rmi`,`audio/midi`],[`rmp`,`audio/x-pn-realaudio-plugin`],[`rms`,`application/vnd.jcp.javame.midlet-rms`],[`rmvb`,`application/vnd.rn-realmedia-vbr`],[`rnc`,`application/relax-ng-compact-syntax`],[`rng`,`application/xml`],[`roa`,`application/rpki-roa`],[`roff`,`text/troff`],[`rp9`,`application/vnd.cloanto.rp9`],[`rpm`,`audio/x-pn-realaudio-plugin`],[`rpss`,`application/vnd.nokia.radio-presets`],[`rpst`,`application/vnd.nokia.radio-preset`],[`rq`,`application/sparql-query`],[`rs`,`application/rls-services+xml`],[`rsa`,`application/x-pkcs7`],[`rsat`,`application/atsc-rsat+xml`],[`rsd`,`application/rsd+xml`],[`rsheet`,`application/urc-ressheet+xml`],[`rss`,`application/rss+xml`],[`rtf`,`text/rtf`],[`rtx`,`text/richtext`],[`run`,`application/x-makeself`],[`rusd`,`application/route-usd+xml`],[`rv`,`video/vnd.rn-realvideo`],[`s`,`text/x-asm`],[`s3m`,`audio/s3m`],[`saf`,`application/vnd.yamaha.smaf-audio`],[`sass`,`text/x-sass`],[`sbml`,`application/sbml+xml`],[`sc`,`application/vnd.ibm.secure-container`],[`scd`,`application/x-msschedule`],[`scm`,`application/vnd.lotus-screencam`],[`scq`,`application/scvp-cv-request`],[`scs`,`application/scvp-cv-response`],[`scss`,`text/x-scss`],[`scurl`,`text/vnd.curl.scurl`],[`sda`,`application/vnd.stardivision.draw`],[`sdc`,`application/vnd.stardivision.calc`],[`sdd`,`application/vnd.stardivision.impress`],[`sdkd`,`application/vnd.solent.sdkm+xml`],[`sdkm`,`application/vnd.solent.sdkm+xml`],[`sdp`,`application/sdp`],[`sdw`,`application/vnd.stardivision.writer`],[`sea`,`application/octet-stream`],[`see`,`application/vnd.seemail`],[`seed`,`application/vnd.fdsn.seed`],[`sema`,`application/vnd.sema`],[`semd`,`application/vnd.semd`],[`semf`,`application/vnd.semf`],[`senmlx`,`application/senml+xml`],[`sensmlx`,`application/sensml+xml`],[`ser`,`application/java-serialized-object`],[`setpay`,`application/set-payment-initiation`],[`setreg`,`application/set-registration-initiation`],[`sfd-hdstx`,`application/vnd.hydrostatix.sof-data`],[`sfs`,`application/vnd.spotfire.sfs`],[`sfv`,`text/x-sfv`],[`sgi`,`image/sgi`],[`sgl`,`application/vnd.stardivision.writer-global`],[`sgm`,`text/sgml`],[`sgml`,`text/sgml`],[`sh`,`application/x-sh`],[`shar`,`application/x-shar`],[`shex`,`text/shex`],[`shf`,`application/shf+xml`],[`shtml`,`text/html`],[`sid`,`image/x-mrsid-image`],[`sieve`,`application/sieve`],[`sig`,`application/pgp-signature`],[`sil`,`audio/silk`],[`silo`,`model/mesh`],[`sis`,`application/vnd.symbian.install`],[`sisx`,`application/vnd.symbian.install`],[`sit`,`application/x-stuffit`],[`sitx`,`application/x-stuffitx`],[`siv`,`application/sieve`],[`skd`,`application/vnd.koan`],[`skm`,`application/vnd.koan`],[`skp`,`application/vnd.koan`],[`skt`,`application/vnd.koan`],[`sldm`,`application/vnd.ms-powerpoint.slide.macroenabled.12`],[`sldx`,`application/vnd.openxmlformats-officedocument.presentationml.slide`],[`slim`,`text/slim`],[`slm`,`text/slim`],[`sls`,`application/route-s-tsid+xml`],[`slt`,`application/vnd.epson.salt`],[`sm`,`application/vnd.stepmania.stepchart`],[`smf`,`application/vnd.stardivision.math`],[`smi`,`application/smil`],[`smil`,`application/smil`],[`smv`,`video/x-smv`],[`smzip`,`application/vnd.stepmania.package`],[`snd`,`audio/basic`],[`snf`,`application/x-font-snf`],[`so`,`application/octet-stream`],[`spc`,`application/x-pkcs7-certificates`],[`spdx`,`text/spdx`],[`spf`,`application/vnd.yamaha.smaf-phrase`],[`spl`,`application/x-futuresplash`],[`spot`,`text/vnd.in3d.spot`],[`spp`,`application/scvp-vp-response`],[`spq`,`application/scvp-vp-request`],[`spx`,`audio/ogg`],[`sql`,`application/x-sql`],[`src`,`application/x-wais-source`],[`srt`,`application/x-subrip`],[`sru`,`application/sru+xml`],[`srx`,`application/sparql-results+xml`],[`ssdl`,`application/ssdl+xml`],[`sse`,`application/vnd.kodak-descriptor`],[`ssf`,`application/vnd.epson.ssf`],[`ssml`,`application/ssml+xml`],[`sst`,`application/octet-stream`],[`st`,`application/vnd.sailingtracker.track`],[`stc`,`application/vnd.sun.xml.calc.template`],[`std`,`application/vnd.sun.xml.draw.template`],[`stf`,`application/vnd.wt.stf`],[`sti`,`application/vnd.sun.xml.impress.template`],[`stk`,`application/hyperstudio`],[`stl`,`model/stl`],[`stpx`,`model/step+xml`],[`stpxz`,`model/step-xml+zip`],[`stpz`,`model/step+zip`],[`str`,`application/vnd.pg.format`],[`stw`,`application/vnd.sun.xml.writer.template`],[`styl`,`text/stylus`],[`stylus`,`text/stylus`],[`sub`,`text/vnd.dvb.subtitle`],[`sus`,`application/vnd.sus-calendar`],[`susp`,`application/vnd.sus-calendar`],[`sv4cpio`,`application/x-sv4cpio`],[`sv4crc`,`application/x-sv4crc`],[`svc`,`application/vnd.dvb.service`],[`svd`,`application/vnd.svd`],[`svg`,`image/svg+xml`],[`svgz`,`image/svg+xml`],[`swa`,`application/x-director`],[`swf`,`application/x-shockwave-flash`],[`swi`,`application/vnd.aristanetworks.swi`],[`swidtag`,`application/swid+xml`],[`sxc`,`application/vnd.sun.xml.calc`],[`sxd`,`application/vnd.sun.xml.draw`],[`sxg`,`application/vnd.sun.xml.writer.global`],[`sxi`,`application/vnd.sun.xml.impress`],[`sxm`,`application/vnd.sun.xml.math`],[`sxw`,`application/vnd.sun.xml.writer`],[`t`,`text/troff`],[`t3`,`application/x-t3vm-image`],[`t38`,`image/t38`],[`taglet`,`application/vnd.mynfc`],[`tao`,`application/vnd.tao.intent-module-archive`],[`tap`,`image/vnd.tencent.tap`],[`tar`,`application/x-tar`],[`tcap`,`application/vnd.3gpp2.tcap`],[`tcl`,`application/x-tcl`],[`td`,`application/urc-targetdesc+xml`],[`teacher`,`application/vnd.smart.teacher`],[`tei`,`application/tei+xml`],[`teicorpus`,`application/tei+xml`],[`tex`,`application/x-tex`],[`texi`,`application/x-texinfo`],[`texinfo`,`application/x-texinfo`],[`text`,`text/plain`],[`tfi`,`application/thraud+xml`],[`tfm`,`application/x-tex-tfm`],[`tfx`,`image/tiff-fx`],[`tga`,`image/x-tga`],[`tgz`,`application/x-tar`],[`thmx`,`application/vnd.ms-officetheme`],[`tif`,`image/tiff`],[`tiff`,`image/tiff`],[`tk`,`application/x-tcl`],[`tmo`,`application/vnd.tmobile-livetv`],[`toml`,`application/toml`],[`torrent`,`application/x-bittorrent`],[`tpl`,`application/vnd.groove-tool-template`],[`tpt`,`application/vnd.trid.tpt`],[`tr`,`text/troff`],[`tra`,`application/vnd.trueapp`],[`trig`,`application/trig`],[`trm`,`application/x-msterminal`],[`ts`,`video/mp2t`],[`tsd`,`application/timestamped-data`],[`tsv`,`text/tab-separated-values`],[`ttc`,`font/collection`],[`ttf`,`font/ttf`],[`ttl`,`text/turtle`],[`ttml`,`application/ttml+xml`],[`twd`,`application/vnd.simtech-mindmapper`],[`twds`,`application/vnd.simtech-mindmapper`],[`txd`,`application/vnd.genomatix.tuxedo`],[`txf`,`application/vnd.mobius.txf`],[`txt`,`text/plain`],[`u8dsn`,`message/global-delivery-status`],[`u8hdr`,`message/global-headers`],[`u8mdn`,`message/global-disposition-notification`],[`u8msg`,`message/global`],[`u32`,`application/x-authorware-bin`],[`ubj`,`application/ubjson`],[`udeb`,`application/x-debian-package`],[`ufd`,`application/vnd.ufdl`],[`ufdl`,`application/vnd.ufdl`],[`ulx`,`application/x-glulx`],[`umj`,`application/vnd.umajin`],[`unityweb`,`application/vnd.unity`],[`uoml`,`application/vnd.uoml+xml`],[`uri`,`text/uri-list`],[`uris`,`text/uri-list`],[`urls`,`text/uri-list`],[`usdz`,`model/vnd.usdz+zip`],[`ustar`,`application/x-ustar`],[`utz`,`application/vnd.uiq.theme`],[`uu`,`text/x-uuencode`],[`uva`,`audio/vnd.dece.audio`],[`uvd`,`application/vnd.dece.data`],[`uvf`,`application/vnd.dece.data`],[`uvg`,`image/vnd.dece.graphic`],[`uvh`,`video/vnd.dece.hd`],[`uvi`,`image/vnd.dece.graphic`],[`uvm`,`video/vnd.dece.mobile`],[`uvp`,`video/vnd.dece.pd`],[`uvs`,`video/vnd.dece.sd`],[`uvt`,`application/vnd.dece.ttml+xml`],[`uvu`,`video/vnd.uvvu.mp4`],[`uvv`,`video/vnd.dece.video`],[`uvva`,`audio/vnd.dece.audio`],[`uvvd`,`application/vnd.dece.data`],[`uvvf`,`application/vnd.dece.data`],[`uvvg`,`image/vnd.dece.graphic`],[`uvvh`,`video/vnd.dece.hd`],[`uvvi`,`image/vnd.dece.graphic`],[`uvvm`,`video/vnd.dece.mobile`],[`uvvp`,`video/vnd.dece.pd`],[`uvvs`,`video/vnd.dece.sd`],[`uvvt`,`application/vnd.dece.ttml+xml`],[`uvvu`,`video/vnd.uvvu.mp4`],[`uvvv`,`video/vnd.dece.video`],[`uvvx`,`application/vnd.dece.unspecified`],[`uvvz`,`application/vnd.dece.zip`],[`uvx`,`application/vnd.dece.unspecified`],[`uvz`,`application/vnd.dece.zip`],[`vbox`,`application/x-virtualbox-vbox`],[`vbox-extpack`,`application/x-virtualbox-vbox-extpack`],[`vcard`,`text/vcard`],[`vcd`,`application/x-cdlink`],[`vcf`,`text/x-vcard`],[`vcg`,`application/vnd.groove-vcard`],[`vcs`,`text/x-vcalendar`],[`vcx`,`application/vnd.vcx`],[`vdi`,`application/x-virtualbox-vdi`],[`vds`,`model/vnd.sap.vds`],[`vhd`,`application/x-virtualbox-vhd`],[`vis`,`application/vnd.visionary`],[`viv`,`video/vnd.vivo`],[`vlc`,`application/videolan`],[`vmdk`,`application/x-virtualbox-vmdk`],[`vob`,`video/x-ms-vob`],[`vor`,`application/vnd.stardivision.writer`],[`vox`,`application/x-authorware-bin`],[`vrml`,`model/vrml`],[`vsd`,`application/vnd.visio`],[`vsf`,`application/vnd.vsf`],[`vss`,`application/vnd.visio`],[`vst`,`application/vnd.visio`],[`vsw`,`application/vnd.visio`],[`vtf`,`image/vnd.valve.source.texture`],[`vtt`,`text/vtt`],[`vtu`,`model/vnd.vtu`],[`vxml`,`application/voicexml+xml`],[`w3d`,`application/x-director`],[`wad`,`application/x-doom`],[`wadl`,`application/vnd.sun.wadl+xml`],[`war`,`application/java-archive`],[`wasm`,`application/wasm`],[`wav`,`audio/x-wav`],[`wax`,`audio/x-ms-wax`],[`wbmp`,`image/vnd.wap.wbmp`],[`wbs`,`application/vnd.criticaltools.wbs+xml`],[`wbxml`,`application/wbxml`],[`wcm`,`application/vnd.ms-works`],[`wdb`,`application/vnd.ms-works`],[`wdp`,`image/vnd.ms-photo`],[`weba`,`audio/webm`],[`webapp`,`application/x-web-app-manifest+json`],[`webm`,`video/webm`],[`webmanifest`,`application/manifest+json`],[`webp`,`image/webp`],[`wg`,`application/vnd.pmi.widget`],[`wgt`,`application/widget`],[`wks`,`application/vnd.ms-works`],[`wm`,`video/x-ms-wm`],[`wma`,`audio/x-ms-wma`],[`wmd`,`application/x-ms-wmd`],[`wmf`,`image/wmf`],[`wml`,`text/vnd.wap.wml`],[`wmlc`,`application/wmlc`],[`wmls`,`text/vnd.wap.wmlscript`],[`wmlsc`,`application/vnd.wap.wmlscriptc`],[`wmv`,`video/x-ms-wmv`],[`wmx`,`video/x-ms-wmx`],[`wmz`,`application/x-msmetafile`],[`woff`,`font/woff`],[`woff2`,`font/woff2`],[`word`,`application/msword`],[`wpd`,`application/vnd.wordperfect`],[`wpl`,`application/vnd.ms-wpl`],[`wps`,`application/vnd.ms-works`],[`wqd`,`application/vnd.wqd`],[`wri`,`application/x-mswrite`],[`wrl`,`model/vrml`],[`wsc`,`message/vnd.wfa.wsc`],[`wsdl`,`application/wsdl+xml`],[`wspolicy`,`application/wspolicy+xml`],[`wtb`,`application/vnd.webturbo`],[`wvx`,`video/x-ms-wvx`],[`x3d`,`model/x3d+xml`],[`x3db`,`model/x3d+fastinfoset`],[`x3dbz`,`model/x3d+binary`],[`x3dv`,`model/x3d-vrml`],[`x3dvz`,`model/x3d+vrml`],[`x3dz`,`model/x3d+xml`],[`x32`,`application/x-authorware-bin`],[`x_b`,`model/vnd.parasolid.transmit.binary`],[`x_t`,`model/vnd.parasolid.transmit.text`],[`xaml`,`application/xaml+xml`],[`xap`,`application/x-silverlight-app`],[`xar`,`application/vnd.xara`],[`xav`,`application/xcap-att+xml`],[`xbap`,`application/x-ms-xbap`],[`xbd`,`application/vnd.fujixerox.docuworks.binder`],[`xbm`,`image/x-xbitmap`],[`xca`,`application/xcap-caps+xml`],[`xcs`,`application/calendar+xml`],[`xdf`,`application/xcap-diff+xml`],[`xdm`,`application/vnd.syncml.dm+xml`],[`xdp`,`application/vnd.adobe.xdp+xml`],[`xdssc`,`application/dssc+xml`],[`xdw`,`application/vnd.fujixerox.docuworks`],[`xel`,`application/xcap-el+xml`],[`xenc`,`application/xenc+xml`],[`xer`,`application/patch-ops-error+xml`],[`xfdf`,`application/vnd.adobe.xfdf`],[`xfdl`,`application/vnd.xfdl`],[`xht`,`application/xhtml+xml`],[`xhtml`,`application/xhtml+xml`],[`xhvml`,`application/xv+xml`],[`xif`,`image/vnd.xiff`],[`xl`,`application/excel`],[`xla`,`application/vnd.ms-excel`],[`xlam`,`application/vnd.ms-excel.addin.macroEnabled.12`],[`xlc`,`application/vnd.ms-excel`],[`xlf`,`application/xliff+xml`],[`xlm`,`application/vnd.ms-excel`],[`xls`,`application/vnd.ms-excel`],[`xlsb`,`application/vnd.ms-excel.sheet.binary.macroEnabled.12`],[`xlsm`,`application/vnd.ms-excel.sheet.macroEnabled.12`],[`xlsx`,`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`],[`xlt`,`application/vnd.ms-excel`],[`xltm`,`application/vnd.ms-excel.template.macroEnabled.12`],[`xltx`,`application/vnd.openxmlformats-officedocument.spreadsheetml.template`],[`xlw`,`application/vnd.ms-excel`],[`xm`,`audio/xm`],[`xml`,`application/xml`],[`xns`,`application/xcap-ns+xml`],[`xo`,`application/vnd.olpc-sugar`],[`xop`,`application/xop+xml`],[`xpi`,`application/x-xpinstall`],[`xpl`,`application/xproc+xml`],[`xpm`,`image/x-xpixmap`],[`xpr`,`application/vnd.is-xpr`],[`xps`,`application/vnd.ms-xpsdocument`],[`xpw`,`application/vnd.intercon.formnet`],[`xpx`,`application/vnd.intercon.formnet`],[`xsd`,`application/xml`],[`xsl`,`application/xml`],[`xslt`,`application/xslt+xml`],[`xsm`,`application/vnd.syncml+xml`],[`xspf`,`application/xspf+xml`],[`xul`,`application/vnd.mozilla.xul+xml`],[`xvm`,`application/xv+xml`],[`xvml`,`application/xv+xml`],[`xwd`,`image/x-xwindowdump`],[`xyz`,`chemical/x-xyz`],[`xz`,`application/x-xz`],[`yaml`,`text/yaml`],[`yang`,`application/yang`],[`yin`,`application/yin+xml`],[`yml`,`text/yaml`],[`ymp`,`text/x-suse-ymp`],[`z`,`application/x-compress`],[`z1`,`application/x-zmachine`],[`z2`,`application/x-zmachine`],[`z3`,`application/x-zmachine`],[`z4`,`application/x-zmachine`],[`z5`,`application/x-zmachine`],[`z6`,`application/x-zmachine`],[`z7`,`application/x-zmachine`],[`z8`,`application/x-zmachine`],[`zaz`,`application/vnd.zzazz.deck+xml`],[`zip`,`application/zip`],[`zir`,`application/vnd.zul`],[`zirz`,`application/vnd.zul`],[`zmm`,`application/vnd.handheld-entertainment+xml`],[`zsh`,`text/x-scriptzsh`]]);function p(e,t,n){let r=m(e),{webkitRelativePath:i}=e,a=typeof t==`string`?t:typeof i==`string`&&i.length>0?i:`./${e.name}`;return typeof r.path!=`string`&&h(r,`path`,a),n!==void 0&&Object.defineProperty(r,`handle`,{value:n,writable:!1,configurable:!1,enumerable:!0}),h(r,`relativePath`,a),r}function m(e){let{name:t}=e;if(t&&t.lastIndexOf(`.`)!==-1&&!e.type){let n=t.split(`.`).pop().toLowerCase(),r=f.get(n);r&&Object.defineProperty(e,`type`,{value:r,writable:!1,configurable:!1,enumerable:!0})}return e}function h(e,t,n){Object.defineProperty(e,t,{value:n,writable:!1,configurable:!1,enumerable:!0})}var g=[`.DS_Store`,`Thumbs.db`];function ee(e){return d(this,void 0,void 0,function*(){return v(e)&&te(e.dataTransfer)?b(e.dataTransfer,e.type):_(e)?y(e):Array.isArray(e)&&e.every(e=>`getFile`in e&&typeof e.getFile==`function`)?ne(e):[]})}function te(e){return v(e)}function _(e){return v(e)&&v(e.target)}function v(e){return typeof e==`object`&&!!e}function y(e){return S(e.target.files).map(e=>p(e))}function ne(e){return d(this,void 0,void 0,function*(){return(yield Promise.all(e.map(e=>e.getFile()))).map(e=>p(e))})}function b(e,t){return d(this,void 0,void 0,function*(){if(e.items){let n=S(e.items).filter(e=>e.kind===`file`);return t===`drop`?x(w(yield Promise.all(n.map(C)))):n}return x(S(e.files).map(e=>p(e)))})}function x(e){return e.filter(e=>g.indexOf(e.name)===-1)}function S(e){if(e===null)return[];let t=[];for(let n=0;n[...e,...Array.isArray(t)?w(t):[t]],[])}function T(e,t){return d(this,void 0,void 0,function*(){if(globalThis.isSecureContext&&typeof e.getAsFileSystemHandle==`function`){let t=yield e.getAsFileSystemHandle();if(t===null)throw Error(`${e} is not a File`);if(t!==void 0){let e=yield t.getFile();return e.handle=t,p(e)}}let n=e.getAsFile();if(!n)throw Error(`${e} is not a File`);return p(n,t?.fullPath??void 0)})}function E(e){return d(this,void 0,void 0,function*(){return e.isDirectory?D(e):O(e)})}function D(e){let t=e.createReader();return new Promise((e,n)=>{let r=[];function i(){t.readEntries(t=>d(this,void 0,void 0,function*(){if(t.length){let e=Promise.all(t.map(E));r.push(e),i()}else try{e(yield Promise.all(r))}catch(e){n(e)}}),e=>{n(e)})}i()})}function O(e){return d(this,void 0,void 0,function*(){return new Promise((t,n)=>{e.file(n=>{t(p(n,e.fullPath))},e=>{n(e)})})})}var k=e(t((e=>{e.__esModule=!0,e.default=function(e,t){if(e&&t){var n=Array.isArray(t)?t:t.split(`,`);if(n.length===0)return!0;var r=e.name||``,i=(e.type||``).toLowerCase(),a=i.replace(/\/.*$/,``);return n.some(function(e){var t=e.trim().toLowerCase();return t.charAt(0)===`.`?r.toLowerCase().endsWith(t):t.endsWith(`/*`)?a===t.replace(/\/.*$/,``):i===t})}return!0}}))());function A(e){return ie(e)||re(e)||I(e)||j()}function j(){throw TypeError(`Invalid attempt to spread non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function re(e){if(typeof Symbol<`u`&&e[Symbol.iterator]!=null||e[`@@iterator`]!=null)return Array.from(e)}function ie(e){if(Array.isArray(e))return L(e)}function M(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function N(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=Array(t);n0&&arguments[0]!==void 0?arguments[0]:``).split(`,`);return{code:z,message:`File type must be ${e.length>1?`one of ${e.join(`, `)}`:e[0]}`}},V=function(e){return{code:B,message:`File is larger than ${e} ${e===1?`byte`:`bytes`}`}},H=function(e){return{code:ce,message:`File is smaller than ${e} ${e===1?`byte`:`bytes`}`}},de={code:le,message:`Too many files`};function U(e){return e.type===``&&typeof e.getAsFile==`function`}function fe(e,t){var n=e.type===`application/x-moz-file`||R(e,t)||U(e);return[n,n?null:ue(t)]}function pe(e,t,n){if(W(e.size)){if(W(t)&&W(n)){if(e.size>n)return[!1,V(n)];if(e.sizen)return[!1,V(n)]}return[!0,null]}function W(e){return e!=null}function me(e){var t=e.files,n=e.accept,r=e.minSize,i=e.maxSize,a=e.multiple,o=e.maxFiles,s=e.validator;return!a&&t.length>1||a&&o>=1&&t.length>o?!1:t.every(function(e){var t=F(fe(e,n),1)[0],a=F(pe(e,r,i),1)[0],o=s?s(e):null;return t&&a&&!o})}function G(e){return typeof e.isPropagationStopped==`function`?e.isPropagationStopped():e.cancelBubble===void 0?!1:e.cancelBubble}function K(e){return e.dataTransfer?Array.prototype.some.call(e.dataTransfer.types,function(e){return e===`Files`||e===`application/x-moz-file`}):!!e.target&&!!e.target.files}function he(e){e.preventDefault()}function q(e){return e.indexOf(`MSIE`)!==-1||e.indexOf(`Trident/`)!==-1}function ge(e){return e.indexOf(`Edge/`)!==-1}function _e(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:window.navigator.userAgent;return q(e)||ge(e)}function J(){var e=[...arguments];return function(t){var n=[...arguments].slice(1);return e.some(function(e){return!G(t)&&e&&e.apply(void 0,[t].concat(n)),G(t)})}}function ve(){return`showOpenFilePicker`in window}function ye(e){return W(e)?[{description:`Files`,accept:Object.entries(e).filter(function(e){var t=F(e,2),n=t[0],r=t[1],i=!0;return Y(n)||(console.warn(`Skipped "${n}" because it is not a valid MIME type. Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types for a list of valid MIME types.`),i=!1),(!Array.isArray(r)||!r.every(Ce))&&(console.warn(`Skipped "${n}" because an invalid file extension was provided.`),i=!1),i}).reduce(function(e,t){var n=F(t,2),r=n[0],i=n[1];return N(N({},e),{},P({},r,i))},{})}]:e}function be(e){if(W(e))return Object.entries(e).reduce(function(e,t){var n=F(t,2),r=n[0],i=n[1];return[].concat(A(e),[r],A(i))},[]).filter(function(e){return Y(e)||Ce(e)}).join(`,`)}function xe(e){return e instanceof DOMException&&(e.name===`AbortError`||e.code===e.ABORT_ERR)}function Se(e){return e instanceof DOMException&&(e.name===`SecurityError`||e.code===e.SECURITY_ERR)}function Y(e){return e===`audio/*`||e===`video/*`||e===`image/*`||e===`text/*`||e===`application/*`||/\w+\/[-+.\w]+/g.test(e)}function Ce(e){return/^.*\.[\w]+$/.test(e)}var X=e(n()),Z=e(u()),we=[`children`],Te=[`open`],Ee=[`refKey`,`role`,`onKeyDown`,`onFocus`,`onBlur`,`onClick`,`onDragEnter`,`onDragOver`,`onDragLeave`,`onDrop`],De=[`refKey`,`onChange`,`onClick`];function Oe(e){return je(e)||Ae(e)||Pe(e)||ke()}function ke(){throw TypeError(`Invalid attempt to spread non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Ae(e){if(typeof Symbol<`u`&&e[Symbol.iterator]!=null||e[`@@iterator`]!=null)return Array.from(e)}function je(e){if(Array.isArray(e))return Fe(e)}function Me(e,t){return Le(e)||Ie(e,t)||Pe(e,t)||Ne()}function Ne(){throw TypeError(`Invalid attempt to destructure non-iterable instance. diff --git a/semantica/static/assets/explorationEffectsPlugin-BUgXLTPa.js b/semantica/static/assets/explorationEffectsPlugin-BUgXLTPa.js deleted file mode 100644 index be630931..00000000 --- a/semantica/static/assets/explorationEffectsPlugin-BUgXLTPa.js +++ /dev/null @@ -1 +0,0 @@ -import{t as e}from"./explorationEffectsPlugin-BhFwJ4hP.js";export{e as explorationEffectsPlugin}; \ No newline at end of file diff --git a/semantica/static/assets/explorationEffectsPlugin-BhFwJ4hP.js b/semantica/static/assets/explorationEffectsPlugin-BhFwJ4hP.js deleted file mode 100644 index 88dc268d..00000000 --- a/semantica/static/assets/explorationEffectsPlugin-BhFwJ4hP.js +++ /dev/null @@ -1 +0,0 @@ -import{a as e}from"./query-vendor-Cbp9LWgA.js";import{r as t}from"./index-BVBOQ8an.js";var n=t(),r=e(),i=`effects-panel`,a=[{key:`pathPulseEnabled`,label:`Path Pulse`,description:`Animated pulse on the active selected path.`},{key:`pathFlowEnabled`,label:`Path Flow`,description:`Directional flow accents along the active selected path.`},{key:`lensEnabled`,label:`Neighborhood Lens`,description:`Local emphasis around the hovered or selected node.`},{key:`legendEnabled`,label:`Semantic Legend`,description:`Compact semantic group legend for graph orientation.`}];function o(e){return e.available?typeof e.visibleSegments==`number`&&typeof e.segmentCap==`number`?`${e.reason} · ${e.visibleSegments}/${e.segmentCap} segments`:e.reason:e.detail?`${e.reason} · ${e.detail}`:e.reason}function s(e){let t=new Map;return e.graph.forEachNode((n,r)=>{let i=String(r.semanticGroup||r.nodeType||`entity`),a=String(r.baseColor||e.theme.palette.semantic[0]),o=t.get(i);t.set(i,{count:(o?.count??0)+1,color:a})}),[...t.entries()].map(([e,t])=>({group:e,...t})).sort((e,t)=>t.count-e.count).slice(0,e.theme.effects.legend.maxGroups)}function c(e){let t=(0,n.c)(20),{label:i,description:a,checked:s,availability:c,onToggle:l}=e,u;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(u={minWidth:0,flex:1},t[0]=u):u=t[0];let d;t[1]===i?d=t[2]:(d=(0,r.jsx)(`div`,{style:h,children:i}),t[1]=i,t[2]=d);let f;t[3]===a?f=t[4]:(f=(0,r.jsx)(`div`,{style:g,children:a}),t[3]=a,t[4]=f);let p;t[5]===c?p=t[6]:(p=o(c),t[5]=c,t[6]=p);let b;t[7]===p?b=t[8]:(b=(0,r.jsx)(`div`,{style:_,children:p}),t[7]=p,t[8]=b);let x;t[9]!==d||t[10]!==f||t[11]!==b?(x=(0,r.jsxs)(`div`,{style:u,children:[d,f,b]}),t[9]=d,t[10]=f,t[11]=b,t[12]=x):x=t[12];let S=s?y:v,C=s?`On`:`Off`,w;t[13]!==l||t[14]!==S||t[15]!==C?(w=(0,r.jsx)(`button`,{type:`button`,onClick:l,style:S,children:C}),t[13]=l,t[14]=S,t[15]=C,t[16]=w):w=t[16];let T;return t[17]!==x||t[18]!==w?(T=(0,r.jsxs)(`div`,{style:m,children:[x,w]}),t[17]=x,t[18]=w,t[19]=T):T=t[19],T}var l={id:`exploration-effects`,mount:()=>{},unmount:()=>{},onStateChange:()=>{},toolbarItems:e=>[{id:`effects-toggle`,label:`Effects`,title:`Open exploration effects controls`,active:e.isPanelOpen(i),order:18,onClick:()=>e.dispatchAction({type:`togglePanel`,panelId:i})}],renderPanel:e=>{if(!e.isPanelOpen(i))return null;let t=e.getEffectsState(),n=e.getDiagnosticsSnapshot()?.effectAvailability,o=t.legendEnabled?s(e):[];return{id:i,title:`Effects`,placement:`bottom`,order:8,defaultOpen:!1,preferredWidth:420,preferredHeight:320,content:(0,r.jsxs)(`div`,{style:u,children:[(0,r.jsx)(`div`,{style:d,children:`Exploration effects`}),(0,r.jsxs)(`div`,{style:f,children:[(0,r.jsx)(`div`,{style:p,children:`Path and focus`}),a.map(i=>(0,r.jsx)(c,{label:i.label,description:i.description,checked:t[i.key],availability:n?.[i.key===`pathPulseEnabled`?`pathPulse`:i.key===`pathFlowEnabled`?`pathFlow`:i.key===`lensEnabled`?`lens`:`legend`]??{enabled:t[i.key],available:!1,reason:`Waiting for graph runtime`},onToggle:()=>e.dispatchAction({type:`toggleEffect`,effect:i.key})},i.key))]}),t.legendEnabled?(0,r.jsxs)(`div`,{style:f,children:[(0,r.jsx)(`div`,{style:p,children:`Semantic legend`}),o.length?(0,r.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:o.map(e=>(0,r.jsxs)(`div`,{style:b,children:[(0,r.jsx)(`span`,{style:{...x,background:e.color,boxShadow:`0 0 0 1px rgba(255,255,255,0.06), 0 0 14px ${e.color}40`}}),(0,r.jsxs)(`div`,{style:{minWidth:0,flex:1},children:[(0,r.jsx)(`div`,{style:h,children:e.group}),(0,r.jsxs)(`div`,{style:_,children:[e.count.toLocaleString(),` nodes`]})]})]},e.group))}):(0,r.jsx)(`div`,{style:S,children:`Legend data will populate when graph metadata is available.`})]}):null,null]})}}},u={display:`flex`,flexDirection:`column`,gap:12},d={color:`#8ea4be`,fontSize:11,fontWeight:700,letterSpacing:`0.08em`,textTransform:`uppercase`},f={display:`flex`,flexDirection:`column`,gap:8,padding:`10px 12px`,borderRadius:14,border:`1px solid rgba(255,255,255,0.06)`,background:`rgba(255,255,255,0.025)`},p={color:`#dce9f8`,fontSize:12,fontWeight:700},m={display:`flex`,alignItems:`center`,gap:12,padding:`8px 0`},h={color:`#f3f7fd`,fontSize:13,fontWeight:600},g={color:`#a1b7cf`,fontSize:12,lineHeight:1.45},_={color:`#7fc6ff`,fontSize:11,lineHeight:1.45},v={minWidth:52,padding:`8px 10px`,borderRadius:999,border:`1px solid rgba(255,255,255,0.08)`,background:`rgba(255,255,255,0.03)`,color:`#cfe0f4`,fontSize:12,fontWeight:700,cursor:`pointer`},y={...v,background:`rgba(31, 111, 235, 0.24)`,border:`1px solid rgba(127, 208, 255, 0.28)`,color:`#eef6ff`},b={display:`flex`,alignItems:`center`,gap:10,padding:`8px 10px`,borderRadius:12,border:`1px solid rgba(255,255,255,0.06)`,background:`rgba(255,255,255,0.025)`},x={width:10,height:10,borderRadius:999,flexShrink:0},S={color:`#8ea4be`,fontSize:12,lineHeight:1.5};export{l as t}; \ No newline at end of file diff --git a/semantica/static/assets/explorationEffectsPluginPhaseC-D23Zx1hX.js b/semantica/static/assets/explorationEffectsPluginPhaseC-D23Zx1hX.js new file mode 100644 index 00000000..dc0df3d4 --- /dev/null +++ b/semantica/static/assets/explorationEffectsPluginPhaseC-D23Zx1hX.js @@ -0,0 +1 @@ +import{t as e}from"./explorationEffectsPluginPhaseC-D5jYu8XU.js";export{e as explorationEffectsPluginPhaseC}; \ No newline at end of file diff --git a/semantica/static/assets/explorationEffectsPluginPhaseC-D5jYu8XU.js b/semantica/static/assets/explorationEffectsPluginPhaseC-D5jYu8XU.js new file mode 100644 index 00000000..8f4f9537 --- /dev/null +++ b/semantica/static/assets/explorationEffectsPluginPhaseC-D5jYu8XU.js @@ -0,0 +1 @@ +import{a as e}from"./query-vendor-Cbp9LWgA.js";import{r as t}from"./index-DDOaKEbH.js";var n=t(),r=e(),i=`effects-panel`,a=[{key:`pathPulseEnabled`,label:`Path Pulse`,description:`Animated pulse on the active selected path.`},{key:`pathFlowEnabled`,label:`Path Flow`,description:`Directional flow accents along the active selected path.`},{key:`lensEnabled`,label:`Neighborhood Lens`,description:`Local emphasis around the hovered or selected node.`},{key:`temporalEmphasisEnabled`,label:`Temporal Emphasis`,description:`Subtle glow around temporally relevant nodes in the active time window.`},{key:`semanticRegionsEnabled`,label:`Semantic Regions`,description:`Quiet semantic hulls around the strongest visible topic clusters.`},{key:`contoursEnabled`,label:`Contours`,description:`Low-contrast density halos around the strongest visible anchors.`},{key:`legendEnabled`,label:`Regions Summary`,description:`Keep the regions and signals summary visible in the Effects panel.`}],o=[{key:`pathfindingEnabled`,label:`Directed Pathfinding`,description:`Compare the traced path against a strict local directed shortest path.`},{key:`communitiesEnabled`,label:`Community Regions`,description:`Detect stable Louvain communities for orientation and scene grouping.`},{key:`centralityEnabled`,label:`Centrality Ranking`,description:`Rank the strongest graph anchors for labels, regions, and navigation.`}],s={pathPulseEnabled:`pathPulse`,pathFlowEnabled:`pathFlow`,lensEnabled:`lens`,temporalEmphasisEnabled:`temporalEmphasis`,semanticRegionsEnabled:`semanticRegions`,contoursEnabled:`contours`,pathfindingEnabled:`pathfinding`,communitiesEnabled:`communities`,centralityEnabled:`centrality`,legendEnabled:`legend`,diagnosticsEnabled:`diagnostics`};function c(e){return e.available?typeof e.visibleSegments==`number`&&typeof e.segmentCap==`number`?`${e.reason} - ${e.visibleSegments}/${e.segmentCap} segments`:e.reason:e.detail?`${e.reason} - ${e.detail}`:e.reason}function l(e){let t=new Map;return e.graph.forEachNode((n,r)=>{let i=String(r.semanticGroup||r.nodeType||`entity`),a=String(r.baseColor||e.theme.palette.semantic[0]),o=t.get(i);t.set(i,{count:(o?.count??0)+1,color:a})}),[...t.entries()].map(([e,t])=>({group:e,...t})).sort((e,t)=>t.count-e.count).slice(0,e.theme.effects.legend.maxGroups)}function u(e,t,n){return e?.[s[t]]??{enabled:n,available:!1,reason:`Waiting for graph runtime`}}function d(e){let t=(0,n.c)(20),{label:i,description:a,checked:o,availability:s,onToggle:l}=e,u;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(u={minWidth:0,flex:1},t[0]=u):u=t[0];let d;t[1]===i?d=t[2]:(d=(0,r.jsx)(`div`,{style:b,children:i}),t[1]=i,t[2]=d);let f;t[3]===a?f=t[4]:(f=(0,r.jsx)(`div`,{style:x,children:a}),t[3]=a,t[4]=f);let p;t[5]===s?p=t[6]:(p=c(s),t[5]=s,t[6]=p);let m;t[7]===p?m=t[8]:(m=(0,r.jsx)(`div`,{style:S,children:p}),t[7]=p,t[8]=m);let h;t[9]!==d||t[10]!==f||t[11]!==m?(h=(0,r.jsxs)(`div`,{style:u,children:[d,f,m]}),t[9]=d,t[10]=f,t[11]=m,t[12]=h):h=t[12];let g=o?w:C,_=o?`On`:`Off`,v;t[13]!==l||t[14]!==g||t[15]!==_?(v=(0,r.jsx)(`button`,{type:`button`,onClick:l,style:g,children:_}),t[13]=l,t[14]=g,t[15]=_,t[16]=v):v=t[16];let T;return t[17]!==h||t[18]!==v?(T=(0,r.jsxs)(`div`,{style:y,children:[h,v]}),t[17]=h,t[18]=v,t[19]=T):T=t[19],T}function f(e,t){let n=l(e),i=t?.semanticRegions.summaries??[],a=t?.communities.summaries??[],o=t?.centrality.topNodes??[],s=t?.directedPath??null;return!i.length&&!a.length&&!o.length&&!n.length&&!s?(0,r.jsx)(`div`,{style:k,children:`Regions and intelligence summaries will populate when graph analytics are ready.`}):(0,r.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:10},children:[i.length?(0,r.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:[(0,r.jsx)(`div`,{style:v,children:`Semantic regions`}),i.map(e=>(0,r.jsxs)(`div`,{style:T,children:[(0,r.jsx)(`span`,{style:{...E,background:e.color,boxShadow:`0 0 0 1px rgba(255,255,255,0.06), 0 0 14px ${e.color}40`}}),(0,r.jsxs)(`div`,{style:{minWidth:0,flex:1},children:[(0,r.jsx)(`div`,{style:b,children:e.semanticGroup}),(0,r.jsxs)(`div`,{style:S,children:[e.visibleNodeCount.toLocaleString(),` visible / `,e.nodeCount.toLocaleString(),` total`]})]}),(0,r.jsx)(`div`,{style:O,children:e.anchorLabel})]},e.semanticGroup))]}):null,a.length?(0,r.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:[(0,r.jsx)(`div`,{style:v,children:`Community anchors`}),a.slice(0,3).map(e=>(0,r.jsxs)(`div`,{style:D,children:[(0,r.jsxs)(`div`,{style:{minWidth:0,flex:1},children:[(0,r.jsx)(`div`,{style:b,children:e.anchorLabel}),(0,r.jsxs)(`div`,{style:S,children:[`Community `,e.communityId,` - `,e.visibleNodeCount,` visible / `,e.nodeCount,` total`]})]}),(0,r.jsx)(`div`,{style:O,children:e.dominantSemanticGroup})]},e.communityId))]}):null,o.length?(0,r.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:[(0,r.jsx)(`div`,{style:v,children:`Centrality leaders`}),o.slice(0,3).map(e=>(0,r.jsxs)(`div`,{style:D,children:[(0,r.jsxs)(`div`,{style:{minWidth:0,flex:1},children:[(0,r.jsx)(`div`,{style:b,children:e.label}),(0,r.jsxs)(`div`,{style:S,children:[e.semanticGroup,` - score `,e.score.toFixed(3)]})]}),(0,r.jsxs)(`div`,{style:O,children:[`deg `,e.degree.toFixed(3)]})]},e.id))]}):null,s?(0,r.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:[(0,r.jsx)(`div`,{style:v,children:`Directed pathfinding`}),(0,r.jsxs)(`div`,{style:D,children:[(0,r.jsxs)(`div`,{style:{minWidth:0,flex:1},children:[(0,r.jsx)(`div`,{style:b,children:s.ready?`Local directed path ready`:`Waiting for path context`}),(0,r.jsx)(`div`,{style:S,children:s.reason})]}),s.ready?(0,r.jsxs)(`div`,{style:O,children:[s.length,` hops`,s.verifiedAgainstActivePath?` - match`:``]}):null]})]}):null,!i.length&&!a.length&&!o.length&&n.length?(0,r.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:[(0,r.jsx)(`div`,{style:v,children:`Fallback semantic legend`}),n.map(e=>(0,r.jsxs)(`div`,{style:T,children:[(0,r.jsx)(`span`,{style:{...E,background:e.color,boxShadow:`0 0 0 1px rgba(255,255,255,0.06), 0 0 14px ${e.color}40`}}),(0,r.jsxs)(`div`,{style:{minWidth:0,flex:1},children:[(0,r.jsx)(`div`,{style:b,children:e.group}),(0,r.jsxs)(`div`,{style:S,children:[e.count.toLocaleString(),` nodes`]})]})]},e.group))]}):null]})}var p={id:`exploration-effects`,mount:()=>{},unmount:()=>{},onStateChange:()=>{},toolbarItems:e=>[{id:`effects-toggle`,label:`Effects`,title:`Open exploration effects controls`,active:e.isPanelOpen(i),order:18,onClick:()=>e.dispatchAction({type:`togglePanel`,panelId:i})}],renderPanel:e=>{if(!e.isPanelOpen(i))return null;let t=e.getEffectsState(),n=e.getDiagnosticsSnapshot(),s=e.getAnalyticsSnapshot(),c=n?.effectAvailability,l=t.legendEnabled||t.semanticRegionsEnabled||t.communitiesEnabled||t.centralityEnabled||t.pathfindingEnabled;return{id:i,title:`Effects`,placement:`bottom`,order:8,defaultOpen:!1,preferredWidth:460,preferredHeight:360,content:(0,r.jsxs)(`div`,{style:m,children:[(0,r.jsx)(`div`,{style:h,children:`Exploration effects`}),(0,r.jsxs)(`div`,{style:g,children:[(0,r.jsx)(`div`,{style:_,children:`Scene effects`}),a.map(n=>(0,r.jsx)(d,{label:n.label,description:n.description,checked:t[n.key],availability:u(c,n.key,t[n.key]),onToggle:()=>e.dispatchAction({type:`toggleEffect`,effect:n.key})},n.key))]}),(0,r.jsxs)(`div`,{style:g,children:[(0,r.jsx)(`div`,{style:_,children:`Graph intelligence`}),o.map(n=>(0,r.jsx)(d,{label:n.label,description:n.description,checked:t[n.key],availability:u(c,n.key,t[n.key]),onToggle:()=>e.dispatchAction({type:`toggleEffect`,effect:n.key})},n.key))]}),l?(0,r.jsxs)(`div`,{style:g,children:[(0,r.jsx)(`div`,{style:_,children:`Regions and signals`}),f(e,s)]}):null,null]})}}},m={display:`flex`,flexDirection:`column`,gap:12},h={color:`#8ea4be`,fontSize:11,fontWeight:700,letterSpacing:`0.08em`,textTransform:`uppercase`},g={display:`flex`,flexDirection:`column`,gap:8,padding:`10px 12px`,borderRadius:14,border:`1px solid rgba(255,255,255,0.06)`,background:`rgba(255,255,255,0.025)`},_={color:`#dce9f8`,fontSize:12,fontWeight:700},v={color:`#9cc4ec`,fontSize:11,fontWeight:700,letterSpacing:`0.05em`,textTransform:`uppercase`},y={display:`flex`,alignItems:`center`,gap:12,padding:`8px 0`},b={color:`#f3f7fd`,fontSize:13,fontWeight:600},x={color:`#a1b7cf`,fontSize:12,lineHeight:1.45},S={color:`#7fc6ff`,fontSize:11,lineHeight:1.45},C={minWidth:52,padding:`8px 10px`,borderRadius:999,border:`1px solid rgba(255,255,255,0.08)`,background:`rgba(255,255,255,0.03)`,color:`#cfe0f4`,fontSize:12,fontWeight:700,cursor:`pointer`},w={...C,background:`rgba(31, 111, 235, 0.24)`,border:`1px solid rgba(127, 208, 255, 0.28)`,color:`#eef6ff`},T={display:`flex`,alignItems:`center`,gap:10,padding:`8px 10px`,borderRadius:12,border:`1px solid rgba(255,255,255,0.06)`,background:`rgba(255,255,255,0.025)`},E={width:10,height:10,borderRadius:999,flexShrink:0},D={display:`flex`,alignItems:`center`,gap:10,padding:`8px 10px`,borderRadius:12,border:`1px solid rgba(255,255,255,0.05)`,background:`rgba(255,255,255,0.02)`},O={padding:`5px 8px`,borderRadius:999,background:`rgba(31, 111, 235, 0.16)`,border:`1px solid rgba(127, 208, 255, 0.16)`,color:`#dce9f8`,fontSize:11,fontWeight:700,whiteSpace:`nowrap`},k={color:`#8ea4be`,fontSize:12,lineHeight:1.5};export{p as t}; \ No newline at end of file diff --git a/semantica/static/assets/graph-vendor-DFSl_YWi.js b/semantica/static/assets/graph-vendor-pbzH-eyf.js similarity index 99% rename from semantica/static/assets/graph-vendor-DFSl_YWi.js rename to semantica/static/assets/graph-vendor-pbzH-eyf.js index 967b77ac..cba1cb16 100644 --- a/semantica/static/assets/graph-vendor-DFSl_YWi.js +++ b/semantica/static/assets/graph-vendor-pbzH-eyf.js @@ -309,4 +309,4 @@ void main() { v_color.a *= bias; } `,En=WebGLRenderingContext,Dn=En.UNSIGNED_BYTE,On=En.FLOAT,kn=[`u_matrix`,`u_zoomRatio`,`u_sizeRatio`,`u_correctionRatio`,`u_pixelRatio`,`u_feather`,`u_minEdgeThickness`],An=function(e){function t(){return K(this,t),J(this,t,arguments)}return Y(t,e),q(t,[{key:`getDefinition`,value:function(){return{VERTICES:6,VERTEX_SHADER_SOURCE:Tn,FRAGMENT_SHADER_SOURCE:hn,METHOD:WebGLRenderingContext.TRIANGLES,UNIFORMS:kn,ATTRIBUTES:[{name:`a_positionStart`,size:2,type:On},{name:`a_positionEnd`,size:2,type:On},{name:`a_normal`,size:2,type:On},{name:`a_color`,size:4,type:Dn,normalized:!0},{name:`a_id`,size:4,type:Dn,normalized:!0}],CONSTANT_ATTRIBUTES:[{name:`a_positionCoef`,size:1,type:On},{name:`a_normalCoef`,size:1,type:On}],CONSTANT_DATA:[[0,1],[0,-1],[1,1],[1,1],[0,-1],[1,-1]]}}},{key:`processVisibleItem`,value:function(e,t,n,r,i){var a=i.size||1,o=n.x,s=n.y,c=r.x,l=r.y,u=Ot(i.color),d=c-o,f=l-s,p=d*d+f*f,m=0,h=0;p&&(p=1/Math.sqrt(p),m=-f*p*a,h=d*p*a);var g=this.array;g[t++]=o,g[t++]=s,g[t++]=c,g[t++]=l,g[t++]=m,g[t++]=h,g[t++]=u,g[t++]=e}},{key:`setUniforms`,value:function(e,t){var n=t.gl,r=t.uniformLocations,i=r.u_matrix,a=r.u_zoomRatio,o=r.u_feather,s=r.u_pixelRatio,c=r.u_correctionRatio,l=r.u_sizeRatio,u=r.u_minEdgeThickness;n.uniformMatrix3fv(i,!1,e.matrix),n.uniform1f(a,e.zoomRatio),n.uniform1f(l,e.sizeRatio),n.uniform1f(c,e.correctionRatio),n.uniform1f(s,e.pixelRatio),n.uniform1f(o,e.antiAliasingFeather),n.uniform1f(u,e.minEdgeThickness)}}])}(Jt),jn=function(e){function t(){var e;return K(this,t),e=J(this,t),e.rawEmitter=e,e}return Y(t,e),q(t)}(n.EventEmitter),Mn=t(((e,t)=>{t.exports=function(e){return typeof e==`object`&&!!e&&typeof e.addUndirectedEdgeWithKey==`function`&&typeof e.dropNode==`function`&&typeof e.multi==`boolean`}})),Nn=e(Mn()),Pn={linear:function(e){return e},quadraticIn:function(e){return e*e},quadraticOut:function(e){return e*(2-e)},quadraticInOut:function(e){return(e*=2)<1?.5*e*e:-.5*(--e*(e-2)-1)},cubicIn:function(e){return e*e*e},cubicOut:function(e){return--e*e*e+1},cubicInOut:function(e){return(e*=2)<1?.5*e*e*e:.5*((e-=2)*e*e+2)}},Fn={easing:`quadraticInOut`,duration:150};function Q(){return Float32Array.of(1,0,0,0,1,0,0,0,1)}function In(e,t,n){return e[0]=t,e[4]=typeof n==`number`?n:t,e}function Ln(e,t){var n=Math.sin(t),r=Math.cos(t);return e[0]=r,e[1]=n,e[3]=-n,e[4]=r,e}function Rn(e,t,n){return e[6]=t,e[7]=n,e}function zn(e,t){var n=e[0],r=e[1],i=e[2],a=e[3],o=e[4],s=e[5],c=e[6],l=e[7],u=e[8],d=t[0],f=t[1],p=t[2],m=t[3],h=t[4],g=t[5],_=t[6],v=t[7],y=t[8];return e[0]=d*n+f*a+p*c,e[1]=d*r+f*o+p*l,e[2]=d*i+f*s+p*u,e[3]=m*n+h*a+g*c,e[4]=m*r+h*o+g*l,e[5]=m*i+h*s+g*u,e[6]=_*n+v*a+y*c,e[7]=_*r+v*o+y*l,e[8]=_*i+v*s+y*u,e}function Bn(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,r=e[0],i=e[1],a=e[3],o=e[4],s=e[6],c=e[7],l=t.x,u=t.y;return{x:l*r+u*a+s*n,y:l*i+u*o+c*n}}function Vn(e,t){var n=e.height/e.width,r=t.height/t.width;return n<1&&r>1||n>1&&r<1?1:Math.min(Math.max(r,1/r),Math.max(1/n,n))}function Hn(e,t,n,r,i){var a=e.angle,o=e.ratio,s=e.x,c=e.y,l=t.width,u=t.height,d=Q(),f=Math.min(l,u)-2*r,p=Vn(t,n);return i?(zn(d,Rn(Q(),s,c)),zn(d,In(Q(),o)),zn(d,Ln(Q(),a)),zn(d,In(Q(),l/f/2/p,u/f/2/p))):(zn(d,In(Q(),f/l*2*p,f/u*2*p)),zn(d,Ln(Q(),-a)),zn(d,In(Q(),1/o)),zn(d,Rn(Q(),-s,-c))),d}function Un(e,t,n){var r=Bn(e,{x:Math.cos(t.angle),y:Math.sin(t.angle)},0),i=r.x,a=r.y;return 1/Math.sqrt(i**2+a**2)/n.width}function Wn(e){if(!e.order)return{x:[0,1],y:[0,1]};var t=1/0,n=-1/0,r=1/0,i=-1/0;return e.forEachNode(function(e,a){var o=a.x,s=a.y;on&&(n=o),si&&(i=s)}),{x:[t,n],y:[r,i]}}function Gn(e){if(!(0,Nn.default)(e))throw Error(`Sigma: invalid graph instance.`);e.forEachNode(function(e,t){if(!Number.isFinite(t.x)||!Number.isFinite(t.y))throw Error(`Sigma: Coordinates of node ${e} are invalid. A node must have a numeric 'x' and 'y' attribute.`)})}function Kn(e,t,n){var r=document.createElement(e);if(t)for(var i in t)r.style[i]=t[i];if(n)for(var a in n)r.setAttribute(a,n[a]);return r}function qn(){return window.devicePixelRatio===void 0?1:window.devicePixelRatio}function Jn(e,t,n){return n.sort(function(e,n){var r=t(e)||0,i=t(n)||0;return ri?1:0})}function Yn(e){var t=_t(e.x,2),n=t[0],r=t[1],i=_t(e.y,2),a=i[0],o=i[1],s=Math.max(r-n,o-a),c=(r+n)/2,l=(o+a)/2;(s===0||Math.abs(s)===1/0||isNaN(s))&&(s=1),isNaN(c)&&(c=0),isNaN(l)&&(l=0);var u=function(e){return{x:.5+(e.x-c)/s,y:.5+(e.y-l)/s}};return u.applyTo=function(e){e.x=.5+(e.x-c)/s,e.y=.5+(e.y-l)/s},u.inverse=function(e){return{x:c+s*(e.x-.5),y:l+s*(e.y-.5)}},u.ratio=s,u}function Xn(e){"@babel/helpers - typeof";return Xn=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},Xn(e)}function Zn(e,t){var n=t.size;if(n!==0){var r=e.length;e.length+=n;var i=0;t.forEach(function(t){e[r+i]=t,i++})}}function Qn(e){e||={};for(var t=0,n=arguments.length<=1?0:arguments.length-1;t1&&arguments[1]!==void 0?arguments[1]:{},r=arguments.length>2?arguments[2]:void 0;if(!r)return new Promise(function(r){return t.animate(e,n,r)});if(this.enabled){var i=Z(Z({},Fn),n),a=this.validateState(e),o=typeof i.easing==`function`?i.easing:Pn[i.easing],s=Date.now(),c=this.getState(),l=function(){var e=(Date.now()-s)/i.duration;if(e>=1){t.nextFrame=null,t.setState(a),t.animationCallback&&=(t.animationCallback.call(null),void 0);return}var n=o(e),r={};typeof a.x==`number`&&(r.x=c.x+(a.x-c.x)*n),typeof a.y==`number`&&(r.y=c.y+(a.y-c.y)*n),t.enabledRotation&&typeof a.angle==`number`&&(r.angle=c.angle+(a.angle-c.angle)*n),typeof a.ratio==`number`&&(r.ratio=c.ratio+(a.ratio-c.ratio)*n),t.setState(r),t.nextFrame=requestAnimationFrame(l)};this.nextFrame?(cancelAnimationFrame(this.nextFrame),this.animationCallback&&this.animationCallback.call(null),this.nextFrame=requestAnimationFrame(l)):l(),this.animationCallback=r}}},{key:`animatedZoom`,value:function(e){return e?typeof e==`number`?this.animate({ratio:this.ratio/e}):this.animate({ratio:this.ratio/(e.factor||ir)},e):this.animate({ratio:this.ratio/ir})}},{key:`animatedUnzoom`,value:function(e){return e?typeof e==`number`?this.animate({ratio:this.ratio*e}):this.animate({ratio:this.ratio*(e.factor||ir)},e):this.animate({ratio:this.ratio*ir})}},{key:`animatedReset`,value:function(e){return this.animate({x:.5,y:.5,ratio:1,angle:0},e)}},{key:`copy`,value:function(){return t.from(this.getState())}}],[{key:`from`,value:function(e){return new t().setState(e)}}])}(jn);function $(e,t){var n=t.getBoundingClientRect();return{x:e.clientX-n.left,y:e.clientY-n.top}}function or(e,t){var n=Z(Z({},$(e,t)),{},{sigmaDefaultPrevented:!1,preventSigmaDefault:function(){n.sigmaDefaultPrevented=!0},original:e});return n}function sr(e){var t=`x`in e?e:Z(Z({},e.touches[0]||e.previousTouches[0]),{},{original:e.original,sigmaDefaultPrevented:e.sigmaDefaultPrevented,preventSigmaDefault:function(){e.sigmaDefaultPrevented=!0,t.sigmaDefaultPrevented=!0}});return t}function cr(e,t){return Z(Z({},or(e,t)),{},{delta:fr(e)})}var lr=2;function ur(e){for(var t=[],n=0,r=Math.min(e.length,lr);n0;t.draggedEvents=0,e&&t.renderer.getSetting(`hideEdgesOnMove`)&&t.renderer.refresh()},0),this.emit(`mouseup`,or(e,this.container))}}},{key:`handleMove`,value:function(e){var t=this;if(this.enabled){var n=or(e,this.container);if(this.emit(`mousemovebody`,n),(e.target===this.container||e.composedPath()[0]===this.container)&&this.emit(`mousemove`,n),!n.sigmaDefaultPrevented&&this.isMouseDown){this.isMoving=!0,this.draggedEvents++,typeof this.movingTimeout==`number`&&clearTimeout(this.movingTimeout),this.movingTimeout=window.setTimeout(function(){t.movingTimeout=null,t.isMoving=!1},this.settings.dragTimeout);var r=this.renderer.getCamera(),i=$(e,this.container),a=i.x,o=i.y,s=this.renderer.viewportToFramedGraph({x:this.lastMouseX,y:this.lastMouseY}),c=this.renderer.viewportToFramedGraph({x:a,y:o}),l=s.x-c.x,u=s.y-c.y,d=r.getState(),f=d.x+l,p=d.y+u;r.setState({x:f,y:p}),this.lastMouseX=a,this.lastMouseY=o,e.preventDefault(),e.stopPropagation()}}}},{key:`handleLeave`,value:function(e){this.emit(`mouseleave`,or(e,this.container))}},{key:`handleEnter`,value:function(e){this.emit(`mouseenter`,or(e,this.container))}},{key:`handleWheel`,value:function(e){var t=this,n=this.renderer.getCamera();if(!(!this.enabled||!n.enabledZooming)){var r=fr(e);if(r){var i=cr(e,this.container);if(this.emit(`wheel`,i),i.sigmaDefaultPrevented){e.preventDefault(),e.stopPropagation();return}var a=n.getState().ratio,o=r>0?1/this.settings.zoomingRatio:this.settings.zoomingRatio,s=n.getBoundedRatio(a*o),c=r>0?1:-1,l=Date.now();a!==s&&(e.preventDefault(),e.stopPropagation(),!(this.currentWheelDirection===c&&this.lastWheelTriggerTime&&l-this.lastWheelTriggerTimet.size?-1:e.sizet.key?1:-1}}])}(),Tr=function(){function e(){K(this,e),X(this,`width`,0),X(this,`height`,0),X(this,`cellSize`,0),X(this,`columns`,0),X(this,`rows`,0),X(this,`cells`,{})}return q(e,[{key:`resizeAndClear`,value:function(e,t){this.width=e.width,this.height=e.height,this.cellSize=t,this.columns=Math.ceil(e.width/t),this.rows=Math.ceil(e.height/t),this.cells={}}},{key:`getIndex`,value:function(e){var t=Math.floor(e.x/this.cellSize);return Math.floor(e.y/this.cellSize)*this.columns+t}},{key:`add`,value:function(e,t,n){var r=new wr(e,t),i=this.getIndex(n),a=this.cells[i];a||(a=[],this.cells[i]=a),a.push(r)}},{key:`organize`,value:function(){for(var e in this.cells)this.cells[e].sort(wr.compare)}},{key:`getLabelsToDisplay`,value:function(e,t){var n=this.cellSize*this.cellSize,r=n/e/e*t/n,i=Math.ceil(r),a=[];for(var o in this.cells)for(var s=this.cells[o],c=0;c2&&arguments[2]!==void 0?arguments[2]:{};if(K(this,t),r=J(this,t),X(r,`elements`,{}),X(r,`canvasContexts`,{}),X(r,`webGLContexts`,{}),X(r,`pickingLayers`,new Set),X(r,`textures`,{}),X(r,`frameBuffers`,{}),X(r,`activeListeners`,{}),X(r,`labelGrid`,new Tr),X(r,`nodeDataCache`,{}),X(r,`edgeDataCache`,{}),X(r,`nodeProgramIndex`,{}),X(r,`edgeProgramIndex`,{}),X(r,`nodesWithForcedLabels`,new Set),X(r,`edgesWithForcedLabels`,new Set),X(r,`nodeExtent`,{x:[0,1],y:[0,1]}),X(r,`nodeZExtent`,[1/0,-1/0]),X(r,`edgeZExtent`,[1/0,-1/0]),X(r,`matrix`,Q()),X(r,`invMatrix`,Q()),X(r,`correctionRatio`,1),X(r,`customBBox`,null),X(r,`normalizationFunction`,Yn({x:[0,1],y:[0,1]})),X(r,`graphToViewportRatio`,1),X(r,`itemIDsIndex`,{}),X(r,`nodeIndices`,{}),X(r,`edgeIndices`,{}),X(r,`width`,0),X(r,`height`,0),X(r,`pixelRatio`,qn()),X(r,`pickingDownSizingRatio`,2*r.pixelRatio),X(r,`displayedNodeLabels`,new Set),X(r,`displayedEdgeLabels`,new Set),X(r,`highlightedNodes`,new Set),X(r,`hoveredNode`,null),X(r,`hoveredEdge`,null),X(r,`renderFrame`,null),X(r,`renderHighlightedNodesFrame`,null),X(r,`needToProcess`,!1),X(r,`checkEdgesEventsFrame`,null),X(r,`nodePrograms`,{}),X(r,`nodeHoverPrograms`,{}),X(r,`edgePrograms`,{}),r.settings=rr(i),nr(r.settings),Gn(e),!(n instanceof HTMLElement))throw Error(`Sigma: container should be an html element.`);for(var a in r.graph=e,r.container=n,r.createWebGLContext(`edges`,{picking:i.enableEdgeEvents}),r.createCanvasContext(`edgeLabels`),r.createWebGLContext(`nodes`,{picking:!0}),r.createCanvasContext(`labels`),r.createCanvasContext(`hovers`),r.createWebGLContext(`hoverNodes`),r.createCanvasContext(`mouse`,{style:{touchAction:`none`,userSelect:`none`}}),r.resize(),r.settings.nodeProgramClasses)r.registerNodeProgram(a,r.settings.nodeProgramClasses[a],r.settings.nodeHoverProgramClasses[a]);for(var o in r.settings.edgeProgramClasses)r.registerEdgeProgram(o,r.settings.edgeProgramClasses[o]);return r.camera=new ar,r.bindCameraHandlers(),r.mouseCaptor=new hr(r.elements.mouse,r),r.mouseCaptor.setSettings(r.settings),r.touchCaptor=new _r(r.elements.mouse,r),r.touchCaptor.setSettings(r.settings),r.bindEventHandlers(),r.bindGraphHandlers(),r.handleSettingsUpdate(),r.refresh(),r}return Y(t,e),q(t,[{key:`registerNodeProgram`,value:function(e,t,n){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new t(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(n||t)(this.webGLContexts.hoverNodes,null,this),this}},{key:`registerEdgeProgram`,value:function(e,t){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new t(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:`unregisterNodeProgram`,value:function(e){if(this.nodePrograms[e]){var t=this.nodePrograms,n=t[e],r=Cr(t,[e].map(at));n.kill(),this.nodePrograms=r}if(this.nodeHoverPrograms[e]){var i=this.nodeHoverPrograms,a=i[e],o=Cr(i,[e].map(at));a.kill(),this.nodePrograms=o}return this}},{key:`unregisterEdgeProgram`,value:function(e){if(this.edgePrograms[e]){var t=this.edgePrograms,n=t[e],r=Cr(t,[e].map(at));n.kill(),this.edgePrograms=r}return this}},{key:`resetWebGLTexture`,value:function(e){var t=this.webGLContexts[e],n=this.frameBuffers[e],r=this.textures[e];r&&t.deleteTexture(r);var i=t.createTexture();return t.bindFramebuffer(t.FRAMEBUFFER,n),t.bindTexture(t.TEXTURE_2D,i),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.width,this.height,0,t.RGBA,t.UNSIGNED_BYTE,null),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,i,0),this.textures[e]=i,this}},{key:`bindCameraHandlers`,value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on(`updated`,this.activeListeners.camera),this}},{key:`unbindCameraHandlers`,value:function(){return this.camera.removeListener(`updated`,this.activeListeners.camera),this}},{key:`getNodeAtPosition`,value:function(e){var t=e.x,n=e.y,r=Mt(this.webGLContexts.nodes,this.frameBuffers.nodes,t,n,this.pixelRatio,this.pickingDownSizingRatio),i=jt.apply(void 0,xr(r)),a=this.itemIDsIndex[i];return a&&a.type===`node`?a.id:null}},{key:`bindEventHandlers`,value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener(`resize`,this.activeListeners.handleResize),this.activeListeners.handleMove=function(t){var n=sr(t),r={event:n,preventSigmaDefault:function(){n.preventSigmaDefault()}},i=e.getNodeAtPosition(n);if(i&&e.hoveredNode!==i&&!e.nodeDataCache[i].hidden){e.hoveredNode&&e.emit(`leaveNode`,Z(Z({},r),{},{node:e.hoveredNode})),e.hoveredNode=i,e.emit(`enterNode`,Z(Z({},r),{},{node:i})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(n)!==e.hoveredNode){var a=e.hoveredNode;e.hoveredNode=null,e.emit(`leaveNode`,Z(Z({},r),{},{node:a})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var o=e.hoveredNode?null:e.getEdgeAtPoint(r.event.x,r.event.y);o!==e.hoveredEdge&&(e.hoveredEdge&&e.emit(`leaveEdge`,Z(Z({},r),{},{edge:e.hoveredEdge})),o&&e.emit(`enterEdge`,Z(Z({},r),{},{edge:o})),e.hoveredEdge=o)}},this.activeListeners.handleMoveBody=function(t){var n=sr(t);e.emit(`moveBody`,{event:n,preventSigmaDefault:function(){n.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(t){var n=sr(t),r={event:n,preventSigmaDefault:function(){n.preventSigmaDefault()}};e.hoveredNode&&(e.emit(`leaveNode`,Z(Z({},r),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit(`leaveEdge`,Z(Z({},r),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit(`leaveStage`,Z({},r))},this.activeListeners.handleEnter=function(t){var n=sr(t),r={event:n,preventSigmaDefault:function(){n.preventSigmaDefault()}};e.emit(`enterStage`,Z({},r))};var t=function(t){return function(n){var r=sr(n),i={event:r,preventSigmaDefault:function(){r.preventSigmaDefault()}},a=e.getNodeAtPosition(r);if(a)return e.emit(`${t}Node`,Z(Z({},i),{},{node:a}));if(e.settings.enableEdgeEvents){var o=e.getEdgeAtPoint(r.x,r.y);if(o)return e.emit(`${t}Edge`,Z(Z({},i),{},{edge:o}))}return e.emit(`${t}Stage`,i)}};return this.activeListeners.handleClick=t(`click`),this.activeListeners.handleRightClick=t(`rightClick`),this.activeListeners.handleDoubleClick=t(`doubleClick`),this.activeListeners.handleWheel=t(`wheel`),this.activeListeners.handleDown=t(`down`),this.activeListeners.handleUp=t(`up`),this.mouseCaptor.on(`mousemove`,this.activeListeners.handleMove),this.mouseCaptor.on(`mousemovebody`,this.activeListeners.handleMoveBody),this.mouseCaptor.on(`click`,this.activeListeners.handleClick),this.mouseCaptor.on(`rightClick`,this.activeListeners.handleRightClick),this.mouseCaptor.on(`doubleClick`,this.activeListeners.handleDoubleClick),this.mouseCaptor.on(`wheel`,this.activeListeners.handleWheel),this.mouseCaptor.on(`mousedown`,this.activeListeners.handleDown),this.mouseCaptor.on(`mouseup`,this.activeListeners.handleUp),this.mouseCaptor.on(`mouseleave`,this.activeListeners.handleLeave),this.mouseCaptor.on(`mouseenter`,this.activeListeners.handleEnter),this.touchCaptor.on(`touchdown`,this.activeListeners.handleDown),this.touchCaptor.on(`touchdown`,this.activeListeners.handleMove),this.touchCaptor.on(`touchup`,this.activeListeners.handleUp),this.touchCaptor.on(`touchmove`,this.activeListeners.handleMove),this.touchCaptor.on(`tap`,this.activeListeners.handleClick),this.touchCaptor.on(`doubletap`,this.activeListeners.handleDoubleClick),this.touchCaptor.on(`touchmove`,this.activeListeners.handleMoveBody),this}},{key:`bindGraphHandlers`,value:function(){var e=this,t=this.graph,n=new Set([`x`,`y`,`zIndex`,`type`]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(r){var i=r.hints?.attributes;e.graph.forEachNode(function(t){return e.updateNode(t)});var a=!i||i.some(function(e){return n.has(e)});e.refresh({partialGraph:{nodes:t.nodes()},skipIndexation:!a,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(n){var r=n.hints?.attributes;e.graph.forEachEdge(function(t){return e.updateEdge(t)});var i=r&&[`zIndex`,`type`].some(function(e){return r?.includes(e)});e.refresh({partialGraph:{edges:t.edges()},skipIndexation:!i,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(t){var n=t.key;e.addNode(n),e.refresh({partialGraph:{nodes:[n]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(t){var n=t.key;e.refresh({partialGraph:{nodes:[n]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(t){var n=t.key;e.removeNode(n),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(t){var n=t.key;e.addEdge(n),e.refresh({partialGraph:{edges:[n]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(t){var n=t.key;e.refresh({partialGraph:{edges:[n]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(t){var n=t.key;e.removeEdge(n),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},t.on(`nodeAdded`,this.activeListeners.addNodeGraphUpdate),t.on(`nodeDropped`,this.activeListeners.dropNodeGraphUpdate),t.on(`nodeAttributesUpdated`,this.activeListeners.updateNodeGraphUpdate),t.on(`eachNodeAttributesUpdated`,this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),t.on(`edgeAdded`,this.activeListeners.addEdgeGraphUpdate),t.on(`edgeDropped`,this.activeListeners.dropEdgeGraphUpdate),t.on(`edgeAttributesUpdated`,this.activeListeners.updateEdgeGraphUpdate),t.on(`eachEdgeAttributesUpdated`,this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),t.on(`edgesCleared`,this.activeListeners.clearEdgesGraphUpdate),t.on(`cleared`,this.activeListeners.clearGraphUpdate),this}},{key:`unbindGraphHandlers`,value:function(){var e=this.graph;e.removeListener(`nodeAdded`,this.activeListeners.addNodeGraphUpdate),e.removeListener(`nodeDropped`,this.activeListeners.dropNodeGraphUpdate),e.removeListener(`nodeAttributesUpdated`,this.activeListeners.updateNodeGraphUpdate),e.removeListener(`eachNodeAttributesUpdated`,this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener(`edgeAdded`,this.activeListeners.addEdgeGraphUpdate),e.removeListener(`edgeDropped`,this.activeListeners.dropEdgeGraphUpdate),e.removeListener(`edgeAttributesUpdated`,this.activeListeners.updateEdgeGraphUpdate),e.removeListener(`eachEdgeAttributesUpdated`,this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener(`edgesCleared`,this.activeListeners.clearEdgesGraphUpdate),e.removeListener(`cleared`,this.activeListeners.clearGraphUpdate)}},{key:`getEdgeAtPoint`,value:function(e,t){var n=Mt(this.webGLContexts.edges,this.frameBuffers.edges,e,t,this.pixelRatio,this.pickingDownSizingRatio),r=jt.apply(void 0,xr(n)),i=this.itemIDsIndex[r];return i&&i.type===`edge`?i.id:null}},{key:`process`,value:function(){var e=this;this.emit(`beforeProcess`);var t=this.graph,n=this.settings,r=this.getDimensions();if(this.nodeExtent=Wn(this.graph),!this.settings.autoRescale){var i=r.width,a=r.height,o=this.nodeExtent,s=o.x,c=o.y;this.nodeExtent={x:[(s[0]+s[1])/2-i/2,(s[0]+s[1])/2+i/2],y:[(c[0]+c[1])/2-a/2,(c[0]+c[1])/2+a/2]}}this.normalizationFunction=Yn(this.customBBox||this.nodeExtent);var l=Hn(new ar().getState(),r,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(r,n.labelGridCellSize);for(var u={},d={},f={},p={},m=1,h=t.nodes(),g=0,_=h.length;g<_;g++){var v=h[g],y=this.nodeDataCache[v],b=t.getNodeAttributes(v);y.x=b.x,y.y=b.y,this.normalizationFunction.applyTo(y),typeof y.label==`string`&&!y.hidden&&this.labelGrid.add(v,y.size,this.framedGraphToViewport(y,{matrix:l})),u[y.type]=(u[y.type]||0)+1}for(var x in this.labelGrid.organize(),this.nodePrograms){if(!kr.call(this.nodePrograms,x))throw Error(`Sigma: could not find a suitable program for node type "${x}"!`);this.nodePrograms[x].reallocate(u[x]||0),u[x]=0}this.settings.zIndex&&this.nodeZExtent[0]!==this.nodeZExtent[1]&&(h=Jn(this.nodeZExtent,function(t){return e.nodeDataCache[t].zIndex},h));for(var S=0,C=h.length;S1&&arguments[1]!==void 0?arguments[1]:{},n=t.tolerance,r=n===void 0?0:n,i=t.boundaries,a=Z({},e),o=i||this.nodeExtent,s=_t(o.x,2),c=s[0],l=s[1],u=_t(o.y,2),d=u[0],f=u[1],p=[this.graphToViewport({x:c,y:d},{cameraState:e}),this.graphToViewport({x:l,y:d},{cameraState:e}),this.graphToViewport({x:c,y:f},{cameraState:e}),this.graphToViewport({x:l,y:f},{cameraState:e})],m=1/0,h=-1/0,g=1/0,_=-1/0;p.forEach(function(e){var t=e.x,n=e.y;m=Math.min(m,t),h=Math.max(h,t),g=Math.min(g,n),_=Math.max(_,n)});var v=h-m,y=_-g,b=this.getDimensions(),x=b.width,S=b.height,C=0,w=0;if(v>=x?hr&&(C=m-r):h>x+r?C=h-(x+r):m<-r&&(C=m+r),y>=S?_r&&(w=g-r):_>S+r?w=_-(S+r):g<-r&&(w=g+r),C||w){var T=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),E=this.viewportToFramedGraph({x:C,y:w},{cameraState:e});C=E.x-T.x,w=E.y-T.y,a.x+=C,a.y+=w}return a}},{key:`renderLabels`,value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),t=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);Zn(t,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var n=this.canvasContexts.labels,r=0,i=t.length;rthis.width+Dr||l<-Or||l>this.height+Or)){this.displayedNodeLabels.add(a);var d=this.settings.defaultDrawNodeLabel;(this.nodePrograms[o.type]?.drawLabel||d)(n,Z(Z({key:a},o),{},{size:u,x:c,y:l}),this.settings)}}}return this}},{key:`renderEdgeLabels`,value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var t=Er({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});Zn(t,this.edgesWithForcedLabels);for(var n=new Set,r=0,i=t.length;rthis.nodeZExtent[1]&&(this.nodeZExtent[1]=n.zIndex))}},{key:`updateNode`,value:function(e){this.addNode(e);var t=this.nodeDataCache[e];this.normalizationFunction.applyTo(t)}},{key:`removeNode`,value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:`addEdge`,value:function(e){var t=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(t=this.settings.edgeReducer(e,t));var n=jr(this.settings,e,t);this.edgeDataCache[e]=n,this.edgesWithForcedLabels.delete(e),n.forceLabel&&!n.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(n.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=n.zIndex))}},{key:`updateEdge`,value:function(e){this.addEdge(e)}},{key:`removeEdge`,value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:`clearNodeIndices`,value:function(){this.labelGrid=new Tr,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:`clearEdgeIndices`,value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:`clearIndices`,value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:`clearNodeState`,value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:`clearEdgeState`,value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:`clearState`,value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:`addNodeToProgram`,value:function(e,t,n){var r=this.nodeDataCache[e],i=this.nodePrograms[r.type];if(!i)throw Error(`Sigma: could not find a suitable program for node type "${r.type}"!`);i.process(t,n,r),this.nodeProgramIndex[e]=n}},{key:`addEdgeToProgram`,value:function(e,t,n){var r=this.edgeDataCache[e],i=this.edgePrograms[r.type];if(!i)throw Error(`Sigma: could not find a suitable program for edge type "${r.type}"!`);var a=this.graph.extremities(e),o=this.nodeDataCache[a[0]],s=this.nodeDataCache[a[1]];i.process(t,n,o,s,r),this.edgeProgramIndex[e]=n}},{key:`getRenderParams`,value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:`getStagePadding`,value:function(){var e=this.settings,t=e.stagePadding;return e.autoRescale&&t||0}},{key:`createLayer`,value:function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw Error(`Sigma: a layer named "${e}" already exists`);var r=Kn(t,{position:`absolute`},{class:`sigma-${e}`});return n.style&&Object.assign(r.style,n.style),this.elements[e]=r,`beforeLayer`in n&&n.beforeLayer?this.elements[n.beforeLayer].before(r):`afterLayer`in n&&n.afterLayer?this.elements[n.afterLayer].after(r):this.container.appendChild(r),r}},{key:`createCanvas`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,`canvas`,t)}},{key:`createCanvasContext`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=this.createCanvas(e,t),r={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=n.getContext(`2d`,r),this}},{key:`createWebGLContext`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=t?.canvas||this.createCanvas(e,t);t.hidden&&n.remove();var r=Z({preserveDrawingBuffer:!1,antialias:!1},t),i=n.getContext(`webgl2`,r);i||=n.getContext(`webgl`,r),i||=n.getContext(`experimental-webgl`,r);var a=i;if(this.webGLContexts[e]=a,a.blendFunc(a.ONE,a.ONE_MINUS_SRC_ALPHA),t.picking){this.pickingLayers.add(e);var o=a.createFramebuffer();if(!o)throw Error(`Sigma: cannot create a new frame buffer for layer ${e}`);this.frameBuffers[e]=o}return a}},{key:`killLayer`,value:function(e){var t=this.elements[e];if(!t)throw Error(`Sigma: cannot kill layer ${e}, which does not exist`);if(this.webGLContexts[e]){var n;(n=this.webGLContexts[e].getExtension(`WEBGL_lose_context`))==null||n.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return t.remove(),delete this.elements[e],this}},{key:`getCamera`,value:function(){return this.camera}},{key:`setCamera`,value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:`getContainer`,value:function(){return this.container}},{key:`getGraph`,value:function(){return this.graph}},{key:`setGraph`,value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:`getMouseCaptor`,value:function(){return this.mouseCaptor}},{key:`getTouchCaptor`,value:function(){return this.touchCaptor}},{key:`getDimensions`,value:function(){return{width:this.width,height:this.height}}},{key:`getGraphDimensions`,value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:`getNodeDisplayData`,value:function(e){var t=this.nodeDataCache[e];return t?Object.assign({},t):void 0}},{key:`getEdgeDisplayData`,value:function(e){var t=this.edgeDataCache[e];return t?Object.assign({},t):void 0}},{key:`getNodeDisplayedLabels`,value:function(){return new Set(this.displayedNodeLabels)}},{key:`getEdgeDisplayedLabels`,value:function(){return new Set(this.displayedEdgeLabels)}},{key:`getSettings`,value:function(){return Z({},this.settings)}},{key:`getSetting`,value:function(e){return this.settings[e]}},{key:`setSetting`,value:function(e,t){var n=Z({},this.settings);return this.settings[e]=t,nr(this.settings),this.handleSettingsUpdate(n),this.scheduleRefresh(),this}},{key:`updateSetting`,value:function(e,t){return this.setSetting(e,t(this.settings[e])),this}},{key:`setSettings`,value:function(e){var t=Z({},this.settings);return this.settings=Z(Z({},this.settings),e),nr(this.settings),this.handleSettingsUpdate(t),this.scheduleRefresh(),this}},{key:`resize`,value:function(e){var t=this.width,n=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=qn(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw Error(`Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.`);if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw Error(`Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.`);if(!e&&t===this.width&&n===this.height)return this;for(var r in this.elements){var i=this.elements[r];i.style.width=this.width+`px`,i.style.height=this.height+`px`}for(var a in this.canvasContexts)this.elements[a].setAttribute(`width`,this.width*this.pixelRatio+`px`),this.elements[a].setAttribute(`height`,this.height*this.pixelRatio+`px`),this.pixelRatio!==1&&this.canvasContexts[a].scale(this.pixelRatio,this.pixelRatio);for(var o in this.webGLContexts){this.elements[o].setAttribute(`width`,this.width*this.pixelRatio+`px`),this.elements[o].setAttribute(`height`,this.height*this.pixelRatio+`px`);var s=this.webGLContexts[o];if(s.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(o)){var c=this.textures[o];c&&s.deleteTexture(c)}}return this.emit(`resize`),this}},{key:`clear`,value:function(){return this.emit(`beforeClear`),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit(`afterClear`),this}},{key:`refresh`,value:function(e){var t=this,n=e?.skipIndexation===void 0?!1:e?.skipIndexation,r=e?.schedule===void 0?!1:e.schedule,i=!e||!e.partialGraph;if(i)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(e){return t.addNode(e)}),this.graph.forEachEdge(function(e){return t.addEdge(e)});else{for(var a,o=e.partialGraph?.nodes||[],s=0,c=o?.length||0;s1&&arguments[1]!==void 0?arguments[1]:{},n=!!t.cameraState||!!t.viewportDimensions||!!t.graphDimensions,r=Bn(t.matrix?t.matrix:n?Hn(t.cameraState||this.camera.getState(),t.viewportDimensions||this.getDimensions(),t.graphDimensions||this.getGraphDimensions(),t.padding||this.getStagePadding()):this.matrix,e);return{x:(1+r.x)*this.width/2,y:(1-r.y)*this.height/2}}},{key:`viewportToFramedGraph`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=!!t.cameraState||!!t.viewportDimensions||!t.graphDimensions,r=Bn(t.matrix?t.matrix:n?Hn(t.cameraState||this.camera.getState(),t.viewportDimensions||this.getDimensions(),t.graphDimensions||this.getGraphDimensions(),t.padding||this.getStagePadding(),!0):this.invMatrix,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(r.x)&&(r.x=0),isNaN(r.y)&&(r.y=0),r}},{key:`viewportToGraph`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,t))}},{key:`graphToViewport`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),t)}},{key:`getGraphToViewportRatio`,value:function(){var e={x:0,y:0},t={x:1,y:1},n=Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2),r=this.graphToViewport(e),i=this.graphToViewport(t);return Math.sqrt((r.x-i.x)**2+(r.y-i.y)**2)/n}},{key:`getBBox`,value:function(){return this.nodeExtent}},{key:`getCustomBBox`,value:function(){return this.customBBox}},{key:`setCustomBBox`,value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:`kill`,value:function(){this.emit(`kill`),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener(`resize`,this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&=(cancelAnimationFrame(this.renderFrame),null),this.renderHighlightedNodesFrame&&=(cancelAnimationFrame(this.renderHighlightedNodesFrame),null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var t in this.nodePrograms)this.nodePrograms[t].kill();for(var n in this.nodeHoverPrograms)this.nodeHoverPrograms[n].kill();for(var r in this.edgePrograms)this.edgePrograms[r].kill();for(var i in this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={},this.elements)this.killLayer(i);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:`scaleSize`,value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(t)*(this.getSetting(`itemSizesReference`)===`positions`?t*this.graphToViewportRatio:1)}},{key:`getCanvases`,value:function(){var e={};for(var t in this.elements)this.elements[t]instanceof HTMLCanvasElement&&(e[t]=this.elements[t]);return e}}])}(jn),Nr=t(((e,t)=>{t.exports=function(){var e,t,n={};(function(){var e=0,t=1,r=2,i=3,a=4,o=5,s=6,c=7,l=8,u=9,d=0,f=1,p=2,m=0,h=1,g=2,_=3,v=4,y=5,b=6,x=7,S=8,C=3,w=10,T=3,E=9,D=10;n.exports=function(n,O,ee){var te,k,A,j,M,N,ne,P,F,re,I=O.length,ie=ee.length,ae=n.adjustSizes,oe=n.barnesHutTheta*n.barnesHutTheta,se,L,R,z,B,V,H,U=[];for(A=0;Ahe?(le-=(me-he)/2,ue=le+me):(W-=(he-me)/2,ce=W+he),U[0+m]=-1,U[0+h]=(W+ce)/2,U[0+g]=(le+ue)/2,U[0+_]=Math.max(ce-W,ue-le),U[0+v]=-1,U[0+y]=-1,U[0+b]=0,U[0+x]=0,U[0+S]=0,te=1,A=0;A=0){de=O[A+e]=0)if(V=(O[A+e]-U[k+x])**2+(O[A+t]-U[k+S])**2,re=U[k+_],4*re*re/V0?(H=L*O[A+s]*U[k+b]/V,O[A+r]+=R*H,O[A+i]+=z*H):V<0&&(H=-L*O[A+s]*U[k+b]/Math.sqrt(V),O[A+r]+=R*H,O[A+i]+=z*H):V>0&&(H=L*O[A+s]*U[k+b]/V,O[A+r]+=R*H,O[A+i]+=z*H),k=U[k+v],k<0)break;continue}else{k=U[k+y];continue}else{if(N=U[k+m],N>=0&&N!==A&&(R=O[A+e]-O[N+e],z=O[A+t]-O[N+t],V=R*R+z*z,ae===!0?V>0?(H=L*O[A+s]*O[N+s]/V,O[A+r]+=R*H,O[A+i]+=z*H):V<0&&(H=-L*O[A+s]*O[N+s]/Math.sqrt(V),O[A+r]+=R*H,O[A+i]+=z*H):V>0&&(H=L*O[A+s]*O[N+s]/V,O[A+r]+=R*H,O[A+i]+=z*H)),k=U[k+v],k<0)break;continue}else for(L=n.scalingRatio,j=0;j0?(H=L*O[j+s]*O[M+s]/V/V,O[j+r]+=R*H,O[j+i]+=z*H,O[M+r]-=R*H,O[M+i]-=z*H):V<0&&(H=100*L*O[j+s]*O[M+s],O[j+r]+=R*H,O[j+i]+=z*H,O[M+r]-=R*H,O[M+i]-=z*H)):(V=Math.sqrt(R*R+z*z),V>0&&(H=L*O[j+s]*O[M+s]/V/V,O[j+r]+=R*H,O[j+i]+=z*H,O[M+r]-=R*H,O[M+i]-=z*H));for(F=n.gravity/n.scalingRatio,L=n.scalingRatio,A=0;A0&&(H=L*O[A+s]*F):V>0&&(H=L*O[A+s]*F/V),O[A+r]-=R*H,O[A+i]-=z*H;for(L=1*(n.outboundAttractionDistribution?se:1),ne=0;ne0&&(H=-L*B*Math.log(1+V)/V/O[j+s]):V>0&&(H=-L*B*Math.log(1+V)/V):n.outboundAttractionDistribution?V>0&&(H=-L*B/O[j+s]):V>0&&(H=-L*B)):(V=Math.sqrt(R**2+z**2),n.linLogMode?n.outboundAttractionDistribution?V>0&&(H=-L*B*Math.log(1+V)/V/O[j+s]):V>0&&(H=-L*B*Math.log(1+V)/V):n.outboundAttractionDistribution?(V=1,H=-L*B/O[j+s]):(V=1,H=-L*B)),V>0&&(O[j+r]+=R*H,O[j+i]+=z*H,O[M+r]-=R*H,O[M+i]-=z*H);var ge,_e,ve,ye,be,xe;if(ae===!0)for(A=0;AD&&(O[A+r]=O[A+r]*D/ge,O[A+i]=O[A+i]*D/ge),_e=O[A+s]*Math.sqrt((O[A+a]-O[A+r])*(O[A+a]-O[A+r])+(O[A+o]-O[A+i])*(O[A+o]-O[A+i])),ve=Math.sqrt((O[A+a]+O[A+r])*(O[A+a]+O[A+r])+(O[A+o]+O[A+i])*(O[A+o]+O[A+i]))/2,ye=.1*Math.log(1+ve)/(1+Math.sqrt(_e)),be=O[A+e]+O[A+r]*(ye/n.slowDown),O[A+e]=be,xe=O[A+t]+O[A+i]*(ye/n.slowDown),O[A+t]=xe);else for(A=0;A{function t(e){return typeof e!=`number`||isNaN(e)?1:e}function n(e,t){var n={},r=function(e){return e===void 0?t:e};typeof t==`function`&&(r=t);var i=function(t){return r(t[e])},a=function(){return r(void 0)};return typeof e==`string`?(n.fromAttributes=i,n.fromGraph=function(e,t){return i(e.getNodeAttributes(t))},n.fromEntry=function(e,t){return i(t)}):typeof e==`function`?(n.fromAttributes=function(){throw Error(`graphology-utils/getters/createNodeValueGetter: irrelevant usage.`)},n.fromGraph=function(t,n){return r(e(n,t.getNodeAttributes(n)))},n.fromEntry=function(t,n){return r(e(t,n))}):(n.fromAttributes=a,n.fromGraph=a,n.fromEntry=a),n}function r(e,t){var n={},r=function(e){return e===void 0?t:e};typeof t==`function`&&(r=t);var i=function(t){return r(t[e])},a=function(){return r(void 0)};return typeof e==`string`?(n.fromAttributes=i,n.fromGraph=function(e,t){return i(e.getEdgeAttributes(t))},n.fromEntry=function(e,t){return i(t)},n.fromPartialEntry=n.fromEntry,n.fromMinimalEntry=n.fromEntry):typeof e==`function`?(n.fromAttributes=function(){throw Error(`graphology-utils/getters/createEdgeValueGetter: irrelevant usage.`)},n.fromGraph=function(t,n){var i=t.extremities(n);return r(e(n,t.getEdgeAttributes(n),i[0],i[1],t.getNodeAttributes(i[0]),t.getNodeAttributes(i[1]),t.isUndirected(n)))},n.fromEntry=function(t,n,i,a,o,s,c){return r(e(t,n,i,a,o,s,c))},n.fromPartialEntry=function(t,n,i,a){return r(e(t,n,i,a))},n.fromMinimalEntry=function(t,n){return r(e(t,n))}):(n.fromAttributes=a,n.fromGraph=a,n.fromEntry=a,n.fromMinimalEntry=a),n}e.createNodeValueGetter=n,e.createEdgeValueGetter=r,e.createEdgeWeightGetter=function(e){return r(e,t)}})),Fr=t((e=>{var t=10,n=3;e.assign=function(e){e||={};var t=Array.prototype.slice.call(arguments).slice(1),n,r,i;for(n=0,i=t.length;n=0)?{message:"the `scalingRatio` setting should be a number >= 0."}:`strongGravityMode`in e&&typeof e.strongGravityMode!=`boolean`?{message:"the `strongGravityMode` setting should be a boolean."}:`gravity`in e&&!(typeof e.gravity==`number`&&e.gravity>=0)?{message:"the `gravity` setting should be a number >= 0."}:`slowDown`in e&&!(typeof e.slowDown==`number`||e.slowDown>=0)?{message:"the `slowDown` setting should be a number >= 0."}:`barnesHutOptimize`in e&&typeof e.barnesHutOptimize!=`boolean`?{message:"the `barnesHutOptimize` setting should be a boolean."}:`barnesHutTheta`in e&&!(typeof e.barnesHutTheta==`number`&&e.barnesHutTheta>=0)?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null},e.graphToByteArrays=function(e,r){var i=e.order,a=e.size,o={},s,c=new Float32Array(i*t),l=new Float32Array(a*n);return s=0,e.forEachNode(function(e,n){o[e]=s,c[s]=n.x,c[s+1]=n.y,c[s+2]=0,c[s+3]=0,c[s+4]=0,c[s+5]=0,c[s+6]=1,c[s+7]=1,c[s+8]=n.size||1,c[s+9]=n.fixed?1:0,s+=t}),s=0,e.forEachEdge(function(e,t,i,a,u,d,f){var p=o[i],m=o[a],h=r(e,t,i,a,u,d,f);c[p+6]+=h,c[m+6]+=h,l[s]=p,l[s+1]=m,l[s+2]=h,s+=n}),{nodes:c,edges:l}},e.assignLayoutChanges=function(e,n,r){var i=0;e.updateEachNodeAttributes(function(e,a){return a.x=n[i],a.y=n[i+1],i+=t,r?r(e,a):a})},e.readGraphPositions=function(e,n){var r=0;e.forEachNode(function(e,i){n[r]=i.x,n[r+1]=i.y,r+=t})},e.collectLayoutChanges=function(e,n,r){for(var i=e.nodes(),a={},o=0,s=0,c=n.length;o{t.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:1,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}})),Lr=t(((e,t)=>{var n=Nr(),r=Mn(),i=Pr().createEdgeWeightGetter,a=Fr(),o=Ir();function s(e,t){if(t||={},!r(e))throw Error(`graphology-layout-forceatlas2/worker: the given graph is not a valid graphology instance.`);var n=i(`getEdgeWeight`in t?t.getEdgeWeight:`weight`).fromEntry,s=a.assign({},o,t.settings),c=a.validateSettings(s);if(c)throw Error(`graphology-layout-forceatlas2/worker: `+c.message);this.worker=null,this.graph=e,this.settings=s,this.getEdgeWeight=n,this.matrices=null,this.running=!1,this.killed=!1,this.outputReducer=typeof t.outputReducer==`function`?t.outputReducer:null,this.handleMessage=this.handleMessage.bind(this);var l=void 0,u=this;this.handleGraphUpdate=function(){u.worker&&u.worker.terminate(),l&&clearTimeout(l),l=setTimeout(function(){l=void 0,u.spawnWorker()},0)},e.on(`nodeAdded`,this.handleGraphUpdate),e.on(`edgeAdded`,this.handleGraphUpdate),e.on(`nodeDropped`,this.handleGraphUpdate),e.on(`edgeDropped`,this.handleGraphUpdate),this.spawnWorker()}s.prototype.isRunning=function(){return this.running},s.prototype.spawnWorker=function(){this.worker&&this.worker.terminate(),this.worker=a.createWorker(n),this.worker.addEventListener(`message`,this.handleMessage),this.running&&(this.running=!1,this.start())},s.prototype.handleMessage=function(e){if(this.running){var t=new Float32Array(e.data.nodes);a.assignLayoutChanges(this.graph,t,this.outputReducer),this.outputReducer&&a.readGraphPositions(this.graph,t),this.matrices.nodes=t,this.askForIterations()}},s.prototype.askForIterations=function(e){var t=this.matrices,n={settings:this.settings,nodes:t.nodes.buffer},r=[t.nodes.buffer];return e&&(n.edges=t.edges.buffer,r.push(t.edges.buffer)),this.worker.postMessage(n,r),this},s.prototype.start=function(){if(this.killed)throw Error(`graphology-layout-forceatlas2/worker.start: layout was killed.`);return this.running?this:(this.matrices=a.graphToByteArrays(this.graph,this.getEdgeWeight),this.running=!0,this.askForIterations(!0),this)},s.prototype.stop=function(){return this.running=!1,this},s.prototype.kill=function(){if(this.killed)return this;this.running=!1,this.killed=!0,this.matrices=null,this.worker.terminate(),this.graph.removeListener(`nodeAdded`,this.handleGraphUpdate),this.graph.removeListener(`edgeAdded`,this.handleGraphUpdate),this.graph.removeListener(`nodeDropped`,this.handleGraphUpdate),this.graph.removeListener(`edgeDropped`,this.handleGraphUpdate)},t.exports=s}));export{Mr as n,G as r,Lr as t}; \ No newline at end of file +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function xr(e){return vr(e)||yr(e)||ht(e)||br()}function Sr(e,t){if(e==null)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)!==-1)continue;n[r]=e[r]}return n}function Cr(e,t){if(e==null)return{};var n,r,i=Sr(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;rt.size?-1:e.sizet.key?1:-1}}])}(),Tr=function(){function e(){K(this,e),X(this,`width`,0),X(this,`height`,0),X(this,`cellSize`,0),X(this,`columns`,0),X(this,`rows`,0),X(this,`cells`,{})}return q(e,[{key:`resizeAndClear`,value:function(e,t){this.width=e.width,this.height=e.height,this.cellSize=t,this.columns=Math.ceil(e.width/t),this.rows=Math.ceil(e.height/t),this.cells={}}},{key:`getIndex`,value:function(e){var t=Math.floor(e.x/this.cellSize);return Math.floor(e.y/this.cellSize)*this.columns+t}},{key:`add`,value:function(e,t,n){var r=new wr(e,t),i=this.getIndex(n),a=this.cells[i];a||(a=[],this.cells[i]=a),a.push(r)}},{key:`organize`,value:function(){for(var e in this.cells)this.cells[e].sort(wr.compare)}},{key:`getLabelsToDisplay`,value:function(e,t){var n=this.cellSize*this.cellSize,r=n/e/e*t/n,i=Math.ceil(r),a=[];for(var o in this.cells)for(var s=this.cells[o],c=0;c2&&arguments[2]!==void 0?arguments[2]:{};if(K(this,t),r=J(this,t),X(r,`elements`,{}),X(r,`canvasContexts`,{}),X(r,`webGLContexts`,{}),X(r,`pickingLayers`,new Set),X(r,`textures`,{}),X(r,`frameBuffers`,{}),X(r,`activeListeners`,{}),X(r,`labelGrid`,new Tr),X(r,`nodeDataCache`,{}),X(r,`edgeDataCache`,{}),X(r,`nodeProgramIndex`,{}),X(r,`edgeProgramIndex`,{}),X(r,`nodesWithForcedLabels`,new Set),X(r,`edgesWithForcedLabels`,new Set),X(r,`nodeExtent`,{x:[0,1],y:[0,1]}),X(r,`nodeZExtent`,[1/0,-1/0]),X(r,`edgeZExtent`,[1/0,-1/0]),X(r,`matrix`,Q()),X(r,`invMatrix`,Q()),X(r,`correctionRatio`,1),X(r,`customBBox`,null),X(r,`normalizationFunction`,Yn({x:[0,1],y:[0,1]})),X(r,`graphToViewportRatio`,1),X(r,`itemIDsIndex`,{}),X(r,`nodeIndices`,{}),X(r,`edgeIndices`,{}),X(r,`width`,0),X(r,`height`,0),X(r,`pixelRatio`,qn()),X(r,`pickingDownSizingRatio`,2*r.pixelRatio),X(r,`displayedNodeLabels`,new Set),X(r,`displayedEdgeLabels`,new Set),X(r,`highlightedNodes`,new Set),X(r,`hoveredNode`,null),X(r,`hoveredEdge`,null),X(r,`renderFrame`,null),X(r,`renderHighlightedNodesFrame`,null),X(r,`needToProcess`,!1),X(r,`checkEdgesEventsFrame`,null),X(r,`nodePrograms`,{}),X(r,`nodeHoverPrograms`,{}),X(r,`edgePrograms`,{}),r.settings=rr(i),nr(r.settings),Gn(e),!(n instanceof HTMLElement))throw Error(`Sigma: container should be an html element.`);for(var a in r.graph=e,r.container=n,r.createWebGLContext(`edges`,{picking:i.enableEdgeEvents}),r.createCanvasContext(`edgeLabels`),r.createWebGLContext(`nodes`,{picking:!0}),r.createCanvasContext(`labels`),r.createCanvasContext(`hovers`),r.createWebGLContext(`hoverNodes`),r.createCanvasContext(`mouse`,{style:{touchAction:`none`,userSelect:`none`}}),r.resize(),r.settings.nodeProgramClasses)r.registerNodeProgram(a,r.settings.nodeProgramClasses[a],r.settings.nodeHoverProgramClasses[a]);for(var o in r.settings.edgeProgramClasses)r.registerEdgeProgram(o,r.settings.edgeProgramClasses[o]);return r.camera=new ar,r.bindCameraHandlers(),r.mouseCaptor=new hr(r.elements.mouse,r),r.mouseCaptor.setSettings(r.settings),r.touchCaptor=new _r(r.elements.mouse,r),r.touchCaptor.setSettings(r.settings),r.bindEventHandlers(),r.bindGraphHandlers(),r.handleSettingsUpdate(),r.refresh(),r}return Y(t,e),q(t,[{key:`registerNodeProgram`,value:function(e,t,n){return this.nodePrograms[e]&&this.nodePrograms[e].kill(),this.nodeHoverPrograms[e]&&this.nodeHoverPrograms[e].kill(),this.nodePrograms[e]=new t(this.webGLContexts.nodes,this.frameBuffers.nodes,this),this.nodeHoverPrograms[e]=new(n||t)(this.webGLContexts.hoverNodes,null,this),this}},{key:`registerEdgeProgram`,value:function(e,t){return this.edgePrograms[e]&&this.edgePrograms[e].kill(),this.edgePrograms[e]=new t(this.webGLContexts.edges,this.frameBuffers.edges,this),this}},{key:`unregisterNodeProgram`,value:function(e){if(this.nodePrograms[e]){var t=this.nodePrograms,n=t[e],r=Cr(t,[e].map(at));n.kill(),this.nodePrograms=r}if(this.nodeHoverPrograms[e]){var i=this.nodeHoverPrograms,a=i[e],o=Cr(i,[e].map(at));a.kill(),this.nodePrograms=o}return this}},{key:`unregisterEdgeProgram`,value:function(e){if(this.edgePrograms[e]){var t=this.edgePrograms,n=t[e],r=Cr(t,[e].map(at));n.kill(),this.edgePrograms=r}return this}},{key:`resetWebGLTexture`,value:function(e){var t=this.webGLContexts[e],n=this.frameBuffers[e],r=this.textures[e];r&&t.deleteTexture(r);var i=t.createTexture();return t.bindFramebuffer(t.FRAMEBUFFER,n),t.bindTexture(t.TEXTURE_2D,i),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.width,this.height,0,t.RGBA,t.UNSIGNED_BYTE,null),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,i,0),this.textures[e]=i,this}},{key:`bindCameraHandlers`,value:function(){var e=this;return this.activeListeners.camera=function(){e.scheduleRender()},this.camera.on(`updated`,this.activeListeners.camera),this}},{key:`unbindCameraHandlers`,value:function(){return this.camera.removeListener(`updated`,this.activeListeners.camera),this}},{key:`getNodeAtPosition`,value:function(e){var t=e.x,n=e.y,r=Mt(this.webGLContexts.nodes,this.frameBuffers.nodes,t,n,this.pixelRatio,this.pickingDownSizingRatio),i=jt.apply(void 0,xr(r)),a=this.itemIDsIndex[i];return a&&a.type===`node`?a.id:null}},{key:`bindEventHandlers`,value:function(){var e=this;this.activeListeners.handleResize=function(){e.scheduleRefresh()},window.addEventListener(`resize`,this.activeListeners.handleResize),this.activeListeners.handleMove=function(t){var n=sr(t),r={event:n,preventSigmaDefault:function(){n.preventSigmaDefault()}},i=e.getNodeAtPosition(n);if(i&&e.hoveredNode!==i&&!e.nodeDataCache[i].hidden){e.hoveredNode&&e.emit(`leaveNode`,Z(Z({},r),{},{node:e.hoveredNode})),e.hoveredNode=i,e.emit(`enterNode`,Z(Z({},r),{},{node:i})),e.scheduleHighlightedNodesRender();return}if(e.hoveredNode&&e.getNodeAtPosition(n)!==e.hoveredNode){var a=e.hoveredNode;e.hoveredNode=null,e.emit(`leaveNode`,Z(Z({},r),{},{node:a})),e.scheduleHighlightedNodesRender();return}if(e.settings.enableEdgeEvents){var o=e.hoveredNode?null:e.getEdgeAtPoint(r.event.x,r.event.y);o!==e.hoveredEdge&&(e.hoveredEdge&&e.emit(`leaveEdge`,Z(Z({},r),{},{edge:e.hoveredEdge})),o&&e.emit(`enterEdge`,Z(Z({},r),{},{edge:o})),e.hoveredEdge=o)}},this.activeListeners.handleMoveBody=function(t){var n=sr(t);e.emit(`moveBody`,{event:n,preventSigmaDefault:function(){n.preventSigmaDefault()}})},this.activeListeners.handleLeave=function(t){var n=sr(t),r={event:n,preventSigmaDefault:function(){n.preventSigmaDefault()}};e.hoveredNode&&(e.emit(`leaveNode`,Z(Z({},r),{},{node:e.hoveredNode})),e.scheduleHighlightedNodesRender()),e.settings.enableEdgeEvents&&e.hoveredEdge&&(e.emit(`leaveEdge`,Z(Z({},r),{},{edge:e.hoveredEdge})),e.scheduleHighlightedNodesRender()),e.emit(`leaveStage`,Z({},r))},this.activeListeners.handleEnter=function(t){var n=sr(t),r={event:n,preventSigmaDefault:function(){n.preventSigmaDefault()}};e.emit(`enterStage`,Z({},r))};var t=function(t){return function(n){var r=sr(n),i={event:r,preventSigmaDefault:function(){r.preventSigmaDefault()}},a=e.getNodeAtPosition(r);if(a)return e.emit(`${t}Node`,Z(Z({},i),{},{node:a}));if(e.settings.enableEdgeEvents){var o=e.getEdgeAtPoint(r.x,r.y);if(o)return e.emit(`${t}Edge`,Z(Z({},i),{},{edge:o}))}return e.emit(`${t}Stage`,i)}};return this.activeListeners.handleClick=t(`click`),this.activeListeners.handleRightClick=t(`rightClick`),this.activeListeners.handleDoubleClick=t(`doubleClick`),this.activeListeners.handleWheel=t(`wheel`),this.activeListeners.handleDown=t(`down`),this.activeListeners.handleUp=t(`up`),this.mouseCaptor.on(`mousemove`,this.activeListeners.handleMove),this.mouseCaptor.on(`mousemovebody`,this.activeListeners.handleMoveBody),this.mouseCaptor.on(`click`,this.activeListeners.handleClick),this.mouseCaptor.on(`rightClick`,this.activeListeners.handleRightClick),this.mouseCaptor.on(`doubleClick`,this.activeListeners.handleDoubleClick),this.mouseCaptor.on(`wheel`,this.activeListeners.handleWheel),this.mouseCaptor.on(`mousedown`,this.activeListeners.handleDown),this.mouseCaptor.on(`mouseup`,this.activeListeners.handleUp),this.mouseCaptor.on(`mouseleave`,this.activeListeners.handleLeave),this.mouseCaptor.on(`mouseenter`,this.activeListeners.handleEnter),this.touchCaptor.on(`touchdown`,this.activeListeners.handleDown),this.touchCaptor.on(`touchdown`,this.activeListeners.handleMove),this.touchCaptor.on(`touchup`,this.activeListeners.handleUp),this.touchCaptor.on(`touchmove`,this.activeListeners.handleMove),this.touchCaptor.on(`tap`,this.activeListeners.handleClick),this.touchCaptor.on(`doubletap`,this.activeListeners.handleDoubleClick),this.touchCaptor.on(`touchmove`,this.activeListeners.handleMoveBody),this}},{key:`bindGraphHandlers`,value:function(){var e=this,t=this.graph,n=new Set([`x`,`y`,`zIndex`,`type`]);return this.activeListeners.eachNodeAttributesUpdatedGraphUpdate=function(r){var i=r.hints?.attributes;e.graph.forEachNode(function(t){return e.updateNode(t)});var a=!i||i.some(function(e){return n.has(e)});e.refresh({partialGraph:{nodes:t.nodes()},skipIndexation:!a,schedule:!0})},this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate=function(n){var r=n.hints?.attributes;e.graph.forEachEdge(function(t){return e.updateEdge(t)});var i=r&&[`zIndex`,`type`].some(function(e){return r?.includes(e)});e.refresh({partialGraph:{edges:t.edges()},skipIndexation:!i,schedule:!0})},this.activeListeners.addNodeGraphUpdate=function(t){var n=t.key;e.addNode(n),e.refresh({partialGraph:{nodes:[n]},skipIndexation:!1,schedule:!0})},this.activeListeners.updateNodeGraphUpdate=function(t){var n=t.key;e.refresh({partialGraph:{nodes:[n]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropNodeGraphUpdate=function(t){var n=t.key;e.removeNode(n),e.refresh({schedule:!0})},this.activeListeners.addEdgeGraphUpdate=function(t){var n=t.key;e.addEdge(n),e.refresh({partialGraph:{edges:[n]},schedule:!0})},this.activeListeners.updateEdgeGraphUpdate=function(t){var n=t.key;e.refresh({partialGraph:{edges:[n]},skipIndexation:!1,schedule:!0})},this.activeListeners.dropEdgeGraphUpdate=function(t){var n=t.key;e.removeEdge(n),e.refresh({schedule:!0})},this.activeListeners.clearEdgesGraphUpdate=function(){e.clearEdgeState(),e.clearEdgeIndices(),e.refresh({schedule:!0})},this.activeListeners.clearGraphUpdate=function(){e.clearEdgeState(),e.clearNodeState(),e.clearEdgeIndices(),e.clearNodeIndices(),e.refresh({schedule:!0})},t.on(`nodeAdded`,this.activeListeners.addNodeGraphUpdate),t.on(`nodeDropped`,this.activeListeners.dropNodeGraphUpdate),t.on(`nodeAttributesUpdated`,this.activeListeners.updateNodeGraphUpdate),t.on(`eachNodeAttributesUpdated`,this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),t.on(`edgeAdded`,this.activeListeners.addEdgeGraphUpdate),t.on(`edgeDropped`,this.activeListeners.dropEdgeGraphUpdate),t.on(`edgeAttributesUpdated`,this.activeListeners.updateEdgeGraphUpdate),t.on(`eachEdgeAttributesUpdated`,this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),t.on(`edgesCleared`,this.activeListeners.clearEdgesGraphUpdate),t.on(`cleared`,this.activeListeners.clearGraphUpdate),this}},{key:`unbindGraphHandlers`,value:function(){var e=this.graph;e.removeListener(`nodeAdded`,this.activeListeners.addNodeGraphUpdate),e.removeListener(`nodeDropped`,this.activeListeners.dropNodeGraphUpdate),e.removeListener(`nodeAttributesUpdated`,this.activeListeners.updateNodeGraphUpdate),e.removeListener(`eachNodeAttributesUpdated`,this.activeListeners.eachNodeAttributesUpdatedGraphUpdate),e.removeListener(`edgeAdded`,this.activeListeners.addEdgeGraphUpdate),e.removeListener(`edgeDropped`,this.activeListeners.dropEdgeGraphUpdate),e.removeListener(`edgeAttributesUpdated`,this.activeListeners.updateEdgeGraphUpdate),e.removeListener(`eachEdgeAttributesUpdated`,this.activeListeners.eachEdgeAttributesUpdatedGraphUpdate),e.removeListener(`edgesCleared`,this.activeListeners.clearEdgesGraphUpdate),e.removeListener(`cleared`,this.activeListeners.clearGraphUpdate)}},{key:`getEdgeAtPoint`,value:function(e,t){var n=Mt(this.webGLContexts.edges,this.frameBuffers.edges,e,t,this.pixelRatio,this.pickingDownSizingRatio),r=jt.apply(void 0,xr(n)),i=this.itemIDsIndex[r];return i&&i.type===`edge`?i.id:null}},{key:`process`,value:function(){var e=this;this.emit(`beforeProcess`);var t=this.graph,n=this.settings,r=this.getDimensions();if(this.nodeExtent=Wn(this.graph),!this.settings.autoRescale){var i=r.width,a=r.height,o=this.nodeExtent,s=o.x,c=o.y;this.nodeExtent={x:[(s[0]+s[1])/2-i/2,(s[0]+s[1])/2+i/2],y:[(c[0]+c[1])/2-a/2,(c[0]+c[1])/2+a/2]}}this.normalizationFunction=Yn(this.customBBox||this.nodeExtent);var l=Hn(new ar().getState(),r,this.getGraphDimensions(),this.getStagePadding());this.labelGrid.resizeAndClear(r,n.labelGridCellSize);for(var u={},d={},f={},p={},m=1,h=t.nodes(),g=0,_=h.length;g<_;g++){var v=h[g],y=this.nodeDataCache[v],b=t.getNodeAttributes(v);y.x=b.x,y.y=b.y,this.normalizationFunction.applyTo(y),typeof y.label==`string`&&!y.hidden&&this.labelGrid.add(v,y.size,this.framedGraphToViewport(y,{matrix:l})),u[y.type]=(u[y.type]||0)+1}for(var x in this.labelGrid.organize(),this.nodePrograms){if(!kr.call(this.nodePrograms,x))throw Error(`Sigma: could not find a suitable program for node type "${x}"!`);this.nodePrograms[x].reallocate(u[x]||0),u[x]=0}this.settings.zIndex&&this.nodeZExtent[0]!==this.nodeZExtent[1]&&(h=Jn(this.nodeZExtent,function(t){return e.nodeDataCache[t].zIndex},h));for(var S=0,C=h.length;S1&&arguments[1]!==void 0?arguments[1]:{},n=t.tolerance,r=n===void 0?0:n,i=t.boundaries,a=Z({},e),o=i||this.nodeExtent,s=_t(o.x,2),c=s[0],l=s[1],u=_t(o.y,2),d=u[0],f=u[1],p=[this.graphToViewport({x:c,y:d},{cameraState:e}),this.graphToViewport({x:l,y:d},{cameraState:e}),this.graphToViewport({x:c,y:f},{cameraState:e}),this.graphToViewport({x:l,y:f},{cameraState:e})],m=1/0,h=-1/0,g=1/0,_=-1/0;p.forEach(function(e){var t=e.x,n=e.y;m=Math.min(m,t),h=Math.max(h,t),g=Math.min(g,n),_=Math.max(_,n)});var v=h-m,y=_-g,b=this.getDimensions(),x=b.width,S=b.height,C=0,w=0;if(v>=x?hr&&(C=m-r):h>x+r?C=h-(x+r):m<-r&&(C=m+r),y>=S?_r&&(w=g-r):_>S+r?w=_-(S+r):g<-r&&(w=g+r),C||w){var T=this.viewportToFramedGraph({x:0,y:0},{cameraState:e}),E=this.viewportToFramedGraph({x:C,y:w},{cameraState:e});C=E.x-T.x,w=E.y-T.y,a.x+=C,a.y+=w}return a}},{key:`renderLabels`,value:function(){if(!this.settings.renderLabels)return this;var e=this.camera.getState(),t=this.labelGrid.getLabelsToDisplay(e.ratio,this.settings.labelDensity);Zn(t,this.nodesWithForcedLabels),this.displayedNodeLabels=new Set;for(var n=this.canvasContexts.labels,r=0,i=t.length;rthis.width+Dr||l<-Or||l>this.height+Or)){this.displayedNodeLabels.add(a);var d=this.settings.defaultDrawNodeLabel;(this.nodePrograms[o.type]?.drawLabel||d)(n,Z(Z({key:a},o),{},{size:u,x:c,y:l}),this.settings)}}}return this}},{key:`renderEdgeLabels`,value:function(){if(!this.settings.renderEdgeLabels)return this;var e=this.canvasContexts.edgeLabels;e.clearRect(0,0,this.width,this.height);var t=Er({graph:this.graph,hoveredNode:this.hoveredNode,displayedNodeLabels:this.displayedNodeLabels,highlightedNodes:this.highlightedNodes});Zn(t,this.edgesWithForcedLabels);for(var n=new Set,r=0,i=t.length;rthis.nodeZExtent[1]&&(this.nodeZExtent[1]=n.zIndex))}},{key:`updateNode`,value:function(e){this.addNode(e);var t=this.nodeDataCache[e];this.normalizationFunction.applyTo(t)}},{key:`removeNode`,value:function(e){delete this.nodeDataCache[e],delete this.nodeProgramIndex[e],this.highlightedNodes.delete(e),this.hoveredNode===e&&(this.hoveredNode=null),this.nodesWithForcedLabels.delete(e)}},{key:`addEdge`,value:function(e){var t=Object.assign({},this.graph.getEdgeAttributes(e));this.settings.edgeReducer&&(t=this.settings.edgeReducer(e,t));var n=jr(this.settings,e,t);this.edgeDataCache[e]=n,this.edgesWithForcedLabels.delete(e),n.forceLabel&&!n.hidden&&this.edgesWithForcedLabels.add(e),this.settings.zIndex&&(n.zIndexthis.edgeZExtent[1]&&(this.edgeZExtent[1]=n.zIndex))}},{key:`updateEdge`,value:function(e){this.addEdge(e)}},{key:`removeEdge`,value:function(e){delete this.edgeDataCache[e],delete this.edgeProgramIndex[e],this.hoveredEdge===e&&(this.hoveredEdge=null),this.edgesWithForcedLabels.delete(e)}},{key:`clearNodeIndices`,value:function(){this.labelGrid=new Tr,this.nodeExtent={x:[0,1],y:[0,1]},this.nodeDataCache={},this.edgeProgramIndex={},this.nodesWithForcedLabels=new Set,this.nodeZExtent=[1/0,-1/0],this.highlightedNodes=new Set}},{key:`clearEdgeIndices`,value:function(){this.edgeDataCache={},this.edgeProgramIndex={},this.edgesWithForcedLabels=new Set,this.edgeZExtent=[1/0,-1/0]}},{key:`clearIndices`,value:function(){this.clearEdgeIndices(),this.clearNodeIndices()}},{key:`clearNodeState`,value:function(){this.displayedNodeLabels=new Set,this.highlightedNodes=new Set,this.hoveredNode=null}},{key:`clearEdgeState`,value:function(){this.displayedEdgeLabels=new Set,this.highlightedNodes=new Set,this.hoveredEdge=null}},{key:`clearState`,value:function(){this.clearEdgeState(),this.clearNodeState()}},{key:`addNodeToProgram`,value:function(e,t,n){var r=this.nodeDataCache[e],i=this.nodePrograms[r.type];if(!i)throw Error(`Sigma: could not find a suitable program for node type "${r.type}"!`);i.process(t,n,r),this.nodeProgramIndex[e]=n}},{key:`addEdgeToProgram`,value:function(e,t,n){var r=this.edgeDataCache[e],i=this.edgePrograms[r.type];if(!i)throw Error(`Sigma: could not find a suitable program for edge type "${r.type}"!`);var a=this.graph.extremities(e),o=this.nodeDataCache[a[0]],s=this.nodeDataCache[a[1]];i.process(t,n,o,s,r),this.edgeProgramIndex[e]=n}},{key:`getRenderParams`,value:function(){return{matrix:this.matrix,invMatrix:this.invMatrix,width:this.width,height:this.height,pixelRatio:this.pixelRatio,zoomRatio:this.camera.ratio,cameraAngle:this.camera.angle,sizeRatio:1/this.scaleSize(),correctionRatio:this.correctionRatio,downSizingRatio:this.pickingDownSizingRatio,minEdgeThickness:this.settings.minEdgeThickness,antiAliasingFeather:this.settings.antiAliasingFeather}}},{key:`getStagePadding`,value:function(){var e=this.settings,t=e.stagePadding;return e.autoRescale&&t||0}},{key:`createLayer`,value:function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(this.elements[e])throw Error(`Sigma: a layer named "${e}" already exists`);var r=Kn(t,{position:`absolute`},{class:`sigma-${e}`});return n.style&&Object.assign(r.style,n.style),this.elements[e]=r,`beforeLayer`in n&&n.beforeLayer?this.elements[n.beforeLayer].before(r):`afterLayer`in n&&n.afterLayer?this.elements[n.afterLayer].after(r):this.container.appendChild(r),r}},{key:`createCanvas`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.createLayer(e,`canvas`,t)}},{key:`createCanvasContext`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=this.createCanvas(e,t),r={preserveDrawingBuffer:!1,antialias:!1};return this.canvasContexts[e]=n.getContext(`2d`,r),this}},{key:`createWebGLContext`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=t?.canvas||this.createCanvas(e,t);t.hidden&&n.remove();var r=Z({preserveDrawingBuffer:!1,antialias:!1},t),i=n.getContext(`webgl2`,r);i||=n.getContext(`webgl`,r),i||=n.getContext(`experimental-webgl`,r);var a=i;if(this.webGLContexts[e]=a,a.blendFunc(a.ONE,a.ONE_MINUS_SRC_ALPHA),t.picking){this.pickingLayers.add(e);var o=a.createFramebuffer();if(!o)throw Error(`Sigma: cannot create a new frame buffer for layer ${e}`);this.frameBuffers[e]=o}return a}},{key:`killLayer`,value:function(e){var t=this.elements[e];if(!t)throw Error(`Sigma: cannot kill layer ${e}, which does not exist`);if(this.webGLContexts[e]){var n;(n=this.webGLContexts[e].getExtension(`WEBGL_lose_context`))==null||n.loseContext(),delete this.webGLContexts[e]}else this.canvasContexts[e]&&delete this.canvasContexts[e];return t.remove(),delete this.elements[e],this}},{key:`getCamera`,value:function(){return this.camera}},{key:`setCamera`,value:function(e){this.unbindCameraHandlers(),this.camera=e,this.bindCameraHandlers()}},{key:`getContainer`,value:function(){return this.container}},{key:`getGraph`,value:function(){return this.graph}},{key:`setGraph`,value:function(e){e!==this.graph&&(this.hoveredNode&&!e.hasNode(this.hoveredNode)&&(this.hoveredNode=null),this.hoveredEdge&&!e.hasEdge(this.hoveredEdge)&&(this.hoveredEdge=null),this.unbindGraphHandlers(),this.checkEdgesEventsFrame!==null&&(cancelAnimationFrame(this.checkEdgesEventsFrame),this.checkEdgesEventsFrame=null),this.graph=e,this.bindGraphHandlers(),this.refresh())}},{key:`getMouseCaptor`,value:function(){return this.mouseCaptor}},{key:`getTouchCaptor`,value:function(){return this.touchCaptor}},{key:`getDimensions`,value:function(){return{width:this.width,height:this.height}}},{key:`getGraphDimensions`,value:function(){var e=this.customBBox||this.nodeExtent;return{width:e.x[1]-e.x[0]||1,height:e.y[1]-e.y[0]||1}}},{key:`getNodeDisplayData`,value:function(e){var t=this.nodeDataCache[e];return t?Object.assign({},t):void 0}},{key:`getEdgeDisplayData`,value:function(e){var t=this.edgeDataCache[e];return t?Object.assign({},t):void 0}},{key:`getNodeDisplayedLabels`,value:function(){return new Set(this.displayedNodeLabels)}},{key:`getEdgeDisplayedLabels`,value:function(){return new Set(this.displayedEdgeLabels)}},{key:`getSettings`,value:function(){return Z({},this.settings)}},{key:`getSetting`,value:function(e){return this.settings[e]}},{key:`setSetting`,value:function(e,t){var n=Z({},this.settings);return this.settings[e]=t,nr(this.settings),this.handleSettingsUpdate(n),this.scheduleRefresh(),this}},{key:`updateSetting`,value:function(e,t){return this.setSetting(e,t(this.settings[e])),this}},{key:`setSettings`,value:function(e){var t=Z({},this.settings);return this.settings=Z(Z({},this.settings),e),nr(this.settings),this.handleSettingsUpdate(t),this.scheduleRefresh(),this}},{key:`resize`,value:function(e){var t=this.width,n=this.height;if(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,this.pixelRatio=qn(),this.width===0)if(this.settings.allowInvalidContainer)this.width=1;else throw Error(`Sigma: Container has no width. You can set the allowInvalidContainer setting to true to stop seeing this error.`);if(this.height===0)if(this.settings.allowInvalidContainer)this.height=1;else throw Error(`Sigma: Container has no height. You can set the allowInvalidContainer setting to true to stop seeing this error.`);if(!e&&t===this.width&&n===this.height)return this;for(var r in this.elements){var i=this.elements[r];i.style.width=this.width+`px`,i.style.height=this.height+`px`}for(var a in this.canvasContexts)this.elements[a].setAttribute(`width`,this.width*this.pixelRatio+`px`),this.elements[a].setAttribute(`height`,this.height*this.pixelRatio+`px`),this.pixelRatio!==1&&this.canvasContexts[a].scale(this.pixelRatio,this.pixelRatio);for(var o in this.webGLContexts){this.elements[o].setAttribute(`width`,this.width*this.pixelRatio+`px`),this.elements[o].setAttribute(`height`,this.height*this.pixelRatio+`px`);var s=this.webGLContexts[o];if(s.viewport(0,0,this.width*this.pixelRatio,this.height*this.pixelRatio),this.pickingLayers.has(o)){var c=this.textures[o];c&&s.deleteTexture(c)}}return this.emit(`resize`),this}},{key:`clear`,value:function(){return this.emit(`beforeClear`),this.webGLContexts.nodes.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.nodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.edges.bindFramebuffer(WebGLRenderingContext.FRAMEBUFFER,null),this.webGLContexts.edges.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.webGLContexts.hoverNodes.clear(WebGLRenderingContext.COLOR_BUFFER_BIT),this.canvasContexts.labels.clearRect(0,0,this.width,this.height),this.canvasContexts.hovers.clearRect(0,0,this.width,this.height),this.canvasContexts.edgeLabels.clearRect(0,0,this.width,this.height),this.emit(`afterClear`),this}},{key:`refresh`,value:function(e){var t=this,n=e?.skipIndexation===void 0?!1:e?.skipIndexation,r=e?.schedule===void 0?!1:e.schedule,i=!e||!e.partialGraph;if(i)this.clearEdgeIndices(),this.clearNodeIndices(),this.graph.forEachNode(function(e){return t.addNode(e)}),this.graph.forEachEdge(function(e){return t.addEdge(e)});else{for(var a,o=e.partialGraph?.nodes||[],s=0,c=o?.length||0;s1&&arguments[1]!==void 0?arguments[1]:{},n=!!t.cameraState||!!t.viewportDimensions||!!t.graphDimensions,r=Bn(t.matrix?t.matrix:n?Hn(t.cameraState||this.camera.getState(),t.viewportDimensions||this.getDimensions(),t.graphDimensions||this.getGraphDimensions(),t.padding||this.getStagePadding()):this.matrix,e);return{x:(1+r.x)*this.width/2,y:(1-r.y)*this.height/2}}},{key:`viewportToFramedGraph`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=!!t.cameraState||!!t.viewportDimensions||!t.graphDimensions,r=Bn(t.matrix?t.matrix:n?Hn(t.cameraState||this.camera.getState(),t.viewportDimensions||this.getDimensions(),t.graphDimensions||this.getGraphDimensions(),t.padding||this.getStagePadding(),!0):this.invMatrix,{x:e.x/this.width*2-1,y:1-e.y/this.height*2});return isNaN(r.x)&&(r.x=0),isNaN(r.y)&&(r.y=0),r}},{key:`viewportToGraph`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.normalizationFunction.inverse(this.viewportToFramedGraph(e,t))}},{key:`graphToViewport`,value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return this.framedGraphToViewport(this.normalizationFunction(e),t)}},{key:`getGraphToViewportRatio`,value:function(){var e={x:0,y:0},t={x:1,y:1},n=Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2),r=this.graphToViewport(e),i=this.graphToViewport(t);return Math.sqrt((r.x-i.x)**2+(r.y-i.y)**2)/n}},{key:`getBBox`,value:function(){return this.nodeExtent}},{key:`getCustomBBox`,value:function(){return this.customBBox}},{key:`setCustomBBox`,value:function(e){return this.customBBox=e,this.scheduleRender(),this}},{key:`kill`,value:function(){this.emit(`kill`),this.removeAllListeners(),this.unbindCameraHandlers(),window.removeEventListener(`resize`,this.activeListeners.handleResize),this.mouseCaptor.kill(),this.touchCaptor.kill(),this.unbindGraphHandlers(),this.clearIndices(),this.clearState(),this.nodeDataCache={},this.edgeDataCache={},this.highlightedNodes.clear(),this.renderFrame&&=(cancelAnimationFrame(this.renderFrame),null),this.renderHighlightedNodesFrame&&=(cancelAnimationFrame(this.renderHighlightedNodesFrame),null);for(var e=this.container;e.firstChild;)e.removeChild(e.firstChild);for(var t in this.nodePrograms)this.nodePrograms[t].kill();for(var n in this.nodeHoverPrograms)this.nodeHoverPrograms[n].kill();for(var r in this.edgePrograms)this.edgePrograms[r].kill();for(var i in this.nodePrograms={},this.nodeHoverPrograms={},this.edgePrograms={},this.elements)this.killLayer(i);this.canvasContexts={},this.webGLContexts={},this.elements={}}},{key:`scaleSize`,value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:this.camera.ratio;return e/this.settings.zoomToSizeRatioFunction(t)*(this.getSetting(`itemSizesReference`)===`positions`?t*this.graphToViewportRatio:1)}},{key:`getCanvases`,value:function(){var e={};for(var t in this.elements)this.elements[t]instanceof HTMLCanvasElement&&(e[t]=this.elements[t]);return e}}])}(jn),Nr=t(((e,t)=>{t.exports=function(){var e,t,n={};(function(){var e=0,t=1,r=2,i=3,a=4,o=5,s=6,c=7,l=8,u=9,d=0,f=1,p=2,m=0,h=1,g=2,_=3,v=4,y=5,b=6,x=7,S=8,C=3,w=10,T=3,E=9,D=10;n.exports=function(n,O,ee){var te,k,A,j,M,N,ne,P,F,re,I=O.length,ie=ee.length,ae=n.adjustSizes,oe=n.barnesHutTheta*n.barnesHutTheta,se,L,R,z,B,V,H,U=[];for(A=0;Ahe?(le-=(me-he)/2,ue=le+me):(W-=(he-me)/2,ce=W+he),U[0+m]=-1,U[0+h]=(W+ce)/2,U[0+g]=(le+ue)/2,U[0+_]=Math.max(ce-W,ue-le),U[0+v]=-1,U[0+y]=-1,U[0+b]=0,U[0+x]=0,U[0+S]=0,te=1,A=0;A=0){de=O[A+e]=0)if(V=(O[A+e]-U[k+x])**2+(O[A+t]-U[k+S])**2,re=U[k+_],4*re*re/V0?(H=L*O[A+s]*U[k+b]/V,O[A+r]+=R*H,O[A+i]+=z*H):V<0&&(H=-L*O[A+s]*U[k+b]/Math.sqrt(V),O[A+r]+=R*H,O[A+i]+=z*H):V>0&&(H=L*O[A+s]*U[k+b]/V,O[A+r]+=R*H,O[A+i]+=z*H),k=U[k+v],k<0)break;continue}else{k=U[k+y];continue}else{if(N=U[k+m],N>=0&&N!==A&&(R=O[A+e]-O[N+e],z=O[A+t]-O[N+t],V=R*R+z*z,ae===!0?V>0?(H=L*O[A+s]*O[N+s]/V,O[A+r]+=R*H,O[A+i]+=z*H):V<0&&(H=-L*O[A+s]*O[N+s]/Math.sqrt(V),O[A+r]+=R*H,O[A+i]+=z*H):V>0&&(H=L*O[A+s]*O[N+s]/V,O[A+r]+=R*H,O[A+i]+=z*H)),k=U[k+v],k<0)break;continue}else for(L=n.scalingRatio,j=0;j0?(H=L*O[j+s]*O[M+s]/V/V,O[j+r]+=R*H,O[j+i]+=z*H,O[M+r]-=R*H,O[M+i]-=z*H):V<0&&(H=100*L*O[j+s]*O[M+s],O[j+r]+=R*H,O[j+i]+=z*H,O[M+r]-=R*H,O[M+i]-=z*H)):(V=Math.sqrt(R*R+z*z),V>0&&(H=L*O[j+s]*O[M+s]/V/V,O[j+r]+=R*H,O[j+i]+=z*H,O[M+r]-=R*H,O[M+i]-=z*H));for(F=n.gravity/n.scalingRatio,L=n.scalingRatio,A=0;A0&&(H=L*O[A+s]*F):V>0&&(H=L*O[A+s]*F/V),O[A+r]-=R*H,O[A+i]-=z*H;for(L=1*(n.outboundAttractionDistribution?se:1),ne=0;ne0&&(H=-L*B*Math.log(1+V)/V/O[j+s]):V>0&&(H=-L*B*Math.log(1+V)/V):n.outboundAttractionDistribution?V>0&&(H=-L*B/O[j+s]):V>0&&(H=-L*B)):(V=Math.sqrt(R**2+z**2),n.linLogMode?n.outboundAttractionDistribution?V>0&&(H=-L*B*Math.log(1+V)/V/O[j+s]):V>0&&(H=-L*B*Math.log(1+V)/V):n.outboundAttractionDistribution?(V=1,H=-L*B/O[j+s]):(V=1,H=-L*B)),V>0&&(O[j+r]+=R*H,O[j+i]+=z*H,O[M+r]-=R*H,O[M+i]-=z*H);var ge,_e,ve,ye,be,xe;if(ae===!0)for(A=0;AD&&(O[A+r]=O[A+r]*D/ge,O[A+i]=O[A+i]*D/ge),_e=O[A+s]*Math.sqrt((O[A+a]-O[A+r])*(O[A+a]-O[A+r])+(O[A+o]-O[A+i])*(O[A+o]-O[A+i])),ve=Math.sqrt((O[A+a]+O[A+r])*(O[A+a]+O[A+r])+(O[A+o]+O[A+i])*(O[A+o]+O[A+i]))/2,ye=.1*Math.log(1+ve)/(1+Math.sqrt(_e)),be=O[A+e]+O[A+r]*(ye/n.slowDown),O[A+e]=be,xe=O[A+t]+O[A+i]*(ye/n.slowDown),O[A+t]=xe);else for(A=0;A{function t(e){return typeof e!=`number`||isNaN(e)?1:e}function n(e,t){var n={},r=function(e){return e===void 0?t:e};typeof t==`function`&&(r=t);var i=function(t){return r(t[e])},a=function(){return r(void 0)};return typeof e==`string`?(n.fromAttributes=i,n.fromGraph=function(e,t){return i(e.getNodeAttributes(t))},n.fromEntry=function(e,t){return i(t)}):typeof e==`function`?(n.fromAttributes=function(){throw Error(`graphology-utils/getters/createNodeValueGetter: irrelevant usage.`)},n.fromGraph=function(t,n){return r(e(n,t.getNodeAttributes(n)))},n.fromEntry=function(t,n){return r(e(t,n))}):(n.fromAttributes=a,n.fromGraph=a,n.fromEntry=a),n}function r(e,t){var n={},r=function(e){return e===void 0?t:e};typeof t==`function`&&(r=t);var i=function(t){return r(t[e])},a=function(){return r(void 0)};return typeof e==`string`?(n.fromAttributes=i,n.fromGraph=function(e,t){return i(e.getEdgeAttributes(t))},n.fromEntry=function(e,t){return i(t)},n.fromPartialEntry=n.fromEntry,n.fromMinimalEntry=n.fromEntry):typeof e==`function`?(n.fromAttributes=function(){throw Error(`graphology-utils/getters/createEdgeValueGetter: irrelevant usage.`)},n.fromGraph=function(t,n){var i=t.extremities(n);return r(e(n,t.getEdgeAttributes(n),i[0],i[1],t.getNodeAttributes(i[0]),t.getNodeAttributes(i[1]),t.isUndirected(n)))},n.fromEntry=function(t,n,i,a,o,s,c){return r(e(t,n,i,a,o,s,c))},n.fromPartialEntry=function(t,n,i,a){return r(e(t,n,i,a))},n.fromMinimalEntry=function(t,n){return r(e(t,n))}):(n.fromAttributes=a,n.fromGraph=a,n.fromEntry=a,n.fromMinimalEntry=a),n}e.createNodeValueGetter=n,e.createEdgeValueGetter=r,e.createEdgeWeightGetter=function(e){return r(e,t)}})),Fr=t((e=>{var t=10,n=3;e.assign=function(e){e||={};var t=Array.prototype.slice.call(arguments).slice(1),n,r,i;for(n=0,i=t.length;n=0)?{message:"the `scalingRatio` setting should be a number >= 0."}:`strongGravityMode`in e&&typeof e.strongGravityMode!=`boolean`?{message:"the `strongGravityMode` setting should be a boolean."}:`gravity`in e&&!(typeof e.gravity==`number`&&e.gravity>=0)?{message:"the `gravity` setting should be a number >= 0."}:`slowDown`in e&&!(typeof e.slowDown==`number`||e.slowDown>=0)?{message:"the `slowDown` setting should be a number >= 0."}:`barnesHutOptimize`in e&&typeof e.barnesHutOptimize!=`boolean`?{message:"the `barnesHutOptimize` setting should be a boolean."}:`barnesHutTheta`in e&&!(typeof e.barnesHutTheta==`number`&&e.barnesHutTheta>=0)?{message:"the `barnesHutTheta` setting should be a number >= 0."}:null},e.graphToByteArrays=function(e,r){var i=e.order,a=e.size,o={},s,c=new Float32Array(i*t),l=new Float32Array(a*n);return s=0,e.forEachNode(function(e,n){o[e]=s,c[s]=n.x,c[s+1]=n.y,c[s+2]=0,c[s+3]=0,c[s+4]=0,c[s+5]=0,c[s+6]=1,c[s+7]=1,c[s+8]=n.size||1,c[s+9]=n.fixed?1:0,s+=t}),s=0,e.forEachEdge(function(e,t,i,a,u,d,f){var p=o[i],m=o[a],h=r(e,t,i,a,u,d,f);c[p+6]+=h,c[m+6]+=h,l[s]=p,l[s+1]=m,l[s+2]=h,s+=n}),{nodes:c,edges:l}},e.assignLayoutChanges=function(e,n,r){var i=0;e.updateEachNodeAttributes(function(e,a){return a.x=n[i],a.y=n[i+1],i+=t,r?r(e,a):a})},e.readGraphPositions=function(e,n){var r=0;e.forEachNode(function(e,i){n[r]=i.x,n[r+1]=i.y,r+=t})},e.collectLayoutChanges=function(e,n,r){for(var i=e.nodes(),a={},o=0,s=0,c=n.length;o{t.exports={linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:1,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5}})),Lr=t(((e,t)=>{var n=Nr(),r=Mn(),i=Pr().createEdgeWeightGetter,a=Fr(),o=Ir();function s(e,t){if(t||={},!r(e))throw Error(`graphology-layout-forceatlas2/worker: the given graph is not a valid graphology instance.`);var n=i(`getEdgeWeight`in t?t.getEdgeWeight:`weight`).fromEntry,s=a.assign({},o,t.settings),c=a.validateSettings(s);if(c)throw Error(`graphology-layout-forceatlas2/worker: `+c.message);this.worker=null,this.graph=e,this.settings=s,this.getEdgeWeight=n,this.matrices=null,this.running=!1,this.killed=!1,this.outputReducer=typeof t.outputReducer==`function`?t.outputReducer:null,this.handleMessage=this.handleMessage.bind(this);var l=void 0,u=this;this.handleGraphUpdate=function(){u.worker&&u.worker.terminate(),l&&clearTimeout(l),l=setTimeout(function(){l=void 0,u.spawnWorker()},0)},e.on(`nodeAdded`,this.handleGraphUpdate),e.on(`edgeAdded`,this.handleGraphUpdate),e.on(`nodeDropped`,this.handleGraphUpdate),e.on(`edgeDropped`,this.handleGraphUpdate),this.spawnWorker()}s.prototype.isRunning=function(){return this.running},s.prototype.spawnWorker=function(){this.worker&&this.worker.terminate(),this.worker=a.createWorker(n),this.worker.addEventListener(`message`,this.handleMessage),this.running&&(this.running=!1,this.start())},s.prototype.handleMessage=function(e){if(this.running){var t=new Float32Array(e.data.nodes);a.assignLayoutChanges(this.graph,t,this.outputReducer),this.outputReducer&&a.readGraphPositions(this.graph,t),this.matrices.nodes=t,this.askForIterations()}},s.prototype.askForIterations=function(e){var t=this.matrices,n={settings:this.settings,nodes:t.nodes.buffer},r=[t.nodes.buffer];return e&&(n.edges=t.edges.buffer,r.push(t.edges.buffer)),this.worker.postMessage(n,r),this},s.prototype.start=function(){if(this.killed)throw Error(`graphology-layout-forceatlas2/worker.start: layout was killed.`);return this.running?this:(this.matrices=a.graphToByteArrays(this.graph,this.getEdgeWeight),this.running=!0,this.askForIterations(!0),this)},s.prototype.stop=function(){return this.running=!1,this},s.prototype.kill=function(){if(this.killed)return this;this.running=!1,this.killed=!0,this.matrices=null,this.worker.terminate(),this.graph.removeListener(`nodeAdded`,this.handleGraphUpdate),this.graph.removeListener(`edgeAdded`,this.handleGraphUpdate),this.graph.removeListener(`nodeDropped`,this.handleGraphUpdate),this.graph.removeListener(`edgeDropped`,this.handleGraphUpdate)},t.exports=s}));export{er as a,Jt as c,G as d,tr as i,qt as l,Pr as n,Mn as o,Mr as r,pn as s,Lr as t,Ot as u}; \ No newline at end of file diff --git a/semantica/static/assets/graphTheme-CLhhQXPS.js b/semantica/static/assets/graphTheme-CLhhQXPS.js deleted file mode 100644 index 2d32ba9e..00000000 --- a/semantica/static/assets/graphTheme-CLhhQXPS.js +++ /dev/null @@ -1 +0,0 @@ -import{r as e}from"./graph-vendor-DFSl_YWi.js";var t=new e({type:`directed`,multi:!1,allowSelfLoops:!1});function n(e){for(let{id:n,attributes:r}of e)t.mergeNode(n,r)}function r(e){for(let{source:n,target:r,attributes:i}of e)t.hasNode(n)&&t.hasNode(r)&&t.mergeDirectedEdge(n,r,i)}function i(){t.clear()}var a={palette:{semantic:[`#63E6FF`,`#30D4C7`,`#72A8FF`,`#8D7CFF`,`#C07CFF`,`#FF67D4`,`#FFB24D`,`#C5F55A`],accent:{selected:`#FFC857`,hovered:`#7FE0FF`,path:`#FFB870`,temporal:`#6DD6FF`,provenance:`#A98CFF`,inferred:`#FF9A61`},muted:{fallback:`rgba(130, 145, 165, 0.12)`,nodeAlpha:.12,edgeOverview:`rgba(116, 166, 255, 0.05)`,edgeStructure:`rgba(109, 164, 255, 0.11)`,edgeInspection:`rgba(146, 194, 255, 0.18)`,edgeFocus:`rgba(162, 184, 255, 0.34)`},background:{canvas:`#060B17`,shell:`rgba(6, 13, 24, 0.76)`,shellBorder:`rgba(112, 196, 255, 0.14)`,shellGlow:`rgba(53, 123, 255, 0.16)`,grid:`rgba(88, 166, 255, 0.038)`,vignette:`rgba(1, 4, 10, 0.82)`,nodeBorder:`#07111C`}},zoomTiers:{overview:{maxRatio:1/0,nodeScale:.9,labelThreshold:.985,labelBudget:18,edgePriorityThreshold:.72,arrowPriorityThreshold:1/0,edgeSizeScale:.72,showBadges:!1,showCurves:!1,showContextualArrows:!1},structure:{maxRatio:1.2,nodeScale:.98,labelThreshold:.88,labelBudget:36,edgePriorityThreshold:.4,arrowPriorityThreshold:.75,edgeSizeScale:.92,showBadges:!0,showCurves:!0,showContextualArrows:!0},inspection:{maxRatio:.5,nodeScale:1,labelThreshold:.7,labelBudget:80,edgePriorityThreshold:0,arrowPriorityThreshold:.58,edgeSizeScale:1.04,showBadges:!0,showCurves:!0,showContextualArrows:!0}},labels:{forceVisibleStates:[`hovered`,`selected`,`neighbor`,`path`],policies:{none:{minZoomTier:`inspection`},priority:{minZoomTier:`overview`},local:{minZoomTier:`structure`},always:{minZoomTier:`overview`}}},nodes:{backgroundScale:.52,mutedAlpha:.12,strokeHierarchy:{overview:{base:.8,emphasis:1.2,muted:.45},structure:{base:1.05,emphasis:1.45,muted:.55},inspection:{base:1.2,emphasis:1.7,muted:.6}},states:{default:{color:`base`,sizeMultiplier:1,minSize:1.45,forceLabel:!1,zIndex:0,borderBoost:0},hovered:{color:`hovered`,sizeMultiplier:1.34,minSize:16,forceLabel:!0,zIndex:4,borderBoost:.5},selected:{color:`selected`,sizeMultiplier:1.18,minSize:12,forceLabel:!0,zIndex:3,borderBoost:.42},neighbor:{color:`base`,sizeMultiplier:1.08,minSize:7.2,forceLabel:!0,zIndex:2,borderBoost:.18},path:{color:`path`,sizeMultiplier:1.08,minSize:7.2,forceLabel:!0,zIndex:2,borderBoost:.24},inactive:{color:`muted`,sizeMultiplier:.52,minSize:.8,forceLabel:!1,zIndex:0,borderBoost:-.15},muted:{color:`muted`,sizeMultiplier:.52,minSize:.8,forceLabel:!1,zIndex:0,borderBoost:-.15}},variants:{default:{sizeMultiplier:1,borderBoost:0,haloBoost:0,badgeVisibleFrom:`inspection`},temporal:{sizeMultiplier:1.02,borderBoost:.12,haloBoost:.1,badgeKind:`temporal`,badgeVisibleFrom:`structure`},inferred:{sizeMultiplier:1.05,borderBoost:.16,haloBoost:.14,badgeKind:`inferred`,badgeVisibleFrom:`structure`},provenance:{sizeMultiplier:1.03,borderBoost:.14,haloBoost:.12,badgeKind:`provenance`,badgeVisibleFrom:`structure`},selected:{sizeMultiplier:1.06,borderBoost:.22,haloBoost:.16,badgeVisibleFrom:`overview`}},selectedRing:{color:`#FFC857`,width:2.4,glowAlpha:.38,visibleFrom:`inspection`},badges:{inferred:{color:`#FF9A61`,label:`I`},temporal:{color:`#6DD6FF`,label:`T`},provenance:{color:`#A98CFF`,label:`P`}},badge:{radius:7,offset:3,fontSize:8,textColor:`#08111d`,background:`rgba(8, 17, 29, 0.9)`,stroke:`rgba(255,255,255,0.2)`,glowAlpha:.34}},edges:{states:{default:{color:`inspection`,sizeMultiplier:1,minSize:.72,zIndex:0,forceArrow:!1,hide:!1},hovered:{color:`hover`,sizeMultiplier:1.55,minSize:1.8,zIndex:3,forceArrow:!0,hide:!1},selected:{color:`hover`,sizeMultiplier:1.55,minSize:1.8,zIndex:3,forceArrow:!0,hide:!1},neighbor:{color:`focus`,sizeMultiplier:1.08,minSize:.95,zIndex:1,forceArrow:!1,hide:!1},path:{color:`path`,sizeMultiplier:1.7,minSize:2.2,zIndex:4,forceArrow:!0,hide:!1},inactive:{color:`muted`,sizeMultiplier:1,minSize:.45,zIndex:0,forceArrow:!1,hide:!0},muted:{color:`muted`,sizeMultiplier:1,minSize:.45,zIndex:0,forceArrow:!1,hide:!0}},variants:{line:{baseType:`line`,arrowPolicy:`hidden`,curveStrength:0,sizeMultiplier:1,glowAlpha:0},directional:{baseType:`line`,arrowPolicy:`contextual`,curveStrength:0,sizeMultiplier:1.04,glowAlpha:.08},bidirectionalCurve:{baseType:`line`,arrowPolicy:`contextual`,curveStrength:.18,sizeMultiplier:1.08,glowAlpha:.1},parallelCurve:{baseType:`line`,arrowPolicy:`contextual`,curveStrength:.24,sizeMultiplier:1.1,glowAlpha:.12},pathSignal:{baseType:`arrow`,arrowPolicy:`always`,curveStrength:.16,sizeMultiplier:1.18,glowAlpha:.2}}},overlays:{hoverGlowAlpha:.26,pathGlowAlpha:.2,glowRadiusMultiplier:4.8,minGlowRadius:16,pulseRadius:11,curveLineWidth:1.7,curveGlowWidth:6,badgeGlowRadius:14},focus:{maxNeighbors:16,ringCapacity:6,ringGap:250,primaryLabels:6},motion:{cameraMs:380},effects:{pathPulse:{minZoomTier:`structure`,maxSegments:18,speed:.22,radius:11,glowAlpha:.92},pathFlow:{minZoomTier:`structure`,maxSegments:14,speed:.36,spacing:.26,opacity:.92,radius:3.8},lens:{minZoomTier:`structure`,radius:136,feather:78,glowAlpha:.18,edgeAlpha:.42,edgeLineWidth:1.8},legend:{maxGroups:8},diagnostics:{enabledInDev:!1}}},o=[`overview`,`structure`,`inspection`];function s(e){let t=0;for(let n=0;n`${e}${e}`).join(``):n;if(r.length===6)return`rgba(${Number.parseInt(r.slice(0,2),16)}, ${Number.parseInt(r.slice(2,4),16)}, ${Number.parseInt(r.slice(4,6),16)}, ${t})`}return e.startsWith(`rgba(`)?e.replace(/rgba\(([^)]+),\s*[\d.]+\)/,`rgba($1, ${t})`):e.startsWith(`rgb(`)?e.replace(`rgb(`,`rgba(`).replace(`)`,`, ${t})`):`rgba(130, 145, 165, ${t})`}function u(e,t){if(!e.startsWith(`#`))return e;let n=e.slice(1),r=n.length===3?n.split(``).map(e=>`${e}${e}`).join(``):n;if(r.length!==6)return e;let i=e=>c(0,e,255);return`#${[i(Number.parseInt(r.slice(0,2),16)-t),i(Number.parseInt(r.slice(2,4),16)-t),i(Number.parseInt(r.slice(4,6),16)-t)].map(e=>e.toString(16).padStart(2,`0`)).join(``)}`}function d(e){return e<=a.zoomTiers.inspection.maxRatio?`inspection`:e<=a.zoomTiers.structure.maxRatio?`structure`:`overview`}function f(e,t){return o.indexOf(e)>=o.indexOf(t)}export{s as a,r as c,t as d,d as i,n as l,c as n,l as o,u as r,f as s,a as t,i as u}; \ No newline at end of file diff --git a/semantica/static/assets/graphTheme-aSRma4TX.js b/semantica/static/assets/graphTheme-aSRma4TX.js new file mode 100644 index 00000000..8b907790 --- /dev/null +++ b/semantica/static/assets/graphTheme-aSRma4TX.js @@ -0,0 +1 @@ +import{d as e}from"./graph-vendor-pbzH-eyf.js";function t(e,t){return JSON.stringify([e,t])}function n(e,t){return JSON.stringify([e,t])}var r=new e({type:`directed`,multi:!0,allowSelfLoops:!1});function i(e,t){let i=[];r.forEachDirectedEdge(e,t,e=>{i.push(String(e))});let a=i.length,o=new Map;i.forEach(e=>{let t=r.getEdgeAttributes(e),n=String(t.familyId||e);o.set(n,(o.get(n)??0)+1)}),i.sort((e,t)=>{let n=r.getEdgeAttributes(e),i=r.getEdgeAttributes(t),a=Number(i.visualPriority??0)-Number(n.visualPriority??0);if(a!==0)return a;let o=Number(i.weight??0)-Number(n.weight??0);return o===0?e.localeCompare(t):o}).forEach((i,s)=>{let c=r.getEdgeAttributes(i),l=String(c.familyId||i);r.mergeEdgeAttributes(i,{edgeId:i,familyId:l,sourceId:e,targetId:t,isParallelPair:a>1,parallelIndex:s,parallelCount:a,familySize:o.get(l)??1,curveGroup:n(e,t)})})}function a(e){for(let{id:t,attributes:n}of e)r.mergeNode(t,n)}function o(e){let n=new Map;for(let{id:i,familyId:a,source:o,target:s,attributes:c}of e){let e=String(c.edgeId||i),l=String(c.familyId||a||e);r.hasNode(o)&&r.hasNode(s)&&(r.mergeDirectedEdgeWithKey(e,o,s,{...c,edgeId:e,familyId:l,sourceId:o,targetId:s}),n.set(t(o,s),{source:o,target:s}))}n.forEach(({source:e,target:t})=>{i(e,t)})}function s(){r.clear()}var c={palette:{semantic:[`#3E79F2`,`#149287`,`#2F9F61`,`#555FD6`,`#8A56D8`,`#B65473`,`#C9922E`],overview:{nodeBase:`#0B1320`,nodeCore:`#435D7A`,nodeMuted:`#121927`,nodeBorder:`#64758C`,nodeTintMix:.03,nodeCoreMix:.52,nodeShellAlpha:.97,nodeCoreAlpha:1,edgeBackbone:`rgba(83, 111, 148, 0.04)`,edgeStructure:`rgba(72, 90, 118, 0.009)`,edgeInspection:`rgba(98, 120, 148, 0.026)`},accent:{selected:`#F2D288`,hovered:`#8FE7FF`,path:`#D79056`,temporal:`#49D7FF`,provenance:`#C9A5FF`,inferred:`#D07B4D`},muted:{fallback:`rgba(96, 112, 136, 0.1)`,nodeAlpha:.085,edgeOverview:`rgba(82, 100, 124, 0.009)`,edgeStructure:`rgba(92, 112, 138, 0.02)`,edgeInspection:`rgba(124, 148, 176, 0.066)`,edgeFocus:`rgba(160, 186, 218, 0.16)`},background:{canvas:`#07101A`,shell:`rgba(8, 15, 26, 0.8)`,shellBorder:`rgba(118, 162, 207, 0.14)`,shellGlow:`rgba(48, 88, 140, 0.14)`,grid:`rgba(92, 126, 170, 0.034)`,vignette:`rgba(2, 5, 11, 0.84)`,nodeBorder:`#0C1522`}},zoomTiers:{overview:{maxRatio:1/0,nodeScale:.66,labelThreshold:.985,labelBudget:10,edgePriorityThreshold:.72,arrowPriorityThreshold:1/0,edgeSizeScale:.34,showBadges:!1,showCurves:!1,showContextualArrows:!1},structure:{maxRatio:1.2,nodeScale:.98,labelThreshold:.88,labelBudget:36,edgePriorityThreshold:.4,arrowPriorityThreshold:.75,edgeSizeScale:.92,showBadges:!0,showCurves:!0,showContextualArrows:!0},inspection:{maxRatio:.5,nodeScale:1,labelThreshold:.7,labelBudget:80,edgePriorityThreshold:0,arrowPriorityThreshold:.58,edgeSizeScale:1.04,showBadges:!0,showCurves:!0,showContextualArrows:!0}},labels:{forceVisibleStates:[`hovered`,`selected`,`neighbor`,`path`],policies:{none:{minZoomTier:`inspection`},priority:{minZoomTier:`overview`},local:{minZoomTier:`structure`},always:{minZoomTier:`overview`}},chip:{fontFamily:`"IBM Plex Sans", Inter, system-ui, sans-serif`,fontWeight:500,fontSize:10,maxFontSize:11,sizeScale:.25,paddingX:6,paddingY:3,radius:6,offsetX:12,offsetY:10,background:`rgba(8, 14, 24, 0.9)`,borderColor:`rgba(154, 181, 212, 0.16)`,borderAlpha:.28,textColor:`#EAF3FF`,shadowColor:`rgba(0, 0, 0, 0.6)`,shadowAlpha:.26,shadowBlur:12},hoverCard:{fontFamily:`"IBM Plex Sans", Inter, system-ui, sans-serif`,titleWeight:700,titleSize:13,metaWeight:500,metaSize:10,paddingX:10,paddingY:7,radius:12,offsetX:16,offsetY:16,metaGap:5,background:`rgba(8, 14, 24, 0.94)`,borderColor:`rgba(154, 181, 212, 0.18)`,borderAlpha:.32,textColor:`#F6FBFF`,metaColor:`rgba(184, 214, 255, 0.58)`,shadowColor:`rgba(0, 0, 0, 0.62)`,shadowAlpha:.34,shadowBlur:15}},nodes:{backgroundScale:.52,mutedAlpha:.08,strokeHierarchy:{overview:{base:.05,emphasis:.34,muted:.02},structure:{base:1.05,emphasis:1.45,muted:.55},inspection:{base:1.2,emphasis:1.7,muted:.6}},states:{default:{color:`base`,sizeMultiplier:.72,minSize:.68,forceLabel:!1,zIndex:0,borderBoost:-.42},hovered:{color:`hovered`,sizeMultiplier:1.18,minSize:12.5,forceLabel:!0,zIndex:4,borderBoost:.22},selected:{color:`selected`,sizeMultiplier:1.06,minSize:10.5,forceLabel:!0,zIndex:3,borderBoost:.2},neighbor:{color:`base`,sizeMultiplier:.84,minSize:4.8,forceLabel:!0,zIndex:2,borderBoost:-.08},path:{color:`path`,sizeMultiplier:1.01,minSize:6.2,forceLabel:!0,zIndex:2,borderBoost:.08},inactive:{color:`muted`,sizeMultiplier:.32,minSize:.46,forceLabel:!1,zIndex:0,borderBoost:-.42},muted:{color:`muted`,sizeMultiplier:.32,minSize:.46,forceLabel:!1,zIndex:0,borderBoost:-.42}},variants:{default:{sizeMultiplier:1,borderBoost:0,haloBoost:0,badgeVisibleFrom:`inspection`},temporal:{sizeMultiplier:1.02,borderBoost:.12,haloBoost:.1,badgeKind:`temporal`,badgeVisibleFrom:`structure`},inferred:{sizeMultiplier:1.05,borderBoost:.16,haloBoost:.14,badgeKind:`inferred`,badgeVisibleFrom:`structure`},provenance:{sizeMultiplier:1.03,borderBoost:.14,haloBoost:.12,badgeKind:`provenance`,badgeVisibleFrom:`structure`},selected:{sizeMultiplier:1.06,borderBoost:.22,haloBoost:.16,badgeVisibleFrom:`overview`}},selectedRing:{color:`#E7C57C`,width:1.9,nativeSize:2.2,glowAlpha:.2,visibleFrom:`overview`},badges:{inferred:{color:`#C98658`,label:`I`},temporal:{color:`#52CDEF`,label:`T`},provenance:{color:`#A289D0`,label:`P`}},badge:{radius:7,offset:3,fontSize:8,textColor:`#08111d`,background:`rgba(8, 17, 29, 0.84)`,stroke:`rgba(255,255,255,0.14)`,glowAlpha:.24}},edges:{states:{default:{color:`structure`,sizeMultiplier:.74,minSize:.18,zIndex:0,forceArrow:!1,hide:!1},backbone:{color:`backbone`,sizeMultiplier:.72,minSize:.18,zIndex:1,forceArrow:!1,hide:!1},hovered:{color:`hover`,sizeMultiplier:1.42,minSize:1.45,zIndex:3,forceArrow:!0,hide:!1},selected:{color:`hover`,sizeMultiplier:1.42,minSize:1.45,zIndex:3,forceArrow:!0,hide:!1},neighbor:{color:`focus`,sizeMultiplier:.92,minSize:.5,zIndex:1,forceArrow:!1,hide:!1},path:{color:`path`,sizeMultiplier:1.5,minSize:1.8,zIndex:4,forceArrow:!0,hide:!1},inactive:{color:`muted`,sizeMultiplier:1,minSize:.16,zIndex:0,forceArrow:!1,hide:!0},muted:{color:`muted`,sizeMultiplier:1,minSize:.16,zIndex:0,forceArrow:!1,hide:!0}},variants:{line:{baseType:`line`,arrowPolicy:`hidden`,curveStrength:0,sizeMultiplier:1,glowAlpha:0},directional:{baseType:`line`,arrowPolicy:`contextual`,curveStrength:0,sizeMultiplier:1.04,glowAlpha:.08},bidirectionalCurve:{baseType:`line`,arrowPolicy:`contextual`,curveStrength:.18,sizeMultiplier:1.08,glowAlpha:.1},parallelCurve:{baseType:`line`,arrowPolicy:`contextual`,curveStrength:.24,sizeMultiplier:1.1,glowAlpha:.12},pathSignal:{baseType:`arrow`,arrowPolicy:`always`,curveStrength:.16,sizeMultiplier:1.18,glowAlpha:.2}}},overlays:{hoverGlowAlpha:.18,pathGlowAlpha:.16,glowRadiusMultiplier:4.8,minGlowRadius:16,pulseRadius:11,curveLineWidth:1.7,curveGlowWidth:6,badgeGlowRadius:14},focus:{maxNeighbors:16,ringCapacity:6,ringGap:250,primaryLabels:6},motion:{cameraMs:380},effects:{pathPulse:{minZoomTier:`structure`,maxSegments:18,speed:.22,radius:11,glowAlpha:.92},pathFlow:{minZoomTier:`structure`,maxSegments:14,speed:.36,spacing:.26,opacity:.92,radius:3.8},lens:{minZoomTier:`structure`,radius:136,feather:78,glowAlpha:.18,edgeAlpha:.42,edgeLineWidth:1.8},temporalEmphasis:{minZoomTier:`structure`,maxHighlights:48,radiusMultiplier:4.2,glowAlpha:.12},semanticRegions:{minZoomTier:`overview`,maxRegions:3,minVisibleSamples:14,fogResolutionScale:.22,splatRadius:13,blurPasses:2,densityThreshold:.16,contourThreshold:.28,minMaskPixels:170,minOccupancyRatio:.0022,dominantMassRatio:.62,outerContourMinMaskPixels:240,fogAlpha:.11,innerContourAlpha:.16,outerContourAlpha:.045},contours:{minZoomTier:`overview`,maxContours:3,baseRadius:88,glowAlpha:.055},legend:{maxGroups:8},diagnostics:{enabledInDev:!1}}},l=[`overview`,`structure`,`inspection`];function u(e){let t=0;for(let n=0;n`${e}${e}`).join(``):n;if(r.length===6)return`rgba(${Number.parseInt(r.slice(0,2),16)}, ${Number.parseInt(r.slice(2,4),16)}, ${Number.parseInt(r.slice(4,6),16)}, ${t})`}return e.startsWith(`rgba(`)?e.replace(/rgba\(([^)]+),\s*[\d.]+\)/,`rgba($1, ${t})`):e.startsWith(`rgb(`)?e.replace(`rgb(`,`rgba(`).replace(`)`,`, ${t})`):`rgba(130, 145, 165, ${t})`}function p(e,t){if(!e.startsWith(`#`))return e;let n=e.slice(1),r=n.length===3?n.split(``).map(e=>`${e}${e}`).join(``):n;if(r.length!==6)return e;let i=e=>d(0,e,255);return`#${[i(Number.parseInt(r.slice(0,2),16)-t),i(Number.parseInt(r.slice(2,4),16)-t),i(Number.parseInt(r.slice(4,6),16)-t)].map(e=>e.toString(16).padStart(2,`0`)).join(``)}`}function m(e,t,n){if(!e.startsWith(`#`)||!t.startsWith(`#`))return t||e;let r=e=>{let t=e.slice(1);return t.length===3?t.split(``).map(e=>`${e}${e}`).join(``):t},i=r(e),a=r(t);if(i.length!==6||a.length!==6)return t||e;let o=d(0,n,1),s=(e,t)=>Math.round(e+(t-e)*o);return`#${[0,2,4].map(e=>s(Number.parseInt(i.slice(e,e+2),16),Number.parseInt(a.slice(e,e+2),16)).toString(16).padStart(2,`0`)).join(``)}`}function h(e){return e<=c.zoomTiers.inspection.maxRatio?`inspection`:e<=c.zoomTiers.structure.maxRatio?`structure`:`overview`}function g(e,t){return l.indexOf(e)>=l.indexOf(t)}export{h as a,g as c,s as d,r as f,p as i,o as l,t as m,m as n,u as o,n as p,d as r,f as s,c as t,a as u}; \ No newline at end of file diff --git a/semantica/static/assets/index-BVBOQ8an.js b/semantica/static/assets/index-DDOaKEbH.js similarity index 99% rename from semantica/static/assets/index-BVBOQ8an.js rename to semantica/static/assets/index-DDOaKEbH.js index 6e8fbf8a..b282c8ec 100644 --- a/semantica/static/assets/index-BVBOQ8an.js +++ b/semantica/static/assets/index-DDOaKEbH.js @@ -1,4 +1,4 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/DecisionWorkspace-DOZnUOYv.js","assets/rolldown-runtime-B1FJdls4.js","assets/query-vendor-Cbp9LWgA.js","assets/DiffMergeWorkspace-BP5v4yP2.js","assets/GraphWorkspace-DGFkh5CZ.js","assets/graph-vendor-DFSl_YWi.js","assets/graphTheme-CLhhQXPS.js","assets/explorationEffectsPlugin-BhFwJ4hP.js","assets/neighborhoodPanelPlugin-Dra5vWrD.js","assets/temporalOverlayPlugin-l3pE8rf_.js","assets/ImportExportWorkspace-CYQpATgz.js","assets/es-BveUcJeu.js","assets/LineageDiagram-DQTOL97h.js","assets/shim-CnYKr5zR.js","assets/LineageDiagram-CHpVij2M.css","assets/ReasoningWorkspace-BGe6HUKK.js","assets/SparqlWorkspace-CK6q2l7f.js","assets/VocabularyWorkspace-Xth7XSJd.js"])))=>i.map(i=>d[i]); +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/DecisionWorkspace-CkoD0QKe.js","assets/rolldown-runtime-B1FJdls4.js","assets/query-vendor-Cbp9LWgA.js","assets/DiffMergeWorkspace-DDK7n-jO.js","assets/GraphWorkspace-Bqx0S-ru.js","assets/graph-vendor-pbzH-eyf.js","assets/graphTheme-aSRma4TX.js","assets/explorationEffectsPluginPhaseC-D5jYu8XU.js","assets/neighborhoodPanelPlugin-qsLfEPn1.js","assets/temporalOverlayPlugin-l3pE8rf_.js","assets/ImportExportWorkspace-BU8nK4nT.js","assets/es-CS4MDIhr.js","assets/LineageDiagram-BcIhRlOg.js","assets/shim-CnYKr5zR.js","assets/LineageDiagram-CHpVij2M.css","assets/ReasoningWorkspace-BGe6HUKK.js","assets/SparqlWorkspace-CK6q2l7f.js","assets/VocabularyWorkspace-BonIpRiP.js"])))=>i.map(i=>d[i]); import{i as e,t}from"./rolldown-runtime-B1FJdls4.js";import{C as n,S as r,T as i,_ as a,a as o,b as s,c,d as l,f as u,g as d,h as f,l as p,m,o as h,p as g,r as _,s as v,u as y,v as b,w as x,x as ee,y as te}from"./query-vendor-Cbp9LWgA.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var ne=t((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,ee||(ee=!0,oe());else{var t=n(l);t!==null&&le(x,t.startTime-e)}}var ee=!1,te=-1,ne=5,re=-1;function ie(){return g?!0:!(e.unstable_now()-ret&&ie());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&le(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?oe():ee=!1}}}var oe;if(typeof y==`function`)oe=function(){y(ae)};else if(typeof MessageChannel<`u`){var se=new MessageChannel,ce=se.port2;se.port1.onmessage=ae,oe=function(){ce.postMessage(null)}}else oe=function(){_(ae,0)};function le(t,n){te=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(te),te=-1):h=!0,le(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,ee||(ee=!0,oe()))),r},e.unstable_shouldYield=ie,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),re=t(((e,t)=>{t.exports=ne()})),ie=t((e=>{var t=i();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=ie()})),oe=t((e=>{var t=re(),n=i(),r=ae();function a(e){var t=`https://react.dev/errors/`+e;if(1ge||(e.current=he[ge],he[ge]=null,ge--)}function T(e,t){ge++,he[ge]=e.current,e.current=t}var ve=_e(null),E=_e(null),ye=_e(null),be=_e(null);function xe(e,t){switch(T(ye,t),T(E,e),T(ve,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}w(ve),T(ve,e)}function Se(){w(ve),w(E),w(ye)}function Ce(e){e.memoizedState!==null&&T(be,e);var t=ve.current,n=Hd(t,e.type);t!==n&&(T(E,e),T(ve,n))}function we(e){E.current===e&&(w(ve),w(E)),be.current===e&&(w(be),Qf._currentValue=me)}var Te,Ee;function De(e){if(Te===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Te=t&&t[1]||``,Ee=-1)`:-1`)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{Oe=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?De(n):``}function ke(e,t){switch(e.tag){case 26:case 27:case 5:return De(e.type);case 16:return De(`Lazy`);case 13:return e.child!==t&&t!==null?De(`Suspense Fallback`):De(`Suspense`);case 19:return De(`SuspenseList`);case 0:case 15:return D(e.type,!1);case 11:return D(e.type.render,!1);case 1:return D(e.type,!0);case 31:return De(`Activity`);default:return``}}function Ae(e){try{var t=``,n=null;do t+=ke(e,n),n=e,e=e.return;while(e);return t}catch(e){return` Error generating stack: `+e.message+` `+e.stack}}var je=Object.prototype.hasOwnProperty,Me=t.unstable_scheduleCallback,Ne=t.unstable_cancelCallback,Pe=t.unstable_shouldYield,Fe=t.unstable_requestPaint,Ie=t.unstable_now,Le=t.unstable_getCurrentPriorityLevel,Re=t.unstable_ImmediatePriority,ze=t.unstable_UserBlockingPriority,Be=t.unstable_NormalPriority,Ve=t.unstable_LowPriority,He=t.unstable_IdlePriority,Ue=t.log,We=t.unstable_setDisableYieldValue,Ge=null,Ke=null;function qe(e){if(typeof Ue==`function`&&We(e),Ke&&typeof Ke.setStrictMode==`function`)try{Ke.setStrictMode(Ge,e)}catch{}}var Je=Math.clz32?Math.clz32:Ze,Ye=Math.log,Xe=Math.LN2;function Ze(e){return e>>>=0,e===0?32:31-(Ye(e)/Xe|0)|0}var Qe=256,$e=262144,et=4194304;function tt(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function nt(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=tt(n))):i=tt(o):i=tt(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=tt(n))):i=tt(o)):i=tt(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function rt(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function it(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function at(){var e=et;return et<<=1,!(et&62914560)&&(et=4194304),e}function ot(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function st(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function ct(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),bn=!1;if(yn)try{var xn={};Object.defineProperty(xn,`passive`,{get:function(){bn=!0}}),window.addEventListener(`test`,xn,xn),window.removeEventListener(`test`,xn,xn)}catch{bn=!1}var Sn=null,Cn=null,wn=null;function Tn(){if(wn)return wn;var e,t=Cn,n=t.length,r,i=`value`in Sn?Sn.value:Sn.textContent,a=i.length;for(e=0;e=rr),or=` `,sr=!1;function cr(e,t){switch(e){case`keyup`:return tr.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function lr(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var ur=!1;function dr(e,t){switch(e){case`compositionend`:return lr(t);case`keypress`:return t.which===32?(sr=!0,or):null;case`textInput`:return e=t.data,e===or&&sr?null:e;default:return null}}function fr(e,t){if(ur)return e===`compositionend`||!nr&&cr(e,t)?(e=Tn(),wn=Cn=Sn=null,ur=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Pr(n)}}function Ir(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Ir(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Lr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Kt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Kt(e.document)}return t}function Rr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var zr=yn&&`documentMode`in document&&11>=document.documentMode,Br=null,Vr=null,Hr=null,Ur=!1;function Wr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Ur||Br==null||Br!==Kt(r)||(r=Br,`selectionStart`in r&&Rr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Hr&&Nr(Hr,r)||(Hr=r,r=Ed(Vr,`onSelect`),0>=o,i-=o,Ii=1<<32-Je(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),A&&Ri(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(i,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(i,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(i,h),A&&Ri(i,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(i,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return A&&Ri(i,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,i,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(i,e)}),A&&Ri(i,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===_&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case h:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===_){if(r.tag===7){n(e,r.sibling),c=i(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===oe&&Fa(l)===r.type){n(e,r.sibling),c=i(r,o.props),Ha(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===_?(c=Ci(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=Si(o.type,o.key,o.props,null,e.mode,c),Ha(c,o),c.return=e,e=c)}return s(e);case g:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=i(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=Ei(o,e.mode,c),c.return=e,e=c}return s(e);case oe:return o=Fa(o),b(e,r,o,c)}if(pe(o))return v(e,r,o,c);if(ue(o)){if(l=ue(o),typeof l!=`function`)throw Error(a(150));return o=l.call(o),y(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Va(o),c);if(o.$$typeof===x)return b(e,r,ua(e,o),c);Ua(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=i(r,o),c.return=e,e=c):(n(e,r),c=wi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Ba=0;var i=b(e,t,n,r);return za=null,i}catch(t){if(t===ka||t===ja)throw t;var a=vi(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Ga=Wa(!0),Ka=Wa(!1),qa=!1;function Ja(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ya(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Xa(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Za(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,W&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=hi(e),mi(e,null,n),t}return di(e,r,t,n),hi(e)}function Qa(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,ut(e,n)}}function $a(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var eo=!1;function to(){if(eo){var e=ba;if(e!==null)throw e}}function no(e,t,n,r){eo=!1;var i=e.updateQueue;qa=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,m=f!==s.lane;if(m?(q&f)===f:(r&f)===f){f!==0&&f===ya&&(eo=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,f);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,f=typeof h==`function`?h.call(_,d,f):h,f==null)break a;d=p({},d,f);break a;case 2:qa=!0}}f=s.callback,f!==null&&(e.flags|=64,m&&(e.flags|=8192),m=i.callbacks,m===null?i.callbacks=[f]:m.push(f))}else m={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=m,c=d):u=u.next=m,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;m=s,s=m.next,m.next=null,i.lastBaseUpdate=m,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Kl|=o,e.lanes=o,e.memoizedState=d}}function ro(e,t){if(typeof e!=`function`)throw Error(a(191,e));e.call(t)}function io(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=S.T,s={};S.T=s,zs(e,!1,t,n);try{var c=i(),l=S.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Rs(e,t,Ca(c,r),pu(e)):Rs(e,t,r,pu(e))}catch(n){Rs(e,t,{then:function(){},status:`rejected`,reason:n},pu())}finally{C.p=a,o!==null&&s.types!==null&&(o.types=s.types),S.T=o}}function Os(){}function ks(e,t,n,r){if(e.tag!==5)throw Error(a(476));var i=As(e).queue;Ds(e,i,t,me,n===null?Os:function(){return js(e),n(r)})}function As(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:me,baseState:me,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Bo,lastRenderedState:me},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Bo,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function js(e){var t=As(e);t.next===null&&(t=e.alternate.memoizedState),Rs(e,t.next.queue,{},pu())}function Ms(){return j(Qf)}function Ns(){return R().memoizedState}function Ps(){return R().memoizedState}function Fs(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=pu();e=Xa(n);var r=Za(t,e,n);r!==null&&(hu(r,t,n),Qa(r,t,n)),t={cache:ha()},e.payload=t;return}t=t.return}}function Is(e,t,n){var r=pu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Bs(e)?Vs(t,n):(n=fi(e,t,n,r),n!==null&&(hu(n,e,r),Hs(n,t,r)))}function Ls(e,t,n){Rs(e,t,n,pu())}function Rs(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Bs(e))Vs(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Mr(s,o))return di(e,t,i,0),G===null&&ui(),!1}catch{}if(n=fi(e,t,i,r),n!==null)return hu(n,e,r),Hs(n,t,r),!0}return!1}function zs(e,t,n,r){if(r={lane:2,revertLane:dd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Bs(e)){if(t)throw Error(a(479))}else t=fi(e,n,r,2),t!==null&&hu(t,e,2)}function Bs(e){var t=e.alternate;return e===P||t!==null&&t===P}function Vs(e,t){xo=bo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Hs(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,ut(e,n)}}var Us={readContext:j,use:Ro,useCallback:L,useContext:L,useEffect:L,useImperativeHandle:L,useLayoutEffect:L,useInsertionEffect:L,useMemo:L,useReducer:L,useRef:L,useState:L,useDebugValue:L,useDeferredValue:L,useTransition:L,useSyncExternalStore:L,useId:L,useHostTransitionStatus:L,useFormState:L,useActionState:L,useOptimistic:L,useMemoCache:L,useCacheRefresh:L};Us.useEffectEvent=L;var Ws={readContext:j,use:Ro,useCallback:function(e,t){return Fo().memoizedState=[e,t===void 0?null:t],e},useContext:j,useEffect:ms,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),fs(4194308,4,bs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return fs(4194308,4,e,t)},useInsertionEffect:function(e,t){fs(4,2,e,t)},useMemo:function(e,t){var n=Fo();t=t===void 0?null:t;var r=e();if(So){qe(!0);try{e()}finally{qe(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=Fo();if(n!==void 0){var i=n(t);if(So){qe(!0);try{n(t)}finally{qe(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=Is.bind(null,P,e),[r.memoizedState,e]},useRef:function(e){var t=Fo();return e={current:e},t.memoizedState=e},useState:function(e){e=Xo(e);var t=e.queue,n=Ls.bind(null,P,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:Ss,useDeferredValue:function(e,t){return Ts(Fo(),e,t)},useTransition:function(){var e=Xo(!1);return e=Ds.bind(null,P,e.queue,!0,!1),Fo().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=P,i=Fo();if(A){if(n===void 0)throw Error(a(407));n=n()}else{if(n=t(),G===null)throw Error(a(349));q&127||Go(r,t,n)}i.memoizedState=n;var o={value:n,getSnapshot:t};return i.queue=o,ms(qo.bind(null,r,o,e),[e]),r.flags|=2048,us(9,{destroy:void 0},Ko.bind(null,r,o,n,t),null),n},useId:function(){var e=Fo(),t=G.identifierPrefix;if(A){var n=Li,r=Ii;n=(r&~(1<<32-Je(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=Co++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(i,{is:r.is}):s.createElement(i)}}o[_t]=t,o[vt]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,i,r),i){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Lc(t)}}return B(t),Rc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Lc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(a(166));if(e=ye.current,Xi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,i=Ui,i!==null)switch(i.tag){case 27:case 5:r=i.memoizedProps}e[_t]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Md(e.nodeValue,n)),e||qi(t,!0)}else e=Bd(e).createTextNode(r),e[_t]=t,t.stateNode=e}return B(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Xi(t),n!==null){if(e===null){if(!r)throw Error(a(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(a(557));e[_t]=t}else Zi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;B(t),e=!1}else n=Qi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(_o(t),t):(_o(t),null);if(t.flags&128)throw Error(a(558))}return B(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(i=Xi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!i)throw Error(a(318));if(i=t.memoizedState,i=i===null?null:i.dehydrated,!i)throw Error(a(317));i[_t]=t}else Zi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;B(t),i=!1}else i=Qi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=i),i=!0;if(!i)return t.flags&256?(_o(t),t):(_o(t),null)}return _o(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,i=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(i=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==i&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Bc(t,t.updateQueue),B(t),null);case 4:return Se(),e===null&&Sd(t.stateNode.containerInfo),B(t),null;case 10:return ia(t.type),B(t),null;case 19:if(w(N),r=t.memoizedState,r===null)return B(t),null;if(i=(t.flags&128)!=0,o=r.rendering,o===null)if(i)Vc(r,!1);else{if(Y!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=vo(e),o!==null){for(t.flags|=128,Vc(r,!1),e=o.updateQueue,t.updateQueue=e,Bc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)xi(n,e),n=n.sibling;return T(N,N.current&1|2),A&&Ri(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Ie()>nu&&(t.flags|=128,i=!0,Vc(r,!1),t.lanes=4194304)}else{if(!i)if(e=vo(o),e!==null){if(t.flags|=128,i=!0,e=e.updateQueue,t.updateQueue=e,Bc(t,e),Vc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!A)return B(t),null}else 2*Ie()-r.renderingStartTime>nu&&n!==536870912&&(t.flags|=128,i=!0,Vc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(B(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Ie(),e.sibling=null,n=N.current,T(N,i?n&1|2:n&1),A&&Ri(t,r.treeForkCount),e);case 22:case 23:return _o(t),lo(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(B(t),t.subtreeFlags&6&&(t.flags|=8192)):B(t),n=t.updateQueue,n!==null&&Bc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&w(Ta),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),ia(M),B(t),null;case 25:return null;case 30:return null}throw Error(a(156,t.tag))}function Uc(e,t){switch(Vi(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return ia(M),Se(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return we(t),null;case 31:if(t.memoizedState!==null){if(_o(t),t.alternate===null)throw Error(a(340));Zi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(_o(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(a(340));Zi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return w(N),null;case 4:return Se(),null;case 10:return ia(t.type),null;case 22:case 23:return _o(t),lo(),e!==null&&w(Ta),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return ia(M),null;case 25:return null;default:return null}}function Wc(e,t){switch(Vi(t),t.tag){case 3:ia(M),Se();break;case 26:case 27:case 5:we(t);break;case 4:Se();break;case 31:t.memoizedState!==null&&_o(t);break;case 13:_o(t);break;case 19:w(N);break;case 10:ia(t.type);break;case 22:case 23:_o(t),lo(),e!==null&&w(Ta);break;case 24:ia(M)}}function Gc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function Kc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function qc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{io(t,n)}catch(t){Z(e,e.return,t)}}}function Jc(e,t,n){n.props=Zs(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Yc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Xc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}function Zc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Z(e,e.return,t)}}function Qc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[vt]=t}catch(t){Z(e,e.return,t)}}function $c(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function el(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||$c(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function tl(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=un));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(tl(e,t,n),e=e.sibling;e!==null;)tl(e,t,n),e=e.sibling}function nl(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(nl(e,t,n),e=e.sibling;e!==null;)nl(e,t,n),e=e.sibling}function rl(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[_t]=e,t[vt]=n}catch(t){Z(e,e.return,t)}}var il=!1,V=!1,al=!1,ol=typeof WeakSet==`function`?WeakSet:Set,H=null;function sl(e,t){if(e=e.containerInfo,Rd=sp,e=Lr(e),Rr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var i=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||i!==0&&f.nodeType!==3||(c=s+i),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===i&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,H=t;H!==null;)if(t=H,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,H=e;else for(;H!==null;){switch(t=H,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[_t]=e,O(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,i).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=Fr(s,h),v=Fr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,S.T=null,n=lu,lu=null;var o=au,s=su;if(X=0,ou=au=null,su=0,W&6)throw Error(a(331));var c=W;if(W|=4,Il(o.current),Ol(o,o.current,s,n),W=c,id(0,!1),Ke&&typeof Ke.onPostCommitFiberRoot==`function`)try{Ke.onPostCommitFiberRoot(Ge,o)}catch{}return!0}finally{C.p=i,S.T=r,Vu(e,t)}}function Wu(e,t,n){t=Oi(n,t),t=rc(e.stateNode,t,2),e=Za(e,t,2),e!==null&&(st(e,2),rd(e))}function Z(e,t,n){if(e.tag===3)Wu(e,e,n);else for(;t!==null;){if(t.tag===3){Wu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(iu===null||!iu.has(r))){e=Oi(n,e),n=ic(2),r=Za(t,n,2),r!==null&&(ac(n,r,t,e),st(r,2),rd(r));break}}t=t.return}}function Gu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Bl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Wl=!0,i.add(n),e=Ku.bind(null,e,t,n),t.then(e,e))}function Ku(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,G===e&&(q&n)===n&&(Y===4||Y===3&&(q&62914560)===q&&300>Ie()-eu?!(W&2)&&Su(e,0):Jl|=n,Xl===q&&(Xl=0)),rd(e)}function qu(e,t){t===0&&(t=at()),e=pi(e,t),e!==null&&(st(e,t),rd(e))}function Ju(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),qu(e,n)}function Yu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,i=e.memoizedState;i!==null&&(n=i.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(a(314))}r!==null&&r.delete(t),qu(e,n)}function Xu(e,t){return Me(e,t)}var Zu=null,Qu=null,$u=!1,ed=!1,td=!1,nd=0;function rd(e){e!==Qu&&e.next===null&&(Qu===null?Zu=Qu=e:Qu=Qu.next=e),ed=!0,$u||($u=!0,ud())}function id(e,t){if(!td&&ed){td=!0;do for(var n=!1,r=Zu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Je(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,ld(r,a))}else a=q,a=nt(r,r===G?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||rt(r,a)||(n=!0,ld(r,a));r=r.next}while(n);td=!1}}function ad(){od()}function od(){ed=$u=!1;var e=0;nd!==0&&Gd()&&(e=nd);for(var t=Ie(),n=null,r=Zu;r!==null;){var i=r.next,a=sd(r,t);a===0?(r.next=null,n===null?Zu=i:n.next=i,i===null&&(Qu=n)):(n=r,(e!==0||a&3)&&(ed=!0)),r=i}X!==0&&X!==5||id(e,!1),nd!==0&&(nd=0)}function sd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Jt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),O(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Jt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Jt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Jt(n.imageSizes)+`"]`)):i+=`[href="`+Jt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=p({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),O(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Jt(r)+`"][href="`+Jt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=p({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),O(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=kt(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=p({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);O(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=kt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),O(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=kt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),O(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var i=(i=ye.current)?gf(i):null;if(!i)throw Error(a(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=kt(i).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=kt(i).hoistableStyles,s=o.get(e);if(s||(i=i.ownerDocument||i,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=i.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(i,e,n,s.state))),t&&r===null)throw Error(a(528,``));return s}if(t&&r!==null)throw Error(a(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=kt(i).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(a(444,e))}}function Af(e){return`href="`+Jt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return p({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),O(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Jt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Jt(n.href)+`"]`);if(r)return t.instance=r,O(r),r;var i=p({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),O(r),Pd(r,`style`,i),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:i=Af(n.href);var o=e.querySelector(jf(i));if(o)return t.state.loading|=4,t.instance=o,O(o),o;r=Mf(n),(i=mf.get(i))&&Rf(r,i),o=(e.ownerDocument||e).createElement(`link`),O(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(i=e.querySelector(Ff(o)))?(t.instance=i,O(i),i):(r=n,(i=mf.get(o))&&(r=p({},n),zf(r,i)),e=e.ownerDocument||e,i=e.createElement(`script`),O(i),Pd(i,`link`,r),e.head.appendChild(i),t.instance=i);case`void`:return null;default:throw Error(a(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,O(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),O(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=oe()}))(),ce=t((e=>{var t=i().__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;e.c=function(e){return t.H.useMemoCache(e)}})),le=t(((e,t)=>{t.exports=ce()}));function ue(e){return{onFetch:(t,n)=>{let r=t.options,i=t.fetchOptions?.meta?.fetchMore?.direction,a=t.state.data?.pages||[],o=t.state.data?.pageParams||[],s={pages:[],pageParams:[]},c=0,d=async()=>{let n=!1,d=e=>{y(e,()=>t.signal,()=>n=!0)},f=g(t.options,t.fetchOptions),p=async(e,r,i)=>{if(n)return Promise.reject();if(r==null&&e.pages.length)return Promise.resolve(e);let a=await f((()=>{let e={client:t.client,queryKey:t.queryKey,pageParam:r,direction:i?`backward`:`forward`,meta:t.options.meta};return d(e),e})()),{maxPages:o}=t.options,s=i?u:l;return{pages:s(e.pages,a,o),pageParams:s(e.pageParams,r,o)}};if(i&&a.length){let e=i===`backward`,t=e?fe:de,n={pages:a,pageParams:o};s=await p(n,t(r,n),e)}else{let t=e??a.length;do{let e=c===0?o[0]??r.initialPageParam:de(r,s);if(c>0&&e==null)break;s=await p(s,e),c++}while(ct.options.persister?.(d,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n):t.fetchFn=d}}}function de(e,{pages:t,pageParams:n}){let r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function fe(e,{pages:t,pageParams:n}){return t.length>0?e.getPreviousPageParam?.(t[0],t,n[0],n):void 0}var pe=class extends x{constructor(e={}){super(),this.config=e,this.#e=new Set,this.#t=new Map,this.#n=0}#e;#t;#n;build(e,t,n){let r=new h({client:e,mutationCache:this,mutationId:++this.#n,options:e.defaultMutationOptions(t),state:n});return this.add(r),r}add(e){this.#e.add(e);let t=S(e);if(typeof t==`string`){let n=this.#t.get(t);n?n.push(e):this.#t.set(t,[e])}this.notify({type:`added`,mutation:e})}remove(e){if(this.#e.delete(e)){let t=S(e);if(typeof t==`string`){let n=this.#t.get(t);if(n)if(n.length>1){let t=n.indexOf(e);t!==-1&&n.splice(t,1)}else n[0]===e&&this.#t.delete(t)}}this.notify({type:`removed`,mutation:e})}canRun(e){let t=S(e);if(typeof t==`string`){let n=this.#t.get(t)?.find(e=>e.state.status===`pending`);return!n||n===e}else return!0}runNext(e){let t=S(e);return typeof t==`string`?(this.#t.get(t)?.find(t=>t!==e&&t.state.isPaused))?.continue()??Promise.resolve():Promise.resolve()}clear(){p.batch(()=>{this.#e.forEach(e=>{this.notify({type:`removed`,mutation:e})}),this.#e.clear(),this.#t.clear()})}getAll(){return Array.from(this.#e)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>a(t,e))}findAll(e={}){return this.getAll().filter(t=>a(e,t))}notify(e){p.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return p.batch(()=>Promise.all(e.map(e=>e.continue().catch(te))))}};function S(e){return e.options.scope?.id}var C=class extends x{constructor(e={}){super(),this.config=e,this.#e=new Map}#e;build(e,t,n){let r=t.queryKey,i=t.queryHash??d(r,t),a=this.get(i);return a||(a=new v({client:e,queryKey:r,queryHash:i,options:e.defaultQueryOptions(t),state:n,defaultOptions:e.getQueryDefaults(r)}),this.add(a)),a}add(e){this.#e.has(e.queryHash)||(this.#e.set(e.queryHash,e),this.notify({type:`added`,query:e}))}remove(e){let t=this.#e.get(e.queryHash);t&&(e.destroy(),t===e&&this.#e.delete(e.queryHash),this.notify({type:`removed`,query:e}))}clear(){p.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#e.get(e)}getAll(){return[...this.#e.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>b(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>b(e,t)):t}notify(e){p.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){p.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){p.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},me=class{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e={}){this.#e=e.queryCache||new C,this.#t=e.mutationCache||new pe,this.#n=e.defaultOptions||{},this.#r=new Map,this.#i=new Map,this.#a=0}mount(){this.#a++,this.#a===1&&(this.#o=n.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onFocus())}),this.#s=c.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onOnline())}))}unmount(){this.#a--,this.#a===0&&(this.#o?.(),this.#o=void 0,this.#s?.(),this.#s=void 0)}isFetching(e){return this.#e.findAll({...e,fetchStatus:`fetching`}).length}isMutating(e){return this.#t.findAll({...e,status:`pending`}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),n=this.#e.build(this,t),r=n.state.data;return r===void 0?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime(ee(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(r))}getQueriesData(e){return this.#e.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,n){let r=this.defaultQueryOptions({queryKey:e}),i=this.#e.get(r.queryHash)?.state.data,a=m(t,i);if(a!==void 0)return this.#e.build(this,r).setData(a,{...n,manual:!0})}setQueriesData(e,t,n){return p.batch(()=>this.#e.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,n)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state}removeQueries(e){let t=this.#e;p.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let n=this.#e;return p.batch(()=>(n.findAll(e).forEach(e=>{e.reset()}),this.refetchQueries({type:`active`,...e},t)))}cancelQueries(e,t={}){let n={revert:!0,...t},r=p.batch(()=>this.#e.findAll(e).map(e=>e.cancel(n)));return Promise.all(r).then(te).catch(te)}invalidateQueries(e,t={}){return p.batch(()=>(this.#e.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType===`none`?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??`active`},t)))}refetchQueries(e,t={}){let n={...t,cancelRefetch:t.cancelRefetch??!0},r=p.batch(()=>this.#e.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,n);return n.throwOnError||(t=t.catch(te)),e.state.fetchStatus===`paused`?Promise.resolve():t}));return Promise.all(r).then(te)}fetchQuery(e){let t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);let n=this.#e.build(this,t);return n.isStaleByTime(ee(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(te).catch(te)}fetchInfiniteQuery(e){return e.behavior=ue(e.pages),this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(te).catch(te)}ensureInfiniteQueryData(e){return e.behavior=ue(e.pages),this.ensureQueryData(e)}resumePausedMutations(){return c.isOnline()?this.#t.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#e}getMutationCache(){return this.#t}getDefaultOptions(){return this.#n}setDefaultOptions(e){this.#n=e}setQueryDefaults(e,t){this.#r.set(f(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#r.values()],n={};return t.forEach(t=>{s(e,t.queryKey)&&Object.assign(n,t.defaultOptions)}),n}setMutationDefaults(e,t){this.#i.set(f(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#i.values()],n={};return t.forEach(t=>{s(e,t.mutationKey)&&Object.assign(n,t.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#n.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||=d(t.queryKey,t),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!==`always`),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode=`offlineFirst`),t.queryFn===r&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#n.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#e.clear(),this.#t.clear()}},he=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),ge=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),_e=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),w=e=>{let t=_e(e);return t.charAt(0).toUpperCase()+t.slice(1)},T={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},ve=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},E=e(i()),ye=(0,E.createContext)({}),be=()=>(0,E.useContext)(ye),xe=(0,E.forwardRef)(({color:e,size:t,strokeWidth:n,absoluteStrokeWidth:r,className:i=``,children:a,iconNode:o,...s},c)=>{let{size:l=24,strokeWidth:u=2,absoluteStrokeWidth:d=!1,color:f=`currentColor`,className:p=``}=be()??{},m=r??d?Number(n??u)*24/Number(t??l):n??u;return(0,E.createElement)(`svg`,{ref:c,...T,width:t??l??T.width,height:t??l??T.height,stroke:e??f,strokeWidth:m,className:he(`lucide`,p,i),...!a&&!ve(s)&&{"aria-hidden":`true`},...s},[...o.map(([e,t])=>(0,E.createElement)(e,t)),...Array.isArray(a)?a:[a]])}),Se=(e,t)=>{let n=(0,E.forwardRef)(({className:n,...r},i)=>(0,E.createElement)(xe,{ref:i,iconNode:t,className:he(`lucide-${ge(w(e))}`,`lucide-${e}`,n),...r}));return n.displayName=w(e),n},Ce=Se(`database`,[[`ellipse`,{cx:`12`,cy:`5`,rx:`9`,ry:`3`,key:`msslwz`}],[`path`,{d:`M3 5V19A9 3 0 0 0 21 19V5`,key:`1wlel7`}],[`path`,{d:`M3 12A9 3 0 0 0 21 12`,key:`mv7ke4`}]]),we=Se(`file-search`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`circle`,{cx:`11.5`,cy:`14.5`,r:`2.5`,key:`1bq0ko`}],[`path`,{d:`M13.3 16.3 15 18`,key:`2quom7`}]]),Te=Se(`git-branch-plus`,[[`path`,{d:`M6 3v12`,key:`qpgusn`}],[`path`,{d:`M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6z`,key:`1d02ji`}],[`path`,{d:`M6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z`,key:`chk6ph`}],[`path`,{d:`M15 6a9 9 0 0 0-9 9`,key:`or332x`}],[`path`,{d:`M18 15v6`,key:`9wciyi`}],[`path`,{d:`M21 18h-6`,key:`139f0c`}]]),Ee=Se(`scale`,[[`path`,{d:`M12 3v18`,key:`108xh3`}],[`path`,{d:`m19 8 3 8a5 5 0 0 1-6 0zV7`,key:`zcdpyk`}],[`path`,{d:`M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1`,key:`1yorad`}],[`path`,{d:`m5 8 3 8a5 5 0 0 1-6 0zV7`,key:`eua70x`}],[`path`,{d:`M7 21h10`,key:`1b0cd5`}]]),De=Se(`settings-2`,[[`path`,{d:`M14 17H5`,key:`gfn3mx`}],[`path`,{d:`M19 7h-9`,key:`6i9tg`}],[`circle`,{cx:`17`,cy:`17`,r:`3`,key:`18b49y`}],[`circle`,{cx:`7`,cy:`7`,r:`3`,key:`dfmy0x`}]]),Oe=le(),D=o(),ke=`modulepreload`,Ae=function(e){return`/`+e},je={},Me=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=Ae(t,n),t in je)return;je[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:ke,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Ne=(0,E.lazy)(()=>Me(()=>import(`./DecisionWorkspace-DOZnUOYv.js`).then(e=>({default:e.DecisionWorkspace})),__vite__mapDeps([0,1,2]))),Pe=(0,E.lazy)(()=>Me(()=>import(`./DiffMergeWorkspace-BP5v4yP2.js`).then(e=>({default:e.DiffMergeWorkspace})),__vite__mapDeps([3,1,2]))),Fe=(0,E.lazy)(()=>Me(()=>import(`./GraphWorkspace-DGFkh5CZ.js`).then(e=>({default:e.GraphWorkspace})),__vite__mapDeps([4,1,2,5,6,7,8,9]))),Ie=(0,E.lazy)(()=>Me(()=>import(`./ImportExportWorkspace-CYQpATgz.js`).then(e=>({default:e.ImportExportWorkspace})),__vite__mapDeps([10,1,2,11]))),Le=(0,E.lazy)(()=>Me(()=>import(`./LineageDiagram-DQTOL97h.js`).then(e=>({default:e.LineageDiagram})),__vite__mapDeps([12,1,2,13,14]))),Re=(0,E.lazy)(()=>Me(()=>import(`./ReasoningWorkspace-BGe6HUKK.js`).then(e=>({default:e.ReasoningWorkspace})),__vite__mapDeps([15,1,2]))),ze=(0,E.lazy)(()=>Me(()=>import(`./SparqlWorkspace-CK6q2l7f.js`).then(e=>({default:e.SparqlWorkspace})),__vite__mapDeps([16,1,2]))),Be=(0,E.lazy)(()=>Me(()=>import(`./VocabularyWorkspace-Xth7XSJd.js`).then(e=>({default:e.VocabularyWorkspace})),__vite__mapDeps([17,1,2,11,13]))),Ve=new me,He=[{id:`explore`,label:`Explore`,hint:`Graph and vocabulary browsing`,icon:Ce},{id:`analyze`,label:`Analyze`,hint:`Query and inspect the dataset`,icon:we},{id:`decisions`,label:`Decisions`,hint:`Decision chains and precedent review`,icon:Ee},{id:`enrich`,label:`Enrich`,hint:`Import, export, and merge workflows`,icon:Te},{id:`manage`,label:`Manage`,hint:`Lineage and governance tooling`,icon:De}],Ue=` +`).replace(Ad,``)}function Md(e,t){return t=jd(t),jd(e)===t}function $(e,t,n,r,i,o){switch(n){case`children`:typeof r==`string`?t===`body`||t===`textarea`&&r===``||tn(e,r):(typeof r==`number`||typeof r==`bigint`)&&t!==`body`&&tn(e,``+r);break;case`className`:zt(e,`class`,r);break;case`tabIndex`:zt(e,`tabindex`,r);break;case`dir`:case`role`:case`viewBox`:case`width`:case`height`:zt(e,n,r);break;case`style`:an(e,r,o);break;case`data`:if(t!==`object`){zt(e,`data`,r);break}case`src`:case`href`:if(r===``&&(t!==`a`||n!==`href`)){e.removeAttribute(n);break}if(r==null||typeof r==`function`||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=ln(``+r),e.setAttribute(n,r);break;case`action`:case`formAction`:if(typeof r==`function`){e.setAttribute(n,`javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')`);break}else typeof o==`function`&&(n===`formAction`?(t!==`input`&&$(e,t,`name`,i.name,i,null),$(e,t,`formEncType`,i.formEncType,i,null),$(e,t,`formMethod`,i.formMethod,i,null),$(e,t,`formTarget`,i.formTarget,i,null)):($(e,t,`encType`,i.encType,i,null),$(e,t,`method`,i.method,i,null),$(e,t,`target`,i.target,i,null)));if(r==null||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=ln(``+r),e.setAttribute(n,r);break;case`onClick`:r!=null&&(e.onclick=un);break;case`onScroll`:r!=null&&Q(`scroll`,e);break;case`onScrollEnd`:r!=null&&Q(`scrollend`,e);break;case`dangerouslySetInnerHTML`:if(r!=null){if(typeof r!=`object`||!(`__html`in r))throw Error(a(61));if(n=r.__html,n!=null){if(i.children!=null)throw Error(a(60));e.innerHTML=n}}break;case`multiple`:e.multiple=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`muted`:e.muted=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`suppressContentEditableWarning`:case`suppressHydrationWarning`:case`defaultValue`:case`defaultChecked`:case`innerHTML`:case`ref`:break;case`autoFocus`:break;case`xlinkHref`:if(r==null||typeof r==`function`||typeof r==`boolean`||typeof r==`symbol`){e.removeAttribute(`xlink:href`);break}n=ln(``+r),e.setAttributeNS(`http://www.w3.org/1999/xlink`,`xlink:href`,n);break;case`contentEditable`:case`spellCheck`:case`draggable`:case`value`:case`autoReverse`:case`externalResourcesRequired`:case`focusable`:case`preserveAlpha`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``+r):e.removeAttribute(n);break;case`inert`:case`allowFullScreen`:case`async`:case`autoPlay`:case`controls`:case`default`:case`defer`:case`disabled`:case`disablePictureInPicture`:case`disableRemotePlayback`:case`formNoValidate`:case`hidden`:case`loop`:case`noModule`:case`noValidate`:case`open`:case`playsInline`:case`readOnly`:case`required`:case`reversed`:case`scoped`:case`seamless`:case`itemScope`:r&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``):e.removeAttribute(n);break;case`capture`:case`download`:!0===r?e.setAttribute(n,``):!1!==r&&r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,r):e.removeAttribute(n);break;case`cols`:case`rows`:case`size`:case`span`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`&&!isNaN(r)&&1<=r?e.setAttribute(n,r):e.removeAttribute(n);break;case`rowSpan`:case`start`:r==null||typeof r==`function`||typeof r==`symbol`||isNaN(r)?e.removeAttribute(n):e.setAttribute(n,r);break;case`popover`:Q(`beforetoggle`,e),Q(`toggle`,e),Rt(e,`popover`,r);break;case`xlinkActuate`:Bt(e,`http://www.w3.org/1999/xlink`,`xlink:actuate`,r);break;case`xlinkArcrole`:Bt(e,`http://www.w3.org/1999/xlink`,`xlink:arcrole`,r);break;case`xlinkRole`:Bt(e,`http://www.w3.org/1999/xlink`,`xlink:role`,r);break;case`xlinkShow`:Bt(e,`http://www.w3.org/1999/xlink`,`xlink:show`,r);break;case`xlinkTitle`:Bt(e,`http://www.w3.org/1999/xlink`,`xlink:title`,r);break;case`xlinkType`:Bt(e,`http://www.w3.org/1999/xlink`,`xlink:type`,r);break;case`xmlBase`:Bt(e,`http://www.w3.org/XML/1998/namespace`,`xml:base`,r);break;case`xmlLang`:Bt(e,`http://www.w3.org/XML/1998/namespace`,`xml:lang`,r);break;case`xmlSpace`:Bt(e,`http://www.w3.org/XML/1998/namespace`,`xml:space`,r);break;case`is`:Rt(e,`is`,r);break;case`innerText`:case`textContent`:break;default:(!(2s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Jt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),O(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Jt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Jt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Jt(n.imageSizes)+`"]`)):i+=`[href="`+Jt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=p({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),O(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Jt(r)+`"][href="`+Jt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=p({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),O(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=kt(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=p({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);O(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=kt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),O(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=kt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),O(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var i=(i=ye.current)?gf(i):null;if(!i)throw Error(a(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=kt(i).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=kt(i).hoistableStyles,s=o.get(e);if(s||(i=i.ownerDocument||i,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=i.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(i,e,n,s.state))),t&&r===null)throw Error(a(528,``));return s}if(t&&r!==null)throw Error(a(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=kt(i).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(a(444,e))}}function Af(e){return`href="`+Jt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return p({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),O(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Jt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Jt(n.href)+`"]`);if(r)return t.instance=r,O(r),r;var i=p({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),O(r),Pd(r,`style`,i),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:i=Af(n.href);var o=e.querySelector(jf(i));if(o)return t.state.loading|=4,t.instance=o,O(o),o;r=Mf(n),(i=mf.get(i))&&Rf(r,i),o=(e.ownerDocument||e).createElement(`link`),O(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(i=e.querySelector(Ff(o)))?(t.instance=i,O(i),i):(r=n,(i=mf.get(o))&&(r=p({},n),zf(r,i)),e=e.ownerDocument||e,i=e.createElement(`script`),O(i),Pd(i,`link`,r),e.head.appendChild(i),t.instance=i);case`void`:return null;default:throw Error(a(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,O(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),O(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=oe()}))(),ce=t((e=>{var t=i().__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;e.c=function(e){return t.H.useMemoCache(e)}})),le=t(((e,t)=>{t.exports=ce()}));function ue(e){return{onFetch:(t,n)=>{let r=t.options,i=t.fetchOptions?.meta?.fetchMore?.direction,a=t.state.data?.pages||[],o=t.state.data?.pageParams||[],s={pages:[],pageParams:[]},c=0,d=async()=>{let n=!1,d=e=>{y(e,()=>t.signal,()=>n=!0)},f=g(t.options,t.fetchOptions),p=async(e,r,i)=>{if(n)return Promise.reject();if(r==null&&e.pages.length)return Promise.resolve(e);let a=await f((()=>{let e={client:t.client,queryKey:t.queryKey,pageParam:r,direction:i?`backward`:`forward`,meta:t.options.meta};return d(e),e})()),{maxPages:o}=t.options,s=i?u:l;return{pages:s(e.pages,a,o),pageParams:s(e.pageParams,r,o)}};if(i&&a.length){let e=i===`backward`,t=e?fe:de,n={pages:a,pageParams:o};s=await p(n,t(r,n),e)}else{let t=e??a.length;do{let e=c===0?o[0]??r.initialPageParam:de(r,s);if(c>0&&e==null)break;s=await p(s,e),c++}while(ct.options.persister?.(d,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n):t.fetchFn=d}}}function de(e,{pages:t,pageParams:n}){let r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function fe(e,{pages:t,pageParams:n}){return t.length>0?e.getPreviousPageParam?.(t[0],t,n[0],n):void 0}var pe=class extends x{constructor(e={}){super(),this.config=e,this.#e=new Set,this.#t=new Map,this.#n=0}#e;#t;#n;build(e,t,n){let r=new h({client:e,mutationCache:this,mutationId:++this.#n,options:e.defaultMutationOptions(t),state:n});return this.add(r),r}add(e){this.#e.add(e);let t=S(e);if(typeof t==`string`){let n=this.#t.get(t);n?n.push(e):this.#t.set(t,[e])}this.notify({type:`added`,mutation:e})}remove(e){if(this.#e.delete(e)){let t=S(e);if(typeof t==`string`){let n=this.#t.get(t);if(n)if(n.length>1){let t=n.indexOf(e);t!==-1&&n.splice(t,1)}else n[0]===e&&this.#t.delete(t)}}this.notify({type:`removed`,mutation:e})}canRun(e){let t=S(e);if(typeof t==`string`){let n=this.#t.get(t)?.find(e=>e.state.status===`pending`);return!n||n===e}else return!0}runNext(e){let t=S(e);return typeof t==`string`?(this.#t.get(t)?.find(t=>t!==e&&t.state.isPaused))?.continue()??Promise.resolve():Promise.resolve()}clear(){p.batch(()=>{this.#e.forEach(e=>{this.notify({type:`removed`,mutation:e})}),this.#e.clear(),this.#t.clear()})}getAll(){return Array.from(this.#e)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>a(t,e))}findAll(e={}){return this.getAll().filter(t=>a(e,t))}notify(e){p.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return p.batch(()=>Promise.all(e.map(e=>e.continue().catch(te))))}};function S(e){return e.options.scope?.id}var C=class extends x{constructor(e={}){super(),this.config=e,this.#e=new Map}#e;build(e,t,n){let r=t.queryKey,i=t.queryHash??d(r,t),a=this.get(i);return a||(a=new v({client:e,queryKey:r,queryHash:i,options:e.defaultQueryOptions(t),state:n,defaultOptions:e.getQueryDefaults(r)}),this.add(a)),a}add(e){this.#e.has(e.queryHash)||(this.#e.set(e.queryHash,e),this.notify({type:`added`,query:e}))}remove(e){let t=this.#e.get(e.queryHash);t&&(e.destroy(),t===e&&this.#e.delete(e.queryHash),this.notify({type:`removed`,query:e}))}clear(){p.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#e.get(e)}getAll(){return[...this.#e.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>b(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>b(e,t)):t}notify(e){p.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){p.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){p.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},me=class{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e={}){this.#e=e.queryCache||new C,this.#t=e.mutationCache||new pe,this.#n=e.defaultOptions||{},this.#r=new Map,this.#i=new Map,this.#a=0}mount(){this.#a++,this.#a===1&&(this.#o=n.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onFocus())}),this.#s=c.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onOnline())}))}unmount(){this.#a--,this.#a===0&&(this.#o?.(),this.#o=void 0,this.#s?.(),this.#s=void 0)}isFetching(e){return this.#e.findAll({...e,fetchStatus:`fetching`}).length}isMutating(e){return this.#t.findAll({...e,status:`pending`}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),n=this.#e.build(this,t),r=n.state.data;return r===void 0?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime(ee(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(r))}getQueriesData(e){return this.#e.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,n){let r=this.defaultQueryOptions({queryKey:e}),i=this.#e.get(r.queryHash)?.state.data,a=m(t,i);if(a!==void 0)return this.#e.build(this,r).setData(a,{...n,manual:!0})}setQueriesData(e,t,n){return p.batch(()=>this.#e.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,n)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state}removeQueries(e){let t=this.#e;p.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let n=this.#e;return p.batch(()=>(n.findAll(e).forEach(e=>{e.reset()}),this.refetchQueries({type:`active`,...e},t)))}cancelQueries(e,t={}){let n={revert:!0,...t},r=p.batch(()=>this.#e.findAll(e).map(e=>e.cancel(n)));return Promise.all(r).then(te).catch(te)}invalidateQueries(e,t={}){return p.batch(()=>(this.#e.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType===`none`?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??`active`},t)))}refetchQueries(e,t={}){let n={...t,cancelRefetch:t.cancelRefetch??!0},r=p.batch(()=>this.#e.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,n);return n.throwOnError||(t=t.catch(te)),e.state.fetchStatus===`paused`?Promise.resolve():t}));return Promise.all(r).then(te)}fetchQuery(e){let t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);let n=this.#e.build(this,t);return n.isStaleByTime(ee(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(te).catch(te)}fetchInfiniteQuery(e){return e.behavior=ue(e.pages),this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(te).catch(te)}ensureInfiniteQueryData(e){return e.behavior=ue(e.pages),this.ensureQueryData(e)}resumePausedMutations(){return c.isOnline()?this.#t.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#e}getMutationCache(){return this.#t}getDefaultOptions(){return this.#n}setDefaultOptions(e){this.#n=e}setQueryDefaults(e,t){this.#r.set(f(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#r.values()],n={};return t.forEach(t=>{s(e,t.queryKey)&&Object.assign(n,t.defaultOptions)}),n}setMutationDefaults(e,t){this.#i.set(f(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#i.values()],n={};return t.forEach(t=>{s(e,t.mutationKey)&&Object.assign(n,t.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#n.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||=d(t.queryKey,t),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!==`always`),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode=`offlineFirst`),t.queryFn===r&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#n.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#e.clear(),this.#t.clear()}},he=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),ge=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),_e=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),w=e=>{let t=_e(e);return t.charAt(0).toUpperCase()+t.slice(1)},T={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},ve=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},E=e(i()),ye=(0,E.createContext)({}),be=()=>(0,E.useContext)(ye),xe=(0,E.forwardRef)(({color:e,size:t,strokeWidth:n,absoluteStrokeWidth:r,className:i=``,children:a,iconNode:o,...s},c)=>{let{size:l=24,strokeWidth:u=2,absoluteStrokeWidth:d=!1,color:f=`currentColor`,className:p=``}=be()??{},m=r??d?Number(n??u)*24/Number(t??l):n??u;return(0,E.createElement)(`svg`,{ref:c,...T,width:t??l??T.width,height:t??l??T.height,stroke:e??f,strokeWidth:m,className:he(`lucide`,p,i),...!a&&!ve(s)&&{"aria-hidden":`true`},...s},[...o.map(([e,t])=>(0,E.createElement)(e,t)),...Array.isArray(a)?a:[a]])}),Se=(e,t)=>{let n=(0,E.forwardRef)(({className:n,...r},i)=>(0,E.createElement)(xe,{ref:i,iconNode:t,className:he(`lucide-${ge(w(e))}`,`lucide-${e}`,n),...r}));return n.displayName=w(e),n},Ce=Se(`database`,[[`ellipse`,{cx:`12`,cy:`5`,rx:`9`,ry:`3`,key:`msslwz`}],[`path`,{d:`M3 5V19A9 3 0 0 0 21 19V5`,key:`1wlel7`}],[`path`,{d:`M3 12A9 3 0 0 0 21 12`,key:`mv7ke4`}]]),we=Se(`file-search`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`circle`,{cx:`11.5`,cy:`14.5`,r:`2.5`,key:`1bq0ko`}],[`path`,{d:`M13.3 16.3 15 18`,key:`2quom7`}]]),Te=Se(`git-branch-plus`,[[`path`,{d:`M6 3v12`,key:`qpgusn`}],[`path`,{d:`M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6z`,key:`1d02ji`}],[`path`,{d:`M6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z`,key:`chk6ph`}],[`path`,{d:`M15 6a9 9 0 0 0-9 9`,key:`or332x`}],[`path`,{d:`M18 15v6`,key:`9wciyi`}],[`path`,{d:`M21 18h-6`,key:`139f0c`}]]),Ee=Se(`scale`,[[`path`,{d:`M12 3v18`,key:`108xh3`}],[`path`,{d:`m19 8 3 8a5 5 0 0 1-6 0zV7`,key:`zcdpyk`}],[`path`,{d:`M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1`,key:`1yorad`}],[`path`,{d:`m5 8 3 8a5 5 0 0 1-6 0zV7`,key:`eua70x`}],[`path`,{d:`M7 21h10`,key:`1b0cd5`}]]),De=Se(`settings-2`,[[`path`,{d:`M14 17H5`,key:`gfn3mx`}],[`path`,{d:`M19 7h-9`,key:`6i9tg`}],[`circle`,{cx:`17`,cy:`17`,r:`3`,key:`18b49y`}],[`circle`,{cx:`7`,cy:`7`,r:`3`,key:`dfmy0x`}]]),Oe=le(),D=o(),ke=`modulepreload`,Ae=function(e){return`/`+e},je={},Me=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}r=o(t.map(t=>{if(t=Ae(t,n),t in je)return;je[t]=!0;let r=t.endsWith(`.css`),i=r?`[rel="stylesheet"]`:``;if(n)for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;let o=document.createElement(`link`);if(o.rel=r?`stylesheet`:ke,r||(o.as=`script`),o.crossOrigin=``,o.href=t,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),r)return new Promise((e,n)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Ne=(0,E.lazy)(()=>Me(()=>import(`./DecisionWorkspace-CkoD0QKe.js`).then(e=>({default:e.DecisionWorkspace})),__vite__mapDeps([0,1,2]))),Pe=(0,E.lazy)(()=>Me(()=>import(`./DiffMergeWorkspace-DDK7n-jO.js`).then(e=>({default:e.DiffMergeWorkspace})),__vite__mapDeps([3,1,2]))),Fe=(0,E.lazy)(()=>Me(()=>import(`./GraphWorkspace-Bqx0S-ru.js`).then(e=>({default:e.GraphWorkspace})),__vite__mapDeps([4,1,2,5,6,7,8,9]))),Ie=(0,E.lazy)(()=>Me(()=>import(`./ImportExportWorkspace-BU8nK4nT.js`).then(e=>({default:e.ImportExportWorkspace})),__vite__mapDeps([10,1,2,11]))),Le=(0,E.lazy)(()=>Me(()=>import(`./LineageDiagram-BcIhRlOg.js`).then(e=>({default:e.LineageDiagram})),__vite__mapDeps([12,1,2,13,14]))),Re=(0,E.lazy)(()=>Me(()=>import(`./ReasoningWorkspace-BGe6HUKK.js`).then(e=>({default:e.ReasoningWorkspace})),__vite__mapDeps([15,1,2]))),ze=(0,E.lazy)(()=>Me(()=>import(`./SparqlWorkspace-CK6q2l7f.js`).then(e=>({default:e.SparqlWorkspace})),__vite__mapDeps([16,1,2]))),Be=(0,E.lazy)(()=>Me(()=>import(`./VocabularyWorkspace-BonIpRiP.js`).then(e=>({default:e.VocabularyWorkspace})),__vite__mapDeps([17,1,2,11,13]))),Ve=new me,He=[{id:`explore`,label:`Explore`,hint:`Graph and vocabulary browsing`,icon:Ce},{id:`analyze`,label:`Analyze`,hint:`Query and inspect the dataset`,icon:we},{id:`decisions`,label:`Decisions`,hint:`Decision chains and precedent review`,icon:Ee},{id:`enrich`,label:`Enrich`,hint:`Import, export, and merge workflows`,icon:Te},{id:`manage`,label:`Manage`,hint:`Lineage and governance tooling`,icon:De}],Ue=` :root { --app-bg: #07111f; --panel-bg: rgba(7, 17, 31, 0.82); diff --git a/semantica/static/assets/neighborhoodPanelPlugin-CJEfjLxQ.js b/semantica/static/assets/neighborhoodPanelPlugin-CJEfjLxQ.js deleted file mode 100644 index cc25fd47..00000000 --- a/semantica/static/assets/neighborhoodPanelPlugin-CJEfjLxQ.js +++ /dev/null @@ -1 +0,0 @@ -import{t as e}from"./neighborhoodPanelPlugin-Dra5vWrD.js";export{e as neighborhoodPanelPlugin}; \ No newline at end of file diff --git a/semantica/static/assets/neighborhoodPanelPlugin-Dra5vWrD.js b/semantica/static/assets/neighborhoodPanelPlugin-Dra5vWrD.js deleted file mode 100644 index e9416848..00000000 --- a/semantica/static/assets/neighborhoodPanelPlugin-Dra5vWrD.js +++ /dev/null @@ -1 +0,0 @@ -import{a as e}from"./query-vendor-Cbp9LWgA.js";var t=e(),n=`neighborhood-panel`,r=10;function i(e){let t=[e.nodeType,`degree ${e.degree}`];return e.weight>0&&t.push(`weight ${e.weight.toFixed(2)}`),t.join(` · `)}var a={id:`neighborhood-panel`,mount:()=>{},unmount:()=>{},onStateChange:()=>{},toolbarItems:e=>[{id:`neighborhood-toggle`,label:`Neighbors`,title:`Toggle neighborhood panel`,active:e.isPanelOpen(n),order:30,onClick:()=>e.dispatchAction({type:`togglePanel`,panelId:n})}],renderPanel:e=>{if(!e.isPanelOpen(n))return null;let a=e.getSelectedNodeState();if(!a)return{id:n,title:`Neighborhood`,placement:`bottom`,order:20,defaultOpen:!1,preferredWidth:360,preferredHeight:260,content:(0,t.jsx)(`div`,{style:p,children:`Select a node to inspect its local neighborhood.`})};let m=e.graph.neighbors(a.id).map(t=>{let n=e.graph.getNodeAttributes(t),r=0;if(e.graph.hasDirectedEdge(a.id,t)){let n=e.graph.getDirectedEdgeAttributes(a.id,t);r=Math.max(r,Number(n.weight??0))}if(e.graph.hasDirectedEdge(t,a.id)){let n=e.graph.getDirectedEdgeAttributes(t,a.id);r=Math.max(r,Number(n.weight??0))}return{id:t,label:String(n.label||t),nodeType:String(n.nodeType||`Entity`),color:String(n.baseColor||n.color||e.theme.palette.semantic[0]),weight:r,degree:e.graph.degree(t)}}).sort((e,t)=>t.weight===e.weight?t.degree===e.degree?e.label.localeCompare(t.label):t.degree-e.degree:t.weight-e.weight).slice(0,r);return{id:n,title:`Neighborhood`,placement:`bottom`,order:20,defaultOpen:!1,preferredWidth:360,preferredHeight:260,content:(0,t.jsxs)(`div`,{style:o,children:[(0,t.jsx)(`div`,{style:s,children:a.label}),(0,t.jsxs)(`div`,{style:c,children:[a.neighborCount.toLocaleString(),` direct neighbors in the full graph`]}),m.length?(0,t.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:m.map(n=>(0,t.jsxs)(`button`,{type:`button`,onClick:()=>e.dispatchAction({type:`selectNode`,nodeId:n.id}),style:l,children:[(0,t.jsx)(`span`,{style:{...u,background:n.color,boxShadow:`0 0 16px ${n.color}40`}}),(0,t.jsxs)(`div`,{style:{minWidth:0,flex:1,textAlign:`left`},children:[(0,t.jsx)(`div`,{style:d,children:n.label}),(0,t.jsx)(`div`,{style:f,children:i(n)})]})]},n.id))}):(0,t.jsx)(`div`,{style:p,children:`No direct neighbors are available for this node.`})]})}}},o={display:`flex`,flexDirection:`column`,gap:12},s={color:`#f3f7fd`,fontSize:14,fontWeight:700},c={color:`#8ea4be`,fontSize:12,lineHeight:1.5},l={display:`flex`,alignItems:`center`,gap:10,width:`100%`,padding:`8px 10px`,background:`rgba(255,255,255,0.025)`,border:`1px solid rgba(255,255,255,0.06)`,borderRadius:12,cursor:`pointer`},u={width:10,height:10,borderRadius:999,flexShrink:0},d={color:`#f3f7fd`,fontSize:13,fontWeight:600,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},f={color:`#8ea4be`,fontSize:12},p={color:`#8ea4be`,fontSize:12,lineHeight:1.5};export{a as t}; \ No newline at end of file diff --git a/semantica/static/assets/neighborhoodPanelPlugin-DtCzBl4D.js b/semantica/static/assets/neighborhoodPanelPlugin-DtCzBl4D.js new file mode 100644 index 00000000..959d94eb --- /dev/null +++ b/semantica/static/assets/neighborhoodPanelPlugin-DtCzBl4D.js @@ -0,0 +1 @@ +import{t as e}from"./neighborhoodPanelPlugin-qsLfEPn1.js";export{e as neighborhoodPanelPlugin}; \ No newline at end of file diff --git a/semantica/static/assets/neighborhoodPanelPlugin-qsLfEPn1.js b/semantica/static/assets/neighborhoodPanelPlugin-qsLfEPn1.js new file mode 100644 index 00000000..878963bb --- /dev/null +++ b/semantica/static/assets/neighborhoodPanelPlugin-qsLfEPn1.js @@ -0,0 +1 @@ +import{a as e}from"./query-vendor-Cbp9LWgA.js";var t=e(),n=`neighborhood-panel`,r=10;function i(e,t,n){let r=0;return e.forEachDirectedEdge(t,n,(e,t)=>{r=Math.max(r,Number(t.weight??0))}),r}function a(e){let t=[e.nodeType,`degree ${e.degree}`];return e.weight>0&&t.push(`weight ${e.weight.toFixed(2)}`),t.join(` · `)}var o={id:`neighborhood-panel`,mount:()=>{},unmount:()=>{},onStateChange:()=>{},toolbarItems:e=>[{id:`neighborhood-toggle`,label:`Neighbors`,title:`Toggle neighborhood panel`,active:e.isPanelOpen(n),order:30,onClick:()=>e.dispatchAction({type:`togglePanel`,panelId:n})}],renderPanel:e=>{if(!e.isPanelOpen(n))return null;let o=e.getSelectedNodeState();if(!o)return{id:n,title:`Neighborhood`,placement:`bottom`,order:20,defaultOpen:!1,preferredWidth:360,preferredHeight:260,content:(0,t.jsx)(`div`,{style:m,children:`Select a node to inspect its local neighborhood.`})};let h=e.graph.neighbors(o.id).map(t=>{let n=e.graph.getNodeAttributes(t),r=Math.max(i(e.graph,o.id,t),i(e.graph,t,o.id));return{id:t,label:String(n.label||t),nodeType:String(n.nodeType||`Entity`),color:String(n.baseColor||n.color||e.theme.palette.semantic[0]),weight:r,degree:e.graph.degree(t)}}).sort((e,t)=>t.weight===e.weight?t.degree===e.degree?e.label.localeCompare(t.label):t.degree-e.degree:t.weight-e.weight).slice(0,r);return{id:n,title:`Neighborhood`,placement:`bottom`,order:20,defaultOpen:!1,preferredWidth:360,preferredHeight:260,content:(0,t.jsxs)(`div`,{style:s,children:[(0,t.jsx)(`div`,{style:c,children:o.label}),(0,t.jsxs)(`div`,{style:l,children:[o.neighborCount.toLocaleString(),` direct neighbors in the full graph`]}),h.length?(0,t.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:h.map(n=>(0,t.jsxs)(`button`,{type:`button`,onClick:()=>e.dispatchAction({type:`selectNode`,nodeId:n.id}),style:u,children:[(0,t.jsx)(`span`,{style:{...d,background:n.color,boxShadow:`0 0 16px ${n.color}40`}}),(0,t.jsxs)(`div`,{style:{minWidth:0,flex:1,textAlign:`left`},children:[(0,t.jsx)(`div`,{style:f,children:n.label}),(0,t.jsx)(`div`,{style:p,children:a(n)})]})]},n.id))}):(0,t.jsx)(`div`,{style:m,children:`No direct neighbors are available for this node.`})]})}}},s={display:`flex`,flexDirection:`column`,gap:12},c={color:`#f3f7fd`,fontSize:14,fontWeight:700},l={color:`#8ea4be`,fontSize:12,lineHeight:1.5},u={display:`flex`,alignItems:`center`,gap:10,width:`100%`,padding:`8px 10px`,background:`rgba(255,255,255,0.025)`,border:`1px solid rgba(255,255,255,0.06)`,borderRadius:12,cursor:`pointer`},d={width:10,height:10,borderRadius:999,flexShrink:0},f={color:`#f3f7fd`,fontSize:13,fontWeight:600,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},p={color:`#8ea4be`,fontSize:12},m={color:`#8ea4be`,fontSize:12,lineHeight:1.5};export{o as t}; \ No newline at end of file diff --git a/semantica/static/index.html b/semantica/static/index.html index 1b1ae455..4d482b1e 100644 --- a/semantica/static/index.html +++ b/semantica/static/index.html @@ -5,7 +5,7 @@ semantica-explorer - + diff --git a/tests/explorer/test_explorer_api.py b/tests/explorer/test_explorer_api.py index a246230c..f0d56859 100644 --- a/tests/explorer/test_explorer_api.py +++ b/tests/explorer/test_explorer_api.py @@ -193,6 +193,43 @@ class TestGraphEdges: {json.dumps(edge, sort_keys=True) for edge in second_payload["edges"]} ) + def test_list_edges_repeated_request_is_stable(self, client): + first_response = client.get("/api/graph/edges?limit=20") + second_response = client.get("/api/graph/edges?limit=20") + + assert first_response.status_code == 200 + assert second_response.status_code == 200 + assert first_response.json() == second_response.json() + + def test_list_edges_pagination_union_matches_total(self, client): + cursor = None + seen_ids: set[str] = set() + seen_rows: set[str] = set() + total = None + + while True: + url = "/api/graph/edges?limit=2" + if cursor: + url = f"{url}&cursor={cursor}" + response = client.get(url) + assert response.status_code == 200 + payload = response.json() + total = payload["total"] if total is None else total + + for edge in payload["edges"]: + row_key = json.dumps(edge, sort_keys=True) + assert row_key not in seen_rows + seen_rows.add(row_key) + assert edge["id"] not in seen_ids + seen_ids.add(edge["id"]) + + cursor = payload["next_cursor"] + if not cursor: + break + + assert total is not None + assert len(seen_ids) == total + class TestSearchAndStats: def test_search(self, client): @@ -385,12 +422,14 @@ class TestImportExport: {"id": "meta_tgt", "type": "test", "properties": {"content": "tgt"}}, ], "edges": [ - { - "source": "meta_src", - "target": "meta_tgt", - "type": "tagged", - "metadata": {"label": "important", "weight": 0.7}, - } + { + "id": "meta-edge-1", + "familyId": "meta-family", + "source": "meta_src", + "target": "meta_tgt", + "type": "tagged", + "metadata": {"label": "important", "weight": 0.7}, + } ], } ) @@ -406,7 +445,10 @@ class TestImportExport: edge_lookup = client.get("/api/graph/edges?source=meta_src&target=meta_tgt") assert edge_lookup.status_code == 200 - props = edge_lookup.json()["edges"][0]["properties"] + edge_payload = edge_lookup.json()["edges"][0] + props = edge_payload["properties"] + assert edge_payload["id"] == "meta-edge-1" + assert edge_payload["familyId"] == "meta-family" assert props["label"] == "important" def test_import_csv(self, client): @@ -518,3 +560,81 @@ class TestGenericGraphFileLoading: payload = edges.json() assert payload["total"] == 1 assert payload["edges"][0]["type"] == "candidate" + + def test_generic_file_loading_assigns_stable_legacy_edge_ids(self): + payload = { + "nodes": [ + {"id": "legacy_src", "type": "entity", "properties": {"content": "Legacy source"}}, + {"id": "legacy_tgt", "type": "entity", "properties": {"content": "Legacy target"}}, + ], + "edges": [ + { + "source": "legacy_src", + "target": "legacy_tgt", + "type": "related_to", + "weight": 0.75, + "metadata": {"evidence": "legacy"}, + } + ], + } + graph_path = self._write_graph_payload(payload) + + session_one = GraphSession.from_file(str(graph_path)) + session_two = GraphSession.from_file(str(graph_path)) + + edges_one, total_one = session_one.get_edges(limit=10) + edges_two, total_two = session_two.get_edges(limit=10) + + assert total_one == 1 + assert total_two == 1 + assert edges_one[0]["id"] == edges_two[0]["id"] + assert edges_one[0]["familyId"] == edges_two[0]["familyId"] + + def test_multi_edges_same_pair_paginate_as_distinct_stable_edges(self): + graph = ContextGraph(advanced_analytics=False) + graph.add_node("shared_src", node_type="entity", content="Shared source") + graph.add_node("shared_tgt", node_type="entity", content="Shared target") + graph.add_edges( + [ + { + "id": "edge-alpha", + "familyId": "family-shared", + "source_id": "shared_src", + "target_id": "shared_tgt", + "type": "supports", + "weight": 0.9, + "properties": {"provenance": "paper-a"}, + }, + { + "id": "edge-beta", + "familyId": "family-shared", + "source_id": "shared_src", + "target_id": "shared_tgt", + "type": "contradicts", + "weight": 0.6, + "properties": {"provenance": "paper-b"}, + }, + ] + ) + + app = create_app(session=GraphSession(graph)) + with TestClient(app) as test_client: + first = test_client.get("/api/graph/edges?source=shared_src&target=shared_tgt&limit=1") + assert first.status_code == 200 + first_payload = first.json() + assert first_payload["total"] == 2 + assert len(first_payload["edges"]) == 1 + assert first_payload["edges"][0]["familyId"] == "family-shared" + + second = test_client.get( + f"/api/graph/edges?source=shared_src&target=shared_tgt&limit=1&cursor={first_payload['next_cursor']}" + ) + assert second.status_code == 200 + second_payload = second.json() + assert len(second_payload["edges"]) == 1 + assert first_payload["edges"][0]["id"] != second_payload["edges"][0]["id"] + + repeat = test_client.get("/api/graph/edges?source=shared_src&target=shared_tgt&limit=10") + assert repeat.status_code == 200 + repeat_ids = [edge["id"] for edge in repeat.json()["edges"]] + assert repeat_ids == ["edge-alpha", "edge-beta"]