import { ChangeSet, Leaf, Pos, Plot, Mark, Schema, Node } from 'wordgard/doc';

/**
The base class for editor selections. Actual selections will be a
subclass of this—usually {@link GardSelection.Text} or {@link
GardSelection.Node}.
*/
declare abstract class GardSelection {
    /**
    The anchor of the selection—the side that doesn't move when
    you extend it.
    */
    readonly anchor: number;
    /**
    The head of the selection, which is moved when it is extended
    (for example by moving the cursor while holding Shift).
    */
    readonly head: number;
    /**
    The goal column (stored vertical offset) associated with a
    selection. This is used to preserve the vertical position when
    moving across lines of different length.
    */
    readonly goalColumn?: number | undefined;
    protected constructor(
    /**
    The anchor of the selection—the side that doesn't move when
    you extend it.
    */
    anchor: number, 
    /**
    The head of the selection, which is moved when it is extended
    (for example by moving the cursor while holding Shift).
    */
    head: number, 
    /**
    The goal column (stored vertical offset) associated with a
    selection. This is used to preserve the vertical position when
    moving across lines of different length.
    */
    goalColumn?: number | undefined);
    /**
    The lower boundary of the selected range.
    */
    get from(): number;
    /**
    The upper boundary of the range.
    */
    get to(): number;
    /**
    True when `anchor` and `head` are at the same position.
    */
    get empty(): boolean;
    /**
    Returns true when this is an empty text selection.
    */
    get isCursor(): boolean;
    /**
    The set of ranges covered by this selection, sorted. By default,
    this is just the selection's main `from` to `to`, but custom
    selection implementations can override it.
    */
    get ranges(): readonly {
        from: number;
        to: number;
    }[];
    /**
    The range that should be used when replacing this selection with
    other content (for example when typing or pasting over it) or
    deleting it. The default implementation returns `this.from` to
    `this.to`.
    */
    get replacementRange(): {
        from: number;
        to: number;
    };
    /**
    This can be overridden to control the DOM selection created for
    a selection. The default is to just return the selection's own
    head and anchor.
    */
    get domSelection(): {
        head: number;
        headSide: -1 | 1;
        anchor: number;
        anchorSide: -1 | 1;
    };
    /**
    The side that the selection head is associated with. -1 means it
    is after the element before its position, 1 means it is before
    the element after its position. This influences where the
    cursor is drawn (for example when on a line wrapping boundary
    or in bidirectional text) and where further motion takes it. It
    is valid for it to point in a direction where the is no element
    (say, -1 when at the start of its parent node).
    
    By default, this points in the direction of the anchor or
    forward if that is equal to the head, but selection types like
    {@link GardSelection.Text} can override it.
    */
    get headSide(): -1 | 1;
    /**
    The {@link GardSelection.headSide side} associated with the
    selection anchor. Also by default points towards the head, or if
    that is the same position, forward.
    */
    get anchorSide(): -1 | 1;
    /**
    Compare this selection to another selection.
    */
    abstract eq(other: GardSelection): boolean;
    /**
    Returns true if this selection has the same head and anchor as
    the given selection.
    */
    eqPos(other: GardSelection): boolean;
    /**
    Map a selection through a change. Used to adjust the selection
    position for changes.
    */
    abstract map(change: ChangeSet, cx: GardSelection.Context, assoc?: -1 | 1): GardSelection;
    /**
    Convert this selection to an object that can be serialized to
    JSON. Each selection type may define its own JSON representation
    format.
    */
    toJSON(state: GardState): unknown;
    /**
    Deserialize a selection. The configuration is used to associate
    custom selection types with their implementation.
    */
    static fromJSON(cx: GardSelection.Context, json: unknown): GardSelection;
    /**
    Create a cursor text selection at the given position.
    */
    static cursor(pos: number, side?: -1 | 1, goalColumn?: number): GardSelection.Text;
    /**
    Create a text selection.
    */
    static range(anchor: number, head?: number, headSide?: -1 | 1, goalColumn?: number): GardSelection.Text;
    /**
    Create a node selection.
    */
    static node(pos: number, node: Leaf, goalColumn?: number): GardSelection.Node;
    /**
    Find the next normal cursor position after or before this selection's
    head. Normal cursor positions are:
    
    - Any inline position, except one directly inside of an inline
      plot that doesn't have {@link Plot.Spec.cursorInsideBounds
      `cursorInsideBounds`} set.
    
    - Positions between two cursor barriers, if not already an
      inline position. Cursor barriers are the sides of the
      document, any block leaves, or plots that are {@link
      Plot.Spec.isolating isolating}, {@link
      Plot.Spec.preserveWhitespace whitespace-preserving}, or
      explicitly defined as a {@link Plot.Spec.cursorBarrier
      cursor barrier}.
    */
    nextNormalCursor(cx: GardSelection.Context, forward?: boolean): GardSelection.Text | null;
    /**
    Get a normal cursor at the start or end of this selection.
    */
    normalCursorAtBound(cx: GardSelection.Context, forward?: boolean): GardSelection.Text | null;
    /**
    Move across one word starting from this selection's head.
    */
    skipWord(cx: GardSelection.Context, forward?: boolean): GardSelection.Text | null;
    /**
    Find a normal selection near the given position.
    */
    static near(cx: GardSelection.Context, pos: number, bias?: -1 | 1): GardSelection.Text;
    /**
    Find a normal selection at the start of the document or the
    given textblock.
    */
    static atStart(cx: GardSelection.Context, block?: Pos.Plot): GardSelection.Text;
    /**
    Find a normal selection at the end of the document or the given
    textblock.
    */
    static atEnd(cx: GardSelection.Context, block?: Pos.Plot): GardSelection.Text;
}
declare namespace GardSelection {
    /**
    Create an extension that registers a custom selection type using
    the given class. Such a selection is only valid in a state that
    has the extension active. The JSON representation of a selection
    will be tagged with the `tag` string, and created and read via
    the functions passed here.
    */
    function define<T extends GardSelection, JSON extends object>(tag: string, cls: {
        new (...args: any[]): T;
    }, toJSON: (sel: T) => JSON, fromJSON: (doc: Plot.Doc, json: JSON) => T): any;
    /**
    Text selections hold a single arbitrary range in the document.
    They represent a cursor when their anchor and head are the same
    position.
    */
    class Text extends GardSelection {
        private _headSide;
        /**
        A set of active marks that should be applied to content
        inserted at this selection (replacing the contextual marks).
        Used mostly for making the effect of toggling inline styles
        stick until something is inserted. Marks that aren't valid for
        the inserted content will be ignored.
        */
        readonly marks: Mark.Set | undefined;
        private constructor();
        get headSide(): 1 | -1;
        get anchorSide(): 1 | -1;
        /**
        Create a text selection.
        */
        static create(spec: GardSelection.Text.Spec): Text;
        map(change: ChangeSet, cx: GardSelection.Context, assoc?: -1 | 1): GardSelection;
        eq(other: GardSelection): boolean;
    }
    namespace Text {
        /**
        Description of a text selection.
        */
        type Spec = {
            /**
            The anchor point of the selection. This is the side that doesn't
            move when extending the selection (for example by moving the
            cursor while holding shift).
            */
            anchor: number;
            /**
            The moving side of the selection. This will default to `anchor`
            when not given.
            */
            head?: number;
            /**
            The side of the head position that the selection is associated
            with, if any. `-1` points at the element before the position,
            `1` at the element after. This is only meaningful for
            empty/cursor selections. It will influence where the cursor is
            drawn.
            */
            headSide?: -1 | 1;
            /**
            Associates a horizontal position with this selection for use
            during vertical cursor motion.
            */
            goalColumn?: number;
            /**
            Marks associated with a cursor selection, which will determine
            the marks of inline content inserted at that selection. This is
            used for things like toggling emphasis on a cursor selection.
            */
            marks?: Mark.Set;
        };
        /**
        The representation of a text selection when serialized to JSON.
        */
        type JSON = {
            anchor: number;
            head?: number;
            side?: -1 | 1;
            marks?: Record<string, any>;
        };
    }
    /**
    Node selections select a single node. They are created, for
    example, when clicking on or moving into a {@link
    doc.Leaf.Spec.selectable selectable} leaf node. Use {@link
    GardSelection.node} to create one.
    */
    class Node extends GardSelection {
        /**
        The selected leaf node.
        */
        readonly node: Leaf;
        private constructor();
        map(change: ChangeSet, cx: GardSelection.Context, assoc?: -1 | 1): Text | Node;
        eq(other: GardSelection): boolean;
    }
    namespace Node {
        /**
        The representation of a node selection when serialized to JSON.
        */
        type JSON = {
            pos: number;
        };
    }
    /**
    A selection object where the selection positions have been
    {@link Plot.Doc.resolve resolved}. For convenience, an editor
    state's {@link GardState.sel `sel` property} provides an
    instance of this, derived from the state's regular selection.
    */
    class Resolved {
        /**
        The original selection.
        */
        readonly selection: GardSelection;
        /**
        The selection anchor.
        */
        anchor: Pos;
        /**
        The head of the selection.
        */
        head: Pos;
        private _ranges;
        private constructor();
        /**
        The lower bound of the selection.
        */
        get from(): Pos;
        /**
        The upper bound of the selection.
        */
        get to(): Pos;
        /**
        The selection ranges.
        */
        get ranges(): readonly {
            from: Pos;
            to: Pos;
        }[];
        private resolveRanges;
        /**
        The resolved replacement range.
        */
        get replacementRange(): {
            from: Pos;
            to: Pos;
        };
        /**
        The active marks for this selection. If this is a cursor
        selection with explicitly stored {@link
        GardSelection.Text.Spec.marks marks}, those are returned.
        Otherwise, this computes the marks that should be applied to
        content inserted in the selection's position, based on
        spanning marks on the surrounding nodes.
        */
        get activeMarks(): Mark.Set;
    }
    /**
    Many selection related functions need access to a configuration
    (to determine text direction and visual motion behavior) and a
    document. Note that {@link GardState} is a subtype of this.
    */
    type Context = {
        doc: Plot.Doc;
        config: GardState.Configuration;
    };
}

/**
Changes to the editor state are grouped into transactions.
Typically, a user action creates a single transaction, which may
contain any number of document changes, may change the selection,
or have other {@link Transaction.Effect effects}. Create a
transaction by calling {@link GardState.update}, or immediately
dispatch one by calling {@link editor.Wordgard.dispatch
`Wordgard.dispatch`}.
*/
declare class Transaction {
    /**
    The state from which this transaction starts.
    */
    readonly startState: GardState;
    /**
    The document changes made by this transaction.
    */
    readonly changes: ChangeSet;
    /**
    The selection set by this transaction, or undefined if it
    doesn't explicitly set a selection.
    */
    readonly selection: GardSelection | undefined;
    /**
    The effects contained in this transaction.
    */
    readonly effects: readonly Transaction.Effect<any>[];
    /**
    Whether the selection should be scrolled into view after this
    transaction is dispatched.
    */
    readonly scrollIntoView: boolean;
    private constructor();
    /**
    The new selection produced by the transaction. If {@link
    Transaction.selection `this.selection`} is undefined, this will
    {@link GardSelection.map map} the start state's current
    selection through the changes made by the transaction.
    */
    newSelection: GardSelection;
    /**
    The new document produced by the transaction. Contrary to
    {@link Transaction.state `.state`}`.doc`, accessing this won't
    force the entire new state to be computed right away, so it is
    recommended that {@link Transaction.extender transaction
    extenders} use this property when they need to look at the new
    document.
    */
    newDoc: Plot.Doc;
    /**
    The new state created by the transaction. Lazily computed so
    that the state is resolved the first time this property is
    accessed.
    */
    get state(): GardState;
    /**
    Get the value of the given transaction {@link
    Transaction.Annotation annotation} type, if any.
    */
    annotation<T>(type: Transaction.Annotation.Type<T>): T | undefined;
    /**
    Indicates whether the transaction changed the document.
    */
    get docChanged(): boolean;
    /**
    Indicates whether this transaction reconfigures the state
    (through a {@link GardState.Compartment configuration
    compartment}, {@link GardState.reconfigure reconfiguration}, or
    {@link GardState.appendConfig appended configuration}).
    */
    get reconfigured(): boolean;
    /**
    Returns true if the transaction has a {@link
    Transaction.userEvent user event} annotation that is equal to or
    more specific than `event`. For example, if the transaction has
    `"select.pointer"` as user event, `"select"` and
    `"select.pointer"` will match it.
    */
    isUserEvent(event: string): boolean;
}
declare namespace Transaction {
    /**
    Describes a {@link Transaction transaction} when calling {@link
    GardState.update `GardState.update`} or {@link Wordgard.dispatch
    `Wordgard.dispatch`}.
    */
    interface Spec {
        /**
        The changes to the document made by this transaction.
        */
        changes?: ChangeSet.Spec;
        /**
        When set, this transaction explicitly updates the selection.
        Offsets in this selection should refer to the document as it
        is _after_ the transaction. If a selection can only be
        computed after the new document is available, you can pass a
        function here.
        */
        selection?: GardSelection | GardSelection.Text.Spec | ((cx: GardSelection.Context, changes: ChangeSet) => GardSelection | null);
        /**
        Attach {@link Transaction.Effect effects} to this transaction.
        Again, when they contain positions and this same spec makes
        changes, those positions should refer to positions in the
        updated document.
        */
        effects?: Transaction.Effect<any> | readonly Transaction.Effect<any>[];
        /**
        Set {@link Transaction.Annotation annotations} for this
        transaction.
        */
        annotations?: Transaction.Annotation<any> | readonly Transaction.Annotation<any>[];
        /**
        Shorthand for `annotations: `{@link Transaction.userEvent `Transaction.userEvent`}`.of(...)`.
        */
        userEvent?: string;
        /**
        When set to `true`, the transaction is marked as needing to
        scroll the current selection into view.
        */
        scrollIntoView?: boolean;
        /**
        Only meaningful for specs that are combined with another
        transaction spec (via {@link Transaction.merge or by being
        returned from an {@link Transaction.extender extender}.
        Normally, when specs are combined, the positions in `changes`
        are taken to refer to the document positions in the initial
        document. When a spec has `sequental` set to true, its
        positions will be taken to refer to the document created by
        the changes in the spec before it.
        */
        sequential?: boolean;
    }
    /**
    Merge two transaction specs into a single one, combining the
    effect of both.
    */
    function merge(state: GardState, a: Transaction.Spec, b: Transaction.Spec): Transaction.Spec;
    /**
    Facet used to register a hook that gets a chance to add to
    transactions before they are applied. If such a function returns
    a transaction spec, it will be combined with the original
    transaction (in the same way as the arguments to
    {@link GardState.update}).
    
    When possible, it is recommended to avoid accessing {@link
    Transaction.state} in an extender, since it will force creation
    of a state that will then be discarded again, if the transaction
    is actually extended.
    
    (This functionality should be used with care. Indiscriminately
    modifying transaction is likely to break something or degrade
    the user experience.)
    */
    let extender: GardState.Facet<(tr: Transaction) => Transaction.Spec | null>;
    /**
    A transaction appender can create more transactions in response
    to a transaction. {@link Transaction.append}, which is
    called by the {@link Wordgard editor} when dispatching a
    transaction, will call appenders on sets of transactions,
    allowing them to add another transaction. When another appender
    adds a transaction, extenders that already ran will be called
    again, but only with the transactions that were added after they
    ran.
    */
    let appender: GardState.Facet<(trs: readonly Transaction[], state: GardState) => Transaction.Spec | null>;
    /**
    Apply {@link Transaction.appender transaction appenders}, return
    an array of the original transaction plus any that were appended.
    */
    function append(tr: Transaction): readonly Transaction[];
    /**
    Annotations are tagged values that are used to add metadata to
    transactions in an extensible way. They should be used to model
    things that effect the entire transaction (such as its {@link
    Transaction.time time stamp} or information about its {@link
    Transaction.userEvent origin}). For effects that happen
    _alongside_ the other changes made by the transaction, {@link
    Transaction.Effect effects} are more appropriate.
    */
    class Annotation<T> {
        /**
        The annotation type.
        */
        readonly type: Transaction.Annotation.Type<T>;
        /**
        The value of this annotation.
        */
        readonly value: T;
        /**
        Define a new type of annotation.
        */
        static define<T>(): Annotation.Type<T>;
        private _isAnnotation;
    }
    namespace Annotation {
        /**
        Marker that identifies a type of {@link Transaction.Annotation
        annotation}.
        */
        class Type<T> {
            /**
            Create an instance of this annotation.
            */
            of(value: T): Transaction.Annotation<T>;
        }
    }
    const foo: number;
    /**
    Annotation used to store transaction timestamps. Automatically
    added to every transaction, holding `Date.now()`.
    */
    const time: Annotation.Type<number>;
    /**
    Annotation used to associate a transaction with a user interface
    event. Holds a string identifying the event, using a
    dot-separated format to support attaching more specific
    information. The events used by the core libraries are:
    
     - `"input"` when content is entered
       - `"input.type"` for typed input
         - `"input.type.compose"` for composition
       - `"input.paste"` for pasted input
       - `"input.drop"` when adding content with drag-and-drop
     - `"delete"` when the user deletes content
       - `"delete.selection"` when deleting the selection
       - `"delete.forward"` when deleting forward from the selection
       - `"delete.backward"` when deleting backward from the selection
       - `"delete.cut"` when cutting to the clipboard
     - `"move"` when content is moved
       - `"move.drop"` when content is moved within the editor
         through drag-and-drop
     - `"select"` when explicitly changing the selection
       - `"select.pointer"` when selecting with a mouse or other pointing
         device
       - `"select.all"` when selecting the entire document
     - `"undo"` and `"redo"` for history actions
     - `"insert"` for actions that insert nodes
     - `"mark"` for actions that manipulate marks
       - `"mark.add"` when a command adds a mark
       - `"mark.remove"` when a command removes one
     - `"split"`, `"wrap"`, `"settype"`, `"wrap"`, `"unwrap"` for
       block manipulation actions
    
    Use {@link Transaction.isUserEvent `isUserEvent`} to check
    whether the annotation matches a given event.
    */
    const userEvent: Annotation.Type<string>;
    /**
    Annotation indicating whether a transaction should be added to
    the undo history or not.
    */
    const addToHistory: Annotation.Type<boolean>;
    /**
    Annotation indicating (when present and true) that a transaction
    represents a change made by some other actor, not the user. This
    is used, for example, to tag other people's changes in
    collaborative editing.
    */
    const remote: Annotation.Type<boolean>;
    /**
    A flag set on transactions created by a {@link
    Transaction.appender transaction appender}.
    */
    const appended: Annotation.Type<boolean>;
    /**
    Transaction effects can be used to represent additional effects
    associated with a {@link Transaction.effects transaction}. They
    are often useful to model changes to custom {@link
    GardState.Field state fields}, when those changes aren't
    implicit in document or selection changes.
    */
    class Effect<Value> {
        /**
        The value of this effect.
        */
        readonly value: Value;
        /**
        Map this effect through a position mapping. Will return
        `undefined` when the changes deleted the effect.
        */
        map(mapping: ChangeSet): Transaction.Effect<Value> | undefined;
        /**
        Tells you whether this effect object is of a given
        {@link Transaction.Effect.Type type}.
        */
        is<T>(type: Transaction.Effect.Type<T>): this is Transaction.Effect<T>;
        /**
        Define a new effect type. The type parameter indicates the
        type of values that his effect holds. It should be a type that
        doesn't include `undefined`, since that is used in {@link
        Transaction.Effect.map mapping} to indicate that an effect is
        removed.
        */
        static define<Value = null>(spec?: Transaction.Effect.Spec<Value>): Transaction.Effect.Type<Value>;
    }
    namespace Effect {
        /**
        Map an array of effects through a change set.
        */
        function mapEffects(effects: readonly Transaction.Effect<any>[], mapping: ChangeSet): readonly Effect<any>[];
        /**
        A type of state effect. Defined with {@link
        Transaction.Effect.define}.
        */
        class Type<Value> {
            /**
            @internal
            */
            readonly map: (value: any, mapping: ChangeSet) => any | undefined;
            /**
            Create an {@link Transaction.Effect effect} instance of this
            type.
            */
            of(value: Value): Transaction.Effect<Value>;
        }
        /**
        Options passed when defining an effect.
        */
        interface Spec<Value> {
            /**
            Provides a way to map an effect like this through a position
            mapping. When not given, the effects will simply not be mapped.
            When the function returns `undefined`, that means the mapping
            deletes the effect.
            */
            map?: (value: Value, mapping: ChangeSet) => Value | undefined;
        }
    }
}

/**
Represents a contiguous range of text that has a single direction
(as in left-to-right or right-to-left).
*/
declare class BidiSpan {
    /**
    The start of the span (relative to the start of the line).
    */
    readonly from: number;
    /**
    The end of the span.
    */
    readonly to: number;
    /**
    The ["bidi
    level"](https://unicode.org/reports/tr9/#Basic_Display_Algorithm)
    of the span. 0 means left-to-right, 1 means right-to-left, 2
    means left-to-right embedded inside right-to-left, and so on,
    with even numbers being left-to-right, odd numbers
    right-to-left..
    */
    readonly level: number;
    /**
    The direction of this span.
    */
    get ltr(): boolean;
    /**
    Query whether the given character has a strong direction.
    Returns null when not, true when left-to-right, and false when
    right-to-left.
    */
    static strongDir(ch: number): boolean | null;
}

/**
A textblock map contains the text in a textblock as a string, and
can help convert between string offsets and document positions.

Note that this is not the way to convert a piece of document to a
string. Use {@link doc.Plot.textContent} for that.
*/
declare class TextblockMap {
    /**
    The start position of the textblock content.
    */
    readonly start: number;
    /**
    The textblock's document node.
    */
    readonly node: Plot;
    /**
    Whether the base direction of this block is left-to-right.
    */
    readonly ltr: boolean;
    /**
    The text in the block. Non-text leaf nodes and nodes with
    block content will be replaced by a single `0xfffc` character
    in this string.
    */
    readonly text: string;
    private _order;
    private sections;
    private constructor();
    /**
    The text order of the text in this block. Will generally be a
    single span, but if the block mixes left-to-right and
    right-to-left text, this describes the individual sections,
    ordered from the block's start to its end.
    */
    get order(): readonly BidiSpan[];
    /**
    Get the map for the given textblock. Will use a cache to reuse
    results for unchanged blocks.
    */
    static get(start: number, node: Plot, ltr: boolean): TextblockMap;
    private static create;
    /**
    Get the string index for a document position. Positions outside
    of the textblock will be clipped to its start or end.
    */
    toIndex(pos: number): number;
    /**
    Get the document position for a given string index.
    */
    fromIndex(index: number): number;
    /**
    Get the position at the start or end of the textblock. Note that
    in bidirectional text this may not be the actual start or end
    position of the node.
    */
    visualSide(start: boolean): {
        pos: number;
        side: -1 | 1;
    };
}

type DocSource = Plot.Doc | HTMLElement | DocumentFragment | string | Node.JSON | ((schema: Schema) => Plot.Doc);
/**
The editor state tracks things like the current document, the
selection, the configuration of the editor, and any extra state
defined by extensions.

The state is a persistent (immutable) data structure. To update a
state, you {@link GardState.update create} a {@link Transaction
transaction}, which produces a _new_ state instance, without
modifying the original object.
*/
declare class GardState {
    /**
    The configuration for this state.
    */
    readonly config: GardState.Configuration;
    private _doc;
    private _selection;
    private resolvedSel;
    private trackAccess;
    /**
    Create a new state. You'll usually only need this when
    initializing an editor or loading a new document—updated states
    are created by applying transactions.
    
    The schema of the state can be provided either via the {@link
    GardState.schemaElement configuration} or by passing in an
    initialized document (which will have its own schema). If the
    configuration contains a document plot type, the schema from the
    configuration will be used, even if a document was provided.
    */
    static create(spec: GardState.Spec): GardState;
    private constructor();
    /**
    The current document.
    */
    get doc(): Plot.Doc;
    /**
    The document's schema.
    */
    get schema(): Schema;
    /**
    The current selection.
    */
    get selection(): GardSelection;
    /**
    A resolved form of the state's selection. Instead of raw
    positions, this object holds {@link Pos document position}
    objects for `head`, `anchor`, `from`, and `to`.
    */
    get sel(): GardSelection.Resolved;
    /**
    Retrieve the value of a {@link GardState.Field state field}.
    Throws an error when the state doesn't have that field, unless
    you pass `false` as second parameter.
    */
    field<T>(field: GardState.Field<T>): T;
    field<T>(field: GardState.Field<T>, require: false): T | undefined;
    /**
    Get the value of a state {@link GardState.Facet facet}.
    */
    facet<Output>(facet: GardState.Facet.Reader<Output>): Output;
    /**
    Create a {@link Transaction transaction} that updates this
    state.
    */
    update(spec: Transaction.Spec): Transaction;
    /**
    Compute the textblock map for the given plot (which should be a
    textblock).
    */
    textblockMap(node: Pos.Plot): TextblockMap;
    /**
    Convert this state to a JSON-serializable object. When custom
    fields should be serialized, you can pass them in as an object
    mapping property names (in the resulting object, which should
    not use `doc` or `selection`) to fields.
    */
    toJSON(fields?: {
        [prop: string]: GardState.Field<any>;
    }): any;
    /**
    Deserialize a state from its JSON representation. When custom
    fields should be deserialized, pass the same object you passed
    to {@link GardState.toJSON `toJSON`} when serializing as third
    argument.
    */
    static fromJSON(json: any, extensions: GardState.Extension, fields?: {
        [prop: string]: GardState.Field<any>;
    }): GardState;
    /**
    Returns true when the editor is {@link GardState.readOnly} to be
    read-only.
    */
    get readOnly(): boolean;
    /**
    Get the global text direction (true when left-to-right, false
    when right-to-left) for the document. Note that the direction of
    individual blocks can be overridden with {@link
    GardState.textblockLTR}.
    */
    get textLTR(): boolean;
    /**
    Return the text direction in a given textblock (by tag).
    */
    textblockLTR(plot: Plot): boolean;
    /**
    Return the extent of the word around the given position, as a
    text selection.
    */
    wordAt(pos: number, bias?: -1 | 1): GardSelection.Text;
    /**
    This effect can be used to reconfigure the root extensions of
    the editor. Doing this will discard any extensions {@link
    GardState.appendConfig appended}, but does not reset the
    content of {@link GardState.Compartment.reconfigure
    reconfigured} compartments.
    */
    static reconfigure: Transaction.Effect.Type<GardState.Extension>;
    /**
    Append extensions to the top-level configuration of the editor.
    */
    static appendConfig: Transaction.Effect.Type<GardState.Extension>;
}
declare namespace GardState {
    /**
    Options passed when {@link GardState.create creating} an editor
    state.
    */
    interface Spec {
        /**
        The initial document. When passing in a {@link Plot.Doc
        document node} here, it is not necessary to include a schema
        in your configuration (though it is allowed, and the document
        content will be moved into that schema if it differs from the
        one on the given document).
        
        All other forms require a schema from the configuration. A
        string or DOM structure will be parsed as HTML. Passing a
        string only works in the browser, where the library can use
        the browser's HTML parser. In other environments, you'll need
        to do the parsing yourself (for example with
        [jsdom](https://jsdom.org/)). A JSON node deserialized, and a
        function called to produce the document.
        */
        doc?: DocSource;
        /**
        The starting selection. Defaults to a cursor at the start of the
        document.
        */
        selection?: GardSelection | GardSelection.Text.Spec | ((cx: GardSelection.Context) => GardSelection);
        /**
        The configuration for this state, either as a resolved {@link
        GardState.Configuration} or as a set of extensions.
        */
        config?: GardState.Extension | GardState.Configuration;
    }
    /**
    Fields can store additional information in an editor state, and
    keep it in sync with the rest of the state. The type parameter
    indicates the type of value stored in the field.
    */
    class Field<Value> {
        private createF;
        private updateF;
        private compareF;
        private constructor();
        /**
        Define a state field.
        */
        static define<Value>(config: GardState.Field.Spec<Value>): GardState.Field<Value>;
        private create;
        /**
        State field instances can be used as {@link
        GardState.Extension `Extension`} values to enable the field in
        a given state.
        */
        get extension(): GardState.Extension;
        /**
        Returns an extension that enables this field and overrides the
        way it is initialized. Can be useful when you need to provide a
        non-default starting value for the field.
        */
        init(create: (state: GardState) => Value): GardState.Extension;
    }
    namespace Field {
        /**
        The options passed when defining a state field.
        */
        type Spec<Value> = {
            /**
            Creates the initial value for the field when a state is created.
            */
            create: (state: GardState) => Value;
            /**
            Compute a new value from the field's previous value and a
            {@link Transaction transaction}. Should not mutate the old
            value (since that will change the existing state), but
            create a fresh one or return the old value unchanged.
            */
            update: (value: Value, transaction: Transaction) => Value;
            /**
            Compare two values of the field, returning `true` when they are
            the same. This is used to avoid recomputing facets that depend
            on the field when its value did not change. Defaults to using
            `===`.
            */
            compare?: (a: Value, b: Value) => boolean;
            /**
            Provide extensions based on this field. The given function
            will be called once with the initialized field. It is
            typically used with a facet's {@link GardState.Facet.from}
            method to create facet inputs from this field, but can also
            return other extensions that should be enabled when the
            field is present in a configuration.
            */
            provide?: (field: GardState.Field<Value>) => GardState.Extension;
            /**
            A function used to serialize this field's content to JSON. Only
            necessary when this field is included in the argument to
            {@link GardState.toJSON}.
            */
            toJSON?: (value: Value, state: GardState) => any;
            /**
            A function that deserializes the JSON representation of this
            field's content.
            */
            fromJSON?: (json: any, state: GardState) => Value;
        };
    }
    /**
    A facet is a labeled value that is associated with an editor
    state. It takes inputs from any number of extensions, and combines
    those into a single output value.
    
    Examples of uses of facets are the {@link GardState.readOnly
    read-only configuration}, {@link
    editor.Wordgard.editorAttributes editor attributes}, and {@link
    editor.Wordgard.updateListener update listeners}.
    
    Note that `Facet` instances can be used anywhere where {@link
    GardState.Facet.Reader} is expected.
    
    Facets have an input type (the type of values provided for it),
    and an output type (the type you get when you read the facet)
    that defaults to an array of input values, but can be anything
    if a {@link GardState.Facet.Spec.combine}
    option is provided.
    */
    class Facet<Input, Output = readonly Input[]> implements GardState.Facet.Reader<Output> {
        /**
        True when this is a static facet.
        */
        readonly isStatic: boolean;
        /**
        The output of the facet when it has no inputs.
        */
        readonly default: Output;
        private constructor();
        /**
        A facet reader for this facet, which can be used to {@link
        GardState.facet read} it but not to define values for it.
        */
        get reader(): GardState.Facet.Reader<Output>;
        /**
        Defines a facet with the given input an output types.
        */
        static define<Input, Output = readonly Input[]>(config?: GardState.Facet.Spec<Input, Output>): Facet<Input, Output>;
        /**
        Returns an extension that provides the given value to this
        facet.
        */
        of(value: Input): GardState.Extension;
        /**
        Create an extension that computes a value for the facet from a
        state. The given function should only depend on the state, not
        any external non-constant inputs. Its return value will be kept
        on state update, unless any of the fields or facets (including
        document and selection) that it read are changed by the update,
        in which case it is called again.
        
        In cases where your value depends only on a single field, you
        can use the {@link GardState.Facet.from `from`} method
        instead.
        */
        compute(get: (state: GardState) => Input): GardState.Extension;
        /**
        Create an extension that computes zero or more values for this
        facet from a state.
        */
        computeN(get: (state: GardState) => readonly Input[]): GardState.Extension;
        /**
        Shorthand method for registering a facet source with a state
        field as input. If the field's type corresponds to this facet's
        input type, the getter function can be omitted. If given, it
        will be used to produce the input from the field value.
        */
        from<T extends Input>(field: GardState.Field<T>): GardState.Extension;
        from<T>(field: GardState.Field<T>, get: (value: T) => Input): GardState.Extension;
        tag: Output;
    }
    namespace Facet {
        /**
        Options passed when {@link GardState.Facet.define defining} a
        facet.
        */
        type Spec<Input, Output> = {
            /**
            How to combine the input values into a single output value. When
            not given, the array of input values becomes the output. This
            function will immediately be called on creating the facet, with
            an empty array, to compute the facet's default value when no
            inputs are present.
            */
            combine?: (value: readonly Input[]) => Output;
            /**
            How to compare output values to determine whether the value
            of the facet changed. When a new value for the facet is
            computed that that compares as equal to the old value, the
            old value is kept. So in most circumstances, facet values
            can be cheaply compared by identity to check for changes.
            Defaults to comparing by `===` or, if no `combine` function
            was given, comparing each element of the array with `===`.
            */
            compare?: (a: Output, b: Output) => boolean;
            /**
            How to compare input values to avoid recomputing the output
            value when no inputs changed. Defaults to comparing with `===`.
            */
            compareInput?: (a: Input, b: Input) => boolean;
            /**
            Forbids dynamic inputs to this facet. Allows the facet to be
            {@link GardState.Configuration.staticFacet read} from a
            configuration.
            */
            static?: boolean;
            /**
            If given, these extensions (or the result of calling the
            given function with the facet) will be added to any state
            where this facet is provided. (Note that, while a facet's
            {@link GardState.Facet.default default} value can be read
            from a state even if the facet wasn't present in the state
            at all, the extensions won't be added in that situation.)
            */
            enables?: GardState.Extension | ((self: GardState.Facet<Input, Output>) => GardState.Extension);
        };
        /**
        A facet reader can be used to fetch the value of a facet,
        through {@link GardState.facet} or as a dependency in {@link
        GardState.Facet.compute `Facet.compute`}, but not to define
        new values for the facet.
        */
        type Reader<Output> = {
            /**
            @hidden
            */
            tag: Output;
        };
        /**
        Utility function for combining multiple configuration objects.
        `defaults` should hold default values for all optional fields
        in `Config`.
        
        The function will, by default, raise an error when a field
        gets two values that aren't `===`-equal, but you can provide
        combine functions per field to do something else.
        */
        function combineConfig<Config extends object>(configs: readonly Partial<Config>[], defaults: Partial<Config>, // Should hold only the optional properties of Config, but I haven't managed to express that
        combine?: {
            [P in keyof Config]?: (first: Config[P], second: Config[P]) => Config[P];
        }): Config;
    }
    /**
    A state configuration stores a set of extensions, structured so
    that state updates can be performed efficiently.
    */
    class Configuration {
        /**
        The set of extensions that this configuration is based on.
        */
        readonly base: GardState.Extension;
        private constructor();
        /**
        Read the value of a static facet.
        */
        staticFacet<Output>(facet: GardState.Facet<any, Output>): Output;
        /**
        Create a configuration from the given set of extensions.
        */
        static create(extensions: GardState.Extension): Configuration;
        /**
        Get the schema defined by this configuration. Will be null if
        the schema does not contain a document plot type.
        */
        get schema(): Schema | null;
    }
    /**
    Extension values can be {@link GardState.Spec.config provided}
    when creating a state to attach various kinds of configuration
    and behavior information. They can either be built-in
    extension-providing objects, such as {@link GardState.Field
    state fields} or {@link GardState.Facet.of facet providers}, or
    objects with an extension in its `extension` property.
    Extensions can be nested in arrays arbitrarily deep—they will be
    flattened when resolved into a configuration.
    */
    type Extension = {
        extension: GardState.Extension;
    } | readonly GardState.Extension[];
    /**
    By default extensions are registered in the order they are found
    in the flattened form of the configuration's extension tree.
    Individual extension values can be assigned a precedence to
    override this. Extensions that do not have a precedence set get
    the precedence of the nearest parent with a precedence, or
    {@link GardState.prec.default `default`} if there is no such
    parent. The final ordering of extensions is determined by first
    sorting by precedence and then by order within each precedence.
    */
    const prec: {
        /**
        The highest precedence level, for extensions that should end up
        near the start of the precedence ordering.
        */
        highest: (ext: GardState.Extension) => GardState.Extension;
        /**
        A higher-than-default precedence, for extensions that should
        come before those with default precedence.
        */
        high: (ext: GardState.Extension) => GardState.Extension;
        /**
        The default precedence, which is also used for extensions
        without an explicit precedence.
        */
        default: (ext: GardState.Extension) => GardState.Extension;
        /**
        A lower-than-default precedence.
        */
        low: (ext: GardState.Extension) => GardState.Extension;
        /**
        The lowest precedence level. Meant for things that should end up
        near the end of the extension order.
        */
        lowest: (ext: GardState.Extension) => GardState.Extension;
    };
    /**
    Extension compartments can be used to make a configuration
    dynamic. By {@link GardState.Compartment.of wrapping} part of your
    configuration in a compartment, you can later {@link
    GardState.Compartment.reconfigure replace} that part through a
    transaction.
    */
    class Compartment {
        private constructor();
        /**
        Define a new compartment.
        */
        static define(): Compartment;
        /**
        Create an instance of this compartment to add to your {@link
        GardState.Spec.config state configuration}.
        */
        of(ext: GardState.Extension): GardState.Extension;
        /**
        Create an {@link Transaction.Spec.effects effect} that
        reconfigures this compartment.
        */
        reconfigure(content: GardState.Extension): Transaction.Effect<unknown>;
        /**
        Get the current content of the compartment in the state, or
        `undefined` if it isn't present.
        */
        get(state: GardState): GardState.Extension | undefined;
    }
    /**
    Facet used to register {@link Schema schema} elements. *If*
    a configuration contains a {@link Plot.defineDoc document}
    type, the editor's document schema will be derived from the
    content of this facet. (Otherwise, the state will try to use the
    schema provided via the {@link GardState.Spec.doc} option, or
    raise an error is none is provided.)
    */
    const schemaElement: Facet<Schema.Element | readonly Schema.Element[], readonly Schema.Element[]>;
    /**
    This facet controls the value of the {@link GardState.readOnly
    `readOnly` getter}, which is consulted by commands and
    extensions that implement editing functionality to determine
    whether they should apply. It defaults to false, but when its
    highest-precedence value is `true`, the state is considered
    read-only, and such functions won't change the document.
    
    Not to be confused with {@link editor.Wordgard.editable}, which
    controls whether the editor's DOM is set to be editable (and
    thus focusable).
    */
    const readOnly: Facet<boolean, boolean>;
    /**
    Facet that indicates the document's default text direction. Note
    that this will not affect the editor CSS, and when the state's
    value disagrees with the direction set in the editor, the editor
    component will automatically inject an instance of this with a
    high precedence to align the state to the DOM. Still, if you
    know the direction in advance, it can be useful to set this, so
    that the direction is already accurate during initialization.
    Defaults to true.
    */
    const textLTR: Facet<boolean, boolean>;
    /**
    Configure the text direction per textblock. All values given for
    this will be consulted in order of precedence, until one returns
    a non-null value. If none set a direction, the editor's {@link
    GardState.textLTR base direction} is used.
    
    Schema elements like {@link schema.direction} register an
    instance of this to make the editor aware of the meaning of the
    {@link types.Direction} mark.
    */
    const textblockLTR: Facet<(plot: Plot) => boolean | null, readonly ((plot: Plot) => boolean | null)[]>;
    /**
    Configure whether to use visual or logical cursor motion in
    bidirectional text. The default is visual, where pressing
    left/right arrow keys moves the cursor in the direction that
    corresponds to the arrow on key. When disabled, the motion uses
    the string index order instead.
    */
    const visualCursorMotion: Facet<boolean, boolean>;
}

/**
The class representing a correction. Counts as an editor
extension.
*/
declare class Correction {
    /**
    To take effect, corrections must be included in an editor
    configuration.
    */
    extension: GardState.Extension;
    private constructor();
    /**
    This method can be used to run a correction agains all matching
    nodes in an existing document. If the correction makes any
    changes, the method returns a transaction with those changes.
    */
    scan(state: GardState): Transaction | null;
    /**
    Create a correction that runs whenever the child list of a node
    that matches the given query changes, or such a node is inserted
    into the document.
    */
    static onChildList(query: Node.Query, correct: (node: Pos.Plot, state: GardState) => ChangeSet.Spec | null): Correction;
    /**
    Create a correction that runs whenever any content inside a node
    that matches the given query changes, or such a node is inserted
    into the document.
    */
    static onContent(query: Node.Query, correct: (node: Pos.Plot, state: GardState) => ChangeSet.Spec | null): Correction;
    /**
    Define a correction that runs whenever the set of marks on a
    matching tag changes.
    */
    static onMarks(query: Node.Query, correct: (node: Pos.Node, state: GardState) => ChangeSet.Spec | null): Correction;
}

export { BidiSpan, Correction, GardSelection, GardState, TextblockMap, Transaction };
