/** * rgui core — one-cell-one-thing + boundary dissolution. * * Rule 1: nodes never overlap. A dragged node that would overlap another is * pushed out along the axis of least penetration until the edges are FLUSH — * i.e. it snaps onto the neighbor instead of covering it. * * Rule 2: nodes whose edges are flush render as one fused shape: the shared * border segment and any wire between the pair are not drawn. The nodes stay * fully standalone (drag one away to split) — this is visual fusion only, * distinct from rg-merge (LOD pseudo-node), which moves as a single unit. */ import { type Edge, type Graph, type GraphNode, type Port, type Side } from "./graph.js"; export type { Side }; /** * Resolve overlaps for a node being dragged to (x, y): push it out along the * axis of least penetration until it sits flush against whatever it hit. * Contact beats grid snap — one-cell-one-thing is the invariant. */ export declare function resolveOverlap(node: GraphNode, x: number, y: number, others: GraphNode[], opts?: { /** cross-axis align magnet in WORLD units (0 disables) */ alignSnap?: number; direction?: "ltr" | "rtl"; }): { x: number; y: number; }; /** * 一格一物 on resize: cap a node's requested size so growth stops at flush * contact with neighbors (width first, then height with the new width). */ export declare function clampSize(node: GraphNode, w: number, h: number, others: GraphNode[]): { w: number; h: number; }; /** A flush contact segment between two nodes (world coords). */ export interface FlushSegment { a: GraphNode; b: GraphNode; /** "v": shared vertical edge; "h": shared horizontal edge */ axis: "v" | "h"; /** the shared edge coordinate (x for "v", y for "h") */ at: number; /** overlap interval along the edge */ from: number; to: number; } /** * Find every pair of nodes whose edges are flush (touching with overlapping * intervals). These boundaries — and wires between the pairs — dissolve. */ export declare function flushSegments(nodes: GraphNode[]): FlushSegment[]; /** Set of "idA|idB" (sorted) pairs in flush contact — their wires dissolve. */ export declare function flushPairKeys(segments: FlushSegment[]): Set; export interface Interval { from: number; to: number; } export type SideCoverage = Record; /** subtract covered intervals from a span, returning the uncovered pieces */ export declare function subtractIntervals(span: Interval, covered: Interval[]): Interval[]; /** per-node covered intervals on each side, from flush segments */ export declare function sideCoverage(segments: FlushSegment[]): Map; /** union-find flush components: nodeId -> component root id */ export declare function flushComponents(nodes: GraphNode[], segments: FlushSegment[]): Map; export interface PortPlacement { x: number; y: number; /** * which edge the port sits on. It starts at the node's flow side and may * flip to the opposite edge — when the wire actually leaves that way, or * when the flow side has dissolved into a flush seam. */ edge: Side; /** true when every wire of this port stays inside one flush component */ hidden: boolean; } /** key: `${nodeId}/${"in"|"out"}/${portId}` */ export declare function computePortLayout(graph: Graph, nodes: GraphNode[], segments: FlushSegment[]): Map; /** * Kind gate for a candidate wire. Defaults to exact signal-kind equality — * text→text, image→image. Hosts widen it (e.g. a "any" kind) via rgui's * isValidConnection. */ export type ConnectGate = (from: { node: GraphNode; port: Port; }, to: { node: GraphNode; port: Port; }) => boolean; export interface SnapConnectOptions { gate?: ConnectGate; /** * how far apart two facing ports may sit along the seam and still capture * each other (world units, default half the seam's port pitch) */ tolerance?: number; /** edges the host authored — an input already wired there is not stolen */ existing?: Edge[]; } /** * SNAP-CONNECT: derive the wires implied by geometry alone. * * When a drag pushes two nodes flush (resolveOverlap guarantees contact, * never overlap), the seam between them may line an output edge up against a * facing input edge. Every pair of ports that meet across that seam within * `tolerance`, and whose kinds pass the gate, becomes an edge marked * `temp: true`. Nothing is stored: the result is a pure function of node * positions, so pulling the nodes apart drops the edges on the next call — * "cutting" a wire costs one drag, not a click on a 2-px curve. * * Ports match nearest-first, one wire per port on each side, and an input * already fed by an authored edge is left alone. */ export declare function snapConnections(nodes: GraphNode[], opts?: SnapConnectOptions): Edge[]; /** world y of a node's i-th port row (matches inputPortPos/outputPortPos) */ export declare function portRowY(n: GraphNode, i: number): number; //# sourceMappingURL=pack.d.ts.map