/**
 * The `Graph` module provides immutable and scoped-mutable graph data
 * structures for modeling relationships between indexed nodes and edges. A
 * graph can be directed or undirected, stores user-defined data on both nodes
 * and edges, and exposes traversal, analysis, path finding, transformation, and
 * diagram export utilities.
 *
 * **Mental model**
 *
 * - Nodes and edges are addressed by stable numeric indices: {@link NodeIndex}
 *   and {@link EdgeIndex}
 * - Node data has type `N`; edge data has type `E`
 * - {@link Graph} values are immutable snapshots; use {@link MutableGraph}
 *   through {@link mutate}, {@link beginMutation}, or constructor callbacks to
 *   add, remove, or update nodes and edges
 * - Directed graphs follow edge direction for neighbors and traversals, while
 *   undirected graphs treat each edge as connecting both endpoints
 * - Missing lookups return `Option`, while structurally invalid operations such
 *   as adding an edge to a missing node throw {@link GraphError}
 *
 * **Common tasks**
 *
 * - Create graphs: {@link directed}, {@link undirected}
 * - Mutate safely: {@link mutate}, {@link addNode}, {@link addEdge},
 *   {@link removeNode}, {@link removeEdge}
 * - Query contents: {@link getNode}, {@link getEdge}, {@link hasNode},
 *   {@link hasEdge}, {@link nodeCount}, {@link edgeCount}, {@link neighbors}
 * - Transform data: {@link updateNode}, {@link updateEdge}, {@link mapNodes},
 *   {@link mapEdges}, {@link filterNodes}, {@link filterEdges},
 *   {@link filterMapNodes}, {@link filterMapEdges}
 * - Traverse lazily: {@link dfs}, {@link bfs}, {@link topo},
 *   {@link dfsPostOrder}, {@link nodes}, {@link edges}, {@link Walker}
 * - Analyze structure: {@link isAcyclic}, {@link isBipartite},
 *   {@link connectedComponents}, {@link stronglyConnectedComponents},
 *   {@link externals}
 * - Find paths: {@link dijkstra}, {@link astar}, {@link bellmanFord},
 *   {@link floydWarshall}
 * - Export diagrams: {@link toGraphViz}, {@link toMermaid}
 *
 * **Gotchas**
 *
 * - Only mutable graphs can be changed. Create one with {@link mutate} or by
 *   passing a callback to {@link directed} / {@link undirected}.
 * - Traversal APIs return lazy {@link Walker} values. Use {@link indices},
 *   {@link values}, or {@link entries} to choose what each iteration yields.
 * - `NodeIndex` and `EdgeIndex` values are identifiers, not array offsets. They
 *   are not reused after removals.
 * - Shortest-path algorithms require a cost function. {@link dijkstra} and
 *   {@link astar} reject negative weights; use {@link bellmanFord} or
 *   {@link floydWarshall} when negative weights are part of the model.
 *
 * @since 4.0.0
 */
import * as Data from "./Data.ts";
import * as Equal from "./Equal.ts";
import type { Inspectable } from "./Inspectable.ts";
import * as Option from "./Option.ts";
import type { Pipeable } from "./Pipeable.ts";
declare const TypeId = "~effect/collections/Graph";
/**
 * Node index for node identification using plain numbers.
 *
 * **When to use**
 *
 * Use when storing or passing the stable identifier of a graph node between
 * `Graph` operations.
 *
 * **Details**
 *
 * `addNode` allocates node identifiers from the graph's next node index.
 *
 * **Gotchas**
 *
 * A `NodeIndex` is an identifier, not an array offset. Removed node identifiers
 * are not reused.
 *
 * @see {@link EdgeIndex} for edge identifiers instead of node identifiers
 * @see {@link addNode} for creating node identifiers
 *
 * @category models
 * @since 3.18.0
 */
export type NodeIndex = number;
/**
 * Edge index for edge identification using plain numbers.
 *
 * **When to use**
 *
 * Use when you need to keep the identifier for a graph edge so you can later
 * read, update, remove, or compare that edge.
 *
 * **Gotchas**
 *
 * An `EdgeIndex` is an identifier, not an array offset. Removed edge
 * identifiers are not reused.
 *
 * @see {@link NodeIndex} for node identifiers instead of edge identifiers
 * @see {@link Edge} for the edge value addressed by this identifier
 * @see {@link addEdge} for creating edge identifiers
 * @see {@link getEdge} for reading edges by identifier
 *
 * @category models
 * @since 3.18.0
 */
export type EdgeIndex = number;
/**
 * Represents edge data containing source, target, and user data.
 *
 * **When to use**
 *
 * Use as the graph edge value returned by `getEdge` and `edges` when you need
 * the source node, target node, and stored edge data together.
 *
 * @see {@link getEdge} for reading a single edge by identifier
 * @see {@link addEdge} for adding edges to a graph
 * @see {@link edges} for iterating graph edges
 *
 * @category models
 * @since 3.18.0
 */
export declare class Edge<E> extends Data.Class<{
    readonly source: NodeIndex;
    readonly target: NodeIndex;
    readonly data: E;
}> {
}
/**
 * Graph type for distinguishing directed and undirected graphs.
 *
 * **When to use**
 *
 * Use when writing graph-polymorphic types or helpers that need to preserve
 * whether a graph is directed or undirected.
 *
 * @see {@link Graph} for immutable graphs parameterized by kind
 * @see {@link MutableGraph} for mutable graphs parameterized by kind
 *
 * @category models
 * @since 3.18.0
 */
export type Kind = "directed" | "undirected";
/**
 * Common structural interface shared by immutable and mutable graphs.
 *
 * **Details**
 *
 * Contains the node and edge maps, adjacency indexes, allocation counters, and
 * shared protocols used by both `Graph` and `MutableGraph`.
 *
 * @category models
 * @since 3.18.0
 */
export interface Proto<out N, out E> extends Iterable<readonly [NodeIndex, N]>, Equal.Equal, Pipeable, Inspectable {
    readonly [TypeId]: typeof TypeId;
    readonly nodes: Map<NodeIndex, N>;
    readonly edges: Map<EdgeIndex, Edge<E>>;
    readonly adjacency: Map<NodeIndex, Array<EdgeIndex>>;
    readonly reverseAdjacency: Map<NodeIndex, Array<EdgeIndex>>;
    nextNodeIndex: NodeIndex;
    nextEdgeIndex: EdgeIndex;
    acyclic: Option.Option<boolean>;
}
/**
 * Immutable graph interface.
 *
 * **When to use**
 *
 * Use as the immutable graph model for code that queries, traverses,
 * transforms, or analyzes graph structure without mutating it.
 *
 * @see {@link MutableGraph} for the mutable counterpart used inside mutation scopes
 * @see {@link DirectedGraph} for a `Graph` fixed to directed edges
 * @see {@link UndirectedGraph} for a `Graph` fixed to undirected edges
 *
 * @category models
 * @since 3.18.0
 */
export interface Graph<out N, out E, T extends Kind = "directed"> extends Proto<N, E> {
    readonly type: T;
    readonly mutable: false;
}
/**
 * Mutable graph interface.
 *
 * **When to use**
 *
 * Use when adding, removing, or updating nodes and edges inside a graph
 * mutation scope.
 *
 * @see {@link Graph} for the immutable graph interface
 * @see {@link mutate} for scoped mutation of an immutable graph
 * @see {@link beginMutation} for opening a mutable graph manually
 * @see {@link endMutation} for returning to an immutable graph
 *
 * @category models
 * @since 3.18.0
 */
export interface MutableGraph<out N, out E, T extends Kind = "directed"> extends Proto<N, E> {
    readonly type: T;
    readonly mutable: true;
}
/**
 * Immutable graph type for source-to-target relationships.
 *
 * **When to use**
 *
 * Use as the immutable graph type when edge direction is part of the model and
 * traversal or neighbor queries should follow source-to-target edges.
 *
 * **Details**
 *
 * `DirectedGraph<N, E>` is a `Graph<N, E, "directed">` with node data of type
 * `N` and edge data of type `E`.
 *
 * @see {@link directed} for constructing directed graphs
 * @see {@link Graph} for the generic immutable graph type
 * @see {@link UndirectedGraph} for graphs whose edges connect both endpoints
 * @see {@link MutableDirectedGraph} for the mutable directed graph type
 *
 * @category models
 * @since 3.18.0
 */
export type DirectedGraph<N, E> = Graph<N, E, "directed">;
/**
 * Immutable graph type for relationships without source-to-target direction.
 *
 * **When to use**
 *
 * Use when modeling relationships where each edge connects both endpoints
 * without a source-to-target direction.
 *
 * **Details**
 *
 * `UndirectedGraph<N, E>` is a `Graph<N, E, "undirected">`.
 *
 * @see {@link undirected} for constructing undirected graphs
 * @see {@link DirectedGraph} for graphs whose edges have source-to-target direction
 * @see {@link MutableUndirectedGraph} for the mutable undirected graph type
 *
 * @category models
 * @since 3.18.0
 */
export type UndirectedGraph<N, E> = Graph<N, E, "undirected">;
/**
 * Mutable directed graph type alias.
 *
 * **When to use**
 *
 * Use when annotating a temporary graph value that can be changed in place and
 * whose edges have source-to-target direction.
 *
 * @see {@link MutableGraph} for the generic mutable graph type
 * @see {@link DirectedGraph} for the immutable directed graph type
 * @see {@link MutableUndirectedGraph} for mutable graphs without edge direction
 *
 * @category models
 * @since 3.18.0
 */
export type MutableDirectedGraph<N, E> = MutableGraph<N, E, "directed">;
/**
 * Mutable undirected graph type alias.
 *
 * **When to use**
 *
 * Use when annotating a temporary graph value that can be changed in place and
 * whose edges connect both endpoints without direction.
 *
 * @see {@link MutableDirectedGraph} for mutable graphs with directed edges
 * @see {@link UndirectedGraph} for the immutable undirected graph type
 * @see {@link MutableGraph} for the generic mutable graph type
 *
 * @category models
 * @since 3.18.0
 */
export type MutableUndirectedGraph<N, E> = MutableGraph<N, E, "undirected">;
declare const GraphError_base: new <A extends Record<string, any> = {}>(args: import("./Types.ts").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("./Cause.ts").YieldableError & {
    readonly _tag: "GraphError";
} & Readonly<A>;
/**
 * Error thrown by graph operations when the requested graph structure is
 * invalid, such as referencing a missing node or using unsupported edge
 * weights.
 *
 * **When to use**
 *
 * Use when handling failures thrown by graph operations that reject invalid
 * graph structure or unsupported algorithm inputs.
 *
 * @category errors
 * @since 3.18.0
 */
export declare class GraphError extends GraphError_base<{
    readonly message: string;
}> {
}
/**
 * Returns `true` if a value has the graph runtime type identifier, narrowing
 * it to a `Graph`.
 *
 * **When to use**
 *
 * Use to narrow an unknown value before treating it as a graph value.
 *
 * **Gotchas**
 *
 * This guard checks the shared graph runtime type identifier and does not
 * distinguish immutable graphs from mutable graphs.
 *
 * @category guards
 * @since 4.0.0
 */
export declare const isGraph: (u: unknown) => u is Graph<unknown, unknown>;
/**
 * Creates a directed graph, optionally with initial mutations.
 *
 * **Example** (Creating a directed graph)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * // Directed graph with initial nodes and edges
 * const graph = Graph.directed<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, "A->B")
 *   Graph.addEdge(mutable, b, c, "B->C")
 * })
 * ```
 *
 * @category constructors
 * @since 3.18.0
 */
export declare const directed: <N, E>(mutate?: (mutable: MutableDirectedGraph<N, E>) => void) => DirectedGraph<N, E>;
/**
 * Creates an undirected graph, optionally with initial mutations.
 *
 * **Example** (Creating an undirected graph)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * // Undirected graph with initial nodes and edges
 * const graph = Graph.undirected<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, "A-B")
 *   Graph.addEdge(mutable, b, c, "B-C")
 * })
 * ```
 *
 * @category constructors
 * @since 3.18.0
 */
export declare const undirected: <N, E>(mutate?: (mutable: MutableUndirectedGraph<N, E>) => void) => UndirectedGraph<N, E>;
/**
 * Creates a mutable scope for safe graph mutations by copying the data structure.
 *
 * **Example** (Beginning a mutation scope)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>()
 * const mutable = Graph.beginMutation(graph)
 * // Now mutable can be safely modified without affecting original graph
 * ```
 *
 * @category mutations
 * @since 3.18.0
 */
export declare const beginMutation: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T>) => MutableGraph<N, E, T>;
/**
 * Converts a mutable graph back to an immutable graph, ending the mutation scope.
 *
 * **Example** (Ending a mutation scope)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>()
 * const mutable = Graph.beginMutation(graph)
 * // ... perform mutations on mutable ...
 * const newGraph = Graph.endMutation(mutable)
 * ```
 *
 * @category mutations
 * @since 3.18.0
 */
export declare const endMutation: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>) => Graph<N, E, T>;
/**
 * Performs scoped mutations on a graph, automatically managing the mutation lifecycle.
 *
 * **Example** (Applying scoped mutations)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>()
 * const newGraph = Graph.mutate(graph, (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "A")
 *   const nodeB = Graph.addNode(mutable, "B")
 *   Graph.addEdge(mutable, nodeA, nodeB, 1)
 * })
 *
 * console.log(Graph.nodeCount(newGraph)) // 2
 * console.log(Graph.edgeCount(newGraph)) // 1
 * ```
 *
 * @category mutations
 * @since 3.18.0
 */
export declare const mutate: {
    /**
     * Performs scoped mutations on a graph, automatically managing the mutation lifecycle.
     *
     * **Example** (Applying scoped mutations)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>()
     * const newGraph = Graph.mutate(graph, (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "A")
     *   const nodeB = Graph.addNode(mutable, "B")
     *   Graph.addEdge(mutable, nodeA, nodeB, 1)
     * })
     *
     * console.log(Graph.nodeCount(newGraph)) // 2
     * console.log(Graph.edgeCount(newGraph)) // 1
     * ```
     *
     * @category mutations
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(f: (mutable: MutableGraph<N, E, T>) => void): (graph: Graph<N, E, T>) => Graph<N, E, T>;
    /**
     * Performs scoped mutations on a graph, automatically managing the mutation lifecycle.
     *
     * **Example** (Applying scoped mutations)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>()
     * const newGraph = Graph.mutate(graph, (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "A")
     *   const nodeB = Graph.addNode(mutable, "B")
     *   Graph.addEdge(mutable, nodeA, nodeB, 1)
     * })
     *
     * console.log(Graph.nodeCount(newGraph)) // 2
     * console.log(Graph.edgeCount(newGraph)) // 1
     * ```
     *
     * @category mutations
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T>, f: (mutable: MutableGraph<N, E, T>) => void): Graph<N, E, T>;
};
/**
 * Adds a new node to a mutable graph and returns its index.
 *
 * **When to use**
 *
 * Use to allocate a new node in a mutable graph before storing edges or
 * querying it by index.
 *
 * **Details**
 *
 * The returned index is allocated from the graph's next node index. The mutable
 * graph stores the node data and initializes empty incoming and outgoing edge
 * indexes for the new node.
 *
 * **Gotchas**
 *
 * `NodeIndex` values are identifiers and are not reused after removals.
 *
 * **Example** (Adding nodes)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   console.log(nodeA) // NodeIndex with value 0
 *   console.log(nodeB) // NodeIndex with value 1
 * })
 * ```
 *
 * @see {@link mutate} for obtaining a mutable graph from an immutable graph
 * @see {@link addEdge} for connecting existing nodes
 * @see {@link removeNode} for removing nodes from a mutable graph
 *
 * @category mutations
 * @since 3.18.0
 */
export declare const addNode: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, data: N) => NodeIndex;
/**
 * Gets the data associated with a node index safely, if it exists.
 *
 * **Example** (Getting node data)
 *
 * ```ts
 * import { Graph, Option } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   Graph.addNode(mutable, "Node A")
 * })
 *
 * const nodeIndex = 0
 * const nodeData = Graph.getNode(graph, nodeIndex)
 *
 * if (Option.isSome(nodeData)) {
 *   console.log(nodeData.value) // "Node A"
 * }
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const getNode: {
    /**
     * Gets the data associated with a node index safely, if it exists.
     *
     * **Example** (Getting node data)
     *
     * ```ts
     * import { Graph, Option } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   Graph.addNode(mutable, "Node A")
     * })
     *
     * const nodeIndex = 0
     * const nodeData = Graph.getNode(graph, nodeIndex)
     *
     * if (Option.isSome(nodeData)) {
     *   console.log(nodeData.value) // "Node A"
     * }
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(nodeIndex: NodeIndex): (graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Option.Option<N>;
    /**
     * Gets the data associated with a node index safely, if it exists.
     *
     * **Example** (Getting node data)
     *
     * ```ts
     * import { Graph, Option } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   Graph.addNode(mutable, "Node A")
     * })
     *
     * const nodeIndex = 0
     * const nodeData = Graph.getNode(graph, nodeIndex)
     *
     * if (Option.isSome(nodeData)) {
     *   console.log(nodeData.value) // "Node A"
     * }
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, nodeIndex: NodeIndex): Option.Option<N>;
};
/**
 * Checks whether a node with the given index exists in the graph.
 *
 * **Example** (Checking node existence)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   Graph.addNode(mutable, "Node A")
 * })
 *
 * const nodeIndex = 0
 * const exists = Graph.hasNode(graph, nodeIndex)
 * console.log(exists) // true
 *
 * const nonExistentIndex = 999
 * const notExists = Graph.hasNode(graph, nonExistentIndex)
 * console.log(notExists) // false
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const hasNode: {
    /**
     * Checks whether a node with the given index exists in the graph.
     *
     * **Example** (Checking node existence)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   Graph.addNode(mutable, "Node A")
     * })
     *
     * const nodeIndex = 0
     * const exists = Graph.hasNode(graph, nodeIndex)
     * console.log(exists) // true
     *
     * const nonExistentIndex = 999
     * const notExists = Graph.hasNode(graph, nonExistentIndex)
     * console.log(notExists) // false
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    (nodeIndex: NodeIndex): <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => boolean;
    /**
     * Checks whether a node with the given index exists in the graph.
     *
     * **Example** (Checking node existence)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   Graph.addNode(mutable, "Node A")
     * })
     *
     * const nodeIndex = 0
     * const exists = Graph.hasNode(graph, nodeIndex)
     * console.log(exists) // true
     *
     * const nonExistentIndex = 999
     * const notExists = Graph.hasNode(graph, nonExistentIndex)
     * console.log(notExists) // false
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, nodeIndex: NodeIndex): boolean;
};
/**
 * Returns the number of nodes in the graph.
 *
 * **Example** (Counting nodes)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const emptyGraph = Graph.directed<string, number>()
 * console.log(Graph.nodeCount(emptyGraph)) // 0
 *
 * const graphWithNodes = Graph.mutate(emptyGraph, (mutable) => {
 *   Graph.addNode(mutable, "Node A")
 *   Graph.addNode(mutable, "Node B")
 *   Graph.addNode(mutable, "Node C")
 * })
 *
 * console.log(Graph.nodeCount(graphWithNodes)) // 3
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const nodeCount: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => number;
/**
 * Finds the first node that matches the given predicate.
 *
 * **Example** (Finding the first matching node)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   Graph.addNode(mutable, "Node A")
 *   Graph.addNode(mutable, "Node B")
 *   Graph.addNode(mutable, "Node C")
 * })
 *
 * const result = Graph.findNode(graph, (data) => data.startsWith("Node B"))
 * console.log(result) // Option.some(1)
 *
 * const notFound = Graph.findNode(graph, (data) => data === "Node D")
 * console.log(notFound) // Option.none()
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const findNode: {
    /**
     * Finds the first node that matches the given predicate.
     *
     * **Example** (Finding the first matching node)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   Graph.addNode(mutable, "Node A")
     *   Graph.addNode(mutable, "Node B")
     *   Graph.addNode(mutable, "Node C")
     * })
     *
     * const result = Graph.findNode(graph, (data) => data.startsWith("Node B"))
     * console.log(result) // Option.some(1)
     *
     * const notFound = Graph.findNode(graph, (data) => data === "Node D")
     * console.log(notFound) // Option.none()
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N>(predicate: (data: N) => boolean): <E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Option.Option<NodeIndex>;
    /**
     * Finds the first node that matches the given predicate.
     *
     * **Example** (Finding the first matching node)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   Graph.addNode(mutable, "Node A")
     *   Graph.addNode(mutable, "Node B")
     *   Graph.addNode(mutable, "Node C")
     * })
     *
     * const result = Graph.findNode(graph, (data) => data.startsWith("Node B"))
     * console.log(result) // Option.some(1)
     *
     * const notFound = Graph.findNode(graph, (data) => data === "Node D")
     * console.log(notFound) // Option.none()
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, predicate: (data: N) => boolean): Option.Option<NodeIndex>;
};
/**
 * Finds all nodes that match the given predicate.
 *
 * **Example** (Finding matching nodes)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   Graph.addNode(mutable, "Start A")
 *   Graph.addNode(mutable, "Node B")
 *   Graph.addNode(mutable, "Start C")
 * })
 *
 * const result = Graph.findNodes(graph, (data) => data.startsWith("Start"))
 * console.log(result) // [0, 2]
 *
 * const empty = Graph.findNodes(graph, (data) => data === "Not Found")
 * console.log(empty) // []
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const findNodes: {
    /**
     * Finds all nodes that match the given predicate.
     *
     * **Example** (Finding matching nodes)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   Graph.addNode(mutable, "Start A")
     *   Graph.addNode(mutable, "Node B")
     *   Graph.addNode(mutable, "Start C")
     * })
     *
     * const result = Graph.findNodes(graph, (data) => data.startsWith("Start"))
     * console.log(result) // [0, 2]
     *
     * const empty = Graph.findNodes(graph, (data) => data === "Not Found")
     * console.log(empty) // []
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N>(predicate: (data: N) => boolean): <E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Array<NodeIndex>;
    /**
     * Finds all nodes that match the given predicate.
     *
     * **Example** (Finding matching nodes)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   Graph.addNode(mutable, "Start A")
     *   Graph.addNode(mutable, "Node B")
     *   Graph.addNode(mutable, "Start C")
     * })
     *
     * const result = Graph.findNodes(graph, (data) => data.startsWith("Start"))
     * console.log(result) // [0, 2]
     *
     * const empty = Graph.findNodes(graph, (data) => data === "Not Found")
     * console.log(empty) // []
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, predicate: (data: N) => boolean): Array<NodeIndex>;
};
/**
 * Finds the first edge that matches the given predicate.
 *
 * **Example** (Finding the first matching edge)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   const nodeC = Graph.addNode(mutable, "Node C")
 *   Graph.addEdge(mutable, nodeA, nodeB, 10)
 *   Graph.addEdge(mutable, nodeB, nodeC, 20)
 * })
 *
 * const result = Graph.findEdge(graph, (data) => data > 15)
 * console.log(result) // Option.some(1)
 *
 * const notFound = Graph.findEdge(graph, (data) => data > 100)
 * console.log(notFound) // Option.none()
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const findEdge: {
    /**
     * Finds the first edge that matches the given predicate.
     *
     * **Example** (Finding the first matching edge)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 10)
     *   Graph.addEdge(mutable, nodeB, nodeC, 20)
     * })
     *
     * const result = Graph.findEdge(graph, (data) => data > 15)
     * console.log(result) // Option.some(1)
     *
     * const notFound = Graph.findEdge(graph, (data) => data > 100)
     * console.log(notFound) // Option.none()
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <E>(predicate: (data: E, source: NodeIndex, target: NodeIndex) => boolean): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Option.Option<EdgeIndex>;
    /**
     * Finds the first edge that matches the given predicate.
     *
     * **Example** (Finding the first matching edge)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 10)
     *   Graph.addEdge(mutable, nodeB, nodeC, 20)
     * })
     *
     * const result = Graph.findEdge(graph, (data) => data > 15)
     * console.log(result) // Option.some(1)
     *
     * const notFound = Graph.findEdge(graph, (data) => data > 100)
     * console.log(notFound) // Option.none()
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, predicate: (data: E, source: NodeIndex, target: NodeIndex) => boolean): Option.Option<EdgeIndex>;
};
/**
 * Finds all edges that match the given predicate.
 *
 * **Example** (Finding matching edges)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   const nodeC = Graph.addNode(mutable, "Node C")
 *   Graph.addEdge(mutable, nodeA, nodeB, 10)
 *   Graph.addEdge(mutable, nodeB, nodeC, 20)
 *   Graph.addEdge(mutable, nodeC, nodeA, 30)
 * })
 *
 * const result = Graph.findEdges(graph, (data) => data >= 20)
 * console.log(result) // [1, 2]
 *
 * const empty = Graph.findEdges(graph, (data) => data > 100)
 * console.log(empty) // []
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const findEdges: {
    /**
     * Finds all edges that match the given predicate.
     *
     * **Example** (Finding matching edges)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 10)
     *   Graph.addEdge(mutable, nodeB, nodeC, 20)
     *   Graph.addEdge(mutable, nodeC, nodeA, 30)
     * })
     *
     * const result = Graph.findEdges(graph, (data) => data >= 20)
     * console.log(result) // [1, 2]
     *
     * const empty = Graph.findEdges(graph, (data) => data > 100)
     * console.log(empty) // []
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <E>(predicate: (data: E, source: NodeIndex, target: NodeIndex) => boolean): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Array<EdgeIndex>;
    /**
     * Finds all edges that match the given predicate.
     *
     * **Example** (Finding matching edges)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 10)
     *   Graph.addEdge(mutable, nodeB, nodeC, 20)
     *   Graph.addEdge(mutable, nodeC, nodeA, 30)
     * })
     *
     * const result = Graph.findEdges(graph, (data) => data >= 20)
     * console.log(result) // [1, 2]
     *
     * const empty = Graph.findEdges(graph, (data) => data > 100)
     * console.log(empty) // []
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, predicate: (data: E, source: NodeIndex, target: NodeIndex) => boolean): Array<EdgeIndex>;
};
/**
 * Updates a single node's data by applying a transformation function.
 *
 * **Example** (Updating node data)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   Graph.addNode(mutable, "Node A")
 *   Graph.addNode(mutable, "Node B")
 *   Graph.updateNode(mutable, 0, (data) => data.toUpperCase())
 * })
 *
 * const nodeData = Graph.getNode(graph, 0)
 * console.log(nodeData) // Option.some("NODE A")
 * ```
 *
 * @category transforming
 * @since 3.18.0
 */
export declare const updateNode: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, index: NodeIndex, f: (data: N) => N) => void;
/**
 * Updates a single edge's data by applying a transformation function.
 *
 * **Example** (Updating edge data)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   const edgeIndex = Graph.addEdge(mutable, nodeA, nodeB, 10)
 *   Graph.updateEdge(mutable, edgeIndex, (data) => data * 2)
 * })
 *
 * const edgeData = Graph.getEdge(result, 0)
 * console.log(edgeData) // Option.some(new Graph.Edge({ source: 0, target: 1, data: 20 }))
 * ```
 *
 * @category mutations
 * @since 3.18.0
 */
export declare const updateEdge: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, edgeIndex: EdgeIndex, f: (data: E) => E) => void;
/**
 * Transforms every node's data in a mutable graph in place using the provided
 * mapping function.
 *
 * **Details**
 *
 * Node indices and edges are preserved; only the stored node data is replaced.
 *
 * **Example** (Mapping node data)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   Graph.addNode(mutable, "node a")
 *   Graph.addNode(mutable, "node b")
 *   Graph.addNode(mutable, "node c")
 *   Graph.mapNodes(mutable, (data) => data.toUpperCase())
 * })
 *
 * const nodeData = Graph.getNode(graph, 0)
 * console.log(nodeData) // Option.some("NODE A")
 * ```
 *
 * @category transforming
 * @since 3.18.0
 */
export declare const mapNodes: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, f: (data: N) => N) => void;
/**
 * Transforms all edge data in a mutable graph using the provided mapping function.
 *
 * **Example** (Mapping edge data)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 10)
 *   Graph.addEdge(mutable, b, c, 20)
 *   Graph.mapEdges(mutable, (data) => data * 2)
 * })
 *
 * const edgeData = Graph.getEdge(graph, 0)
 * console.log(edgeData) // Option.some(new Graph.Edge({ source: 0, target: 1, data: 20 }))
 * ```
 *
 * @category transforming
 * @since 3.18.0
 */
export declare const mapEdges: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, f: (data: E) => E) => void;
/**
 * Swaps source and target nodes for every edge in a mutable graph.
 *
 * **Example** (Reversing edge directions)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 1) // A -> B
 *   Graph.addEdge(mutable, b, c, 2) // B -> C
 *   Graph.reverse(mutable) // Now B -> A, C -> B
 * })
 *
 * const edge0 = Graph.getEdge(graph, 0)
 * console.log(edge0) // Option.some(new Graph.Edge({ source: 1, target: 0, data: 1 }))
 * ```
 *
 * @category transforming
 * @since 3.18.0
 */
export declare const reverse: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>) => void;
/**
 * Filters and optionally transforms nodes in a mutable graph using a predicate function.
 * Nodes that return Option.none are removed along with all their connected edges.
 *
 * **Example** (Filtering and mapping nodes)
 *
 * ```ts
 * import { Graph, Option } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "active")
 *   const b = Graph.addNode(mutable, "inactive")
 *   const c = Graph.addNode(mutable, "active")
 *   Graph.addEdge(mutable, a, b, 1)
 *   Graph.addEdge(mutable, b, c, 2)
 *
 *   // Keep only "active" nodes and transform to uppercase
 *   Graph.filterMapNodes(
 *     mutable,
 *     (data) =>
 *       data === "active" ? Option.some(data.toUpperCase()) : Option.none()
 *   )
 * })
 *
 * console.log(Graph.nodeCount(graph)) // 2 (only "active" nodes remain)
 * ```
 *
 * @category transforming
 * @since 3.18.0
 */
export declare const filterMapNodes: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, f: (data: N) => Option.Option<N>) => void;
/**
 * Filters and optionally transforms edges in a mutable graph using a predicate function.
 * Edges that return Option.none are removed from the graph.
 *
 * **Example** (Filtering and mapping edges)
 *
 * ```ts
 * import { Graph, Option } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 5)
 *   Graph.addEdge(mutable, b, c, 15)
 *   Graph.addEdge(mutable, c, a, 25)
 *
 *   // Keep only edges with weight >= 10 and double their weight
 *   Graph.filterMapEdges(
 *     mutable,
 *     (data) => data >= 10 ? Option.some(data * 2) : Option.none()
 *   )
 * })
 *
 * console.log(Graph.edgeCount(graph)) // 2 (edges with weight 5 removed)
 * ```
 *
 * @category transforming
 * @since 3.18.0
 */
export declare const filterMapEdges: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, f: (data: E) => Option.Option<E>) => void;
/**
 * Filters nodes by removing those that don't match the predicate.
 * This function modifies the mutable graph in place.
 *
 * **Example** (Filtering nodes)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   Graph.addNode(mutable, "active")
 *   Graph.addNode(mutable, "inactive")
 *   Graph.addNode(mutable, "pending")
 *   Graph.addNode(mutable, "active")
 *
 *   // Keep only "active" nodes
 *   Graph.filterNodes(mutable, (data) => data === "active")
 * })
 *
 * console.log(Graph.nodeCount(graph)) // 2 (only "active" nodes remain)
 * ```
 *
 * @category transforming
 * @since 3.18.0
 */
export declare const filterNodes: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, predicate: (data: N) => boolean) => void;
/**
 * Filters edges by removing those that don't match the predicate.
 * This function modifies the mutable graph in place.
 *
 * **Example** (Filtering edges)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *
 *   Graph.addEdge(mutable, a, b, 5)
 *   Graph.addEdge(mutable, b, c, 15)
 *   Graph.addEdge(mutable, c, a, 25)
 *
 *   // Keep only edges with weight >= 10
 *   Graph.filterEdges(mutable, (data) => data >= 10)
 * })
 *
 * console.log(Graph.edgeCount(graph)) // 2 (edge with weight 5 removed)
 * ```
 *
 * @category transforming
 * @since 3.18.0
 */
export declare const filterEdges: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, predicate: (data: E) => boolean) => void;
/**
 * Adds a new edge to a mutable graph and returns its index.
 *
 * **When to use**
 *
 * Use to connect two existing nodes in a mutable graph while storing edge data
 * and receiving the new edge identifier.
 *
 * **Details**
 *
 * Creates an `Edge` with the source, target, and data at the next edge index,
 * updates adjacency indexes, and increments the graph's next edge index.
 * Undirected graphs register the same edge for both endpoints.
 *
 * **Gotchas**
 *
 * The source and target nodes must already exist in the mutable graph; missing
 * endpoints throw a `GraphError`.
 *
 * **Example** (Adding edges)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   const edge = Graph.addEdge(mutable, nodeA, nodeB, 42)
 *   console.log(edge) // EdgeIndex with value 0
 * })
 * ```
 *
 * @see {@link mutate} for obtaining a mutable graph from an immutable graph
 * @see {@link addNode} for creating node indexes before connecting them
 * @see {@link getEdge} for reading the returned edge
 * @see {@link removeEdge} for removing an edge from a mutable graph
 *
 * @category mutations
 * @since 3.18.0
 */
export declare const addEdge: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, source: NodeIndex, target: NodeIndex, data: E) => EdgeIndex;
/**
 * Removes a node and all its incident edges from a mutable graph.
 *
 * **Example** (Removing a node)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   Graph.addEdge(mutable, nodeA, nodeB, 42)
 *
 *   // Remove nodeA and all edges connected to it
 *   Graph.removeNode(mutable, nodeA)
 * })
 * ```
 *
 * @category mutations
 * @since 3.18.0
 */
export declare const removeNode: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, nodeIndex: NodeIndex) => void;
/**
 * Removes an edge from a mutable graph.
 *
 * **Example** (Removing an edge)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   const edge = Graph.addEdge(mutable, nodeA, nodeB, 42)
 *
 *   // Remove the edge
 *   Graph.removeEdge(mutable, edge)
 * })
 * ```
 *
 * @category mutations
 * @since 3.18.0
 */
export declare const removeEdge: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, edgeIndex: EdgeIndex) => void;
/**
 * Gets the edge data associated with an edge index safely, if it exists.
 *
 * **Example** (Getting edge data)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   Graph.addEdge(mutable, nodeA, nodeB, 42)
 * })
 *
 * const edgeIndex = 0
 * const edgeData = Graph.getEdge(graph, edgeIndex)
 *
 * if (edgeData._tag === "Some") {
 *   console.log(edgeData.value.data) // 42
 *   console.log(edgeData.value.source) // 0
 *   console.log(edgeData.value.target) // 1
 * }
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const getEdge: {
    /**
     * Gets the edge data associated with an edge index safely, if it exists.
     *
     * **Example** (Getting edge data)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   Graph.addEdge(mutable, nodeA, nodeB, 42)
     * })
     *
     * const edgeIndex = 0
     * const edgeData = Graph.getEdge(graph, edgeIndex)
     *
     * if (edgeData._tag === "Some") {
     *   console.log(edgeData.value.data) // 42
     *   console.log(edgeData.value.source) // 0
     *   console.log(edgeData.value.target) // 1
     * }
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <E>(edgeIndex: EdgeIndex): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Option.Option<Edge<E>>;
    /**
     * Gets the edge data associated with an edge index safely, if it exists.
     *
     * **Example** (Getting edge data)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   Graph.addEdge(mutable, nodeA, nodeB, 42)
     * })
     *
     * const edgeIndex = 0
     * const edgeData = Graph.getEdge(graph, edgeIndex)
     *
     * if (edgeData._tag === "Some") {
     *   console.log(edgeData.value.data) // 42
     *   console.log(edgeData.value.source) // 0
     *   console.log(edgeData.value.target) // 1
     * }
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, edgeIndex: EdgeIndex): Option.Option<Edge<E>>;
};
/**
 * Checks whether an edge exists between two nodes in the graph.
 *
 * **Example** (Checking edge existence)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   const nodeC = Graph.addNode(mutable, "Node C")
 *   Graph.addEdge(mutable, nodeA, nodeB, 42)
 * })
 *
 * const nodeA = 0
 * const nodeB = 1
 * const nodeC = 2
 *
 * const hasAB = Graph.hasEdge(graph, nodeA, nodeB)
 * console.log(hasAB) // true
 *
 * const hasAC = Graph.hasEdge(graph, nodeA, nodeC)
 * console.log(hasAC) // false
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const hasEdge: {
    /**
     * Checks whether an edge exists between two nodes in the graph.
     *
     * **Example** (Checking edge existence)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 42)
     * })
     *
     * const nodeA = 0
     * const nodeB = 1
     * const nodeC = 2
     *
     * const hasAB = Graph.hasEdge(graph, nodeA, nodeB)
     * console.log(hasAB) // true
     *
     * const hasAC = Graph.hasEdge(graph, nodeA, nodeC)
     * console.log(hasAC) // false
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    (source: NodeIndex, target: NodeIndex): <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => boolean;
    /**
     * Checks whether an edge exists between two nodes in the graph.
     *
     * **Example** (Checking edge existence)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 42)
     * })
     *
     * const nodeA = 0
     * const nodeB = 1
     * const nodeC = 2
     *
     * const hasAB = Graph.hasEdge(graph, nodeA, nodeB)
     * console.log(hasAB) // true
     *
     * const hasAC = Graph.hasEdge(graph, nodeA, nodeC)
     * console.log(hasAC) // false
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, source: NodeIndex, target: NodeIndex): boolean;
};
/**
 * Returns the number of edges in the graph.
 *
 * **Example** (Counting edges)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const emptyGraph = Graph.directed<string, number>()
 * console.log(Graph.edgeCount(emptyGraph)) // 0
 *
 * const graphWithEdges = Graph.mutate(emptyGraph, (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   const nodeC = Graph.addNode(mutable, "Node C")
 *   Graph.addEdge(mutable, nodeA, nodeB, 1)
 *   Graph.addEdge(mutable, nodeB, nodeC, 2)
 *   Graph.addEdge(mutable, nodeC, nodeA, 3)
 * })
 *
 * console.log(Graph.edgeCount(graphWithEdges)) // 3
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const edgeCount: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => number;
/**
 * Returns the neighboring node indices for a node.
 *
 * **Details**
 *
 * For directed graphs, neighbors are the targets of outgoing edges. For
 * undirected graphs, neighbors are the other endpoints of incident edges.
 *
 * **Example** (Getting outgoing neighbors)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   const nodeC = Graph.addNode(mutable, "Node C")
 *   Graph.addEdge(mutable, nodeA, nodeB, 1)
 *   Graph.addEdge(mutable, nodeA, nodeC, 2)
 * })
 *
 * const nodeA = 0
 * const nodeB = 1
 * const nodeC = 2
 *
 * const neighborsA = Graph.neighbors(graph, nodeA)
 * console.log(neighborsA) // [1, 2]
 *
 * const neighborsB = Graph.neighbors(graph, nodeB)
 * console.log(neighborsB) // []
 * ```
 *
 * @category getters
 * @since 3.18.0
 */
export declare const neighbors: {
    /**
     * Returns the neighboring node indices for a node.
     *
     * **Details**
     *
     * For directed graphs, neighbors are the targets of outgoing edges. For
     * undirected graphs, neighbors are the other endpoints of incident edges.
     *
     * **Example** (Getting outgoing neighbors)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 1)
     *   Graph.addEdge(mutable, nodeA, nodeC, 2)
     * })
     *
     * const nodeA = 0
     * const nodeB = 1
     * const nodeC = 2
     *
     * const neighborsA = Graph.neighbors(graph, nodeA)
     * console.log(neighborsA) // [1, 2]
     *
     * const neighborsB = Graph.neighbors(graph, nodeB)
     * console.log(neighborsB) // []
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    (nodeIndex: NodeIndex): <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Array<NodeIndex>;
    /**
     * Returns the neighboring node indices for a node.
     *
     * **Details**
     *
     * For directed graphs, neighbors are the targets of outgoing edges. For
     * undirected graphs, neighbors are the other endpoints of incident edges.
     *
     * **Example** (Getting outgoing neighbors)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 1)
     *   Graph.addEdge(mutable, nodeA, nodeC, 2)
     * })
     *
     * const nodeA = 0
     * const nodeB = 1
     * const nodeC = 2
     *
     * const neighborsA = Graph.neighbors(graph, nodeA)
     * console.log(neighborsA) // [1, 2]
     *
     * const neighborsB = Graph.neighbors(graph, nodeB)
     * console.log(neighborsB) // []
     * ```
     *
     * @category getters
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, nodeIndex: NodeIndex): Array<NodeIndex>;
};
/**
 * Gets neighbors of a node in a specific direction for bidirectional traversal.
 *
 * **Example** (Traversing directed neighbors)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   Graph.addEdge(mutable, a, b, "A->B")
 * })
 *
 * const nodeA = 0
 * const nodeB = 1
 *
 * // Get outgoing neighbors (nodes that nodeA points to)
 * const outgoing = Graph.neighborsDirected(graph, nodeA, "outgoing")
 *
 * // Get incoming neighbors (nodes that point to nodeB)
 * const incoming = Graph.neighborsDirected(graph, nodeB, "incoming")
 * ```
 *
 * @category queries
 * @since 3.18.0
 */
export declare const neighborsDirected: {
    /**
     * Gets neighbors of a node in a specific direction for bidirectional traversal.
     *
     * **Example** (Traversing directed neighbors)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, string>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   Graph.addEdge(mutable, a, b, "A->B")
     * })
     *
     * const nodeA = 0
     * const nodeB = 1
     *
     * // Get outgoing neighbors (nodes that nodeA points to)
     * const outgoing = Graph.neighborsDirected(graph, nodeA, "outgoing")
     *
     * // Get incoming neighbors (nodes that point to nodeB)
     * const incoming = Graph.neighborsDirected(graph, nodeB, "incoming")
     * ```
     *
     * @category queries
     * @since 3.18.0
     */
    (nodeIndex: NodeIndex, direction: Direction): <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Array<NodeIndex>;
    /**
     * Gets neighbors of a node in a specific direction for bidirectional traversal.
     *
     * **Example** (Traversing directed neighbors)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, string>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   Graph.addEdge(mutable, a, b, "A->B")
     * })
     *
     * const nodeA = 0
     * const nodeB = 1
     *
     * // Get outgoing neighbors (nodes that nodeA points to)
     * const outgoing = Graph.neighborsDirected(graph, nodeA, "outgoing")
     *
     * // Get incoming neighbors (nodes that point to nodeB)
     * const incoming = Graph.neighborsDirected(graph, nodeB, "incoming")
     * ```
     *
     * @category queries
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, nodeIndex: NodeIndex, direction: Direction): Array<NodeIndex>;
};
/**
 * Configuration options for GraphViz DOT format generation from graphs.
 *
 * **Details**
 *
 * These options customize node labels, edge labels, and graph naming in DOT
 * format compatible with GraphViz tools.
 *
 * **Example** (Configuring GraphViz labels)
 *
 * ```ts
 * import type { Graph } from "effect"
 *
 * // Basic options with custom labels
 * const basicOptions: Graph.GraphVizOptions<string, number> = {
 *   nodeLabel: (data) => `Node: ${data}`,
 *   edgeLabel: (data) => `Weight: ${data}`
 * }
 *
 * // Complete options with graph naming
 * const namedOptions: Graph.GraphVizOptions<string, string> = {
 *   nodeLabel: (data) => data.toUpperCase(),
 *   edgeLabel: (data) => data,
 *   graphName: "MyDependencyGraph"
 * }
 * ```
 *
 * @category options
 * @since 3.18.0
 */
export interface GraphVizOptions<N, E> {
    /**
     * Function to generate custom labels for nodes.
     * Defaults to String(data) if not provided.
     */
    readonly nodeLabel?: (data: N) => string;
    /**
     * Function to generate custom labels for edges.
     * Defaults to String(data) if not provided.
     */
    readonly edgeLabel?: (data: E) => string;
    /**
     * Name for the DOT graph.
     * Defaults to "G" if not provided.
     */
    readonly graphName?: string;
}
/**
 * Exports a graph to GraphViz DOT format for visualization.
 *
 * **Example** (Exporting GraphViz DOT)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
 *   const nodeA = Graph.addNode(mutable, "Node A")
 *   const nodeB = Graph.addNode(mutable, "Node B")
 *   const nodeC = Graph.addNode(mutable, "Node C")
 *   Graph.addEdge(mutable, nodeA, nodeB, 1)
 *   Graph.addEdge(mutable, nodeB, nodeC, 2)
 *   Graph.addEdge(mutable, nodeC, nodeA, 3)
 * })
 *
 * const dot = Graph.toGraphViz(graph)
 * console.log(dot)
 * // digraph G {
 * //   "0" [label="Node A"];
 * //   "1" [label="Node B"];
 * //   "2" [label="Node C"];
 * //   "0" -> "1" [label="1"];
 * //   "1" -> "2" [label="2"];
 * //   "2" -> "0" [label="3"];
 * // }
 * ```
 *
 * @category converting
 * @since 3.18.0
 */
export declare const toGraphViz: {
    /**
     * Exports a graph to GraphViz DOT format for visualization.
     *
     * **Example** (Exporting GraphViz DOT)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 1)
     *   Graph.addEdge(mutable, nodeB, nodeC, 2)
     *   Graph.addEdge(mutable, nodeC, nodeA, 3)
     * })
     *
     * const dot = Graph.toGraphViz(graph)
     * console.log(dot)
     * // digraph G {
     * //   "0" [label="Node A"];
     * //   "1" [label="Node B"];
     * //   "2" [label="Node C"];
     * //   "0" -> "1" [label="1"];
     * //   "1" -> "2" [label="2"];
     * //   "2" -> "0" [label="3"];
     * // }
     * ```
     *
     * @category converting
     * @since 3.18.0
     */
    <N, E>(options?: GraphVizOptions<N, E>): <T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => string;
    /**
     * Exports a graph to GraphViz DOT format for visualization.
     *
     * **Example** (Exporting GraphViz DOT)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
     *   const nodeA = Graph.addNode(mutable, "Node A")
     *   const nodeB = Graph.addNode(mutable, "Node B")
     *   const nodeC = Graph.addNode(mutable, "Node C")
     *   Graph.addEdge(mutable, nodeA, nodeB, 1)
     *   Graph.addEdge(mutable, nodeB, nodeC, 2)
     *   Graph.addEdge(mutable, nodeC, nodeA, 3)
     * })
     *
     * const dot = Graph.toGraphViz(graph)
     * console.log(dot)
     * // digraph G {
     * //   "0" [label="Node A"];
     * //   "1" [label="Node B"];
     * //   "2" [label="Node C"];
     * //   "0" -> "1" [label="1"];
     * //   "1" -> "2" [label="2"];
     * //   "2" -> "0" [label="3"];
     * // }
     * ```
     *
     * @category converting
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, options?: GraphVizOptions<N, E>): string;
};
/**
 * Mermaid node shape types for diagram visualization.
 *
 * **Details**
 *
 * Each shape produces different visual representations in Mermaid diagrams:
 * - `rectangle`: Standard rectangular nodes `A["label"]`
 * - `rounded`: Rounded rectangular nodes `A("label")`
 * - `circle`: Circular nodes `A(("label"))`
 * - `diamond`: Diamond-shaped nodes `A{"label"}`
 * - `hexagon`: Hexagonal nodes `A{{"label"}}`
 * - `stadium`: Stadium-shaped nodes `A(["label"])`
 * - `subroutine`: Subroutine-style nodes `A[["label"]]`
 * - `cylindrical`: Cylindrical database-style nodes `A[("label")]`
 *
 * **Example** (Selecting Mermaid node shapes)
 *
 * ```ts
 * import type { Graph } from "effect"
 *
 * // Shape selector function for different node types
 * const shapeSelector = (nodeData: string): Graph.MermaidNodeShape => {
 *   if (nodeData.includes("start") || nodeData.includes("end")) return "circle"
 *   if (nodeData.includes("decision")) return "diamond"
 *   if (nodeData.includes("process")) return "rectangle"
 *   if (nodeData.includes("data")) return "cylindrical"
 *   return "rounded"
 * }
 *
 * const options: Graph.MermaidOptions<string, string> = {
 *   nodeShape: shapeSelector
 * }
 * ```
 *
 * @category models
 * @since 3.18.0
 */
export type MermaidNodeShape = "rectangle" | "rounded" | "circle" | "diamond" | "hexagon" | "stadium" | "subroutine" | "cylindrical";
/**
 * Mermaid diagram direction types for controlling layout orientation.
 *
 * **Details**
 *
 * Determines the flow direction of nodes and edges in the diagram:
 * - `TB`/`TD`: Top to Bottom (vertical layout, default)
 * - `BT`: Bottom to Top (reverse vertical)
 * - `LR`: Left to Right (horizontal layout)
 * - `RL`: Right to Left (reverse horizontal)
 *
 * **Example** (Configuring Mermaid directions)
 *
 * ```ts
 * import type { Graph } from "effect"
 *
 * // Horizontal workflow diagram
 * const horizontalOptions: Graph.MermaidOptions<string, string> = {
 *   direction: "LR"
 * }
 *
 * // Vertical hierarchy (default)
 * const verticalOptions: Graph.MermaidOptions<string, string> = {
 *   direction: "TB"
 * }
 *
 * // Bottom-up flow
 * const bottomUpOptions: Graph.MermaidOptions<string, string> = {
 *   direction: "BT"
 * }
 * ```
 *
 * @category models
 * @since 3.18.0
 */
export type MermaidDirection = "TB" | "TD" | "BT" | "RL" | "LR";
/**
 * Mermaid diagram types for different visualization formats.
 *
 * **Details**
 *
 * Specifies the Mermaid diagram syntax to use:
 * - `flowchart`: For directed graphs with arrows (`A --> B`)
 * - `graph`: For undirected graphs with lines (`A --- B`)
 *
 * When not specified, automatically selects based on graph type:
 * directed graphs use "flowchart", undirected graphs use "graph".
 *
 * **Example** (Selecting Mermaid diagram types)
 *
 * ```ts
 * import type { Graph } from "effect"
 *
 * // Force flowchart format (even for undirected graphs)
 * const flowchartOptions: Graph.MermaidOptions<string, string> = {
 *   diagramType: "flowchart"
 * }
 *
 * // Force graph format (shows undirected connections)
 * const graphOptions: Graph.MermaidOptions<string, string> = {
 *   diagramType: "graph"
 * }
 *
 * // Auto-detection (recommended, default behavior)
 * const autoOptions: Graph.MermaidOptions<string, string> = {}
 * ```
 *
 * @category models
 * @since 3.18.0
 */
export type MermaidDiagramType = "flowchart" | "graph";
/**
 * Configuration options for Mermaid diagram generation, following GraphViz pattern.
 *
 * @category models
 * @since 4.0.0
 */
/**
 * Configuration options for Mermaid diagram generation from graphs.
 *
 * **Details**
 *
 * These options customize node labels, edge labels, diagram type, layout
 * direction, node shapes, and graph naming in Mermaid format.
 *
 * **Example** (Configuring Mermaid output)
 *
 * ```ts
 * import type { Graph } from "effect"
 *
 * // Basic options with custom labels
 * const basicOptions: Graph.MermaidOptions<string, number> = {
 *   nodeLabel: (data) => `Node: ${data}`,
 *   edgeLabel: (data) => `Weight: ${data}`
 * }
 *
 * // Advanced options with all features
 * const advancedOptions: Graph.MermaidOptions<string, string> = {
 *   nodeLabel: (data) => data.toUpperCase(),
 *   edgeLabel: (data) => data,
 *   diagramType: "flowchart",
 *   direction: "LR",
 *   nodeShape: (data) => data.includes("start") ? "circle" : "rectangle"
 * }
 * ```
 *
 * @category options
 * @since 3.18.0
 */
export interface MermaidOptions<N, E> {
    /**
     * Function to generate custom labels for nodes.
     * Defaults to String(data) if not provided.
     */
    readonly nodeLabel?: (data: N) => string;
    /**
     * Function to generate custom labels for edges.
     * Defaults to String(data) if not provided.
     */
    readonly edgeLabel?: (data: E) => string;
    /**
     * Diagram type override. If not specified, automatically detects:
     * - "flowchart" for directed graphs
     * - "graph" for undirected graphs
     */
    readonly diagramType?: MermaidDiagramType;
    /**
     * Direction for diagram layout.
     * Defaults to "TD" (Top Down) if not provided.
     */
    readonly direction?: MermaidDirection;
    /**
     * Function to determine node shape for each node.
     * Defaults to "rectangle" for all nodes if not provided.
     */
    readonly nodeShape?: (data: N) => MermaidNodeShape;
}
/**
 * Exports a graph to Mermaid diagram format for visualization.
 *
 * **Details**
 *
 * Mermaid is a popular diagram-as-code tool that generates flowcharts and other
 * visualizations from text-based definitions. This function converts Effect Graph
 * structures to valid Mermaid syntax for use in documentation, web applications,
 * and visualization tools.
 *
 * **Example** (Exporting a directed Mermaid diagram)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * // Basic directed graph export
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const app = Graph.addNode(mutable, "App")
 *   const db = Graph.addNode(mutable, "Database")
 *   const cache = Graph.addNode(mutable, "Cache")
 *   Graph.addEdge(mutable, app, db, 1)
 *   Graph.addEdge(mutable, app, cache, 2)
 * })
 *
 * const mermaid = Graph.toMermaid(graph)
 * console.log(mermaid)
 * // flowchart TD
 * //   0["App"]
 * //   1["Database"]
 * //   2["Cache"]
 * //   0 -->|"1"| 1
 * //   0 -->|"2"| 2
 * ```
 *
 * **Example** (Exporting an undirected Mermaid diagram)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * // Undirected graph with custom labels and direction
 * const socialGraph = Graph.undirected<{ name: string }, string>((mutable) => {
 *   const alice = Graph.addNode(mutable, { name: "Alice" })
 *   const bob = Graph.addNode(mutable, { name: "Bob" })
 *   const charlie = Graph.addNode(mutable, { name: "Charlie" })
 *   Graph.addEdge(mutable, alice, bob, "friends")
 *   Graph.addEdge(mutable, bob, charlie, "colleagues")
 * })
 *
 * const mermaid = Graph.toMermaid(socialGraph, {
 *   nodeLabel: (person) => person.name,
 *   edgeLabel: (relationship) => relationship,
 *   direction: "LR"
 * })
 * console.log(mermaid)
 * // graph LR
 * //   0["Alice"]
 * //   1["Bob"]
 * //   2["Charlie"]
 * //   0 ---|"friends"| 1
 * //   1 ---|"colleagues"| 2
 * ```
 *
 * **Example** (Customizing Mermaid node shapes)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * // Advanced styling with node shapes for flowchart
 * const workflow = Graph.directed<{ type: string; name: string }, string>(
 *   (mutable) => {
 *     const start = Graph.addNode(mutable, { type: "start", name: "Begin" })
 *     const process = Graph.addNode(mutable, {
 *       type: "process",
 *       name: "Process Data"
 *     })
 *     const decision = Graph.addNode(mutable, {
 *       type: "decision",
 *       name: "Valid?"
 *     })
 *     const end = Graph.addNode(mutable, { type: "end", name: "Complete" })
 *     Graph.addEdge(mutable, start, process, "")
 *     Graph.addEdge(mutable, process, decision, "")
 *     Graph.addEdge(mutable, decision, end, "yes")
 *   }
 * )
 *
 * const mermaid = Graph.toMermaid(workflow, {
 *   nodeLabel: (node) => node.name,
 *   nodeShape: (node) => {
 *     switch (node.type) {
 *       case "start":
 *         return "stadium"
 *       case "process":
 *         return "rectangle"
 *       case "decision":
 *         return "diamond"
 *       case "end":
 *         return "stadium"
 *       default:
 *         return "rectangle"
 *     }
 *   }
 * })
 * console.log(mermaid)
 * // flowchart TD
 * //   0(["Begin"])
 * //   1["Process Data"]
 * //   2{"Valid?"}
 * //   3(["Complete"])
 * //   0 --> 1
 * //   1 --> 2
 * //   2 --> 3
 * ```
 *
 * **Example** (Visualizing dependency graphs)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * // Real-world example: Software dependency graph
 * interface Dependency {
 *   name: string
 *   version: string
 *   type: "library" | "framework" | "tool"
 * }
 *
 * const dependencyGraph = Graph.directed<Dependency, string>((mutable) => {
 *   const app = Graph.addNode(mutable, {
 *     name: "MyApp",
 *     version: "1.0.0",
 *     type: "library"
 *   })
 *   const react = Graph.addNode(mutable, {
 *     name: "React",
 *     version: "18.0.0",
 *     type: "framework"
 *   })
 *   const lodash = Graph.addNode(mutable, {
 *     name: "Lodash",
 *     version: "4.17.0",
 *     type: "library"
 *   })
 *   const webpack = Graph.addNode(mutable, {
 *     name: "Webpack",
 *     version: "5.0.0",
 *     type: "tool"
 *   })
 *
 *   Graph.addEdge(mutable, app, react, "depends on")
 *   Graph.addEdge(mutable, app, lodash, "depends on")
 *   Graph.addEdge(mutable, app, webpack, "builds with")
 * })
 *
 * const dependencyDiagram = Graph.toMermaid(dependencyGraph, {
 *   nodeLabel: (dep) => `${dep.name}\\nv${dep.version}`,
 *   edgeLabel: (edge) => edge,
 *   nodeShape: (dep) =>
 *     dep.type === "framework" ?
 *       "hexagon" :
 *       dep.type === "tool"
 *       ? "diamond"
 *       : "rectangle",
 *   direction: "TB"
 * })
 *
 * console.log(dependencyDiagram)
 * // flowchart TB
 * //   0["MyApp\nv1.0.0"]
 * //   1{{"React\nv18.0.0"}}
 * //   2["Lodash\nv4.17.0"]
 * //   3{"Webpack\nv5.0.0"}
 * //   0 -->|"depends on"| 1
 * //   0 -->|"depends on"| 2
 * //   0 -->|"builds with"| 3
 * ```
 *
 * @category converting
 * @since 3.18.0
 */
export declare const toMermaid: {
    /**
     * Exports a graph to Mermaid diagram format for visualization.
     *
     * **Details**
     *
     * Mermaid is a popular diagram-as-code tool that generates flowcharts and other
     * visualizations from text-based definitions. This function converts Effect Graph
     * structures to valid Mermaid syntax for use in documentation, web applications,
     * and visualization tools.
     *
     * **Example** (Exporting a directed Mermaid diagram)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * // Basic directed graph export
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const app = Graph.addNode(mutable, "App")
     *   const db = Graph.addNode(mutable, "Database")
     *   const cache = Graph.addNode(mutable, "Cache")
     *   Graph.addEdge(mutable, app, db, 1)
     *   Graph.addEdge(mutable, app, cache, 2)
     * })
     *
     * const mermaid = Graph.toMermaid(graph)
     * console.log(mermaid)
     * // flowchart TD
     * //   0["App"]
     * //   1["Database"]
     * //   2["Cache"]
     * //   0 -->|"1"| 1
     * //   0 -->|"2"| 2
     * ```
     *
     * **Example** (Exporting an undirected Mermaid diagram)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * // Undirected graph with custom labels and direction
     * const socialGraph = Graph.undirected<{ name: string }, string>((mutable) => {
     *   const alice = Graph.addNode(mutable, { name: "Alice" })
     *   const bob = Graph.addNode(mutable, { name: "Bob" })
     *   const charlie = Graph.addNode(mutable, { name: "Charlie" })
     *   Graph.addEdge(mutable, alice, bob, "friends")
     *   Graph.addEdge(mutable, bob, charlie, "colleagues")
     * })
     *
     * const mermaid = Graph.toMermaid(socialGraph, {
     *   nodeLabel: (person) => person.name,
     *   edgeLabel: (relationship) => relationship,
     *   direction: "LR"
     * })
     * console.log(mermaid)
     * // graph LR
     * //   0["Alice"]
     * //   1["Bob"]
     * //   2["Charlie"]
     * //   0 ---|"friends"| 1
     * //   1 ---|"colleagues"| 2
     * ```
     *
     * **Example** (Customizing Mermaid node shapes)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * // Advanced styling with node shapes for flowchart
     * const workflow = Graph.directed<{ type: string; name: string }, string>(
     *   (mutable) => {
     *     const start = Graph.addNode(mutable, { type: "start", name: "Begin" })
     *     const process = Graph.addNode(mutable, {
     *       type: "process",
     *       name: "Process Data"
     *     })
     *     const decision = Graph.addNode(mutable, {
     *       type: "decision",
     *       name: "Valid?"
     *     })
     *     const end = Graph.addNode(mutable, { type: "end", name: "Complete" })
     *     Graph.addEdge(mutable, start, process, "")
     *     Graph.addEdge(mutable, process, decision, "")
     *     Graph.addEdge(mutable, decision, end, "yes")
     *   }
     * )
     *
     * const mermaid = Graph.toMermaid(workflow, {
     *   nodeLabel: (node) => node.name,
     *   nodeShape: (node) => {
     *     switch (node.type) {
     *       case "start":
     *         return "stadium"
     *       case "process":
     *         return "rectangle"
     *       case "decision":
     *         return "diamond"
     *       case "end":
     *         return "stadium"
     *       default:
     *         return "rectangle"
     *     }
     *   }
     * })
     * console.log(mermaid)
     * // flowchart TD
     * //   0(["Begin"])
     * //   1["Process Data"]
     * //   2{"Valid?"}
     * //   3(["Complete"])
     * //   0 --> 1
     * //   1 --> 2
     * //   2 --> 3
     * ```
     *
     * **Example** (Visualizing dependency graphs)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * // Real-world example: Software dependency graph
     * interface Dependency {
     *   name: string
     *   version: string
     *   type: "library" | "framework" | "tool"
     * }
     *
     * const dependencyGraph = Graph.directed<Dependency, string>((mutable) => {
     *   const app = Graph.addNode(mutable, {
     *     name: "MyApp",
     *     version: "1.0.0",
     *     type: "library"
     *   })
     *   const react = Graph.addNode(mutable, {
     *     name: "React",
     *     version: "18.0.0",
     *     type: "framework"
     *   })
     *   const lodash = Graph.addNode(mutable, {
     *     name: "Lodash",
     *     version: "4.17.0",
     *     type: "library"
     *   })
     *   const webpack = Graph.addNode(mutable, {
     *     name: "Webpack",
     *     version: "5.0.0",
     *     type: "tool"
     *   })
     *
     *   Graph.addEdge(mutable, app, react, "depends on")
     *   Graph.addEdge(mutable, app, lodash, "depends on")
     *   Graph.addEdge(mutable, app, webpack, "builds with")
     * })
     *
     * const dependencyDiagram = Graph.toMermaid(dependencyGraph, {
     *   nodeLabel: (dep) => `${dep.name}\\nv${dep.version}`,
     *   edgeLabel: (edge) => edge,
     *   nodeShape: (dep) =>
     *     dep.type === "framework" ?
     *       "hexagon" :
     *       dep.type === "tool"
     *       ? "diamond"
     *       : "rectangle",
     *   direction: "TB"
     * })
     *
     * console.log(dependencyDiagram)
     * // flowchart TB
     * //   0["MyApp\nv1.0.0"]
     * //   1{{"React\nv18.0.0"}}
     * //   2["Lodash\nv4.17.0"]
     * //   3{"Webpack\nv5.0.0"}
     * //   0 -->|"depends on"| 1
     * //   0 -->|"depends on"| 2
     * //   0 -->|"builds with"| 3
     * ```
     *
     * @category converting
     * @since 3.18.0
     */
    <N, E>(options?: MermaidOptions<N, E>): <T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => string;
    /**
     * Exports a graph to Mermaid diagram format for visualization.
     *
     * **Details**
     *
     * Mermaid is a popular diagram-as-code tool that generates flowcharts and other
     * visualizations from text-based definitions. This function converts Effect Graph
     * structures to valid Mermaid syntax for use in documentation, web applications,
     * and visualization tools.
     *
     * **Example** (Exporting a directed Mermaid diagram)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * // Basic directed graph export
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const app = Graph.addNode(mutable, "App")
     *   const db = Graph.addNode(mutable, "Database")
     *   const cache = Graph.addNode(mutable, "Cache")
     *   Graph.addEdge(mutable, app, db, 1)
     *   Graph.addEdge(mutable, app, cache, 2)
     * })
     *
     * const mermaid = Graph.toMermaid(graph)
     * console.log(mermaid)
     * // flowchart TD
     * //   0["App"]
     * //   1["Database"]
     * //   2["Cache"]
     * //   0 -->|"1"| 1
     * //   0 -->|"2"| 2
     * ```
     *
     * **Example** (Exporting an undirected Mermaid diagram)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * // Undirected graph with custom labels and direction
     * const socialGraph = Graph.undirected<{ name: string }, string>((mutable) => {
     *   const alice = Graph.addNode(mutable, { name: "Alice" })
     *   const bob = Graph.addNode(mutable, { name: "Bob" })
     *   const charlie = Graph.addNode(mutable, { name: "Charlie" })
     *   Graph.addEdge(mutable, alice, bob, "friends")
     *   Graph.addEdge(mutable, bob, charlie, "colleagues")
     * })
     *
     * const mermaid = Graph.toMermaid(socialGraph, {
     *   nodeLabel: (person) => person.name,
     *   edgeLabel: (relationship) => relationship,
     *   direction: "LR"
     * })
     * console.log(mermaid)
     * // graph LR
     * //   0["Alice"]
     * //   1["Bob"]
     * //   2["Charlie"]
     * //   0 ---|"friends"| 1
     * //   1 ---|"colleagues"| 2
     * ```
     *
     * **Example** (Customizing Mermaid node shapes)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * // Advanced styling with node shapes for flowchart
     * const workflow = Graph.directed<{ type: string; name: string }, string>(
     *   (mutable) => {
     *     const start = Graph.addNode(mutable, { type: "start", name: "Begin" })
     *     const process = Graph.addNode(mutable, {
     *       type: "process",
     *       name: "Process Data"
     *     })
     *     const decision = Graph.addNode(mutable, {
     *       type: "decision",
     *       name: "Valid?"
     *     })
     *     const end = Graph.addNode(mutable, { type: "end", name: "Complete" })
     *     Graph.addEdge(mutable, start, process, "")
     *     Graph.addEdge(mutable, process, decision, "")
     *     Graph.addEdge(mutable, decision, end, "yes")
     *   }
     * )
     *
     * const mermaid = Graph.toMermaid(workflow, {
     *   nodeLabel: (node) => node.name,
     *   nodeShape: (node) => {
     *     switch (node.type) {
     *       case "start":
     *         return "stadium"
     *       case "process":
     *         return "rectangle"
     *       case "decision":
     *         return "diamond"
     *       case "end":
     *         return "stadium"
     *       default:
     *         return "rectangle"
     *     }
     *   }
     * })
     * console.log(mermaid)
     * // flowchart TD
     * //   0(["Begin"])
     * //   1["Process Data"]
     * //   2{"Valid?"}
     * //   3(["Complete"])
     * //   0 --> 1
     * //   1 --> 2
     * //   2 --> 3
     * ```
     *
     * **Example** (Visualizing dependency graphs)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * // Real-world example: Software dependency graph
     * interface Dependency {
     *   name: string
     *   version: string
     *   type: "library" | "framework" | "tool"
     * }
     *
     * const dependencyGraph = Graph.directed<Dependency, string>((mutable) => {
     *   const app = Graph.addNode(mutable, {
     *     name: "MyApp",
     *     version: "1.0.0",
     *     type: "library"
     *   })
     *   const react = Graph.addNode(mutable, {
     *     name: "React",
     *     version: "18.0.0",
     *     type: "framework"
     *   })
     *   const lodash = Graph.addNode(mutable, {
     *     name: "Lodash",
     *     version: "4.17.0",
     *     type: "library"
     *   })
     *   const webpack = Graph.addNode(mutable, {
     *     name: "Webpack",
     *     version: "5.0.0",
     *     type: "tool"
     *   })
     *
     *   Graph.addEdge(mutable, app, react, "depends on")
     *   Graph.addEdge(mutable, app, lodash, "depends on")
     *   Graph.addEdge(mutable, app, webpack, "builds with")
     * })
     *
     * const dependencyDiagram = Graph.toMermaid(dependencyGraph, {
     *   nodeLabel: (dep) => `${dep.name}\\nv${dep.version}`,
     *   edgeLabel: (edge) => edge,
     *   nodeShape: (dep) =>
     *     dep.type === "framework" ?
     *       "hexagon" :
     *       dep.type === "tool"
     *       ? "diamond"
     *       : "rectangle",
     *   direction: "TB"
     * })
     *
     * console.log(dependencyDiagram)
     * // flowchart TB
     * //   0["MyApp\nv1.0.0"]
     * //   1{{"React\nv18.0.0"}}
     * //   2["Lodash\nv4.17.0"]
     * //   3{"Webpack\nv5.0.0"}
     * //   0 -->|"depends on"| 1
     * //   0 -->|"depends on"| 2
     * //   0 -->|"builds with"| 3
     * ```
     *
     * @category converting
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, options?: MermaidOptions<N, E>): string;
};
/**
 * Direction for graph traversal, indicating which edges to follow.
 *
 * **Example** (Traversing by direction)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   Graph.addEdge(mutable, a, b, "A->B")
 * })
 *
 * // Follow outgoing edges (normal direction)
 * const outgoingNodes = Array.from(
 *   Graph.indices(Graph.dfs(graph, { start: [0], direction: "outgoing" }))
 * )
 *
 * // Follow incoming edges (reverse direction)
 * const incomingNodes = Array.from(
 *   Graph.indices(Graph.dfs(graph, { start: [1], direction: "incoming" }))
 * )
 * ```
 *
 * @category models
 * @since 3.18.0
 */
export type Direction = "outgoing" | "incoming";
/**
 * Checks whether the graph is acyclic (contains no cycles).
 *
 * **Details**
 *
 * Uses depth-first search to detect back edges, which indicate cycles.
 * For directed graphs, any back edge creates a cycle. For undirected graphs,
 * a back edge that doesn't go to the immediate parent creates a cycle.
 *
 * **Example** (Checking cycles)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * // Acyclic directed graph (DAG)
 * const dag = Graph.directed<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, "A->B")
 *   Graph.addEdge(mutable, b, c, "B->C")
 * })
 * console.log(Graph.isAcyclic(dag)) // true
 *
 * // Cyclic directed graph
 * const cyclic = Graph.directed<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   Graph.addEdge(mutable, a, b, "A->B")
 *   Graph.addEdge(mutable, b, a, "B->A") // Creates cycle
 * })
 * console.log(Graph.isAcyclic(cyclic)) // false
 * ```
 *
 * @category algorithms
 * @since 3.18.0
 */
export declare const isAcyclic: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => boolean;
/**
 * Checks whether an undirected graph is bipartite.
 *
 * **Details**
 *
 * A bipartite graph is one whose vertices can be divided into two disjoint sets
 * such that no two vertices within the same set are adjacent. Uses BFS coloring
 * to determine bipartiteness.
 *
 * **Example** (Checking bipartite graphs)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * // Bipartite graph (alternating coloring possible)
 * const bipartite = Graph.undirected<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   const d = Graph.addNode(mutable, "D")
 *   Graph.addEdge(mutable, a, b, "edge") // Set 1: {A, C}, Set 2: {B, D}
 *   Graph.addEdge(mutable, b, c, "edge")
 *   Graph.addEdge(mutable, c, d, "edge")
 * })
 * console.log(Graph.isBipartite(bipartite)) // true
 *
 * // Non-bipartite graph (odd cycle)
 * const triangle = Graph.undirected<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, "edge")
 *   Graph.addEdge(mutable, b, c, "edge")
 *   Graph.addEdge(mutable, c, a, "edge") // Triangle (3-cycle)
 * })
 * console.log(Graph.isBipartite(triangle)) // false
 * ```
 *
 * @category algorithms
 * @since 3.18.0
 */
export declare const isBipartite: <N, E>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">) => boolean;
/**
 * Finds connected components in an undirected graph.
 * Each component is represented as an array of node indices.
 *
 * **Example** (Finding connected components)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.undirected<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   const d = Graph.addNode(mutable, "D")
 *   Graph.addEdge(mutable, a, b, "edge") // Component 1: A-B
 *   Graph.addEdge(mutable, c, d, "edge") // Component 2: C-D
 * })
 *
 * const components = Graph.connectedComponents(graph)
 * console.log(components) // [[0, 1], [2, 3]]
 * ```
 *
 * @category algorithms
 * @since 3.18.0
 */
export declare const connectedComponents: <N, E>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">) => Array<Array<NodeIndex>>;
/**
 * Finds strongly connected components in a directed graph using Kosaraju's algorithm.
 * Each SCC is represented as an array of node indices.
 *
 * **Example** (Finding strongly connected components)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, string>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, "A->B")
 *   Graph.addEdge(mutable, b, c, "B->C")
 *   Graph.addEdge(mutable, c, a, "C->A") // Creates SCC: A-B-C
 * })
 *
 * const sccs = Graph.stronglyConnectedComponents(graph)
 * console.log(sccs) // [[0, 1, 2]]
 * ```
 *
 * @category algorithms
 * @since 3.18.0
 */
export declare const stronglyConnectedComponents: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Array<Array<NodeIndex>>;
/**
 * Result of a shortest path computation.
 *
 * **When to use**
 *
 * Use to read the successful source-to-target shortest path returned by
 * path-finding algorithms, including the ordered node indices, total distance,
 * and traversed edge data.
 *
 * **Details**
 *
 * Contains the node-index path, the total numeric distance, and the edge data
 * encountered along the path.
 *
 * **Gotchas**
 *
 * `costs` contains original edge data, not the numeric output of the cost
 * function unless the edge data is numeric.
 *
 * @see {@link dijkstra} for shortest paths with non-negative edge costs
 * @see {@link astar} for heuristic shortest-path search
 * @see {@link bellmanFord} for shortest paths that may include negative edge weights
 * @see {@link AllPairsResult} for the all-pairs shortest-path result shape
 *
 * @category models
 * @since 3.18.0
 */
export interface PathResult<E> {
    readonly path: Array<NodeIndex>;
    readonly distance: number;
    readonly costs: Array<E>;
}
/**
 * Configuration for finding a shortest path with Dijkstra's algorithm.
 *
 * **When to use**
 *
 * Use when configuring `dijkstra` to find a shortest path between two existing
 * node indices with non-negative edge costs.
 *
 * **Details**
 *
 * Specifies the source and target node indices, plus a cost function that maps
 * each edge's data to a non-negative numeric weight.
 *
 * **Gotchas**
 *
 * `dijkstra` throws a `GraphError` when either endpoint does not exist or when
 * the cost function returns a negative weight.
 *
 * @see {@link dijkstra} for the algorithm that consumes this configuration
 * @see {@link AstarConfig} for heuristic shortest-path search
 * @see {@link BellmanFordConfig} for shortest paths that may include negative edge weights
 *
 * @category models
 * @since 3.18.0
 */
export interface DijkstraConfig<E> {
    source: NodeIndex;
    target: NodeIndex;
    cost: (edgeData: E) => number;
}
/**
 * Finds the shortest path from the configured source node to the target node
 * using Dijkstra's algorithm.
 *
 * **Details**
 *
 * Edge costs must be non-negative. Returns `Option.none()` when the target is
 * not reachable, and throws a `GraphError` when either endpoint is missing or a
 * negative edge cost is encountered.
 *
 * **Example** (Finding shortest paths with Dijkstra)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 5)
 *   Graph.addEdge(mutable, a, c, 10)
 *   Graph.addEdge(mutable, b, c, 2)
 * })
 *
 * const result = Graph.dijkstra(graph, {
 *   source: 0,
 *   target: 2,
 *   cost: (edgeData) => edgeData
 * })
 *
 * if (result._tag === "Some") {
 *   console.log(result.value.path) // [0, 1, 2] - shortest path A->B->C
 *   console.log(result.value.distance) // 7 - total distance
 * }
 * ```
 *
 * @category algorithms
 * @since 3.18.0
 */
export declare const dijkstra: {
    /**
     * Finds the shortest path from the configured source node to the target node
     * using Dijkstra's algorithm.
     *
     * **Details**
     *
     * Edge costs must be non-negative. Returns `Option.none()` when the target is
     * not reachable, and throws a `GraphError` when either endpoint is missing or a
     * negative edge cost is encountered.
     *
     * **Example** (Finding shortest paths with Dijkstra)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 5)
     *   Graph.addEdge(mutable, a, c, 10)
     *   Graph.addEdge(mutable, b, c, 2)
     * })
     *
     * const result = Graph.dijkstra(graph, {
     *   source: 0,
     *   target: 2,
     *   cost: (edgeData) => edgeData
     * })
     *
     * if (result._tag === "Some") {
     *   console.log(result.value.path) // [0, 1, 2] - shortest path A->B->C
     *   console.log(result.value.distance) // 7 - total distance
     * }
     * ```
     *
     * @category algorithms
     * @since 3.18.0
     */
    <E>(config: DijkstraConfig<E>): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Option.Option<PathResult<E>>;
    /**
     * Finds the shortest path from the configured source node to the target node
     * using Dijkstra's algorithm.
     *
     * **Details**
     *
     * Edge costs must be non-negative. Returns `Option.none()` when the target is
     * not reachable, and throws a `GraphError` when either endpoint is missing or a
     * negative edge cost is encountered.
     *
     * **Example** (Finding shortest paths with Dijkstra)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 5)
     *   Graph.addEdge(mutable, a, c, 10)
     *   Graph.addEdge(mutable, b, c, 2)
     * })
     *
     * const result = Graph.dijkstra(graph, {
     *   source: 0,
     *   target: 2,
     *   cost: (edgeData) => edgeData
     * })
     *
     * if (result._tag === "Some") {
     *   console.log(result.value.path) // [0, 1, 2] - shortest path A->B->C
     *   console.log(result.value.distance) // 7 - total distance
     * }
     * ```
     *
     * @category algorithms
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config: DijkstraConfig<E>): Option.Option<PathResult<E>>;
};
/**
 * Result of an all-pairs shortest path computation.
 *
 * **When to use**
 *
 * Use when storing or passing around the complete output of `floydWarshall` so
 * callers can look up shortest distances, node paths, and edge data for any
 * source and target node pair.
 *
 * **Details**
 *
 * Contains distance, node-path, and edge-data maps keyed by source and target
 * node indices.
 *
 * @see {@link floydWarshall} for computing an all-pairs shortest path result
 * @see {@link PathResult} for the single source-to-target result shape used by path-finding algorithms
 *
 * @category models
 * @since 3.18.0
 */
export interface AllPairsResult<E> {
    readonly distances: Map<NodeIndex, Map<NodeIndex, number>>;
    readonly paths: Map<NodeIndex, Map<NodeIndex, Array<NodeIndex> | null>>;
    readonly costs: Map<NodeIndex, Map<NodeIndex, Array<E>>>;
}
/**
 * Finds shortest paths between all pairs of nodes using the Floyd-Warshall
 * algorithm.
 *
 * **Details**
 *
 * Computes distances, reconstructed node paths, and edge-data paths for every
 * source and target pair in O(V^3) time. Negative edge weights are allowed, but
 * a `GraphError` is thrown if any negative cycle is detected.
 *
 * **Example** (Finding all-pairs shortest paths)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 3)
 *   Graph.addEdge(mutable, b, c, 2)
 *   Graph.addEdge(mutable, a, c, 7)
 * })
 *
 * const result = Graph.floydWarshall(graph, (edgeData) => edgeData)
 * const distanceAToC = result.distances.get(0)?.get(2) // 5 (A->B->C)
 * const pathAToC = result.paths.get(0)?.get(2) // [0, 1, 2]
 * ```
 *
 * @category algorithms
 * @since 3.18.0
 */
export declare const floydWarshall: {
    /**
     * Finds shortest paths between all pairs of nodes using the Floyd-Warshall
     * algorithm.
     *
     * **Details**
     *
     * Computes distances, reconstructed node paths, and edge-data paths for every
     * source and target pair in O(V^3) time. Negative edge weights are allowed, but
     * a `GraphError` is thrown if any negative cycle is detected.
     *
     * **Example** (Finding all-pairs shortest paths)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 3)
     *   Graph.addEdge(mutable, b, c, 2)
     *   Graph.addEdge(mutable, a, c, 7)
     * })
     *
     * const result = Graph.floydWarshall(graph, (edgeData) => edgeData)
     * const distanceAToC = result.distances.get(0)?.get(2) // 5 (A->B->C)
     * const pathAToC = result.paths.get(0)?.get(2) // [0, 1, 2]
     * ```
     *
     * @category algorithms
     * @since 3.18.0
     */
    <E>(cost: (edgeData: E) => number): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => AllPairsResult<E>;
    /**
     * Finds shortest paths between all pairs of nodes using the Floyd-Warshall
     * algorithm.
     *
     * **Details**
     *
     * Computes distances, reconstructed node paths, and edge-data paths for every
     * source and target pair in O(V^3) time. Negative edge weights are allowed, but
     * a `GraphError` is thrown if any negative cycle is detected.
     *
     * **Example** (Finding all-pairs shortest paths)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 3)
     *   Graph.addEdge(mutable, b, c, 2)
     *   Graph.addEdge(mutable, a, c, 7)
     * })
     *
     * const result = Graph.floydWarshall(graph, (edgeData) => edgeData)
     * const distanceAToC = result.distances.get(0)?.get(2) // 5 (A->B->C)
     * const pathAToC = result.paths.get(0)?.get(2) // [0, 1, 2]
     * ```
     *
     * @category algorithms
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, cost: (edgeData: E) => number): AllPairsResult<E>;
};
/**
 * Configuration for finding a shortest path with the A* algorithm.
 *
 * **When to use**
 *
 * Use when configuring `astar` for point-to-point shortest-path searches where
 * node data can provide a heuristic estimate toward the target.
 *
 * **Details**
 *
 * Specifies the source and target node indices, an edge-cost function, and a
 * heuristic that estimates the remaining cost from a node to the target.
 *
 * @see {@link astar} for the algorithm that consumes this configuration
 * @see {@link DijkstraConfig} for shortest paths without a heuristic
 * @see {@link BellmanFordConfig} for shortest paths that may include negative edge weights
 *
 * @category models
 * @since 3.18.0
 */
export interface AstarConfig<E, N> {
    source: NodeIndex;
    target: NodeIndex;
    cost: (edgeData: E) => number;
    heuristic: (sourceNodeData: N, targetNodeData: N) => number;
}
/**
 * Finds the shortest path from the configured source node to the target node
 * using the A* pathfinding algorithm.
 *
 * **Details**
 *
 * The edge-cost function must return non-negative weights, and the heuristic
 * should be admissible to preserve shortest-path guarantees. Returns
 * `Option.none()` when the target is not reachable, and throws a `GraphError`
 * when either endpoint is missing or a negative edge cost is encountered.
 *
 * **Example** (Finding shortest paths with A-star)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<{ x: number; y: number }, number>((mutable) => {
 *   const a = Graph.addNode(mutable, { x: 0, y: 0 })
 *   const b = Graph.addNode(mutable, { x: 1, y: 0 })
 *   const c = Graph.addNode(mutable, { x: 2, y: 0 })
 *   Graph.addEdge(mutable, a, b, 1)
 *   Graph.addEdge(mutable, b, c, 1)
 * })
 *
 * // Manhattan distance heuristic
 * const heuristic = (
 *   nodeData: { x: number; y: number },
 *   targetData: { x: number; y: number }
 * ) => Math.abs(nodeData.x - targetData.x) + Math.abs(nodeData.y - targetData.y)
 *
 * const result = Graph.astar(graph, {
 *   source: 0,
 *   target: 2,
 *   cost: (edgeData) => edgeData,
 *   heuristic
 * })
 *
 * if (result._tag === "Some") {
 *   console.log(result.value.path) // [0, 1, 2] - shortest path
 *   console.log(result.value.distance) // 2 - total distance
 * }
 * ```
 *
 * @category algorithms
 * @since 3.18.0
 */
export declare const astar: {
    /**
     * Finds the shortest path from the configured source node to the target node
     * using the A* pathfinding algorithm.
     *
     * **Details**
     *
     * The edge-cost function must return non-negative weights, and the heuristic
     * should be admissible to preserve shortest-path guarantees. Returns
     * `Option.none()` when the target is not reachable, and throws a `GraphError`
     * when either endpoint is missing or a negative edge cost is encountered.
     *
     * **Example** (Finding shortest paths with A-star)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<{ x: number; y: number }, number>((mutable) => {
     *   const a = Graph.addNode(mutable, { x: 0, y: 0 })
     *   const b = Graph.addNode(mutable, { x: 1, y: 0 })
     *   const c = Graph.addNode(mutable, { x: 2, y: 0 })
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, c, 1)
     * })
     *
     * // Manhattan distance heuristic
     * const heuristic = (
     *   nodeData: { x: number; y: number },
     *   targetData: { x: number; y: number }
     * ) => Math.abs(nodeData.x - targetData.x) + Math.abs(nodeData.y - targetData.y)
     *
     * const result = Graph.astar(graph, {
     *   source: 0,
     *   target: 2,
     *   cost: (edgeData) => edgeData,
     *   heuristic
     * })
     *
     * if (result._tag === "Some") {
     *   console.log(result.value.path) // [0, 1, 2] - shortest path
     *   console.log(result.value.distance) // 2 - total distance
     * }
     * ```
     *
     * @category algorithms
     * @since 3.18.0
     */
    <E, N>(config: AstarConfig<E, N>): <T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Option.Option<PathResult<E>>;
    /**
     * Finds the shortest path from the configured source node to the target node
     * using the A* pathfinding algorithm.
     *
     * **Details**
     *
     * The edge-cost function must return non-negative weights, and the heuristic
     * should be admissible to preserve shortest-path guarantees. Returns
     * `Option.none()` when the target is not reachable, and throws a `GraphError`
     * when either endpoint is missing or a negative edge cost is encountered.
     *
     * **Example** (Finding shortest paths with A-star)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<{ x: number; y: number }, number>((mutable) => {
     *   const a = Graph.addNode(mutable, { x: 0, y: 0 })
     *   const b = Graph.addNode(mutable, { x: 1, y: 0 })
     *   const c = Graph.addNode(mutable, { x: 2, y: 0 })
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, c, 1)
     * })
     *
     * // Manhattan distance heuristic
     * const heuristic = (
     *   nodeData: { x: number; y: number },
     *   targetData: { x: number; y: number }
     * ) => Math.abs(nodeData.x - targetData.x) + Math.abs(nodeData.y - targetData.y)
     *
     * const result = Graph.astar(graph, {
     *   source: 0,
     *   target: 2,
     *   cost: (edgeData) => edgeData,
     *   heuristic
     * })
     *
     * if (result._tag === "Some") {
     *   console.log(result.value.path) // [0, 1, 2] - shortest path
     *   console.log(result.value.distance) // 2 - total distance
     * }
     * ```
     *
     * @category algorithms
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config: AstarConfig<E, N>): Option.Option<PathResult<E>>;
};
/**
 * Configuration for finding a shortest path with the Bellman-Ford algorithm.
 *
 * **When to use**
 *
 * Use when configuring `bellmanFord` to find a shortest path where edge
 * weights may be negative.
 *
 * **Details**
 *
 * Specifies the source and target node indices, plus a cost function that maps
 * each edge's data to a numeric weight.
 *
 * @see {@link bellmanFord} for the algorithm that consumes this configuration
 * @see {@link DijkstraConfig} for non-negative edge costs
 * @see {@link AstarConfig} for heuristic shortest-path search
 *
 * @category models
 * @since 3.18.0
 */
export interface BellmanFordConfig<E> {
    source: NodeIndex;
    target: NodeIndex;
    cost: (edgeData: E) => number;
}
/**
 * Finds the shortest path from the configured source node to the target node
 * using the Bellman-Ford algorithm.
 *
 * **Details**
 *
 * Negative edge weights are allowed. Returns `Option.none()` when the target is
 * unreachable or when a negative cycle affects the path to the target. Throws a
 * `GraphError` when either endpoint is missing.
 *
 * **Example** (Finding shortest paths with Bellman-Ford)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, -1) // Negative weight allowed
 *   Graph.addEdge(mutable, b, c, 3)
 *   Graph.addEdge(mutable, a, c, 5)
 * })
 *
 * const result = Graph.bellmanFord(graph, {
 *   source: 0,
 *   target: 2,
 *   cost: (edgeData) => edgeData
 * })
 *
 * if (result._tag === "Some") {
 *   console.log(result.value.path) // [0, 1, 2] - shortest path A->B->C
 *   console.log(result.value.distance) // 2 - total distance
 * }
 * ```
 *
 * @category algorithms
 * @since 3.18.0
 */
export declare const bellmanFord: {
    /**
     * Finds the shortest path from the configured source node to the target node
     * using the Bellman-Ford algorithm.
     *
     * **Details**
     *
     * Negative edge weights are allowed. Returns `Option.none()` when the target is
     * unreachable or when a negative cycle affects the path to the target. Throws a
     * `GraphError` when either endpoint is missing.
     *
     * **Example** (Finding shortest paths with Bellman-Ford)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, -1) // Negative weight allowed
     *   Graph.addEdge(mutable, b, c, 3)
     *   Graph.addEdge(mutable, a, c, 5)
     * })
     *
     * const result = Graph.bellmanFord(graph, {
     *   source: 0,
     *   target: 2,
     *   cost: (edgeData) => edgeData
     * })
     *
     * if (result._tag === "Some") {
     *   console.log(result.value.path) // [0, 1, 2] - shortest path A->B->C
     *   console.log(result.value.distance) // 2 - total distance
     * }
     * ```
     *
     * @category algorithms
     * @since 3.18.0
     */
    <E>(config: BellmanFordConfig<E>): <N, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Option.Option<PathResult<E>>;
    /**
     * Finds the shortest path from the configured source node to the target node
     * using the Bellman-Ford algorithm.
     *
     * **Details**
     *
     * Negative edge weights are allowed. Returns `Option.none()` when the target is
     * unreachable or when a negative cycle affects the path to the target. Throws a
     * `GraphError` when either endpoint is missing.
     *
     * **Example** (Finding shortest paths with Bellman-Ford)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, -1) // Negative weight allowed
     *   Graph.addEdge(mutable, b, c, 3)
     *   Graph.addEdge(mutable, a, c, 5)
     * })
     *
     * const result = Graph.bellmanFord(graph, {
     *   source: 0,
     *   target: 2,
     *   cost: (edgeData) => edgeData
     * })
     *
     * if (result._tag === "Some") {
     *   console.log(result.value.path) // [0, 1, 2] - shortest path A->B->C
     *   console.log(result.value.distance) // 2 - total distance
     * }
     * ```
     *
     * @category algorithms
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config: BellmanFordConfig<E>): Option.Option<PathResult<E>>;
};
/**
 * Represents an iterable wrapper used by graph traversal and listing APIs.
 *
 * **Details**
 *
 * A `Walker` yields `[index, data]` pairs lazily and can be viewed as just the
 * indices, just the values, or mapped entries with `indices`, `values`,
 * `entries`, and `visit`.
 *
 * **Example** (Working with node walkers)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   Graph.addEdge(mutable, a, b, 1)
 * })
 *
 * // Both traversal and element iterators return NodeWalker
 * const dfsNodes: Graph.NodeWalker<string> = Graph.dfs(graph, { start: [0] })
 * const allNodes: Graph.NodeWalker<string> = Graph.nodes(graph)
 *
 * // Common interface for working with node iterables
 * function processNodes<N>(nodeIterable: Graph.NodeWalker<N>): Array<number> {
 *   return Array.from(Graph.indices(nodeIterable))
 * }
 *
 * // Access node data using values() or entries()
 * const nodeData = Array.from(Graph.values(dfsNodes)) // ["A", "B"]
 * const nodeEntries = Array.from(Graph.entries(allNodes)) // [[0, "A"], [1, "B"]]
 * ```
 *
 * @category models
 * @since 3.18.0
 */
export declare class Walker<T, N> implements Iterable<[T, N]> {
    readonly [Symbol.iterator]: () => Iterator<[T, N]>;
    /**
     * Visits each element and maps it to a value using the provided function.
     *
     * **Details**
     *
     * Takes a function that receives the index and data,
     * and returns an iterable of the mapped values. Skips elements that
     * no longer exist in the graph.
     *
     * **Example** (Visiting walker elements)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   Graph.addEdge(mutable, a, b, 1)
     * })
     *
     * const dfs = Graph.dfs(graph, { start: [0] })
     *
     * // Map to just the node data
     * const values = Array.from(dfs.visit((index, data) => data))
     * console.log(values) // ["A", "B"]
     *
     * // Map to custom objects
     * const custom = Array.from(
     *   dfs.visit((index, data) => ({ id: index, name: data }))
     * )
     * console.log(custom) // [{ id: 0, name: "A" }, { id: 1, name: "B" }]
     * ```
     *
     * @since 4.0.0
     */
    readonly visit: <U>(f: (index: T, data: N) => U) => Iterable<U>;
    constructor(
    /**
     * Visits each element and maps it to a value using the provided function.
     *
     * Takes a function that receives the index and data,
     * and returns an iterable of the mapped values. Skips elements that
     * no longer exist in the graph.
     *
     * **Example** (Visiting walker elements)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   Graph.addEdge(mutable, a, b, 1)
     * })
     *
     * const dfs = Graph.dfs(graph, { start: [0] })
     *
     * // Map to just the node data
     * const values = Array.from(dfs.visit((index, data) => data))
     * console.log(values) // ["A", "B"]
     *
     * // Map to custom objects
     * const custom = Array.from(
     *   dfs.visit((index, data) => ({ id: index, name: data }))
     * )
     * console.log(custom) // [{ id: 0, name: "A" }, { id: 1, name: "B" }]
     * ```
     *
     * @category iterators
     * @since 4.0.0
     */
    visit: <U>(f: (index: T, data: N) => U) => Iterable<U>);
}
/**
 * Type alias for node iteration using Walker.
 * NodeWalker is represented as Walker<NodeIndex, N>.
 *
 * **When to use**
 *
 * Use as the shared node walker type returned by graph traversal and node
 * listing APIs.
 *
 * @see {@link Walker} for the generic lazy iterator wrapper
 * @see {@link EdgeWalker} for edge iterators
 *
 * @category models
 * @since 3.18.0
 */
export type NodeWalker<N> = Walker<NodeIndex, N>;
/**
 * Type alias for edge iteration using Walker.
 * EdgeWalker is represented as Walker<EdgeIndex, Edge<E>>.
 *
 * **When to use**
 *
 * Use to type helpers or parameters that consume edge iterators returned by
 * `Graph` APIs, where each item is keyed by an `EdgeIndex` and carries the
 * full `Edge`.
 *
 * @see {@link Walker} for the generic lazy iterator wrapper
 * @see {@link NodeWalker} for node iterators
 * @see {@link edges} for creating edge walkers
 *
 * @category models
 * @since 3.18.0
 */
export type EdgeWalker<E> = Walker<EdgeIndex, Edge<E>>;
/**
 * Returns an iterator over the indices in the walker.
 *
 * **Example** (Iterating walker indices)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   Graph.addEdge(mutable, a, b, 1)
 * })
 *
 * const dfs = Graph.dfs(graph, { start: [0] })
 * const indices = Array.from(Graph.indices(dfs))
 * console.log(indices) // [0, 1]
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const indices: <T, N>(walker: Walker<T, N>) => Iterable<T>;
/**
 * Returns an iterator over the values (data) in the walker.
 *
 * **Example** (Iterating walker values)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   Graph.addEdge(mutable, a, b, 1)
 * })
 *
 * const dfs = Graph.dfs(graph, { start: [0] })
 * const values = Array.from(Graph.values(dfs))
 * console.log(values) // ["A", "B"]
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const values: <T, N>(walker: Walker<T, N>) => Iterable<N>;
/**
 * Returns an iterator over [index, data] entries in the walker.
 *
 * **Example** (Iterating walker entries)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   Graph.addEdge(mutable, a, b, 1)
 * })
 *
 * const dfs = Graph.dfs(graph, { start: [0] })
 * const entries = Array.from(Graph.entries(dfs))
 * console.log(entries) // [[0, "A"], [1, "B"]]
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const entries: <T, N>(walker: Walker<T, N>) => Iterable<[T, N]>;
/**
 * Configuration for DFS, BFS, and postorder graph traversals.
 *
 * **When to use**
 *
 * Use to configure the starting node indices and edge-following direction for
 * lazy graph traversals.
 *
 * **Details**
 *
 * `start` supplies the node indices where traversal begins. If it is omitted,
 * the iterator is empty. `direction` chooses whether traversal follows
 * outgoing or incoming edges.
 *
 * **Gotchas**
 *
 * Traversal creation throws a `GraphError` when any configured `start` node
 * does not exist.
 *
 * @see {@link dfs} for depth-first traversal
 * @see {@link bfs} for breadth-first traversal
 * @see {@link dfsPostOrder} for depth-first postorder traversal
 *
 * @category models
 * @since 3.18.0
 */
export interface SearchConfig {
    readonly start?: Array<NodeIndex>;
    readonly direction?: Direction;
}
/**
 * Creates a lazy depth-first traversal iterator from the configured start
 * nodes.
 *
 * **Details**
 *
 * If no start nodes are supplied, the iterator is empty. The `direction` option
 * chooses whether to follow outgoing or incoming edges. Throws a `GraphError`
 * if any configured start node does not exist.
 *
 * **Example** (Traversing depth-first)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 1)
 *   Graph.addEdge(mutable, b, c, 1)
 * })
 *
 * // Start from a specific node
 * const dfs1 = Graph.dfs(graph, { start: [0] })
 * for (const nodeIndex of Graph.indices(dfs1)) {
 *   console.log(nodeIndex) // Traverses in DFS order: 0, 1, 2
 * }
 *
 * // Empty iterator (no starting nodes)
 * const dfs2 = Graph.dfs(graph)
 * // Can be used programmatically
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const dfs: {
    /**
     * Creates a lazy depth-first traversal iterator from the configured start
     * nodes.
     *
     * **Details**
     *
     * If no start nodes are supplied, the iterator is empty. The `direction` option
     * chooses whether to follow outgoing or incoming edges. Throws a `GraphError`
     * if any configured start node does not exist.
     *
     * **Example** (Traversing depth-first)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, c, 1)
     * })
     *
     * // Start from a specific node
     * const dfs1 = Graph.dfs(graph, { start: [0] })
     * for (const nodeIndex of Graph.indices(dfs1)) {
     *   console.log(nodeIndex) // Traverses in DFS order: 0, 1, 2
     * }
     *
     * // Empty iterator (no starting nodes)
     * const dfs2 = Graph.dfs(graph)
     * // Can be used programmatically
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    (config?: SearchConfig): <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => NodeWalker<N>;
    /**
     * Creates a lazy depth-first traversal iterator from the configured start
     * nodes.
     *
     * **Details**
     *
     * If no start nodes are supplied, the iterator is empty. The `direction` option
     * chooses whether to follow outgoing or incoming edges. Throws a `GraphError`
     * if any configured start node does not exist.
     *
     * **Example** (Traversing depth-first)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, c, 1)
     * })
     *
     * // Start from a specific node
     * const dfs1 = Graph.dfs(graph, { start: [0] })
     * for (const nodeIndex of Graph.indices(dfs1)) {
     *   console.log(nodeIndex) // Traverses in DFS order: 0, 1, 2
     * }
     *
     * // Empty iterator (no starting nodes)
     * const dfs2 = Graph.dfs(graph)
     * // Can be used programmatically
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: SearchConfig): NodeWalker<N>;
};
/**
 * Creates a lazy breadth-first traversal iterator from the configured start
 * nodes.
 *
 * **Details**
 *
 * If no start nodes are supplied, the iterator is empty. The `direction` option
 * chooses whether to follow outgoing or incoming edges. Throws a `GraphError`
 * if any configured start node does not exist.
 *
 * **Example** (Traversing breadth-first)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 1)
 *   Graph.addEdge(mutable, b, c, 1)
 * })
 *
 * // Start from a specific node
 * const bfs1 = Graph.bfs(graph, { start: [0] })
 * for (const nodeIndex of Graph.indices(bfs1)) {
 *   console.log(nodeIndex) // Traverses in BFS order: 0, 1, 2
 * }
 *
 * // Empty iterator (no starting nodes)
 * const bfs2 = Graph.bfs(graph)
 * // Can be used programmatically
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const bfs: {
    /**
     * Creates a lazy breadth-first traversal iterator from the configured start
     * nodes.
     *
     * **Details**
     *
     * If no start nodes are supplied, the iterator is empty. The `direction` option
     * chooses whether to follow outgoing or incoming edges. Throws a `GraphError`
     * if any configured start node does not exist.
     *
     * **Example** (Traversing breadth-first)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, c, 1)
     * })
     *
     * // Start from a specific node
     * const bfs1 = Graph.bfs(graph, { start: [0] })
     * for (const nodeIndex of Graph.indices(bfs1)) {
     *   console.log(nodeIndex) // Traverses in BFS order: 0, 1, 2
     * }
     *
     * // Empty iterator (no starting nodes)
     * const bfs2 = Graph.bfs(graph)
     * // Can be used programmatically
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    (config?: SearchConfig): <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => NodeWalker<N>;
    /**
     * Creates a lazy breadth-first traversal iterator from the configured start
     * nodes.
     *
     * **Details**
     *
     * If no start nodes are supplied, the iterator is empty. The `direction` option
     * chooses whether to follow outgoing or incoming edges. Throws a `GraphError`
     * if any configured start node does not exist.
     *
     * **Example** (Traversing breadth-first)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, c, 1)
     * })
     *
     * // Start from a specific node
     * const bfs1 = Graph.bfs(graph, { start: [0] })
     * for (const nodeIndex of Graph.indices(bfs1)) {
     *   console.log(nodeIndex) // Traverses in BFS order: 0, 1, 2
     * }
     *
     * // Empty iterator (no starting nodes)
     * const bfs2 = Graph.bfs(graph)
     * // Can be used programmatically
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: SearchConfig): NodeWalker<N>;
};
/**
 * Configuration for the topological sort iterator.
 *
 * **When to use**
 *
 * Use to seed a topological sort with specific initial node indices instead of
 * starting from every zero in-degree node.
 *
 * **Details**
 *
 * `initials` optionally supplies the node indices used as initial queue
 * entries. When omitted, topological sorting starts from all nodes with zero
 * in-degree.
 *
 * @see {@link topo} for the iterator that consumes this configuration
 *
 * @category models
 * @since 3.18.0
 */
export interface TopoConfig {
    readonly initials?: Array<NodeIndex>;
}
/**
 * Creates a new topological sort iterator with optional configuration.
 *
 * **Details**
 *
 * The iterator uses Kahn's algorithm to lazily produce nodes in topological order.
 * Throws an error if the graph contains cycles.
 *
 * **Example** (Sorting topologically)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 1)
 *   Graph.addEdge(mutable, b, c, 1)
 * })
 *
 * // Standard topological sort
 * const topo1 = Graph.topo(graph)
 * for (const nodeIndex of Graph.indices(topo1)) {
 *   console.log(nodeIndex) // 0, 1, 2 (topological order)
 * }
 *
 * // With initial nodes
 * const topo2 = Graph.topo(graph, { initials: [0] })
 *
 * // Check before sorting a cyclic graph
 * const cyclicGraph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   Graph.addEdge(mutable, a, b, 1)
 *   Graph.addEdge(mutable, b, a, 2) // Creates cycle
 * })
 *
 * if (!Graph.isAcyclic(cyclicGraph)) {
 *   console.log("cyclic graph") // cyclic graph
 * }
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const topo: {
    /**
     * Creates a new topological sort iterator with optional configuration.
     *
     * **Details**
     *
     * The iterator uses Kahn's algorithm to lazily produce nodes in topological order.
     * Throws an error if the graph contains cycles.
     *
     * **Example** (Sorting topologically)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, c, 1)
     * })
     *
     * // Standard topological sort
     * const topo1 = Graph.topo(graph)
     * for (const nodeIndex of Graph.indices(topo1)) {
     *   console.log(nodeIndex) // 0, 1, 2 (topological order)
     * }
     *
     * // With initial nodes
     * const topo2 = Graph.topo(graph, { initials: [0] })
     *
     * // Check before sorting a cyclic graph
     * const cyclicGraph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, a, 2) // Creates cycle
     * })
     *
     * if (!Graph.isAcyclic(cyclicGraph)) {
     *   console.log("cyclic graph") // cyclic graph
     * }
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    (config?: TopoConfig): <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => NodeWalker<N>;
    /**
     * Creates a new topological sort iterator with optional configuration.
     *
     * **Details**
     *
     * The iterator uses Kahn's algorithm to lazily produce nodes in topological order.
     * Throws an error if the graph contains cycles.
     *
     * **Example** (Sorting topologically)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   const c = Graph.addNode(mutable, "C")
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, c, 1)
     * })
     *
     * // Standard topological sort
     * const topo1 = Graph.topo(graph)
     * for (const nodeIndex of Graph.indices(topo1)) {
     *   console.log(nodeIndex) // 0, 1, 2 (topological order)
     * }
     *
     * // With initial nodes
     * const topo2 = Graph.topo(graph, { initials: [0] })
     *
     * // Check before sorting a cyclic graph
     * const cyclicGraph = Graph.directed<string, number>((mutable) => {
     *   const a = Graph.addNode(mutable, "A")
     *   const b = Graph.addNode(mutable, "B")
     *   Graph.addEdge(mutable, a, b, 1)
     *   Graph.addEdge(mutable, b, a, 2) // Creates cycle
     * })
     *
     * if (!Graph.isAcyclic(cyclicGraph)) {
     *   console.log("cyclic graph") // cyclic graph
     * }
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig): NodeWalker<N>;
};
/**
 * Creates a lazy depth-first postorder traversal iterator from the configured
 * start nodes.
 *
 * **Details**
 *
 * Nodes are emitted after their reachable descendants have been processed. If
 * no start nodes are supplied, the iterator is empty. The `direction` option
 * chooses whether to follow outgoing or incoming edges.
 *
 * **Example** (Traversing in postorder)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const root = Graph.addNode(mutable, "root")
 *   const child1 = Graph.addNode(mutable, "child1")
 *   const child2 = Graph.addNode(mutable, "child2")
 *   Graph.addEdge(mutable, root, child1, 1)
 *   Graph.addEdge(mutable, root, child2, 1)
 * })
 *
 * // Postorder: children before parents
 * const postOrder = Graph.dfsPostOrder(graph, { start: [0] })
 * for (const node of postOrder) {
 *   console.log(node) // 1, 2, 0
 * }
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const dfsPostOrder: {
    /**
     * Creates a lazy depth-first postorder traversal iterator from the configured
     * start nodes.
     *
     * **Details**
     *
     * Nodes are emitted after their reachable descendants have been processed. If
     * no start nodes are supplied, the iterator is empty. The `direction` option
     * chooses whether to follow outgoing or incoming edges.
     *
     * **Example** (Traversing in postorder)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const root = Graph.addNode(mutable, "root")
     *   const child1 = Graph.addNode(mutable, "child1")
     *   const child2 = Graph.addNode(mutable, "child2")
     *   Graph.addEdge(mutable, root, child1, 1)
     *   Graph.addEdge(mutable, root, child2, 1)
     * })
     *
     * // Postorder: children before parents
     * const postOrder = Graph.dfsPostOrder(graph, { start: [0] })
     * for (const node of postOrder) {
     *   console.log(node) // 1, 2, 0
     * }
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    (config?: SearchConfig): <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => NodeWalker<N>;
    /**
     * Creates a lazy depth-first postorder traversal iterator from the configured
     * start nodes.
     *
     * **Details**
     *
     * Nodes are emitted after their reachable descendants have been processed. If
     * no start nodes are supplied, the iterator is empty. The `direction` option
     * chooses whether to follow outgoing or incoming edges.
     *
     * **Example** (Traversing in postorder)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const root = Graph.addNode(mutable, "root")
     *   const child1 = Graph.addNode(mutable, "child1")
     *   const child2 = Graph.addNode(mutable, "child2")
     *   Graph.addEdge(mutable, root, child1, 1)
     *   Graph.addEdge(mutable, root, child2, 1)
     * })
     *
     * // Postorder: children before parents
     * const postOrder = Graph.dfsPostOrder(graph, { start: [0] })
     * for (const node of postOrder) {
     *   console.log(node) // 1, 2, 0
     * }
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: SearchConfig): NodeWalker<N>;
};
/**
 * Creates an iterator over all node indices in the graph.
 *
 * **Details**
 *
 * The iterator produces node indices in the order they were added to the graph.
 * This provides access to all nodes regardless of connectivity.
 *
 * **Example** (Iterating all nodes)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 1)
 * })
 *
 * const indices = Array.from(Graph.indices(Graph.nodes(graph)))
 * console.log(indices) // [0, 1, 2]
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const nodes: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => NodeWalker<N>;
/**
 * Creates an iterator over all edge indices in the graph.
 *
 * **Details**
 *
 * The iterator produces edge indices in the order they were added to the graph.
 * This provides access to all edges regardless of connectivity.
 *
 * **Example** (Iterating all edges)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const a = Graph.addNode(mutable, "A")
 *   const b = Graph.addNode(mutable, "B")
 *   const c = Graph.addNode(mutable, "C")
 *   Graph.addEdge(mutable, a, b, 1)
 *   Graph.addEdge(mutable, b, c, 2)
 * })
 *
 * const indices = Array.from(Graph.indices(Graph.edges(graph)))
 * console.log(indices) // [0, 1]
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const edges: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => EdgeWalker<E>;
/**
 * Configuration for selecting external nodes.
 *
 * **When to use**
 *
 * Use to configure how `externals` identifies graph boundary nodes when you
 * need sinks with no outgoing edges or sources with no incoming edges.
 *
 * **Details**
 *
 * `direction` chooses which missing edge direction makes a node external:
 * `"outgoing"` selects nodes with no outgoing edges, and `"incoming"` selects
 * nodes with no incoming edges. If omitted, `direction` defaults to
 * `"outgoing"`.
 *
 * @see {@link externals} for the iterator that consumes this configuration
 *
 * @category models
 * @since 3.18.0
 */
export interface ExternalsConfig {
    readonly direction?: Direction;
}
/**
 * Creates an iterator over external nodes (nodes without edges in the specified direction).
 *
 * **Details**
 *
 * External nodes have no outgoing edges (`direction: "outgoing"`) or no
 * incoming edges (`direction: "incoming"`). These are useful for finding
 * sources, sinks, or isolated nodes.
 *
 * **Example** (Iterating external nodes)
 *
 * ```ts
 * import { Graph } from "effect"
 *
 * const graph = Graph.directed<string, number>((mutable) => {
 *   const source = Graph.addNode(mutable, "source") // 0 - no incoming
 *   const middle = Graph.addNode(mutable, "middle") // 1 - has both
 *   const sink = Graph.addNode(mutable, "sink") // 2 - no outgoing
 *   const isolated = Graph.addNode(mutable, "isolated") // 3 - no edges
 *
 *   Graph.addEdge(mutable, source, middle, 1)
 *   Graph.addEdge(mutable, middle, sink, 2)
 * })
 *
 * // Nodes with no outgoing edges (sinks + isolated)
 * const sinks = Array.from(
 *   Graph.indices(Graph.externals(graph, { direction: "outgoing" }))
 * )
 * console.log(sinks) // [2, 3]
 *
 * // Nodes with no incoming edges (sources + isolated)
 * const sources = Array.from(
 *   Graph.indices(Graph.externals(graph, { direction: "incoming" }))
 * )
 * console.log(sources) // [0, 3]
 * ```
 *
 * @category iterators
 * @since 3.18.0
 */
export declare const externals: {
    /**
     * Creates an iterator over external nodes (nodes without edges in the specified direction).
     *
     * **Details**
     *
     * External nodes have no outgoing edges (`direction: "outgoing"`) or no
     * incoming edges (`direction: "incoming"`). These are useful for finding
     * sources, sinks, or isolated nodes.
     *
     * **Example** (Iterating external nodes)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const source = Graph.addNode(mutable, "source") // 0 - no incoming
     *   const middle = Graph.addNode(mutable, "middle") // 1 - has both
     *   const sink = Graph.addNode(mutable, "sink") // 2 - no outgoing
     *   const isolated = Graph.addNode(mutable, "isolated") // 3 - no edges
     *
     *   Graph.addEdge(mutable, source, middle, 1)
     *   Graph.addEdge(mutable, middle, sink, 2)
     * })
     *
     * // Nodes with no outgoing edges (sinks + isolated)
     * const sinks = Array.from(
     *   Graph.indices(Graph.externals(graph, { direction: "outgoing" }))
     * )
     * console.log(sinks) // [2, 3]
     *
     * // Nodes with no incoming edges (sources + isolated)
     * const sources = Array.from(
     *   Graph.indices(Graph.externals(graph, { direction: "incoming" }))
     * )
     * console.log(sources) // [0, 3]
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    (config?: ExternalsConfig): <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => NodeWalker<N>;
    /**
     * Creates an iterator over external nodes (nodes without edges in the specified direction).
     *
     * **Details**
     *
     * External nodes have no outgoing edges (`direction: "outgoing"`) or no
     * incoming edges (`direction: "incoming"`). These are useful for finding
     * sources, sinks, or isolated nodes.
     *
     * **Example** (Iterating external nodes)
     *
     * ```ts
     * import { Graph } from "effect"
     *
     * const graph = Graph.directed<string, number>((mutable) => {
     *   const source = Graph.addNode(mutable, "source") // 0 - no incoming
     *   const middle = Graph.addNode(mutable, "middle") // 1 - has both
     *   const sink = Graph.addNode(mutable, "sink") // 2 - no outgoing
     *   const isolated = Graph.addNode(mutable, "isolated") // 3 - no edges
     *
     *   Graph.addEdge(mutable, source, middle, 1)
     *   Graph.addEdge(mutable, middle, sink, 2)
     * })
     *
     * // Nodes with no outgoing edges (sinks + isolated)
     * const sinks = Array.from(
     *   Graph.indices(Graph.externals(graph, { direction: "outgoing" }))
     * )
     * console.log(sinks) // [2, 3]
     *
     * // Nodes with no incoming edges (sources + isolated)
     * const sources = Array.from(
     *   Graph.indices(Graph.externals(graph, { direction: "incoming" }))
     * )
     * console.log(sources) // [0, 3]
     * ```
     *
     * @category iterators
     * @since 3.18.0
     */
    <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: ExternalsConfig): NodeWalker<N>;
};
export {};
//# sourceMappingURL=Graph.d.ts.map