@visualli/core 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -105
- package/dist/chunk-25AJTPMS.js +68 -0
- package/dist/chunk-25AJTPMS.js.map +1 -0
- package/dist/{chunk-6NXADJK2.js → chunk-7NJWM7ZE.js} +84 -117
- package/dist/chunk-7NJWM7ZE.js.map +1 -0
- package/dist/chunk-KVSM3APM.js +96 -0
- package/dist/chunk-KVSM3APM.js.map +1 -0
- package/dist/{chunk-PDP5CVUL.js → chunk-LOQLNYB3.js} +2 -2
- package/dist/chunk-LV3EXUQY.js +753 -0
- package/dist/chunk-LV3EXUQY.js.map +1 -0
- package/dist/chunk-N7HCYULH.js +12 -0
- package/dist/chunk-N7HCYULH.js.map +1 -0
- package/dist/{chunk-I75TMOE4.js → chunk-P6PKWVYF.js} +2 -2
- package/dist/chunk-TPLJJKAU.js +151 -0
- package/dist/chunk-TPLJJKAU.js.map +1 -0
- package/dist/chunk-UAMEJG2C.js +267 -0
- package/dist/chunk-UAMEJG2C.js.map +1 -0
- package/dist/{chunk-LJYSKSCE.js → chunk-W2CAOOJJ.js} +6 -6
- package/dist/chunk-W2CAOOJJ.js.map +1 -0
- package/dist/config/index.cjs +250 -349
- package/dist/config/index.cjs.map +1 -1
- package/dist/config/index.d.cts +107 -66
- package/dist/config/index.d.ts +107 -66
- package/dist/config/index.js +52 -34
- package/dist/constants/index.cjs +14 -333
- package/dist/constants/index.cjs.map +1 -1
- package/dist/constants/index.d.cts +5 -243
- package/dist/constants/index.d.ts +5 -243
- package/dist/constants/index.js +5 -75
- package/dist/designSystem-BOrZHfEq.d.cts +150 -0
- package/dist/designSystem-BOrZHfEq.d.ts +150 -0
- package/dist/document-BFBwn93X.d.ts +26 -0
- package/dist/document-MEJEfxl3.d.cts +26 -0
- package/dist/ideaSize-CLDKeyqD.d.cts +11 -0
- package/dist/ideaSize-DxxGy2E8.d.ts +11 -0
- package/dist/index-BmILeKj6.d.cts +99 -0
- package/dist/index-CcPRwVUL.d.ts +99 -0
- package/dist/index.cjs +1636 -961
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +350 -27
- package/dist/index.d.ts +350 -27
- package/dist/index.js +445 -190
- package/dist/index.js.map +1 -1
- package/dist/{document-B3hnNr-F.d.cts → layer-B2A3Ki48.d.cts} +2 -16
- package/dist/{document-B3hnNr-F.d.ts → layer-B2A3Ki48.d.ts} +2 -16
- package/dist/layout/index.d.cts +2 -1
- package/dist/layout/index.d.ts +2 -1
- package/dist/mindmap-C3Qr0qKW.d.cts +182 -0
- package/dist/mindmap-DHeVa86G.d.ts +182 -0
- package/dist/parser/index.cjs +745 -179
- package/dist/parser/index.cjs.map +1 -1
- package/dist/parser/index.d.cts +23 -8
- package/dist/parser/index.d.ts +23 -8
- package/dist/parser/index.js +7 -2
- package/dist/performance/index.cjs +13 -0
- package/dist/performance/index.cjs.map +1 -1
- package/dist/performance/index.js +2 -2
- package/dist/theme/index.cjs +884 -0
- package/dist/theme/index.cjs.map +1 -0
- package/dist/theme/index.d.cts +2 -0
- package/dist/theme/index.d.ts +2 -0
- package/dist/theme/index.js +53 -0
- package/dist/types/index.d.cts +4 -2
- package/dist/types/index.d.ts +4 -2
- package/dist/viewport/index.cjs +17 -6
- package/dist/viewport/index.cjs.map +1 -1
- package/dist/viewport/index.d.cts +6 -4
- package/dist/viewport/index.d.ts +6 -4
- package/dist/viewport/index.js +2 -2
- package/licenses/visualli-design-system/LICENSE +9 -0
- package/licenses/visualli-design-system/NOTICE.md +6 -0
- package/package.json +13 -5
- package/src/config/README.md +2 -4
- package/src/config/USAGE_EXAMPLES.md +0 -4
- package/src/config/index.ts +3 -4
- package/src/constants/index.ts +1 -1
- package/src/constants/layout.ts +11 -0
- package/src/constants/performanceConstants.ts +8 -27
- package/src/generated/README.md +12 -0
- package/src/generated/designSystem.ts +758 -0
- package/src/generated/geometry/blob.ts +99 -0
- package/src/generated/geometry/blobShapes.ts +4 -0
- package/src/generated/geometry/color.ts +37 -0
- package/src/generated/geometry/container.ts +84 -0
- package/src/generated/geometry/detail.ts +22 -0
- package/src/generated/geometry/idea.ts +56 -0
- package/src/generated/geometry/interaction.ts +122 -0
- package/src/generated/geometry/motion.ts +140 -0
- package/src/index.ts +18 -1
- package/src/parser/configUtils.ts +12 -19
- package/src/parser/visualliConverter.ts +71 -112
- package/src/parser/visualliParser.ts +16 -1
- package/src/rendering/culling.ts +16 -12
- package/src/rendering/ideaSize.ts +21 -0
- package/src/rendering/nodeGeometry.ts +97 -0
- package/src/theme/index.ts +136 -0
- package/src/types/document.ts +9 -0
- package/src/types/layer.ts +1 -1
- package/src/types/mindmap.ts +13 -0
- package/src/utils/navigation.ts +33 -63
- package/src/viewport/viewportUtils.ts +6 -4
- package/dist/animations/index.cjs +0 -146
- package/dist/animations/index.cjs.map +0 -1
- package/dist/animations/index.d.cts +0 -81
- package/dist/animations/index.d.ts +0 -81
- package/dist/animations/index.js +0 -35
- package/dist/chunk-6NXADJK2.js.map +0 -1
- package/dist/chunk-F36SMC3K.js +0 -106
- package/dist/chunk-F36SMC3K.js.map +0 -1
- package/dist/chunk-G5H3P4YZ.js +0 -273
- package/dist/chunk-G5H3P4YZ.js.map +0 -1
- package/dist/chunk-LDJRGT2Q.js +0 -163
- package/dist/chunk-LDJRGT2Q.js.map +0 -1
- package/dist/chunk-LJYSKSCE.js.map +0 -1
- package/dist/chunk-LNTJTDB2.js +0 -349
- package/dist/chunk-LNTJTDB2.js.map +0 -1
- package/dist/mindmap-DWS0WZT_.d.cts +0 -118
- package/dist/mindmap-DWS0WZT_.d.ts +0 -118
- package/src/animations/constants.ts +0 -72
- package/src/animations/easing.ts +0 -70
- package/src/animations/index.ts +0 -2
- package/src/config/blobShapes.ts +0 -146
- package/src/config/textScaling.ts +0 -54
- package/src/constants/design.ts +0 -281
- /package/dist/{chunk-PDP5CVUL.js.map → chunk-LOQLNYB3.js.map} +0 -0
- /package/dist/{chunk-I75TMOE4.js.map → chunk-P6PKWVYF.js.map} +0 -0
- /package/dist/{animations → theme}/index.js.map +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/spatial/spatialIndex.ts","../../../../../node_modules/zustand/esm/vanilla.mjs","../src/stores/index.ts","../src/utils/navigation.ts","../src/rendering/culling.ts"],"sourcesContent":["// ─── Spatial Index ────────────────────────────────────────────────────────────\n//\n// RBush-backed R-tree for O(log n) viewport culling queries.\n// Wraps the `rbush` library with a typed, domain-specific interface.\n\nimport RBush from 'rbush';\n\nexport interface BoundingBox {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\ninterface SpatialItem extends BoundingBox {\n nodeId: string;\n}\n\nexport interface ISpatialIndex {\n insert(nodeId: string, bounds: BoundingBox): void;\n remove(nodeId: string, bounds: BoundingBox): void;\n update(nodeId: string, oldBounds: BoundingBox, newBounds: BoundingBox): void;\n query(bounds: BoundingBox): string[];\n clear(): void;\n size(): number;\n bulkLoad(items: Array<{ nodeId: string; bounds: BoundingBox }>): void;\n}\n\n/**\n * RBush-based spatial index for efficient viewport culling.\n *\n * - Insert / remove / update: O(log n)\n * - Query: O(log n + k) where k = result count\n * - Bulk load: O(n log n) — use instead of repeated inserts for initial load\n */\nexport class RBushSpatialIndex implements ISpatialIndex {\n private tree: RBush<SpatialItem>;\n private cache: Map<string, BoundingBox>;\n\n constructor() {\n this.tree = new RBush<SpatialItem>();\n this.cache = new Map();\n }\n\n insert(nodeId: string, bounds: BoundingBox): void {\n this.tree.insert({ ...bounds, nodeId });\n this.cache.set(nodeId, bounds);\n }\n\n remove(nodeId: string, bounds: BoundingBox): void {\n this.tree.remove({ ...bounds, nodeId }, (a, b) => a.nodeId === b.nodeId);\n this.cache.delete(nodeId);\n }\n\n update(nodeId: string, oldBounds: BoundingBox, newBounds: BoundingBox): void {\n this.remove(nodeId, oldBounds);\n this.insert(nodeId, newBounds);\n }\n\n query(bounds: BoundingBox): string[] {\n return this.tree.search(bounds).map(item => item.nodeId);\n }\n\n clear(): void {\n this.tree.clear();\n this.cache.clear();\n }\n\n size(): number {\n return this.cache.size;\n }\n\n bulkLoad(items: Array<{ nodeId: string; bounds: BoundingBox }>): void {\n const rbushItems = items.map(({ nodeId, bounds }) => ({ ...bounds, nodeId }));\n this.tree.load(rbushItems);\n for (const { nodeId, bounds } of items) this.cache.set(nodeId, bounds);\n }\n\n /** Return the cached bounding box for a node (undefined if not indexed). */\n getBounds(nodeId: string): BoundingBox | undefined {\n return this.cache.get(nodeId);\n }\n}\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const destroy = () => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected.\"\n );\n }\n listeners.clear();\n };\n const api = { setState, getState, getInitialState, subscribe, destroy };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;\nvar vanilla = (createState) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] Default export is deprecated. Instead use import { createStore } from 'zustand/vanilla'.\"\n );\n }\n return createStore(createState);\n};\n\nexport { createStore, vanilla as default };\n","import { createStore } from 'zustand/vanilla';\nimport type { NodeSelection, RenderConfig } from '../types/index.js';\nimport {\n DEFAULT_RENDER_CONFIG,\n getOptimalQualityLevel,\n getRenderConfigForQuality,\n isFeatureEnabled,\n FEATURE_FLAGS,\n} from '../constants/renderConfig.js';\n\n// ─── Selection Store ──────────────────────────────────────────────────────────\n\nexport interface ISelectionStore extends NodeSelection {\n select: (nodeId: string) => void;\n clear: () => void;\n toggle: (nodeId: string) => void;\n isSelected: (nodeId: string) => boolean;\n}\n\nexport const selectionStore = createStore<ISelectionStore>((set, get) => ({\n selectedId: null,\n select: (nodeId) => set({ selectedId: nodeId }),\n clear: () => set({ selectedId: null }),\n toggle: (nodeId) => set((s) => ({ selectedId: s.selectedId === nodeId ? null : nodeId })),\n isSelected: (nodeId) => get().selectedId === nodeId,\n}));\n\n// ─── Render Config Store ──────────────────────────────────────────────────────\n\nexport interface IRenderConfigStore extends RenderConfig {\n setQualityLevel: (level: RenderConfig['qualityLevel']) => void;\n setRenderMode: (mode: RenderConfig['renderMode']) => void;\n setCullingEnabled: (enabled: boolean) => void;\n autoAdjustQuality: (currentFPS: number) => void;\n autoAdjustQualityByMemory: (memoryMB: number) => void;\n resetToDefaults: () => void;\n isFeatureEnabled: (feature: keyof typeof FEATURE_FLAGS) => boolean;\n}\n\nexport const renderConfigStore = createStore<IRenderConfigStore>((set, get) => ({\n ...DEFAULT_RENDER_CONFIG,\n\n setQualityLevel: (level) => set(getRenderConfigForQuality(level)),\n setRenderMode: (mode) => set({ renderMode: mode }),\n setCullingEnabled: (enabled) => set({ cullingEnabled: enabled }),\n\n autoAdjustQuality: (fps) =>\n set((s) => {\n const q = getOptimalQualityLevel(fps, s.qualityLevel);\n return q !== s.qualityLevel ? getRenderConfigForQuality(q) : s;\n }),\n\n autoAdjustQualityByMemory: (mb) =>\n set((s) => {\n const q = mb > 500 ? 'low' : mb > 400 && s.qualityLevel === 'high' ? 'medium' : s.qualityLevel;\n return q !== s.qualityLevel ? getRenderConfigForQuality(q as RenderConfig['qualityLevel']) : s;\n }),\n\n resetToDefaults: () => set({ ...DEFAULT_RENDER_CONFIG }),\n isFeatureEnabled: (feature) => isFeatureEnabled(feature, get()),\n}));\n","import type { VisualliDocument, VisualliLayer, FlatNode, MindMapConnection } from '../types/index.js';\nimport { ZOOM_MAX, ZOOM_NAV_OUT_THRESHOLD } from '../constants/performanceConstants.js';\n\n// ── Connection helpers ────────────────────────────────────────────────────────\n\n/**\n * Returns all top-level connections that originate from the given layer.\n * A \"top-level connection\" links two nodes that both live in `layerId`.\n */\nexport function getConnectionsForLayer(\n doc: VisualliDocument,\n layerId: string,\n): MindMapConnection[] {\n const layer = doc.layers.get(layerId);\n if (!layer) return [];\n // Convert schema LayerConnection to simplified mindmap MindMapConnection\n return layer.connections.map(c => ({\n from: c.from,\n to: c.to,\n level: layer.level,\n label: c.data?.label,\n } satisfies MindMapConnection));\n}\n\n/**\n * Given a node in the current layer, returns the child layer (if any) that the\n * node \"owns\" — i.e. the node is the entry-point into that child layer.\n */\nexport function getChildLayerForNode(\n doc: VisualliDocument,\n nodeId: string,\n currentLayerId: string,\n): VisualliLayer | null {\n // Walk all layers looking for one whose `parentNodeId` matches\n for (const [, layer] of doc.layers) {\n if (layer.parentLayerId === currentLayerId && layer.parentNodeId === nodeId) {\n return layer;\n }\n }\n return null;\n}\n\n/**\n * \n */\nexport function getLayerForNavigation(\n doc: VisualliDocument,\n nodeId: string,\n currentLayerId: string,\n): VisualliLayer | null {\n return getChildLayerForNode(doc, nodeId, currentLayerId);\n}\n\n// ── Viewport fitting math ─────────────────────────────────────────────────────\n\nexport interface FitResult {\n centerX: number;\n centerY: number;\n zoomLevel: number;\n}\n\n/**\n * Calculates the zoom level needed to fit all `nodes` inside a canvas of\n * `(canvasWidth, canvasHeight)`.\n *\n * @param paddingFraction - Fractional padding on each side (0.15 = 15%).\n * Pixel-padding variant still available when a value >=1 is passed.\n */\nexport function calculateFitZoom(\n nodes: FlatNode[],\n canvasWidth: number,\n canvasHeight: number,\n padding = 0.15,\n): number {\n if (nodes.length === 0) return 1;\n\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const n of nodes) {\n // Use the actual node boundaries (center +/- half-width/height)\n minX = Math.min(minX, n.x - n.width / 2);\n minY = Math.min(minY, n.y - n.height / 2);\n maxX = Math.max(maxX, n.x + n.width / 2);\n maxY = Math.max(maxY, n.y + n.height / 2);\n }\n\n const rawW = maxX - minX;\n const rawH = maxY - minY;\n\n // Minimum spread — single isolated node should appear comfortably\n // Matches visualli.ai's spread logic for single nodes\n const spreadW = nodes.length === 1 ? Math.max(rawW, 600) : rawW;\n const spreadH = nodes.length === 1 ? Math.max(rawH, 400) : rawH;\n\n const zoomX = (canvasWidth * (1 - padding)) / spreadW;\n const zoomY = (canvasHeight * (1 - padding)) / spreadH;\n\n const z = Math.min(zoomX, zoomY);\n\n // Scale back 20% so nodes aren't edge-to-edge, clamp to at least\n // ZOOM_NAV_OUT_THRESHOLD so arriving at the layer never immediately\n // re-triggers the zoom-out transition.\n return Math.max(z * 0.80, ZOOM_NAV_OUT_THRESHOLD);\n}\n\n/**\n * Calculates the world-space center point that puts all `nodes` in the middle\n * of the viewport. Matches the visualli.ai `calculateFitCenter` approach:\n * uses bounding-box midpoint rather than centroid so the layout is always\n * geometrically centred.\n */\nexport function calculateFitCenter(nodes: FlatNode[]): { x: number; y: number } {\n if (nodes.length === 0) return { x: 0, y: 0 };\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const n of nodes) {\n minX = Math.min(minX, n.x - n.width / 2);\n minY = Math.min(minY, n.y - n.height / 2);\n maxX = Math.max(maxX, n.x + n.width / 2);\n maxY = Math.max(maxY, n.y + n.height / 2);\n }\n return { x: (minX + maxX) / 2, y: (minY + maxY) / 2 };\n}\n\n// ── Container helpers ────────────────────────────────────────────────────────\n\n// Inline the container shape here to avoid a circular import with KonvaContainerLayer.\nexport interface ContainerGroupInfo {\n id: string;\n label?: string;\n nodeIds: string[];\n level: number;\n}\n\n/**\n * Returns the container groups for the given layer, normalising both the\n * nested-data format `{data:{label,formation}}` and the flat format `{label}`.\n */\nexport function getContainersForLayer(\n doc: VisualliDocument,\n layerId: string,\n): ContainerGroupInfo[] {\n const layer = doc.layers.get(layerId);\n if (!layer) return [];\n \n // Defensive: ensure containers is an array\n const containers = layer.containers ?? [];\n if (!Array.isArray(containers)) return [];\n \n return containers.map(c => {\n // Schema Container has nested data.label structure\n const label = c.data?.label ?? c.id;\n return { id: c.id, label, nodeIds: c.nodes, level: layer.level };\n });\n}\n\n/** Convenience: returns both center and zoom for a single `fitView` call. */\nexport function calculateFitView(\n nodes: FlatNode[],\n canvasWidth: number,\n canvasHeight: number,\n): FitResult {\n const center = calculateFitCenter(nodes);\n const zoom = calculateFitZoom(nodes, canvasWidth, canvasHeight);\n return { centerX: center.x, centerY: center.y, zoomLevel: zoom };\n}\n\n","import type { FlatNode, ViewportState } from '../types/index.js';\nimport { RBushSpatialIndex } from '../spatial/spatialIndex.js';\nimport { calculateViewportBounds } from '../viewport/viewportUtils.js';\n\nexport interface CullingOptions {\n nodes: FlatNode[];\n viewport: ViewportState;\n canvasWidth: number;\n canvasHeight: number;\n levelFilter?: number;\n skipCulling?: boolean;\n isDragging?: boolean;\n spatialIndex?: RBushSpatialIndex | null;\n spatialIndexThreshold?: number;\n}\n\nconst DEFAULT_SPATIAL_INDEX_THRESHOLD = 200;\n\n/**\n * Returns the subset of nodes currently visible in the viewport.\n * Framework-agnostic logic for culling and spatial indexing.\n */\nexport function getViewportVisibleNodes(options: CullingOptions): FlatNode[] {\n const {\n nodes,\n viewport,\n canvasWidth,\n canvasHeight,\n levelFilter,\n skipCulling = false,\n isDragging = false,\n spatialIndex,\n spatialIndexThreshold = DEFAULT_SPATIAL_INDEX_THRESHOLD,\n } = options;\n\n const filtered = levelFilter !== undefined\n ? nodes.filter(n => n.level === levelFilter)\n : nodes;\n\n if (filtered.length === 0) return [];\n\n // During transitions or drags show all nodes to avoid partial layer appearance\n if (skipCulling || isDragging) return filtered;\n\n const bounds = calculateViewportBounds(viewport, canvasWidth, canvasHeight);\n\n if (filtered.length < spatialIndexThreshold) {\n return filtered.filter(n =>\n n.x + n.width >= bounds.minX &&\n n.x <= bounds.maxX &&\n n.y + n.height >= bounds.minY &&\n n.y <= bounds.maxY,\n );\n }\n\n if (spatialIndex) {\n const nodeIds = spatialIndex.query({\n minX: bounds.minX, minY: bounds.minY, maxX: bounds.maxX, maxY: bounds.maxY,\n });\n const idSet = new Set(nodeIds);\n return filtered.filter(n => idSet.has(n.id));\n }\n\n // Fallback to simple filter if no index provided but threshold exceeded\n return filtered.filter(n =>\n n.x + n.width >= bounds.minX &&\n n.x <= bounds.maxX &&\n n.y + n.height >= bounds.minY &&\n n.y <= bounds.maxY,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,OAAO,WAAW;AA8BX,IAAM,oBAAN,MAAiD;AAAA,EAItD,cAAc;AACZ,SAAK,OAAQ,IAAI,MAAmB;AACpC,SAAK,QAAQ,oBAAI,IAAI;AAAA,EACvB;AAAA,EAEA,OAAO,QAAgB,QAA2B;AAChD,SAAK,KAAK,OAAO,EAAE,GAAG,QAAQ,OAAO,CAAC;AACtC,SAAK,MAAM,IAAI,QAAQ,MAAM;AAAA,EAC/B;AAAA,EAEA,OAAO,QAAgB,QAA2B;AAChD,SAAK,KAAK,OAAO,EAAE,GAAG,QAAQ,OAAO,GAAG,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,MAAM;AACvE,SAAK,MAAM,OAAO,MAAM;AAAA,EAC1B;AAAA,EAEA,OAAO,QAAgB,WAAwB,WAA8B;AAC3E,SAAK,OAAO,QAAQ,SAAS;AAC7B,SAAK,OAAO,QAAQ,SAAS;AAAA,EAC/B;AAAA,EAEA,MAAM,QAA+B;AACnC,WAAO,KAAK,KAAK,OAAO,MAAM,EAAE,IAAI,UAAQ,KAAK,MAAM;AAAA,EACzD;AAAA,EAEA,QAAc;AACZ,SAAK,KAAK,MAAM;AAChB,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA,EAEA,OAAe;AACb,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,SAAS,OAA6D;AACpE,UAAM,aAAa,MAAM,IAAI,CAAC,EAAE,QAAQ,OAAO,OAAO,EAAE,GAAG,QAAQ,OAAO,EAAE;AAC5E,SAAK,KAAK,KAAK,UAAU;AACzB,eAAW,EAAE,QAAQ,OAAO,KAAK,MAAO,MAAK,MAAM,IAAI,QAAQ,MAAM;AAAA,EACvE;AAAA;AAAA,EAGA,UAAU,QAAyC;AACjD,WAAO,KAAK,MAAM,IAAI,MAAM;AAAA,EAC9B;AACF;;;AClFA,IAAM,kBAAkB,CAAC,gBAAgB;AACvC,MAAI;AACJ,QAAM,YAA4B,oBAAI,IAAI;AAC1C,QAAM,WAAW,CAAC,SAAS,YAAY;AACrC,UAAM,YAAY,OAAO,YAAY,aAAa,QAAQ,KAAK,IAAI;AACnE,QAAI,CAAC,OAAO,GAAG,WAAW,KAAK,GAAG;AAChC,YAAM,gBAAgB;AACtB,eAAS,WAAW,OAAO,UAAU,OAAO,cAAc,YAAY,cAAc,QAAQ,YAAY,OAAO,OAAO,CAAC,GAAG,OAAO,SAAS;AAC1I,gBAAU,QAAQ,CAAC,aAAa,SAAS,OAAO,aAAa,CAAC;AAAA,IAChE;AAAA,EACF;AACA,QAAM,WAAW,MAAM;AACvB,QAAM,kBAAkB,MAAM;AAC9B,QAAM,YAAY,CAAC,aAAa;AAC9B,cAAU,IAAI,QAAQ;AACtB,WAAO,MAAM,UAAU,OAAO,QAAQ;AAAA,EACxC;AACA,QAAM,UAAU,MAAM;AACpB,SAAK,YAAY,MAAM,YAAY,IAAI,OAAO,YAAY,cAAc;AACtE,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AACA,cAAU,MAAM;AAAA,EAClB;AACA,QAAM,MAAM,EAAE,UAAU,UAAU,iBAAiB,WAAW,QAAQ;AACtE,QAAM,eAAe,QAAQ,YAAY,UAAU,UAAU,GAAG;AAChE,SAAO;AACT;AACA,IAAM,cAAc,CAAC,gBAAgB,cAAc,gBAAgB,WAAW,IAAI;;;ACV3E,IAAM,iBAAiB,YAA6B,CAAC,KAAK,SAAS;AAAA,EACxE,YAAY;AAAA,EACZ,QAAQ,CAAC,WAAW,IAAI,EAAE,YAAY,OAAO,CAAC;AAAA,EAC9C,OAAO,MAAM,IAAI,EAAE,YAAY,KAAK,CAAC;AAAA,EACrC,QAAQ,CAAC,WAAW,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,eAAe,SAAS,OAAO,OAAO,EAAE;AAAA,EACxF,YAAY,CAAC,WAAW,IAAI,EAAE,eAAe;AAC/C,EAAE;AAcK,IAAM,oBAAoB,YAAgC,CAAC,KAAK,SAAS;AAAA,EAC9E,GAAG;AAAA,EAEH,iBAAiB,CAAC,UAAU,IAAI,0BAA0B,KAAK,CAAC;AAAA,EAChE,eAAiB,CAAC,SAAU,IAAI,EAAE,YAAY,KAAK,CAAC;AAAA,EACpD,mBAAmB,CAAC,YAAY,IAAI,EAAE,gBAAgB,QAAQ,CAAC;AAAA,EAE/D,mBAAmB,CAAC,QAClB,IAAI,CAAC,MAAM;AACT,UAAM,IAAI,uBAAuB,KAAK,EAAE,YAAY;AACpD,WAAO,MAAM,EAAE,eAAe,0BAA0B,CAAC,IAAI;AAAA,EAC/D,CAAC;AAAA,EAEH,2BAA2B,CAAC,OAC1B,IAAI,CAAC,MAAM;AACT,UAAM,IAAI,KAAK,MAAM,QAAQ,KAAK,OAAO,EAAE,iBAAiB,SAAS,WAAW,EAAE;AAClF,WAAO,MAAM,EAAE,eAAe,0BAA0B,CAAiC,IAAI;AAAA,EAC/F,CAAC;AAAA,EAEH,iBAAiB,MAAM,IAAI,EAAE,GAAG,sBAAsB,CAAC;AAAA,EACvD,kBAAkB,CAAC,YAAY,iBAAiB,SAAS,IAAI,CAAC;AAChE,EAAE;;;ACnDK,SAAS,uBACd,KACA,SACqB;AACrB,QAAM,QAAQ,IAAI,OAAO,IAAI,OAAO;AACpC,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,SAAO,MAAM,YAAY,IAAI,QAAM;AAAA,IACjC,MAAM,EAAE;AAAA,IACR,IAAI,EAAE;AAAA,IACN,OAAO,MAAM;AAAA,IACb,OAAO,EAAE,MAAM;AAAA,EACjB,EAA8B;AAChC;AAMO,SAAS,qBACd,KACA,QACA,gBACsB;AAEpB,aAAW,CAAC,EAAE,KAAK,KAAK,IAAI,QAAQ;AAClC,QAAI,MAAM,kBAAkB,kBAAkB,MAAM,iBAAiB,QAAQ;AAC3E,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACX;AAKO,SAAS,sBACd,KACA,QACA,gBACsB;AACtB,SAAO,qBAAqB,KAAK,QAAQ,cAAc;AACzD;AAiBO,SAAS,iBACd,OACA,aACA,cACA,UAAU,MACF;AACR,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,MAAI,OAAO,UAAU,OAAO,UAAU,OAAO,WAAW,OAAO;AAC/D,aAAW,KAAK,OAAO;AAErB,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;AACvC,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC;AACxC,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;AACvC,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC;AAAA,EAC1C;AAEA,QAAM,OAAO,OAAO;AACpB,QAAM,OAAO,OAAO;AAIpB,QAAM,UAAU,MAAM,WAAW,IAAI,KAAK,IAAI,MAAM,GAAG,IAAI;AAC3D,QAAM,UAAU,MAAM,WAAW,IAAI,KAAK,IAAI,MAAM,GAAG,IAAI;AAE3D,QAAM,QAAS,eAAe,IAAI,WAAY;AAC9C,QAAM,QAAS,gBAAgB,IAAI,WAAY;AAE/C,QAAM,IAAI,KAAK,IAAI,OAAO,KAAK;AAK/B,SAAO,KAAK,IAAI,IAAI,KAAM,sBAAsB;AAClD;AAQO,SAAS,mBAAmB,OAA6C;AAC9E,MAAI,MAAM,WAAW,EAAG,QAAO,EAAE,GAAG,GAAG,GAAG,EAAE;AAC5C,MAAI,OAAO,UAAU,OAAO,UAAU,OAAO,WAAW,OAAO;AAC/D,aAAW,KAAK,OAAO;AACrB,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;AACvC,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC;AACxC,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;AACvC,WAAO,KAAK,IAAI,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC;AAAA,EAC1C;AACA,SAAO,EAAE,IAAI,OAAO,QAAQ,GAAG,IAAI,OAAO,QAAQ,EAAE;AACtD;AAgBO,SAAS,sBACd,KACA,SACsB;AACtB,QAAM,QAAQ,IAAI,OAAO,IAAI,OAAO;AACpC,MAAI,CAAC,MAAO,QAAO,CAAC;AAGpB,QAAM,aAAa,MAAM,cAAc,CAAC;AACxC,MAAI,CAAC,MAAM,QAAQ,UAAU,EAAG,QAAO,CAAC;AAExC,SAAO,WAAW,IAAI,OAAK;AAEzB,UAAM,QAAQ,EAAE,MAAM,SAAS,EAAE;AACjC,WAAO,EAAE,IAAI,EAAE,IAAI,OAAO,SAAS,EAAE,OAAO,OAAO,MAAM,MAAM;AAAA,EACjE,CAAC;AACH;AAGO,SAAS,iBACd,OACA,aACA,cACW;AACX,QAAM,SAAS,mBAAmB,KAAK;AACvC,QAAM,OAAS,iBAAiB,OAAO,aAAa,YAAY;AAChE,SAAO,EAAE,SAAS,OAAO,GAAG,SAAS,OAAO,GAAG,WAAW,KAAK;AACjE;;;ACnJA,IAAM,kCAAkC;AAMjC,SAAS,wBAAwB,SAAqC;AAC3E,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,aAAa;AAAA,IACb;AAAA,IACA,wBAAwB;AAAA,EAC1B,IAAI;AAEJ,QAAM,WAAW,gBAAgB,SAC7B,MAAM,OAAO,OAAK,EAAE,UAAU,WAAW,IACzC;AAEJ,MAAI,SAAS,WAAW,EAAG,QAAO,CAAC;AAGnC,MAAI,eAAe,WAAY,QAAO;AAEtC,QAAM,SAAS,wBAAwB,UAAU,aAAa,YAAY;AAE1E,MAAI,SAAS,SAAS,uBAAuB;AAC3C,WAAO,SAAS;AAAA,MAAO,OACrB,EAAE,IAAI,EAAE,SAAU,OAAO,QACzB,EAAE,KAAgB,OAAO,QACzB,EAAE,IAAI,EAAE,UAAU,OAAO,QACzB,EAAE,KAAgB,OAAO;AAAA,IAC3B;AAAA,EACF;AAEA,MAAI,cAAc;AAChB,UAAM,UAAU,aAAa,MAAM;AAAA,MACjC,MAAM,OAAO;AAAA,MAAM,MAAM,OAAO;AAAA,MAAM,MAAM,OAAO;AAAA,MAAM,MAAM,OAAO;AAAA,IACxE,CAAC;AACD,UAAM,QAAQ,IAAI,IAAI,OAAO;AAC7B,WAAO,SAAS,OAAO,OAAK,MAAM,IAAI,EAAE,EAAE,CAAC;AAAA,EAC7C;AAGA,SAAO,SAAS;AAAA,IAAO,OACrB,EAAE,IAAI,EAAE,SAAU,OAAO,QACzB,EAAE,KAAgB,OAAO,QACzB,EAAE,IAAI,EAAE,UAAU,OAAO,QACzB,EAAE,KAAgB,OAAO;AAAA,EAC3B;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/spatial/spatialIndex.ts","../../../../../node_modules/zustand/esm/vanilla.mjs","../src/stores/index.ts","../src/generated/geometry/container.ts","../src/utils/navigation.ts","../src/rendering/culling.ts","../src/generated/geometry/motion.ts","../src/generated/geometry/detail.ts"],"sourcesContent":["// ─── Spatial Index ────────────────────────────────────────────────────────────\n//\n// RBush-backed R-tree for O(log n) viewport culling queries.\n// Wraps the `rbush` library with a typed, domain-specific interface.\n\nimport RBush from 'rbush';\n\nexport interface BoundingBox {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\ninterface SpatialItem extends BoundingBox {\n nodeId: string;\n}\n\nexport interface ISpatialIndex {\n insert(nodeId: string, bounds: BoundingBox): void;\n remove(nodeId: string, bounds: BoundingBox): void;\n update(nodeId: string, oldBounds: BoundingBox, newBounds: BoundingBox): void;\n query(bounds: BoundingBox): string[];\n clear(): void;\n size(): number;\n bulkLoad(items: Array<{ nodeId: string; bounds: BoundingBox }>): void;\n}\n\n/**\n * RBush-based spatial index for efficient viewport culling.\n *\n * - Insert / remove / update: O(log n)\n * - Query: O(log n + k) where k = result count\n * - Bulk load: O(n log n) — use instead of repeated inserts for initial load\n */\nexport class RBushSpatialIndex implements ISpatialIndex {\n private tree: RBush<SpatialItem>;\n private cache: Map<string, BoundingBox>;\n\n constructor() {\n this.tree = new RBush<SpatialItem>();\n this.cache = new Map();\n }\n\n insert(nodeId: string, bounds: BoundingBox): void {\n this.tree.insert({ ...bounds, nodeId });\n this.cache.set(nodeId, bounds);\n }\n\n remove(nodeId: string, bounds: BoundingBox): void {\n this.tree.remove({ ...bounds, nodeId }, (a, b) => a.nodeId === b.nodeId);\n this.cache.delete(nodeId);\n }\n\n update(nodeId: string, oldBounds: BoundingBox, newBounds: BoundingBox): void {\n this.remove(nodeId, oldBounds);\n this.insert(nodeId, newBounds);\n }\n\n query(bounds: BoundingBox): string[] {\n return this.tree.search(bounds).map(item => item.nodeId);\n }\n\n clear(): void {\n this.tree.clear();\n this.cache.clear();\n }\n\n size(): number {\n return this.cache.size;\n }\n\n bulkLoad(items: Array<{ nodeId: string; bounds: BoundingBox }>): void {\n const rbushItems = items.map(({ nodeId, bounds }) => ({ ...bounds, nodeId }));\n this.tree.load(rbushItems);\n for (const { nodeId, bounds } of items) this.cache.set(nodeId, bounds);\n }\n\n /** Return the cached bounding box for a node (undefined if not indexed). */\n getBounds(nodeId: string): BoundingBox | undefined {\n return this.cache.get(nodeId);\n }\n}\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const destroy = () => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected.\"\n );\n }\n listeners.clear();\n };\n const api = { setState, getState, getInitialState, subscribe, destroy };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;\nvar vanilla = (createState) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] Default export is deprecated. Instead use import { createStore } from 'zustand/vanilla'.\"\n );\n }\n return createStore(createState);\n};\n\nexport { createStore, vanilla as default };\n","import { createStore } from 'zustand/vanilla';\nimport type { NodeSelection, RenderConfig } from '../types/index.js';\nimport {\n DEFAULT_RENDER_CONFIG,\n getOptimalQualityLevel,\n getRenderConfigForQuality,\n isFeatureEnabled,\n FEATURE_FLAGS,\n} from '../constants/renderConfig.js';\n\n// ─── Selection Store ──────────────────────────────────────────────────────────\n\nexport interface ISelectionStore extends NodeSelection {\n select: (nodeId: string) => void;\n clear: () => void;\n toggle: (nodeId: string) => void;\n isSelected: (nodeId: string) => boolean;\n}\n\nexport const selectionStore = createStore<ISelectionStore>((set, get) => ({\n selectedId: null,\n select: (nodeId) => set({ selectedId: nodeId }),\n clear: () => set({ selectedId: null }),\n toggle: (nodeId) => set((s) => ({ selectedId: s.selectedId === nodeId ? null : nodeId })),\n isSelected: (nodeId) => get().selectedId === nodeId,\n}));\n\n// ─── Render Config Store ──────────────────────────────────────────────────────\n\nexport interface IRenderConfigStore extends RenderConfig {\n setQualityLevel: (level: RenderConfig['qualityLevel']) => void;\n setRenderMode: (mode: RenderConfig['renderMode']) => void;\n setCullingEnabled: (enabled: boolean) => void;\n autoAdjustQuality: (currentFPS: number) => void;\n autoAdjustQualityByMemory: (memoryMB: number) => void;\n resetToDefaults: () => void;\n isFeatureEnabled: (feature: keyof typeof FEATURE_FLAGS) => boolean;\n}\n\nexport const renderConfigStore = createStore<IRenderConfigStore>((set, get) => ({\n ...DEFAULT_RENDER_CONFIG,\n\n setQualityLevel: (level) => set(getRenderConfigForQuality(level)),\n setRenderMode: (mode) => set({ renderMode: mode }),\n setCullingEnabled: (enabled) => set({ cullingEnabled: enabled }),\n\n autoAdjustQuality: (fps) =>\n set((s) => {\n const q = getOptimalQualityLevel(fps, s.qualityLevel);\n return q !== s.qualityLevel ? getRenderConfigForQuality(q) : s;\n }),\n\n autoAdjustQualityByMemory: (mb) =>\n set((s) => {\n const q = mb > 500 ? 'low' : mb > 400 && s.qualityLevel === 'high' ? 'medium' : s.qualityLevel;\n return q !== s.qualityLevel ? getRenderConfigForQuality(q as RenderConfig['qualityLevel']) : s;\n }),\n\n resetToDefaults: () => set({ ...DEFAULT_RENDER_CONFIG }),\n isFeatureEnabled: (feature) => isFeatureEnabled(feature, get()),\n}));\n","// Generated from visualli.ai design-system/components/src/container.ts — do not edit here.\n/* Containers: the dashed hull around a group of ideas, and where its name goes.\n The name is a pill straddling the hull's boundary. Which point of the boundary depends on what's inside and around\n the container: the spot is chosen by scoring candidates along all four edges against the ideas, the connectors and\n the names already placed — deterministic, so every renderer (VisualMap, the spec SDK on a canvas, PDF export) puts\n it in the same place for the same file. Pure functions, no dependencies. World units (the map's coordinates). */\n\nexport type Pt = { x: number; y: number };\nexport type Box = { x0: number; y0: number; x1: number; y1: number };\nexport type Hull = Box & { radius: number };\nexport type LabelSide = 'bottom' | 'top' | 'left' | 'right';\nexport type LabelPlacement = { x: number; y: number; side: LabelSide; score: number };\n\n/** The hull reaches this far beyond its ideas' centers, and rounds its corners this much. */\nexport const HULL = { padX: 150, padY: 125, radius: 48 };\n/** Penalties: an idea or another name under the pill is never fine; a connector through it is bad; order breaks ties. */\nconst WEIGHT = { idea: 1000, label: 1000, connector: 60, preference: 1 };\n\n/** Room kept between a member's outline and the hull, for ideas larger than the base size. */\nexport const HULL_CLEAR = { x: 50, y: 51 } as const;\n\n/** The hull around a group's ideas: `padX` / `padY` beyond their centres, or more for an idea that has grown to show\n * its label (`rx` / `ry`, its half size: then its outline plus HULL_CLEAR). */\nexport function containerHull(members: ReadonlyArray<Pt & { rx?: number; ry?: number }>): Hull | null {\n if (!members.length) return null;\n let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;\n for (const m of members) {\n const px = Math.max(HULL.padX, (m.rx ?? 0) + HULL_CLEAR.x), py = Math.max(HULL.padY, (m.ry ?? 0) + HULL_CLEAR.y);\n x0 = Math.min(x0, m.x - px); x1 = Math.max(x1, m.x + px); y0 = Math.min(y0, m.y - py); y1 = Math.max(y1, m.y + py);\n }\n return { x0, x1, y0, y1, radius: HULL.radius };\n}\n\n/** Candidate spots for a w × h pill, in preference order: bottom center (the default look), top center, the thirds of\n * bottom and top, then the sides. Spots keep the whole pill on the straight part of an edge, clear of the corners. */\nexport function labelCandidates(hull: Hull, w: number, h: number): { x: number; y: number; side: LabelSide }[] {\n const { x0, x1, y0, y1, radius } = hull;\n const cx = (x0 + x1) / 2, cy = (y0 + y1) / 2;\n const minX = x0 + radius + w / 2, maxX = x1 - radius - w / 2; // horizontal room on top / bottom\n const minY = y0 + radius + h / 2, maxY = y1 - radius - h / 2; // vertical room on the sides\n const along = (lo: number, hi: number, f: number) => (lo > hi ? (lo + hi) / 2 : lo + (hi - lo) * f);\n const out: { x: number; y: number; side: LabelSide }[] = [\n { x: cx, y: y1, side: 'bottom' }, { x: cx, y: y0, side: 'top' },\n { x: along(minX, maxX, 0.2), y: y1, side: 'bottom' }, { x: along(minX, maxX, 0.8), y: y1, side: 'bottom' },\n { x: along(minX, maxX, 0.2), y: y0, side: 'top' }, { x: along(minX, maxX, 0.8), y: y0, side: 'top' },\n { x: x1, y: cy, side: 'right' }, { x: x0, y: cy, side: 'left' },\n { x: x1, y: along(minY, maxY, 0.25), side: 'right' }, { x: x1, y: along(minY, maxY, 0.75), side: 'right' },\n { x: x0, y: along(minY, maxY, 0.25), side: 'left' }, { x: x0, y: along(minY, maxY, 0.75), side: 'left' },\n ];\n // The extremes of the top / bottom edges, for wide labels on narrow hulls.\n out.push({ x: along(minX, maxX, 0), y: y1, side: 'bottom' }, { x: along(minX, maxX, 1), y: y1, side: 'bottom' },\n { x: along(minX, maxX, 0), y: y0, side: 'top' }, { x: along(minX, maxX, 1), y: y0, side: 'top' });\n return out;\n}\n\nconst overlap = (a: Box, b: Box) => Math.max(0, Math.min(a.x1, b.x1) - Math.max(a.x0, b.x0)) * Math.max(0, Math.min(a.y1, b.y1) - Math.max(a.y0, b.y0));\n\n/** Where a container's name goes. `ideas`: the boxes of every idea on the layer (outermost ring included);\n * `connectors`: points sampled along every connector; `labels`: the pills already placed on this layer.\n * `gap` keeps a little air between the pill and what it avoids. */\nexport function placeContainerLabel(hull: Hull, size: { w: number; h: number }, obstacles: { ideas: Box[]; connectors?: Pt[][]; labels?: Box[] }, gap = 10): LabelPlacement {\n const { w, h } = size;\n let best: LabelPlacement | null = null;\n labelCandidates(hull, w, h).forEach((c, i) => {\n const box = { x0: c.x - w / 2 - gap, x1: c.x + w / 2 + gap, y0: c.y - h / 2 - gap, y1: c.y + h / 2 + gap };\n const area = w * h;\n let score = i * WEIGHT.preference;\n for (const b of obstacles.ideas) score += (overlap(box, b) / area) * WEIGHT.idea;\n for (const b of obstacles.labels || []) score += (overlap(box, b) / area) * WEIGHT.label;\n for (const line of obstacles.connectors || []) if (line.some((p) => p.x > box.x0 && p.x < box.x1 && p.y > box.y0 && p.y < box.y1)) score += WEIGHT.connector;\n if (!best || score < best.score) best = { x: c.x, y: c.y, side: c.side, score };\n });\n return best!;\n}\n\n/** Points along a connector, for `connectors`: the same cubic edgePath draws (control points two-thirds of the way\n * from each end to the bowed midpoint `mid`, which edgePath returns). */\nexport function connectorSamples(a: Pt, mid: Pt, b: Pt, n = 16): Pt[] {\n const c1 = { x: a.x + (mid.x - a.x) * 0.66, y: a.y + (mid.y - a.y) * 0.66 }, c2 = { x: b.x + (mid.x - b.x) * 0.66, y: b.y + (mid.y - b.y) * 0.66 };\n return Array.from({ length: n + 1 }, (_, k) => {\n const t = k / n, u = 1 - t;\n return { x: u * u * u * a.x + 3 * u * u * t * c1.x + 3 * u * t * t * c2.x + t * t * t * b.x, y: u * u * u * a.y + 3 * u * u * t * c1.y + 3 * u * t * t * c2.y + t * t * t * b.y };\n });\n}\n","import type { VisualliDocument, VisualliLayer, FlatNode, MindMapConnection } from '../types/index.js';\nimport { fitView, layerBounds, type FrameBox } from '../generated/geometry/interaction.js';\nimport { containerHull } from '../generated/geometry/container.js';\n\n// ── Connection helpers ────────────────────────────────────────────────────────\n\n/**\n * Returns all top-level connections that originate from the given layer.\n * A \"top-level connection\" links two nodes that both live in `layerId`.\n */\nexport function getConnectionsForLayer(\n doc: VisualliDocument,\n layerId: string,\n): MindMapConnection[] {\n const layer = doc.layers.get(layerId);\n if (!layer) return [];\n // Convert schema LayerConnection to simplified mindmap MindMapConnection\n return layer.connections.map(c => ({\n from: c.from,\n to: c.to,\n level: layer.level,\n label: c.data?.label,\n style: c.data?.style === 'dashed' ? 'dashed' : 'solid',\n } satisfies MindMapConnection));\n}\n\n/**\n * Given a node in the current layer, returns the child layer (if any) that the\n * node \"owns\" — i.e. the node is the entry-point into that child layer.\n */\nexport function getChildLayerForNode(\n doc: VisualliDocument,\n nodeId: string,\n currentLayerId: string,\n): VisualliLayer | null {\n // Walk all layers looking for one whose `parentNodeId` matches\n for (const [, layer] of doc.layers) {\n if (layer.parentLayerId === currentLayerId && layer.parentNodeId === nodeId) {\n return layer;\n }\n }\n return null;\n}\n\n/**\n * \n */\nexport function getLayerForNavigation(\n doc: VisualliDocument,\n nodeId: string,\n currentLayerId: string,\n): VisualliLayer | null {\n return getChildLayerForNode(doc, nodeId, currentLayerId);\n}\n\n// ── Fit to view ───────────────────────────────────────────────────────────────\n//\n// The design system's fit (geometry/interaction.ts → layerBounds / fitView): every\n// idea at its real size with room around it, and every container hull with room for\n// its name pill; never enlarging a layer beyond VIEW.fitMax.\n\nexport interface FitResult {\n centerX: number;\n centerY: number;\n zoomLevel: number;\n}\n\n/** The box a layer is framed by: its ideas (their real sizes) and the hulls of its `containers`. */\nexport function layerFrame(nodes: ReadonlyArray<FlatNode>, containers: ReadonlyArray<{ nodeIds: string[] }> = []): FrameBox {\n const byId = new Map(nodes.map((n) => [n.id, n]));\n const hulls: FrameBox[] = [];\n for (const c of containers) {\n const hull = containerHull(c.nodeIds.flatMap((id) => { const n = byId.get(id); return n ? [{ x: n.x, y: n.y, rx: n.width / 2, ry: n.height / 2 }] : []; }));\n if (hull) hulls.push(hull);\n }\n return layerBounds(nodes.map((n) => ({ x: n.x, y: n.y, rx: n.width / 2, ry: n.height / 2 })), hulls);\n}\n\n/** The zoom that fits a layer's ideas (and container hulls) into a canvas of `canvasWidth` × `canvasHeight`. */\nexport function calculateFitZoom(nodes: FlatNode[], canvasWidth: number, canvasHeight: number, containers: ReadonlyArray<{ nodeIds: string[] }> = []): number {\n if (nodes.length === 0) return 1;\n return fitView(layerFrame(nodes, containers), canvasWidth, canvasHeight).scale;\n}\n\n/** The world point a fitted layer is centred on: the middle of its frame. */\nexport function calculateFitCenter(nodes: FlatNode[], containers: ReadonlyArray<{ nodeIds: string[] }> = []): { x: number; y: number } {\n if (nodes.length === 0) return { x: 0, y: 0 };\n const f = layerFrame(nodes, containers);\n return { x: (f.x0 + f.x1) / 2, y: (f.y0 + f.y1) / 2 };\n}\n\n// ── Container helpers ────────────────────────────────────────────────────────\n\n// Inline the container shape here to avoid a circular import with KonvaContainerLayer.\nexport interface ContainerGroupInfo {\n id: string;\n label?: string;\n nodeIds: string[];\n level: number;\n}\n\n/**\n * Returns the container groups the given layer draws, normalising both the\n * nested-data format `{data:{label,formation}}` and the flat format `{label}`.\n */\nexport function getContainersForLayer(\n doc: VisualliDocument,\n layerId: string,\n): ContainerGroupInfo[] {\n const layer = doc.layers.get(layerId);\n if (!layer) return [];\n \n // Defensive: ensure containers is an array\n const containers = layer.containers ?? [];\n if (!Array.isArray(containers)) return [];\n \n // A container whose style is 'none' groups ideas without a hull or a name (the design system draws nothing for it).\n return containers.filter(c => c.data?.style !== 'none').map(c => {\n // Schema Container has nested data.label structure\n const label = c.data?.label ?? c.id;\n return { id: c.id, label, nodeIds: c.nodes, level: layer.level };\n });\n}\n\n/** Fit to view: centre and zoom for a layer in one call (the design system's fitView). */\nexport function calculateFitView(\n nodes: FlatNode[],\n canvasWidth: number,\n canvasHeight: number,\n containers: ReadonlyArray<{ nodeIds: string[] }> = [],\n): FitResult {\n if (nodes.length === 0) return { centerX: 0, centerY: 0, zoomLevel: 1 };\n const { scale, center } = fitView(layerFrame(nodes, containers), canvasWidth, canvasHeight);\n return { centerX: center.x, centerY: center.y, zoomLevel: scale };\n}\n","import type { FlatNode, ViewportState } from '../types/index.js';\nimport { RBushSpatialIndex } from '../spatial/spatialIndex.js';\nimport { calculateViewportBounds } from '../viewport/viewportUtils.js';\nimport { nodeBounds } from './nodeGeometry.js';\n\nexport interface CullingOptions {\n nodes: FlatNode[];\n viewport: ViewportState;\n canvasWidth: number;\n canvasHeight: number;\n levelFilter?: number;\n skipCulling?: boolean;\n isDragging?: boolean;\n spatialIndex?: RBushSpatialIndex | null;\n spatialIndexThreshold?: number;\n}\n\nconst DEFAULT_SPATIAL_INDEX_THRESHOLD = 200;\n\n/**\n * True when anything drawn for the node touches the viewport. Nodes are drawn\n * CENTRED on (x, y) with rings and stroke around them, so the test uses the\n * node's real visual bounds (not a top-left rectangle).\n */\nexport function intersectsViewport(\n n: FlatNode,\n bounds: { minX: number; minY: number; maxX: number; maxY: number },\n): boolean {\n const b = nodeBounds(n);\n return b.maxX >= bounds.minX && b.minX <= bounds.maxX && b.maxY >= bounds.minY && b.minY <= bounds.maxY;\n}\n\n/**\n * Returns the subset of nodes currently visible in the viewport.\n * Framework-agnostic logic for culling and spatial indexing.\n */\nexport function getViewportVisibleNodes(options: CullingOptions): FlatNode[] {\n const {\n nodes,\n viewport,\n canvasWidth,\n canvasHeight,\n levelFilter,\n skipCulling = false,\n isDragging = false,\n spatialIndex,\n spatialIndexThreshold = DEFAULT_SPATIAL_INDEX_THRESHOLD,\n } = options;\n\n const filtered = levelFilter !== undefined\n ? nodes.filter(n => n.level === levelFilter)\n : nodes;\n\n if (filtered.length === 0) return [];\n\n // During transitions or drags show all nodes to avoid partial layer appearance\n if (skipCulling || isDragging) return filtered;\n\n const bounds = calculateViewportBounds(viewport, canvasWidth, canvasHeight);\n\n if (filtered.length < spatialIndexThreshold) {\n return filtered.filter(n => intersectsViewport(n, bounds));\n }\n\n if (spatialIndex) {\n const nodeIds = spatialIndex.query({\n minX: bounds.minX, minY: bounds.minY, maxX: bounds.maxX, maxY: bounds.maxY,\n });\n const idSet = new Set(nodeIds);\n return filtered.filter(n => idSet.has(n.id));\n }\n\n // Fallback to simple filter if no index provided but threshold exceeded\n return filtered.filter(n => intersectsViewport(n, bounds));\n}\n","// Generated from visualli.ai design-system/components/src/motion.ts — do not edit here.\n/* The canvas choreography — how a layer arrives, how you step inside and back out, how an idea answers hover.\n One source for every renderer: VisualMap drives its CSS animations from these values (as CSS variables and\n animation delays), and a canvas renderer (e.g. the spec SDK on Konva) can run the same timeline from its own loop.\n Times in ms, scales as factors, easings as cubic-bezier control points. No dependencies, so it can travel alone.\n The durations and easings equal the motion tokens (duration-*, ease-*, stagger-reveal); the build checks that. */\n\nexport type Bezier = readonly [number, number, number, number];\n\nexport const EASE = {\n /** ease-standard — UI and connector drawing. */ standard: [0.4, 0, 0.2, 1] as Bezier,\n /** ease-zoom — diving into and out of layers. */ zoom: [0.2, 0.8, 0.2, 1] as Bezier,\n /** ease-bloom — ideas arriving, with a little overshoot. */ bloom: [0.34, 1.4, 0.64, 1] as Bezier,\n};\n\nexport const MOTION = {\n /** A layer arrives: ideas bloom one by one in sibling order, center first, then connectors draw. */\n reveal: {\n /** duration-reveal: each idea's bloom. */ duration: 420,\n /** stagger-reveal: delay between consecutive ideas. */ stagger: 70,\n /** An idea starts at this scale… */ fromScale: 0.55,\n /** …and this fraction of the way from its place toward the layer's center. */ fromCenter: 0.5,\n ease: EASE.bloom,\n /** Settle time after the last bloom before the map is idle (interactive again). */ tail: 200,\n },\n /** Connectors of an arriving layer: they start once the ideas are mostly in. */\n connector: {\n /** Lead time before the first connector, on top of the ideas' stagger. */ lead: 240,\n /** Delay between consecutive connectors. */ stagger: 60,\n /** A solid connector draws from source to target; a dashed one fades in instead. */ draw: 500,\n /** The connector group's fade (duration-base). */ fade: 240,\n ease: EASE.standard,\n },\n /** Step inside: the current layer zooms toward the idea and fades; the inner layer then arrives (reveal). */\n dive: {\n /** The old layer's zoom, toward the idea's position. */ scale: 3.2,\n /** duration-zoom. */ duration: 500,\n /** It fades out after this delay, over `fade`. */ fadeDelay: 150, fade: 160,\n /** The layers swap (and the reveal starts) this long after the dive starts. */ swapAfter: 320,\n ease: EASE.zoom,\n },\n /** Back out (depth trail): the current layer shrinks toward the center and fades; the outer layer arrives. */\n surface: {\n scale: 0.6, duration: 220, fade: 200,\n swapAfter: 220,\n ease: EASE.zoom,\n },\n /** The arriving layer as a whole settles from slightly small. */\n settle: { fromScale: 0.94, duration: 260, ease: EASE.standard },\n /** Hover (pointer) or select: the idea lifts; its rings turn and grow a touch — a nudge, not a wobble. */\n hover: {\n lift: 2, ringRotate: -2, ringScale: 1.015,\n /** duration-base, for both the lift (ease-bloom) and the rings (ease-standard). */ duration: 240,\n liftEase: EASE.bloom, ringEase: EASE.standard,\n },\n /** Reduced motion, or Gradual reveal off: everything appears together with a short fade; dives become cross-fades. */\n reduced: { fade: 120 },\n /** Large layers. The stagger is written for a dozen ideas; a layer of hundreds would take minutes to arrive and\n * every frame of a bloom repaints the whole layer. Above `staggerSlots` ideas (and connectors), they share that many\n * slots, so a layer never takes longer to arrive than `staggerSlots` ideas would. Above `bloomMax` ideas the layer\n * fades in together (the reduced fade) and hover lifts snap instead of easing. */\n largeLayer: { staggerSlots: 30, bloomMax: 150 },\n} as const;\n\nexport type Point = { x: number; y: number };\n\n/** Delay before idea `i` (sibling order) starts to bloom. */\nexport function revealDelay(i: number): number { return i * MOTION.reveal.stagger; }\n\n/** Delay before connector `i` starts, in a layer of `nodeCount` ideas. */\nexport function connectorDelay(i: number, nodeCount: number): number {\n return MOTION.connector.lead + nodeCount * MOTION.reveal.stagger + i * MOTION.connector.stagger;\n}\n\n/** How long a layer's arrival takes, until the map is idle again. 0 with reduced motion. */\nexport function revealTotal(nodeCount: number, reduced = false): number {\n return reduced ? 0 : MOTION.reveal.duration + nodeCount * MOTION.reveal.stagger + MOTION.reveal.tail;\n}\n\n/** Where an idea starts its bloom, as an offset from its final position: part of the way toward the layer's center. */\nexport function bloomOffset(node: Point, center: Point): Point {\n const k = MOTION.reveal.fromCenter;\n return { x: (center.x - node.x) * k, y: (center.y - node.y) * k };\n}\n\n/** When the layers swap after Step inside ('in') or Back out ('out'). 0 with reduced motion (a cross-fade). */\nexport function swapDelay(dir: 'in' | 'out', reduced = false): number {\n return reduced ? 0 : dir === 'in' ? MOTION.dive.swapAfter : MOTION.surface.swapAfter;\n}\n\n/** The stagger slot of item `i` of `count` (ideas or connectors): its own index up to `staggerSlots`, then shared. */\nexport function revealSlot(i: number, count: number): number {\n const slots = Math.min(count, MOTION.largeLayer.staggerSlots);\n return count > slots ? Math.floor((i * slots) / count) : i;\n}\n\n/** Whether a layer of `nodeCount` ideas blooms in one by one (else it fades in together and hover lifts snap). */\nexport function layerBlooms(nodeCount: number): boolean { return nodeCount <= MOTION.largeLayer.bloomMax; }\n\n/** A layer's whole arrival, large layers included: when idea `i` and connector `i` start, and when the layer is idle. */\nexport function layerReveal(nodeCount: number, connectorCount: number, reduced = false) {\n const instant = reduced || !layerBlooms(nodeCount);\n const slots = Math.min(nodeCount, MOTION.largeLayer.staggerSlots);\n const edgeSlots = Math.min(connectorCount, MOTION.largeLayer.staggerSlots);\n return {\n /** Fades in together (reduced motion, Gradual reveal off, or a layer past `bloomMax`). */ instant,\n ideaDelay: (i: number) => (instant ? 0 : revealDelay(revealSlot(i, nodeCount))),\n connectorDelay: (i: number) => (instant ? 0 : connectorDelay(revealSlot(i, connectorCount), slots)),\n /** Until the map is idle again. */\n total: instant ? (reduced ? 0 : MOTION.reduced.fade) : Math.max(revealTotal(slots), edgeSlots ? connectorDelay(edgeSlots - 1, slots) + MOTION.connector.draw : 0),\n };\n}\n\n/** CSS form of an easing. */\nexport function cssEase(e: Bezier): string { return `cubic-bezier(${e.join(', ')})`; }\n\n/** Evaluate an easing at progress t (0–1), for renderers that animate in their own loop. */\nexport function ease(e: Bezier, t: number): number {\n const [x1, y1, x2, y2] = e;\n if (t <= 0) return 0; if (t >= 1) return 1;\n const bx = (u: number) => 3 * x1 * u * (1 - u) ** 2 + 3 * x2 * u * u * (1 - u) + u ** 3;\n const by = (u: number) => 3 * y1 * u * (1 - u) ** 2 + 3 * y2 * u * u * (1 - u) + u ** 3;\n let lo = 0, hi = 1, u = t;\n for (let k = 0; k < 24; k++) { u = (lo + hi) / 2; if (bx(u) < t) lo = u; else hi = u; }\n return by(u);\n}\n\n/** The CSS variables VisualMap sets on its root, so its stylesheet animates with exactly these values. */\nexport function motionVars(): Record<string, string> {\n const m = MOTION;\n return {\n '--vi-bloom-from': String(m.reveal.fromScale),\n '--vi-line-draw': `${m.connector.draw}ms`,\n '--vi-dive-scale': String(m.dive.scale), '--vi-dive-fade': `${m.dive.fade}ms`, '--vi-dive-fade-delay': `${m.dive.fadeDelay}ms`,\n '--vi-surface-scale': String(m.surface.scale), '--vi-surface-dur': `${m.surface.duration}ms`, '--vi-surface-fade': `${m.surface.fade}ms`,\n '--vi-settle-from': String(m.settle.fromScale), '--vi-settle-dur': `${m.settle.duration}ms`,\n '--vi-reduced-fade': `${m.reduced.fade}ms`,\n '--vi-lift': `${m.hover.lift}px`, '--vi-ring-turn': `${m.hover.ringRotate}deg`, '--vi-ring-grow': String(m.hover.ringScale),\n };\n}\n","// Generated from visualli.ai design-system/components/src/detail.ts — do not edit here.\n/* Level of detail: what an idea draws at the size it's seen. Far-out views of large maps show ideas as specks; the\n rings, label and shadow of an idea a few pixels wide can't be seen, and drawing them makes large maps slow. Every\n renderer follows the same thresholds, so a map simplifies alike everywhere. Sizes are on-screen CSS pixels of the\n idea's width. No dependencies, so it can travel alone. */\n\nexport const DETAIL = {\n /** Below this on-screen width an idea draws only its body: no rings, label or shadow. */ bodyOnlyBelow: 24,\n /** Below this it may be drawn as a plain filled speck in its topic fill (no outline) — indistinguishable at this size. */ speckBelow: 12,\n /** Above this many ideas in view, idea shadows are skipped (the costliest effect to draw). */ shadowsMaxVisible: 150,\n} as const;\n\nexport type IdeaDetail = 'full' | 'body' | 'speck';\n\n/** What an idea of this on-screen width draws. A selected, focused or hovered idea always draws in full. */\nexport function ideaDetail(screenWidth: number, emphasised = false): IdeaDetail {\n if (emphasised || screenWidth >= DETAIL.bodyOnlyBelow) return 'full';\n return screenWidth < DETAIL.speckBelow ? 'speck' : 'body';\n}\n\n/** Whether idea shadows are drawn with this many ideas in view. */\nexport function shadowsShown(visibleIdeas: number): boolean { return visibleIdeas <= DETAIL.shadowsMaxVisible; }\n"],"mappings":"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","names":["u"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Connection, Container
|
|
1
|
+
import { Node, Connection, Container } from '@visualli/bindings';
|
|
2
2
|
|
|
3
3
|
/** Alias to schema Node type for SDK consistency */
|
|
4
4
|
type LayerNode = Node;
|
|
@@ -56,18 +56,4 @@ interface VisualliRenderConnection {
|
|
|
56
56
|
style?: 'dashed' | 'solid';
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
type VisualliMeta = Meta;
|
|
61
|
-
|
|
62
|
-
/** Parsed .visualli document structure. */
|
|
63
|
-
interface VisualliDocument {
|
|
64
|
-
meta: VisualliMeta;
|
|
65
|
-
/** Keyed by layer ID */
|
|
66
|
-
layers: Map<string, VisualliLayer>;
|
|
67
|
-
/** Quick lookup by level */
|
|
68
|
-
layersByLevel: Map<number, VisualliLayer[]>;
|
|
69
|
-
/** The level-0 layer */
|
|
70
|
-
rootLayer: VisualliLayer | null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export type { LayerConnection as L, VisualliDocument as V, VisualliLayer as a, LayerContainer as b, LayerNode as c, VisualliMeta as d, VisualliRenderConnection as e, VisualliRenderNode as f };
|
|
59
|
+
export type { LayerConnection as L, VisualliLayer as V, LayerContainer as a, LayerNode as b, VisualliRenderConnection as c, VisualliRenderNode as d };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Connection, Container
|
|
1
|
+
import { Node, Connection, Container } from '@visualli/bindings';
|
|
2
2
|
|
|
3
3
|
/** Alias to schema Node type for SDK consistency */
|
|
4
4
|
type LayerNode = Node;
|
|
@@ -56,18 +56,4 @@ interface VisualliRenderConnection {
|
|
|
56
56
|
style?: 'dashed' | 'solid';
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
type VisualliMeta = Meta;
|
|
61
|
-
|
|
62
|
-
/** Parsed .visualli document structure. */
|
|
63
|
-
interface VisualliDocument {
|
|
64
|
-
meta: VisualliMeta;
|
|
65
|
-
/** Keyed by layer ID */
|
|
66
|
-
layers: Map<string, VisualliLayer>;
|
|
67
|
-
/** Quick lookup by level */
|
|
68
|
-
layersByLevel: Map<number, VisualliLayer[]>;
|
|
69
|
-
/** The level-0 layer */
|
|
70
|
-
rootLayer: VisualliLayer | null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export type { LayerConnection as L, VisualliDocument as V, VisualliLayer as a, LayerContainer as b, LayerNode as c, VisualliMeta as d, VisualliRenderConnection as e, VisualliRenderNode as f };
|
|
59
|
+
export type { LayerConnection as L, VisualliLayer as V, LayerContainer as a, LayerNode as b, VisualliRenderConnection as c, VisualliRenderNode as d };
|
package/dist/layout/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { F as FlatNode,
|
|
1
|
+
import { F as FlatNode, d as MindMapNode } from '../mindmap-C3Qr0qKW.cjs';
|
|
2
|
+
import '../designSystem-BOrZHfEq.cjs';
|
|
2
3
|
|
|
3
4
|
interface CircularLayoutOptions {
|
|
4
5
|
/** Radius as a fraction of the container's minimum dimension (0–1). Default: 0.135 */
|
package/dist/layout/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { F as FlatNode,
|
|
1
|
+
import { F as FlatNode, d as MindMapNode } from '../mindmap-DHeVa86G.js';
|
|
2
|
+
import '../designSystem-BOrZHfEq.js';
|
|
2
3
|
|
|
3
4
|
interface CircularLayoutOptions {
|
|
4
5
|
/** Radius as a fraction of the container's minimum dimension (0–1). Default: 0.135 */
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { T as TopicName } from './designSystem-BOrZHfEq.cjs';
|
|
2
|
+
|
|
3
|
+
type IdeaKind = 'root' | 'node' | 'mini';
|
|
4
|
+
/** How much labels grow when zoomed out (`scale` = the map's zoom): never smaller than their size, up to these caps.
|
|
5
|
+
* Idea labels and container names use `idea`; connector labels `connector`. Below 100% they grow; above, they don't. */
|
|
6
|
+
declare const LABEL_GROWTH: {
|
|
7
|
+
readonly idea: 1.3;
|
|
8
|
+
readonly connector: 1.6;
|
|
9
|
+
};
|
|
10
|
+
declare const IDEA: {
|
|
11
|
+
/** Width an idea starts at… */ readonly baseWidth: {
|
|
12
|
+
readonly root: 240;
|
|
13
|
+
readonly node: 200;
|
|
14
|
+
readonly mini: 120;
|
|
15
|
+
};
|
|
16
|
+
/** …and the widest it gets before it grows taller instead. */ readonly maxWidth: {
|
|
17
|
+
readonly root: 400;
|
|
18
|
+
readonly node: 360;
|
|
19
|
+
readonly mini: 200;
|
|
20
|
+
};
|
|
21
|
+
/** Width grows in steps of this. */ readonly step: 20;
|
|
22
|
+
/** Height = width × aspect (at least `minRy` × 2), more if the label needs it. */ readonly aspect: 0.74;
|
|
23
|
+
readonly minRy: 64;
|
|
24
|
+
/** The label's box is the idea's width less this (22 each side). */ readonly labelInset: 44;
|
|
25
|
+
/** The idea widens until its label fits in this many lines. */ readonly labelLines: 3;
|
|
26
|
+
/** Label size (before the label scale and zoom growth), weight from the canvas type styles. */ readonly labelSize: {
|
|
27
|
+
readonly root: 30;
|
|
28
|
+
readonly node: 22;
|
|
29
|
+
readonly mini: 15;
|
|
30
|
+
};
|
|
31
|
+
readonly labelLineHeight: 1.15;
|
|
32
|
+
/** The label may fill at most this share of the idea's height. */ readonly labelFillHeight: 0.7;
|
|
33
|
+
};
|
|
34
|
+
/** Greedy word wrap of `text` into lines no wider than `maxWidth` (a single word longer than that gets its own line). */
|
|
35
|
+
declare function wrapLines(text: string, maxWidth: number, measure: (s: string) => number): string[];
|
|
36
|
+
/** An idea's size for its label: width, half-width / half-height for the blob, and the label's lines. The label is
|
|
37
|
+
* measured at its largest drawn size — its type size × `labelScale` (Comfort: larger text) × LABEL_GROWTH.idea (zoomed
|
|
38
|
+
* out) — so it fits at every zoom and the idea never changes size while zooming. `measure(text, px)` returns the
|
|
39
|
+
* text's width in px in the label's face at `px`. */
|
|
40
|
+
declare function ideaSize(kind: IdeaKind, label: string, measure: (text: string, px: number) => number, labelScale?: number): {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
rx: number;
|
|
44
|
+
ry: number;
|
|
45
|
+
lines: string[];
|
|
46
|
+
};
|
|
47
|
+
declare function labelGrowth(scale: number): {
|
|
48
|
+
idea: number;
|
|
49
|
+
connector: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
interface MindMapNode {
|
|
53
|
+
id: string;
|
|
54
|
+
title: string;
|
|
55
|
+
level: number;
|
|
56
|
+
x: number;
|
|
57
|
+
y: number;
|
|
58
|
+
children?: MindMapNode[];
|
|
59
|
+
parent?: string;
|
|
60
|
+
color?: string;
|
|
61
|
+
relationshipLabel?: string;
|
|
62
|
+
}
|
|
63
|
+
/** Flat structure for performance-optimised storage (10K+ nodes). */
|
|
64
|
+
interface FlatNode {
|
|
65
|
+
id: string;
|
|
66
|
+
parentId: string | null;
|
|
67
|
+
/** IDs of child nodes for quick tree traversal */
|
|
68
|
+
childrenIds?: string[];
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
/** Alternative position format for compatibility */
|
|
72
|
+
position?: {
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
};
|
|
76
|
+
/** Depth in tree hierarchy */
|
|
77
|
+
level: number;
|
|
78
|
+
title: string;
|
|
79
|
+
description?: string;
|
|
80
|
+
/** Label describing relationship to parent */
|
|
81
|
+
relationshipLabel?: string;
|
|
82
|
+
/** Colour as authored in the document (any CSS colour, or a topic name); empty when the file gives none. */
|
|
83
|
+
color: string;
|
|
84
|
+
/** Design-system topic this idea is drawn with (fill + ring colour per theme): a named or missing colour. */
|
|
85
|
+
topic?: TopicName;
|
|
86
|
+
/** A colour that isn't a topic, drawn as given (the design system's customColor); `ring` null → the `edge` token. */
|
|
87
|
+
custom?: {
|
|
88
|
+
fill: string;
|
|
89
|
+
ring: string | null;
|
|
90
|
+
};
|
|
91
|
+
/** The idea's size kind (the design system's idea.ts): 'root' for a radial map's centre, else 'node'. */
|
|
92
|
+
kind?: IdeaKind;
|
|
93
|
+
/** The idea's size for its label (idea.ts ideaSize): the outline's half width is width / 2, half height height / 2. */
|
|
94
|
+
width: number;
|
|
95
|
+
height: number;
|
|
96
|
+
/** Whether this node's children are visible */
|
|
97
|
+
isExpanded?: boolean;
|
|
98
|
+
branchCount?: number;
|
|
99
|
+
createdAt: Date;
|
|
100
|
+
updatedAt: Date;
|
|
101
|
+
}
|
|
102
|
+
/** Map-based node storage for O(1) lookups. */
|
|
103
|
+
type NodeMap = Map<string, FlatNode>;
|
|
104
|
+
/** Spatial bounds for RBush indexing. */
|
|
105
|
+
interface SpatialBounds {
|
|
106
|
+
minX: number;
|
|
107
|
+
minY: number;
|
|
108
|
+
maxX: number;
|
|
109
|
+
maxY: number;
|
|
110
|
+
nodeId: string;
|
|
111
|
+
}
|
|
112
|
+
/** Viewport state for camera position and zoom. */
|
|
113
|
+
interface ViewportState {
|
|
114
|
+
centerX: number;
|
|
115
|
+
centerY: number;
|
|
116
|
+
zoomLevel: number;
|
|
117
|
+
rotation: number;
|
|
118
|
+
visibleBounds: {
|
|
119
|
+
minX: number;
|
|
120
|
+
minY: number;
|
|
121
|
+
maxX: number;
|
|
122
|
+
maxY: number;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** Single-selection node state. */
|
|
126
|
+
interface NodeSelection {
|
|
127
|
+
selectedId: string | null;
|
|
128
|
+
}
|
|
129
|
+
/** Render configuration flags. */
|
|
130
|
+
interface RenderConfig {
|
|
131
|
+
renderMode: 'canvas' | 'simplified';
|
|
132
|
+
qualityLevel: 'high' | 'medium' | 'low';
|
|
133
|
+
cullingEnabled: boolean;
|
|
134
|
+
fpsTarget: number;
|
|
135
|
+
memoryLimit: number;
|
|
136
|
+
}
|
|
137
|
+
interface MindMapData {
|
|
138
|
+
nodes: MindMapNode[];
|
|
139
|
+
connections: MindMapConnection[];
|
|
140
|
+
}
|
|
141
|
+
/** Simplified connection type for mindmap rendering (not to be confused with schema Connection) */
|
|
142
|
+
interface MindMapConnection {
|
|
143
|
+
from: string;
|
|
144
|
+
to: string;
|
|
145
|
+
level: number;
|
|
146
|
+
label?: string;
|
|
147
|
+
/** 'dashed' draws the connector dashed (design-system `is-dashed`). */
|
|
148
|
+
style?: 'solid' | 'dashed';
|
|
149
|
+
}
|
|
150
|
+
interface TopLevelConnection {
|
|
151
|
+
from: string;
|
|
152
|
+
to: string;
|
|
153
|
+
label: string;
|
|
154
|
+
}
|
|
155
|
+
/** Complete mindmap configuration schema. */
|
|
156
|
+
interface MindMapConfig {
|
|
157
|
+
metadata: {
|
|
158
|
+
id?: string;
|
|
159
|
+
title: string;
|
|
160
|
+
description?: string;
|
|
161
|
+
version: string;
|
|
162
|
+
created: string;
|
|
163
|
+
lastModified: string;
|
|
164
|
+
};
|
|
165
|
+
nodes: MindMapNode[];
|
|
166
|
+
topLevelConnections: TopLevelConnection[];
|
|
167
|
+
settings?: {
|
|
168
|
+
defaultColors?: {
|
|
169
|
+
level0: string;
|
|
170
|
+
level1: string;
|
|
171
|
+
level2: string;
|
|
172
|
+
level3: string;
|
|
173
|
+
[key: `level${number}`]: string;
|
|
174
|
+
};
|
|
175
|
+
layout?: {
|
|
176
|
+
nodeSpacing: number;
|
|
177
|
+
levelSpacing: number;
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export { type FlatNode as F, type IdeaKind as I, LABEL_GROWTH as L, type MindMapConnection as M, type NodeSelection as N, type RenderConfig as R, type SpatialBounds as S, type TopLevelConnection as T, type ViewportState as V, IDEA as a, type MindMapConfig as b, type MindMapData as c, type MindMapNode as d, type NodeMap as e, ideaSize as i, labelGrowth as l, wrapLines as w };
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { T as TopicName } from './designSystem-BOrZHfEq.js';
|
|
2
|
+
|
|
3
|
+
type IdeaKind = 'root' | 'node' | 'mini';
|
|
4
|
+
/** How much labels grow when zoomed out (`scale` = the map's zoom): never smaller than their size, up to these caps.
|
|
5
|
+
* Idea labels and container names use `idea`; connector labels `connector`. Below 100% they grow; above, they don't. */
|
|
6
|
+
declare const LABEL_GROWTH: {
|
|
7
|
+
readonly idea: 1.3;
|
|
8
|
+
readonly connector: 1.6;
|
|
9
|
+
};
|
|
10
|
+
declare const IDEA: {
|
|
11
|
+
/** Width an idea starts at… */ readonly baseWidth: {
|
|
12
|
+
readonly root: 240;
|
|
13
|
+
readonly node: 200;
|
|
14
|
+
readonly mini: 120;
|
|
15
|
+
};
|
|
16
|
+
/** …and the widest it gets before it grows taller instead. */ readonly maxWidth: {
|
|
17
|
+
readonly root: 400;
|
|
18
|
+
readonly node: 360;
|
|
19
|
+
readonly mini: 200;
|
|
20
|
+
};
|
|
21
|
+
/** Width grows in steps of this. */ readonly step: 20;
|
|
22
|
+
/** Height = width × aspect (at least `minRy` × 2), more if the label needs it. */ readonly aspect: 0.74;
|
|
23
|
+
readonly minRy: 64;
|
|
24
|
+
/** The label's box is the idea's width less this (22 each side). */ readonly labelInset: 44;
|
|
25
|
+
/** The idea widens until its label fits in this many lines. */ readonly labelLines: 3;
|
|
26
|
+
/** Label size (before the label scale and zoom growth), weight from the canvas type styles. */ readonly labelSize: {
|
|
27
|
+
readonly root: 30;
|
|
28
|
+
readonly node: 22;
|
|
29
|
+
readonly mini: 15;
|
|
30
|
+
};
|
|
31
|
+
readonly labelLineHeight: 1.15;
|
|
32
|
+
/** The label may fill at most this share of the idea's height. */ readonly labelFillHeight: 0.7;
|
|
33
|
+
};
|
|
34
|
+
/** Greedy word wrap of `text` into lines no wider than `maxWidth` (a single word longer than that gets its own line). */
|
|
35
|
+
declare function wrapLines(text: string, maxWidth: number, measure: (s: string) => number): string[];
|
|
36
|
+
/** An idea's size for its label: width, half-width / half-height for the blob, and the label's lines. The label is
|
|
37
|
+
* measured at its largest drawn size — its type size × `labelScale` (Comfort: larger text) × LABEL_GROWTH.idea (zoomed
|
|
38
|
+
* out) — so it fits at every zoom and the idea never changes size while zooming. `measure(text, px)` returns the
|
|
39
|
+
* text's width in px in the label's face at `px`. */
|
|
40
|
+
declare function ideaSize(kind: IdeaKind, label: string, measure: (text: string, px: number) => number, labelScale?: number): {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
rx: number;
|
|
44
|
+
ry: number;
|
|
45
|
+
lines: string[];
|
|
46
|
+
};
|
|
47
|
+
declare function labelGrowth(scale: number): {
|
|
48
|
+
idea: number;
|
|
49
|
+
connector: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
interface MindMapNode {
|
|
53
|
+
id: string;
|
|
54
|
+
title: string;
|
|
55
|
+
level: number;
|
|
56
|
+
x: number;
|
|
57
|
+
y: number;
|
|
58
|
+
children?: MindMapNode[];
|
|
59
|
+
parent?: string;
|
|
60
|
+
color?: string;
|
|
61
|
+
relationshipLabel?: string;
|
|
62
|
+
}
|
|
63
|
+
/** Flat structure for performance-optimised storage (10K+ nodes). */
|
|
64
|
+
interface FlatNode {
|
|
65
|
+
id: string;
|
|
66
|
+
parentId: string | null;
|
|
67
|
+
/** IDs of child nodes for quick tree traversal */
|
|
68
|
+
childrenIds?: string[];
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
/** Alternative position format for compatibility */
|
|
72
|
+
position?: {
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
};
|
|
76
|
+
/** Depth in tree hierarchy */
|
|
77
|
+
level: number;
|
|
78
|
+
title: string;
|
|
79
|
+
description?: string;
|
|
80
|
+
/** Label describing relationship to parent */
|
|
81
|
+
relationshipLabel?: string;
|
|
82
|
+
/** Colour as authored in the document (any CSS colour, or a topic name); empty when the file gives none. */
|
|
83
|
+
color: string;
|
|
84
|
+
/** Design-system topic this idea is drawn with (fill + ring colour per theme): a named or missing colour. */
|
|
85
|
+
topic?: TopicName;
|
|
86
|
+
/** A colour that isn't a topic, drawn as given (the design system's customColor); `ring` null → the `edge` token. */
|
|
87
|
+
custom?: {
|
|
88
|
+
fill: string;
|
|
89
|
+
ring: string | null;
|
|
90
|
+
};
|
|
91
|
+
/** The idea's size kind (the design system's idea.ts): 'root' for a radial map's centre, else 'node'. */
|
|
92
|
+
kind?: IdeaKind;
|
|
93
|
+
/** The idea's size for its label (idea.ts ideaSize): the outline's half width is width / 2, half height height / 2. */
|
|
94
|
+
width: number;
|
|
95
|
+
height: number;
|
|
96
|
+
/** Whether this node's children are visible */
|
|
97
|
+
isExpanded?: boolean;
|
|
98
|
+
branchCount?: number;
|
|
99
|
+
createdAt: Date;
|
|
100
|
+
updatedAt: Date;
|
|
101
|
+
}
|
|
102
|
+
/** Map-based node storage for O(1) lookups. */
|
|
103
|
+
type NodeMap = Map<string, FlatNode>;
|
|
104
|
+
/** Spatial bounds for RBush indexing. */
|
|
105
|
+
interface SpatialBounds {
|
|
106
|
+
minX: number;
|
|
107
|
+
minY: number;
|
|
108
|
+
maxX: number;
|
|
109
|
+
maxY: number;
|
|
110
|
+
nodeId: string;
|
|
111
|
+
}
|
|
112
|
+
/** Viewport state for camera position and zoom. */
|
|
113
|
+
interface ViewportState {
|
|
114
|
+
centerX: number;
|
|
115
|
+
centerY: number;
|
|
116
|
+
zoomLevel: number;
|
|
117
|
+
rotation: number;
|
|
118
|
+
visibleBounds: {
|
|
119
|
+
minX: number;
|
|
120
|
+
minY: number;
|
|
121
|
+
maxX: number;
|
|
122
|
+
maxY: number;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** Single-selection node state. */
|
|
126
|
+
interface NodeSelection {
|
|
127
|
+
selectedId: string | null;
|
|
128
|
+
}
|
|
129
|
+
/** Render configuration flags. */
|
|
130
|
+
interface RenderConfig {
|
|
131
|
+
renderMode: 'canvas' | 'simplified';
|
|
132
|
+
qualityLevel: 'high' | 'medium' | 'low';
|
|
133
|
+
cullingEnabled: boolean;
|
|
134
|
+
fpsTarget: number;
|
|
135
|
+
memoryLimit: number;
|
|
136
|
+
}
|
|
137
|
+
interface MindMapData {
|
|
138
|
+
nodes: MindMapNode[];
|
|
139
|
+
connections: MindMapConnection[];
|
|
140
|
+
}
|
|
141
|
+
/** Simplified connection type for mindmap rendering (not to be confused with schema Connection) */
|
|
142
|
+
interface MindMapConnection {
|
|
143
|
+
from: string;
|
|
144
|
+
to: string;
|
|
145
|
+
level: number;
|
|
146
|
+
label?: string;
|
|
147
|
+
/** 'dashed' draws the connector dashed (design-system `is-dashed`). */
|
|
148
|
+
style?: 'solid' | 'dashed';
|
|
149
|
+
}
|
|
150
|
+
interface TopLevelConnection {
|
|
151
|
+
from: string;
|
|
152
|
+
to: string;
|
|
153
|
+
label: string;
|
|
154
|
+
}
|
|
155
|
+
/** Complete mindmap configuration schema. */
|
|
156
|
+
interface MindMapConfig {
|
|
157
|
+
metadata: {
|
|
158
|
+
id?: string;
|
|
159
|
+
title: string;
|
|
160
|
+
description?: string;
|
|
161
|
+
version: string;
|
|
162
|
+
created: string;
|
|
163
|
+
lastModified: string;
|
|
164
|
+
};
|
|
165
|
+
nodes: MindMapNode[];
|
|
166
|
+
topLevelConnections: TopLevelConnection[];
|
|
167
|
+
settings?: {
|
|
168
|
+
defaultColors?: {
|
|
169
|
+
level0: string;
|
|
170
|
+
level1: string;
|
|
171
|
+
level2: string;
|
|
172
|
+
level3: string;
|
|
173
|
+
[key: `level${number}`]: string;
|
|
174
|
+
};
|
|
175
|
+
layout?: {
|
|
176
|
+
nodeSpacing: number;
|
|
177
|
+
levelSpacing: number;
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export { type FlatNode as F, type IdeaKind as I, LABEL_GROWTH as L, type MindMapConnection as M, type NodeSelection as N, type RenderConfig as R, type SpatialBounds as S, type TopLevelConnection as T, type ViewportState as V, IDEA as a, type MindMapConfig as b, type MindMapData as c, type MindMapNode as d, type NodeMap as e, ideaSize as i, labelGrowth as l, wrapLines as w };
|