import type { GraphEdge, GraphLayout, GraphNode, GraphNodeState } from './graph.types'; export interface ForceSettings { /** Node-node repulsion. Larger spreads the graph out. @default 900 */ repulsion?: number; /** Edge spring stiffness, 0-1. @default 0.08 */ springStrength?: number; /** Preferred edge length at rest. @default 70 */ springLength?: number; /** Pull toward the origin, which stops islands drifting away. @default 0.015 */ centering?: number; /** Velocity retained per tick. @default 0.82 */ damping?: number; /** Barnes-Hut accuracy; see `octree.ts`. @default 0.8 */ theta?: number; /** Below this total movement the layout is considered settled. @default 0.05 */ settleThreshold?: number; /** * Floor on the separation used for repulsion, in layout units. * @default 6 */ minDistance?: number; /** * Hard cap on how far a node may move in one tick. * * A speed limit is what keeps a bad initial configuration from throwing nodes * off to infinity before damping has any chance to bite. * @default 30 */ maxVelocity?: number; /** * Fraction of the remaining energy shed each tick. * * This is what *guarantees* termination: forces are scaled by a cooling alpha, * so the layout always converges instead of orbiting forever and pinning a CPU * core on a dashboard nobody is looking at. * @default 0.022 */ alphaDecay?: number; /** Alpha below which the layout is done. @default 0.002 */ alphaMin?: number; } /** Places nodes on a sphere (or circle in 2D) before the forces take over. */ export declare function seedPositions(nodes: GraphNode[], layout: GraphLayout): GraphNodeState[]; export interface TickResult { /** Average distance a node moved this tick. */ movement: number; settled: boolean; /** Remaining energy, to be fed into the next tick. */ alpha: number; } /** * Advances the layout by one step. * * @description * Three forces: Barnes-Hut repulsion between all nodes, Hooke springs along the * edges, and a weak pull toward the origin so disconnected components do not * drift off screen forever. * * `states` is mutated in place — a tick allocates only the octree, which matters * when this runs sixty times a second over thousands of nodes. */ export declare function tick(states: GraphNodeState[], edges: GraphEdge[], indexById: Map, layout: GraphLayout, settings?: ForceSettings, /** Remaining energy, from the previous tick. */ alpha?: number): TickResult; /** * Runs the layout to rest without animating. * * Used when the viewer asked for reduced motion, and when producing a static * image: the diagram appears already arranged rather than visibly settling. */ export declare function runToSettle(states: GraphNodeState[], edges: GraphEdge[], indexById: Map, layout: GraphLayout, settings?: ForceSettings, maxIterations?: number): number;