| 
							
								 | 
							
							import OrderedMap from 'orderedmap';
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							function findDiffStart(a, b, pos) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let i = 0;; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (i == a.childCount || i == b.childCount)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return a.childCount == b.childCount ? null : pos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let childA = a.child(i), childB = b.child(i);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (childA == childB) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            pos += childA.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            continue;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!childA.sameMarkup(childB))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return pos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (childA.isText && childA.text != childB.text) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let j = 0; childA.text[j] == childB.text[j]; j++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                pos++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return pos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (childA.content.size || childB.content.size) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let inner = findDiffStart(childA.content, childB.content, pos + 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (inner != null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return inner;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        pos += childA.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function findDiffEnd(a, b, posA, posB) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let iA = a.childCount, iB = b.childCount;;) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (iA == 0 || iB == 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return iA == iB ? null : { a: posA, b: posB };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let childA = a.child(--iA), childB = b.child(--iB), size = childA.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (childA == childB) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            posA -= size;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            posB -= size;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            continue;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!childA.sameMarkup(childB))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return { a: posA, b: posB };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (childA.isText && childA.text != childB.text) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let same = 0, minSize = Math.min(childA.text.length, childB.text.length);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                same++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                posA--;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                posB--;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return { a: posA, b: posB };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (childA.content.size || childB.content.size) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let inner = findDiffEnd(childA.content, childB.content, posA - 1, posB - 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (inner)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return inner;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        posA -= size;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        posB -= size;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							A fragment represents a node's collection of child nodes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							Like nodes, fragments are persistent data structures, and you
 | 
						
						
						
						
							 | 
							
								 | 
							
							should not mutate them or their content. Rather, you create new
 | 
						
						
						
						
							 | 
							
								 | 
							
							instances whenever needed. The API tries to make this easy.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class Fragment {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    content, size) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.content = content;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.size = size || 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (size == null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < content.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.size += content[i].nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Invoke a callback for all descendant nodes between the given two
 | 
						
						
						
						
							 | 
							
								 | 
							
							    positions (relative to start of this fragment). Doesn't descend
 | 
						
						
						
						
							 | 
							
								 | 
							
							    into a node when the callback returns `false`.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    nodesBetween(from, to, f, nodeStart = 0, parent) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0, pos = 0; pos < to; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let child = this.content[i], end = pos + child.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (end > from && f(child, nodeStart + pos, parent || null, i) !== false && child.content.size) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let start = pos + 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                child.nodesBetween(Math.max(0, from - start), Math.min(child.content.size, to - start), f, nodeStart + start);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            pos = end;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Call the given callback for every descendant node. `pos` will be
 | 
						
						
						
						
							 | 
							
								 | 
							
							    relative to the start of the fragment. The callback may return
 | 
						
						
						
						
							 | 
							
								 | 
							
							    `false` to prevent traversal of a given node's children.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    descendants(f) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.nodesBetween(0, this.size, f);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Extract the text between `from` and `to`. See the same method on
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [`Node`](https://prosemirror.net/docs/ref/#model.Node.textBetween).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    textBetween(from, to, blockSeparator, leafText) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let text = "", separated = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.nodesBetween(from, to, (node, pos) => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (node.isText) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                text += node.text.slice(Math.max(from, pos) - pos, to - pos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                separated = !blockSeparator;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (node.isLeaf) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (leafText) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    text += typeof leafText === "function" ? leafText(node) : leafText;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                else if (node.type.spec.leafText) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    text += node.type.spec.leafText(node);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                separated = !blockSeparator;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (!separated && node.isBlock) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                text += blockSeparator;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                separated = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }, 0);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return text;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a new fragment containing the combined content of this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    fragment and the other.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    append(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!other.size)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!this.size)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return other;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let last = this.lastChild, first = other.firstChild, content = this.content.slice(), i = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (last.isText && last.sameMarkup(first)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content[content.length - 1] = last.withText(last.text + first.text);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            i = 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (; i < other.content.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content.push(other.content[i]);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Fragment(content, this.size + other.size);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Cut out the sub-fragment between the two given positions.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    cut(from, to = this.size) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (from == 0 && to == this.size)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let result = [], size = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (to > from)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0, pos = 0; pos < to; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let child = this.content[i], end = pos + child.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (end > from) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (pos < from || end > to) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (child.isText)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            child = child.cut(Math.max(0, from - pos), Math.min(child.text.length, to - pos));
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        else
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            child = child.cut(Math.max(0, from - pos - 1), Math.min(child.content.size, to - pos - 1));
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    result.push(child);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    size += child.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                pos = end;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Fragment(result, size);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    cutByIndex(from, to) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (from == to)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return Fragment.empty;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (from == 0 && to == this.content.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Fragment(this.content.slice(from, to));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a new fragment in which the node at the given index is
 | 
						
						
						
						
							 | 
							
								 | 
							
							    replaced by the given node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    replaceChild(index, node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let current = this.content[index];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (current == node)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let copy = this.content.slice();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let size = this.size + node.nodeSize - current.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        copy[index] = node;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Fragment(copy, size);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a new fragment by prepending the given node to this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    fragment.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addToStart(node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Fragment([node].concat(this.content), this.size + node.nodeSize);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a new fragment by appending the given node to this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    fragment.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addToEnd(node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Fragment(this.content.concat(node), this.size + node.nodeSize);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Compare this fragment to another one.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    eq(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.content.length != other.content.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < this.content.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!this.content[i].eq(other.content[i]))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The first child of the fragment, or `null` if it is empty.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get firstChild() { return this.content.length ? this.content[0] : null; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The last child of the fragment, or `null` if it is empty.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get lastChild() { return this.content.length ? this.content[this.content.length - 1] : null; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The number of child nodes in this fragment.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get childCount() { return this.content.length; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the child node at the given index. Raise an error when the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    index is out of range.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    child(index) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let found = this.content[index];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!found)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Index " + index + " out of range for " + this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return found;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the child node at the given index, if it exists.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    maybeChild(index) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.content[index] || null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Call `f` for every child node, passing the node, its offset
 | 
						
						
						
						
							 | 
							
								 | 
							
							    into this parent node, and its index.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    forEach(f) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0, p = 0; i < this.content.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let child = this.content[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            f(child, p, i);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            p += child.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Find the first position at which this fragment and another
 | 
						
						
						
						
							 | 
							
								 | 
							
							    fragment differ, or `null` if they are the same.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findDiffStart(other, pos = 0) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return findDiffStart(this, other, pos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Find the first position, searching from the end, at which this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    fragment and the given fragment differ, or `null` if they are
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the same. Since this position will not be the same in both
 | 
						
						
						
						
							 | 
							
								 | 
							
							    nodes, an object with two separate positions is returned.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findDiffEnd(other, pos = this.size, otherPos = other.size) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return findDiffEnd(this, other, pos, otherPos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Find the index and inner offset corresponding to a given relative
 | 
						
						
						
						
							 | 
							
								 | 
							
							    position in this fragment. The result object will be reused
 | 
						
						
						
						
							 | 
							
								 | 
							
							    (overwritten) the next time the function is called. (Not public.)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findIndex(pos, round = -1) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (pos == 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return retIndex(0, pos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (pos == this.size)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return retIndex(this.content.length, pos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (pos > this.size || pos < 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError(`Position ${pos} outside of fragment (${this})`);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0, curPos = 0;; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let cur = this.child(i), end = curPos + cur.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (end >= pos) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (end == pos || round > 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return retIndex(i + 1, end);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return retIndex(i, curPos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            curPos = end;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Return a debugging string that describes this fragment.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toString() { return "<" + this.toStringInner() + ">"; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toStringInner() { return this.content.join(", "); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a JSON-serializeable representation of this fragment.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toJSON() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.content.length ? this.content.map(n => n.toJSON()) : null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Deserialize a fragment from its JSON representation.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static fromJSON(schema, value) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!value)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return Fragment.empty;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!Array.isArray(value))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Invalid input for Fragment.fromJSON");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Fragment(value.map(schema.nodeFromJSON));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Build a fragment from an array of nodes. Ensures that adjacent
 | 
						
						
						
						
							 | 
							
								 | 
							
							    text nodes with the same marks are joined together.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static fromArray(array) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!array.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return Fragment.empty;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let joined, size = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < array.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let node = array[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            size += node.nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (i && node.isText && array[i - 1].sameMarkup(node)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!joined)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    joined = array.slice(0, i);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                joined[joined.length - 1] = node
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    .withText(joined[joined.length - 1].text + node.text);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (joined) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                joined.push(node);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Fragment(joined || array, size);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a fragment from something that can be interpreted as a
 | 
						
						
						
						
							 | 
							
								 | 
							
							    set of nodes. For `null`, it returns the empty fragment. For a
 | 
						
						
						
						
							 | 
							
								 | 
							
							    fragment, the fragment itself. For a node or array of nodes, a
 | 
						
						
						
						
							 | 
							
								 | 
							
							    fragment containing those nodes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static from(nodes) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!nodes)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return Fragment.empty;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (nodes instanceof Fragment)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return nodes;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (Array.isArray(nodes))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.fromArray(nodes);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (nodes.attrs)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return new Fragment([nodes], nodes.nodeSize);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        throw new RangeError("Can not convert " + nodes + " to a Fragment" +
 | 
						
						
						
						
							 | 
							
								 | 
							
							            (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							An empty fragment. Intended to be reused whenever a node doesn't
 | 
						
						
						
						
							 | 
							
								 | 
							
							contain anything (rather than allocating a new empty fragment for
 | 
						
						
						
						
							 | 
							
								 | 
							
							each leaf node).
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							Fragment.empty = new Fragment([], 0);
 | 
						
						
						
						
							 | 
							
								 | 
							
							const found = { index: 0, offset: 0 };
 | 
						
						
						
						
							 | 
							
								 | 
							
							function retIndex(index, offset) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    found.index = index;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    found.offset = offset;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return found;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							function compareDeep(a, b) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (a === b)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!(a && typeof a == "object") ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							        !(b && typeof b == "object"))
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let array = Array.isArray(a);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (Array.isArray(b) != array)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (array) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (a.length != b.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < a.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!compareDeep(a[i], b[i]))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let p in a)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!(p in b) || !compareDeep(a[p], b[p]))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let p in b)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!(p in a))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							A mark is a piece of information that can be attached to a node,
 | 
						
						
						
						
							 | 
							
								 | 
							
							such as it being emphasized, in code font, or a link. It has a
 | 
						
						
						
						
							 | 
							
								 | 
							
							type and optionally a set of attributes that provide further
 | 
						
						
						
						
							 | 
							
								 | 
							
							information (such as the target of the link). Marks are created
 | 
						
						
						
						
							 | 
							
								 | 
							
							through a `Schema`, which controls which types exist and which
 | 
						
						
						
						
							 | 
							
								 | 
							
							attributes they have.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class Mark {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The type of this mark.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    type, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The attributes associated with this mark.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    attrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.type = type;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.attrs = attrs;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Given a set of marks, create a new set which contains this one as
 | 
						
						
						
						
							 | 
							
								 | 
							
							    well, in the right position. If this mark is already in the set,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the set itself is returned. If any marks that are set to be
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    those are replaced by this one.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addToSet(set) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let copy, placed = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < set.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let other = set[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (this.eq(other))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return set;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (this.type.excludes(other.type)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!copy)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    copy = set.slice(0, i);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (other.type.excludes(this.type)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return set;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!placed && other.type.rank > this.type.rank) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (!copy)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        copy = set.slice(0, i);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    copy.push(this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    placed = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (copy)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    copy.push(other);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!copy)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            copy = set.slice();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!placed)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            copy.push(this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return copy;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Remove this mark from the given set, returning a new set. If this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    mark is not in the set, the set itself is returned.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    removeFromSet(set) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < set.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (this.eq(set[i]))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return set.slice(0, i).concat(set.slice(i + 1));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return set;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Test whether this mark is in the given set of marks.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    isInSet(set) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < set.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (this.eq(set[i]))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Test whether this mark has the same type and attributes as
 | 
						
						
						
						
							 | 
							
								 | 
							
							    another mark.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    eq(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this == other ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							            (this.type == other.type && compareDeep(this.attrs, other.attrs));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Convert this mark to a JSON-serializeable representation.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toJSON() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let obj = { type: this.type.name };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let _ in this.attrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            obj.attrs = this.attrs;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return obj;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Deserialize a mark from JSON.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static fromJSON(schema, json) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!json)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Invalid input for Mark.fromJSON");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let type = schema.marks[json.type];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!type)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError(`There is no mark type ${json.type} in this schema`);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return type.create(json.attrs);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Test whether two sets of marks are identical.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static sameSet(a, b) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (a == b)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (a.length != b.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < a.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!a[i].eq(b[i]))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a properly sorted mark set from null, a single mark, or an
 | 
						
						
						
						
							 | 
							
								 | 
							
							    unsorted array of marks.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static setFrom(marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!marks || Array.isArray(marks) && marks.length == 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return Mark.none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (marks instanceof Mark)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return [marks];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let copy = marks.slice();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        copy.sort((a, b) => a.type.rank - b.type.rank);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return copy;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							The empty set of marks.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							Mark.none = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							Error type raised by [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) when
 | 
						
						
						
						
							 | 
							
								 | 
							
							given an invalid replacement.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class ReplaceError extends Error {
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							/*
 | 
						
						
						
						
							 | 
							
								 | 
							
							ReplaceError = function(this: any, message: string) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							  let err = Error.call(this, message)
 | 
						
						
						
						
							 | 
							
								 | 
							
							  ;(err as any).__proto__ = ReplaceError.prototype
 | 
						
						
						
						
							 | 
							
								 | 
							
							  return err
 | 
						
						
						
						
							 | 
							
								 | 
							
							} as any
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							ReplaceError.prototype = Object.create(Error.prototype)
 | 
						
						
						
						
							 | 
							
								 | 
							
							ReplaceError.prototype.constructor = ReplaceError
 | 
						
						
						
						
							 | 
							
								 | 
							
							ReplaceError.prototype.name = "ReplaceError"
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							A slice represents a piece cut out of a larger document. It
 | 
						
						
						
						
							 | 
							
								 | 
							
							stores not only a fragment, but also the depth up to which nodes on
 | 
						
						
						
						
							 | 
							
								 | 
							
							both side are ‘open’ (cut through).
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class Slice {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a slice. When specifying a non-zero open depth, you must
 | 
						
						
						
						
							 | 
							
								 | 
							
							    make sure that there are nodes of at least that depth at the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    appropriate side of the fragment—i.e. if the fragment is an
 | 
						
						
						
						
							 | 
							
								 | 
							
							    empty paragraph node, `openStart` and `openEnd` can't be greater
 | 
						
						
						
						
							 | 
							
								 | 
							
							    than 1.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    
 | 
						
						
						
						
							 | 
							
								 | 
							
							    It is not necessary for the content of open nodes to conform to
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the schema's content constraints, though it should be a valid
 | 
						
						
						
						
							 | 
							
								 | 
							
							    start/end/middle for such a node, depending on which sides are
 | 
						
						
						
						
							 | 
							
								 | 
							
							    open.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The slice's content.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    content, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The open depth at the start of the fragment.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    openStart, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The open depth at the end.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    openEnd) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.content = content;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.openStart = openStart;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.openEnd = openEnd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The size this slice would add when inserted into a document.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get size() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.content.size - this.openStart - this.openEnd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    insertAt(pos, fragment) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let content = insertInto(this.content, pos + this.openStart, fragment);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return content && new Slice(content, this.openStart, this.openEnd);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    removeBetween(from, to) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Tests whether this slice is equal to another slice.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    eq(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toString() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.content + "(" + this.openStart + "," + this.openEnd + ")";
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Convert a slice to a JSON-serializable representation.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toJSON() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!this.content.size)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let json = { content: this.content.toJSON() };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.openStart > 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            json.openStart = this.openStart;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.openEnd > 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            json.openEnd = this.openEnd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return json;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Deserialize a slice from its JSON representation.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static fromJSON(schema, json) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!json)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return Slice.empty;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (typeof openStart != "number" || typeof openEnd != "number")
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Invalid input for Slice.fromJSON");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Slice(Fragment.fromJSON(schema, json.content), openStart, openEnd);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a slice from a fragment by taking the maximum possible
 | 
						
						
						
						
							 | 
							
								 | 
							
							    open value on both side of the fragment.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static maxOpen(fragment, openIsolating = true) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let openStart = 0, openEnd = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            openStart++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            openEnd++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Slice(fragment, openStart, openEnd);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							The empty slice.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							Slice.empty = new Slice(Fragment.empty, 0, 0);
 | 
						
						
						
						
							 | 
							
								 | 
							
							function removeRange(content, from, to) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let { index, offset } = content.findIndex(from), child = content.maybeChild(index);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let { index: indexTo, offset: offsetTo } = content.findIndex(to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (offset == from || child.isText) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (offsetTo != to && !content.child(indexTo).isText)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Removing non-flat range");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return content.cut(0, from).append(content.cut(to));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (index != indexTo)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        throw new RangeError("Removing non-flat range");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1)));
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function insertInto(content, dist, insert, parent) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let { index, offset } = content.findIndex(dist), child = content.maybeChild(index);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (offset == dist || child.isText) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (parent && !parent.canReplace(index, index, insert))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return content.cut(0, dist).append(insert).append(content.cut(dist));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let inner = insertInto(child.content, dist - offset - 1, insert);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return inner && content.replaceChild(index, child.copy(inner));
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function replace($from, $to, slice) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (slice.openStart > $from.depth)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        throw new ReplaceError("Inserted content deeper than insertion position");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ($from.depth - slice.openStart != $to.depth - slice.openEnd)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        throw new ReplaceError("Inconsistent open depths");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return replaceOuter($from, $to, slice, 0);
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function replaceOuter($from, $to, slice, depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let index = $from.index(depth), node = $from.node(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (index == $to.index(depth) && depth < $from.depth - slice.openStart) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let inner = replaceOuter($from, $to, slice, depth + 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return node.copy(node.content.replaceChild(index, inner));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if (!slice.content.size) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return close(node, replaceTwoWay($from, $to, depth));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if (!slice.openStart && !slice.openEnd && $from.depth == depth && $to.depth == depth) { // Simple, flat case
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let parent = $from.parent, content = parent.content;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return close(parent, content.cut(0, $from.parentOffset).append(slice.content).append(content.cut($to.parentOffset)));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let { start, end } = prepareSliceForReplace(slice, $from);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return close(node, replaceThreeWay($from, start, end, $to, depth));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function checkJoin(main, sub) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!sub.type.compatibleContent(main.type))
 | 
						
						
						
						
							 | 
							
								 | 
							
							        throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main.type.name);
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function joinable($before, $after, depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let node = $before.node(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    checkJoin(node, $after.node(depth));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return node;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function addNode(child, target) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let last = target.length - 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (last >= 0 && child.isText && child.sameMarkup(target[last]))
 | 
						
						
						
						
							 | 
							
								 | 
							
							        target[last] = child.withText(target[last].text + child.text);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else
 | 
						
						
						
						
							 | 
							
								 | 
							
							        target.push(child);
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function addRange($start, $end, depth, target) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let node = ($end || $start).node(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ($start) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        startIndex = $start.index(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ($start.depth > depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            startIndex++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if ($start.textOffset) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            addNode($start.nodeAfter, target);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            startIndex++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let i = startIndex; i < endIndex; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        addNode(node.child(i), target);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ($end && $end.depth == depth && $end.textOffset)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        addNode($end.nodeBefore, target);
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function close(node, content) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node.type.checkContent(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return node.copy(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function replaceThreeWay($from, $start, $end, $to, depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let openStart = $from.depth > depth && joinable($from, $start, depth + 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let openEnd = $to.depth > depth && joinable($end, $to, depth + 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let content = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addRange(null, $from, depth, content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (openStart && openEnd && $start.index(depth) == $end.index(depth)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        checkJoin(openStart, openEnd);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (openStart)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        addRange($start, $end, depth, content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (openEnd)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addRange($to, null, depth, content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return new Fragment(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function replaceTwoWay($from, $to, depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let content = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addRange(null, $from, depth, content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ($from.depth > depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let type = joinable($from, $to, depth + 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addRange($to, null, depth, content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return new Fragment(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function prepareSliceForReplace(slice, $along) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let extra = $along.depth - slice.openStart, parent = $along.node(extra);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let node = parent.copy(slice.content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let i = extra - 1; i >= 0; i--)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        node = $along.node(i).copy(Fragment.from(node));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return { start: node.resolveNoCache(slice.openStart + extra),
 | 
						
						
						
						
							 | 
							
								 | 
							
							        end: node.resolveNoCache(node.content.size - slice.openEnd - extra) };
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							You can [_resolve_](https://prosemirror.net/docs/ref/#model.Node.resolve) a position to get more
 | 
						
						
						
						
							 | 
							
								 | 
							
							information about it. Objects of this class represent such a
 | 
						
						
						
						
							 | 
							
								 | 
							
							resolved position, providing various pieces of context
 | 
						
						
						
						
							 | 
							
								 | 
							
							information, and some helper methods.
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							Throughout this interface, methods that take an optional `depth`
 | 
						
						
						
						
							 | 
							
								 | 
							
							parameter will interpret undefined as `this.depth` and negative
 | 
						
						
						
						
							 | 
							
								 | 
							
							numbers as `this.depth + value`.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class ResolvedPos {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The position that was resolved.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    pos, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    path, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The offset this position has into its parent node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parentOffset) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.pos = pos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.path = path;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.parentOffset = parentOffset;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.depth = path.length / 3 - 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    resolveDepth(val) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (val == null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.depth;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (val < 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.depth + val;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return val;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The parent node that the position points into. Note that even if
 | 
						
						
						
						
							 | 
							
								 | 
							
							    a position points into a text node, that node is not considered
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the parent—text nodes are ‘flat’ in this model, and have no content.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get parent() { return this.node(this.depth); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The root node in which the position was resolved.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get doc() { return this.node(0); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The ancestor node at the given level. `p.node(p.depth)` is the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    same as `p.parent`.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node(depth) { return this.path[this.resolveDepth(depth) * 3]; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The index into the ancestor at the given level. If this points
 | 
						
						
						
						
							 | 
							
								 | 
							
							    at the 3rd node in the 2nd paragraph on the top level, for
 | 
						
						
						
						
							 | 
							
								 | 
							
							    example, `p.index(0)` is 1 and `p.index(1)` is 2.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    index(depth) { return this.path[this.resolveDepth(depth) * 3 + 1]; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The index pointing after this position into the ancestor at the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    given level.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    indexAfter(depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        depth = this.resolveDepth(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The (absolute) position at the start of the node at the given
 | 
						
						
						
						
							 | 
							
								 | 
							
							    level.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    start(depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        depth = this.resolveDepth(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The (absolute) position at the end of the node at the given
 | 
						
						
						
						
							 | 
							
								 | 
							
							    level.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    end(depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        depth = this.resolveDepth(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.start(depth) + this.node(depth).content.size;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The (absolute) position directly before the wrapping node at the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    given level, or, when `depth` is `this.depth + 1`, the original
 | 
						
						
						
						
							 | 
							
								 | 
							
							    position.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    before(depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        depth = this.resolveDepth(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!depth)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("There is no position before the top-level node");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The (absolute) position directly after the wrapping node at the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    given level, or the original position when `depth` is `this.depth + 1`.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    after(depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        depth = this.resolveDepth(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!depth)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("There is no position after the top-level node");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    When this position points into a text node, this returns the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    distance between the position and the start of the text node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Will be zero for positions that point between nodes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get textOffset() { return this.pos - this.path[this.path.length - 1]; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the node directly after the position, if any. If the position
 | 
						
						
						
						
							 | 
							
								 | 
							
							    points into a text node, only the part of that node after the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    position is returned.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get nodeAfter() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let parent = this.parent, index = this.index(this.depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (index == parent.childCount)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return dOff ? parent.child(index).cut(dOff) : child;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the node directly before the position, if any. If the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    position points into a text node, only the part of that node
 | 
						
						
						
						
							 | 
							
								 | 
							
							    before the position is returned.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get nodeBefore() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let index = this.index(this.depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let dOff = this.pos - this.path[this.path.length - 1];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (dOff)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.parent.child(index).cut(0, dOff);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return index == 0 ? null : this.parent.child(index - 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the position at the given index in the parent node at the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    given depth (which defaults to `this.depth`).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    posAtIndex(index, depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        depth = this.resolveDepth(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < index; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            pos += node.child(i).nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return pos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the marks at this position, factoring in the surrounding
 | 
						
						
						
						
							 | 
							
								 | 
							
							    marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    position is at the start of a non-empty node, the marks of the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node after it (if any) are returned.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    marks() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let parent = this.parent, index = this.index();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // In an empty parent, return the empty array
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (parent.content.size == 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return Mark.none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // When inside a text node, just return the text node's marks
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.textOffset)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return parent.child(index).marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let main = parent.maybeChild(index - 1), other = parent.maybeChild(index);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // If the `after` flag is true of there is no node before, make
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // the node after this position the main reference.
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!main) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let tmp = main;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            main = other;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            other = tmp;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // Use all marks in the main node, except those that have
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // `inclusive` set to false and are not present in the other node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let marks = main.marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (var i = 0; i < marks.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (marks[i].type.spec.inclusive === false && (!other || !marks[i].isInSet(other.marks)))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                marks = marks[i--].removeFromSet(marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the marks after the current position, if any, except those
 | 
						
						
						
						
							 | 
							
								 | 
							
							    that are non-inclusive and not present at position `$end`. This
 | 
						
						
						
						
							 | 
							
								 | 
							
							    is mostly useful for getting the set of marks to preserve after a
 | 
						
						
						
						
							 | 
							
								 | 
							
							    deletion. Will return `null` if this position is at the end of
 | 
						
						
						
						
							 | 
							
								 | 
							
							    its parent node or its parent node isn't a textblock (in which
 | 
						
						
						
						
							 | 
							
								 | 
							
							    case no marks should be preserved).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    marksAcross($end) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let after = this.parent.maybeChild(this.index());
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!after || !after.isInline)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let marks = after.marks, next = $end.parent.maybeChild($end.index());
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (var i = 0; i < marks.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (marks[i].type.spec.inclusive === false && (!next || !marks[i].isInSet(next.marks)))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                marks = marks[i--].removeFromSet(marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The depth up to which this position and the given (non-resolved)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    position share the same parent nodes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    sharedDepth(pos) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let depth = this.depth; depth > 0; depth--)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (this.start(depth) <= pos && this.end(depth) >= pos)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return depth;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Returns a range based on the place where this position and the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    given position diverge around block content. If both point into
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the same textblock, for example, a range around that textblock
 | 
						
						
						
						
							 | 
							
								 | 
							
							    will be returned. If they point into different blocks, the range
 | 
						
						
						
						
							 | 
							
								 | 
							
							    around those blocks in their shared ancestor is returned. You can
 | 
						
						
						
						
							 | 
							
								 | 
							
							    pass in an optional predicate that will be called with a parent
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node to see if a range into that parent is acceptable.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    blockRange(other = this, pred) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (other.pos < this.pos)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return other.blockRange(this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let d = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d >= 0; d--)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (other.pos <= this.end(d) && (!pred || pred(this.node(d))))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return new NodeRange(this, other, d);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Query whether the given position shares the same parent node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    sameParent(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.pos - this.parentOffset == other.pos - other.parentOffset;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Return the greater of this and the given position.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    max(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return other.pos > this.pos ? other : this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Return the smaller of this and the given position.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    min(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return other.pos < this.pos ? other : this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toString() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let str = "";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 1; i <= this.depth; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            str += (str ? "/" : "") + this.node(i).type.name + "_" + this.index(i - 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return str + ":" + this.parentOffset;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static resolve(doc, pos) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!(pos >= 0 && pos <= doc.content.size))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Position " + pos + " out of range");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let path = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let start = 0, parentOffset = pos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let node = doc;;) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let { index, offset } = node.content.findIndex(parentOffset);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let rem = parentOffset - offset;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            path.push(node, index, start + offset);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!rem)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            node = node.child(index);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (node.isText)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            parentOffset = rem - 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            start += offset + 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new ResolvedPos(pos, path, parentOffset);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static resolveCached(doc, pos) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < resolveCache.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let cached = resolveCache[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (cached.pos == pos && cached.doc == doc)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return cached;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let result = resolveCache[resolveCachePos] = ResolvedPos.resolve(doc, pos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        resolveCachePos = (resolveCachePos + 1) % resolveCacheSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							let resolveCache = [], resolveCachePos = 0, resolveCacheSize = 12;
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							Represents a flat range of content, i.e. one that starts and
 | 
						
						
						
						
							 | 
							
								 | 
							
							ends in the same node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class NodeRange {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Construct a node range. `$from` and `$to` should point into the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    same node until at least the given `depth`, since a node range
 | 
						
						
						
						
							 | 
							
								 | 
							
							    denotes an adjacent set of nodes in a single parent node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    A resolved position along the start of the content. May have a
 | 
						
						
						
						
							 | 
							
								 | 
							
							    `depth` greater than this object's `depth` property, since
 | 
						
						
						
						
							 | 
							
								 | 
							
							    these are the positions that were used to compute the range,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    not re-resolved positions directly at its boundaries.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    $from, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    A position along the end of the content. See
 | 
						
						
						
						
							 | 
							
								 | 
							
							    caveat for [`$from`](https://prosemirror.net/docs/ref/#model.NodeRange.$from).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    $to, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The depth of the node that this range points into.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    depth) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.$from = $from;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.$to = $to;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.depth = depth;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The position at the start of the range.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get start() { return this.$from.before(this.depth + 1); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The position at the end of the range.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get end() { return this.$to.after(this.depth + 1); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The parent node that the range points into.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get parent() { return this.$from.node(this.depth); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The start index of the range in the parent node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get startIndex() { return this.$from.index(this.depth); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The end index of the range in the parent node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get endIndex() { return this.$to.indexAfter(this.depth); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							const emptyAttrs = Object.create(null);
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							This class represents a node in the tree that makes up a
 | 
						
						
						
						
							 | 
							
								 | 
							
							ProseMirror document. So a document is an instance of `Node`, with
 | 
						
						
						
						
							 | 
							
								 | 
							
							children that are also instances of `Node`.
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							Nodes are persistent data structures. Instead of changing them, you
 | 
						
						
						
						
							 | 
							
								 | 
							
							create new ones with the content you want. Old ones keep pointing
 | 
						
						
						
						
							 | 
							
								 | 
							
							at the old document shape. This is made cheaper by sharing
 | 
						
						
						
						
							 | 
							
								 | 
							
							structure between the old and new data as much as possible, which a
 | 
						
						
						
						
							 | 
							
								 | 
							
							tree shape like this (without back pointers) makes easy.
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							**Do not** directly mutate the properties of a `Node` object. See
 | 
						
						
						
						
							 | 
							
								 | 
							
							[the guide](/docs/guide/#doc) for more information.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class Node {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The type of node that this is.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    type, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    An object mapping attribute names to values. The kind of
 | 
						
						
						
						
							 | 
							
								 | 
							
							    attributes allowed and required are
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [determined](https://prosemirror.net/docs/ref/#model.NodeSpec.attrs) by the node type.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    attrs, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // A fragment holding the node's children.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    content, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The marks (things like whether it is emphasized or part of a
 | 
						
						
						
						
							 | 
							
								 | 
							
							    link) applied to this node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    marks = Mark.none) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.type = type;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.attrs = attrs;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.marks = marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.content = content || Fragment.empty;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The size of this node, as defined by the integer-based [indexing
 | 
						
						
						
						
							 | 
							
								 | 
							
							    scheme](/docs/guide/#doc.indexing). For text nodes, this is the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    amount of characters. For other leaf nodes, it is one. For
 | 
						
						
						
						
							 | 
							
								 | 
							
							    non-leaf nodes, it is the size of the content plus two (the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    start and end token).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get nodeSize() { return this.isLeaf ? 1 : 2 + this.content.size; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The number of children that the node has.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get childCount() { return this.content.childCount; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the child node at the given index. Raises an error when the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    index is out of range.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    child(index) { return this.content.child(index); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the child node at the given index, if it exists.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    maybeChild(index) { return this.content.maybeChild(index); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Call `f` for every child node, passing the node, its offset
 | 
						
						
						
						
							 | 
							
								 | 
							
							    into this parent node, and its index.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    forEach(f) { this.content.forEach(f); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Invoke a callback for all descendant nodes recursively between
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the given two positions that are relative to start of this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node's content. The callback is invoked with the node, its
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parent-relative position, its parent node, and its child index.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    When the callback returns false for a given node, that node's
 | 
						
						
						
						
							 | 
							
								 | 
							
							    children will not be recursed over. The last parameter can be
 | 
						
						
						
						
							 | 
							
								 | 
							
							    used to specify a starting position to count from.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    nodesBetween(from, to, f, startPos = 0) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.content.nodesBetween(from, to, f, startPos, this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Call the given callback for every descendant node. Doesn't
 | 
						
						
						
						
							 | 
							
								 | 
							
							    descend into a node when the callback returns `false`.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    descendants(f) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.nodesBetween(0, this.content.size, f);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Concatenates all the text nodes found in this fragment and its
 | 
						
						
						
						
							 | 
							
								 | 
							
							    children.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get textContent() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return (this.isLeaf && this.type.spec.leafText)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            ? this.type.spec.leafText(this)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            : this.textBetween(0, this.content.size, "");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get all text between positions `from` and `to`. When
 | 
						
						
						
						
							 | 
							
								 | 
							
							    `blockSeparator` is given, it will be inserted to separate text
 | 
						
						
						
						
							 | 
							
								 | 
							
							    from different block nodes. If `leafText` is given, it'll be
 | 
						
						
						
						
							 | 
							
								 | 
							
							    inserted for every non-text leaf node encountered, otherwise
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec^leafText) will be used.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    textBetween(from, to, blockSeparator, leafText) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.content.textBetween(from, to, blockSeparator, leafText);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Returns this node's first child, or `null` if there are no
 | 
						
						
						
						
							 | 
							
								 | 
							
							    children.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get firstChild() { return this.content.firstChild; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Returns this node's last child, or `null` if there are no
 | 
						
						
						
						
							 | 
							
								 | 
							
							    children.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get lastChild() { return this.content.lastChild; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Test whether two nodes represent the same piece of document.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    eq(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this == other || (this.sameMarkup(other) && this.content.eq(other.content));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Compare the markup (type, attributes, and marks) of this node to
 | 
						
						
						
						
							 | 
							
								 | 
							
							    those of another. Returns `true` if both have the same markup.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    sameMarkup(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.hasMarkup(other.type, other.attrs, other.marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Check whether this node's markup correspond to the given type,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    attributes, and marks.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    hasMarkup(type, attrs, marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.type == type &&
 | 
						
						
						
						
							 | 
							
								 | 
							
							            compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) &&
 | 
						
						
						
						
							 | 
							
								 | 
							
							            Mark.sameSet(this.marks, marks || Mark.none);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a new node with the same markup as this node, containing
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the given content (or empty, if no content is given).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    copy(content = null) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (content == this.content)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Node(this.type, this.attrs, content, this.marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a copy of this node, with the given set of marks instead
 | 
						
						
						
						
							 | 
							
								 | 
							
							    of the node's own marks.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    mark(marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return marks == this.marks ? this : new Node(this.type, this.attrs, this.content, marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a copy of this node with only the content between the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    given positions. If `to` is not given, it defaults to the end of
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    cut(from, to = this.content.size) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (from == 0 && to == this.content.size)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.copy(this.content.cut(from, to));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Cut out the part of the document between the given positions, and
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return it as a `Slice` object.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    slice(from, to = this.content.size, includeParents = false) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (from == to)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return Slice.empty;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let $from = this.resolve(from), $to = this.resolve(to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let depth = includeParents ? 0 : $from.sharedDepth(to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let start = $from.start(depth), node = $from.node(depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let content = node.content.cut($from.pos - start, $to.pos - start);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Slice(content, $from.depth - depth, $to.depth - depth);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Replace the part of the document between the given positions with
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the given slice. The slice must 'fit', meaning its open sides
 | 
						
						
						
						
							 | 
							
								 | 
							
							    must be able to connect to the surrounding content, and its
 | 
						
						
						
						
							 | 
							
								 | 
							
							    content nodes must be valid children for the node they are placed
 | 
						
						
						
						
							 | 
							
								 | 
							
							    into. If any of this is violated, an error of type
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    replace(from, to, slice) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return replace(this.resolve(from), this.resolve(to), slice);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Find the node directly after the given position.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    nodeAt(pos) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let node = this;;) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let { index, offset } = node.content.findIndex(pos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            node = node.maybeChild(index);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!node)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (offset == pos || node.isText)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return node;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            pos -= offset + 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Find the (direct) child node after the given offset, if any,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    and return it along with its index and offset relative to this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    childAfter(pos) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let { index, offset } = this.content.findIndex(pos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return { node: this.content.maybeChild(index), index, offset };
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Find the (direct) child node before the given offset, if any,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    and return it along with its index and offset relative to this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    childBefore(pos) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (pos == 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return { node: null, index: 0, offset: 0 };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let { index, offset } = this.content.findIndex(pos);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (offset < pos)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return { node: this.content.child(index), index, offset };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let node = this.content.child(index - 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return { node, index: index - 1, offset: offset - node.nodeSize };
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Resolve the given position in the document, returning an
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    resolve(pos) { return ResolvedPos.resolveCached(this, pos); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    resolveNoCache(pos) { return ResolvedPos.resolve(this, pos); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Test whether a given mark or mark type occurs in this document
 | 
						
						
						
						
							 | 
							
								 | 
							
							    between the two given positions.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    rangeHasMark(from, to, type) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let found = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (to > from)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.nodesBetween(from, to, node => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (type.isInSet(node.marks))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    found = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return !found;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return found;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True when this is a block (non-inline node)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isBlock() { return this.type.isBlock; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True when this is a textblock node, a block node with inline
 | 
						
						
						
						
							 | 
							
								 | 
							
							    content.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isTextblock() { return this.type.isTextblock; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True when this node allows inline content.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get inlineContent() { return this.type.inlineContent; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True when this is an inline node (a text node or a node that can
 | 
						
						
						
						
							 | 
							
								 | 
							
							    appear among text).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isInline() { return this.type.isInline; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True when this is a text node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isText() { return this.type.isText; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True when this is a leaf node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isLeaf() { return this.type.isLeaf; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True when this is an atom, i.e. when it does not have directly
 | 
						
						
						
						
							 | 
							
								 | 
							
							    editable content. This is usually the same as `isLeaf`, but can
 | 
						
						
						
						
							 | 
							
								 | 
							
							    be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    on a node's spec (typically used when the node is displayed as
 | 
						
						
						
						
							 | 
							
								 | 
							
							    an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isAtom() { return this.type.isAtom; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Return a string representation of this node for debugging
 | 
						
						
						
						
							 | 
							
								 | 
							
							    purposes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toString() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.type.spec.toDebugString)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.type.spec.toDebugString(this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let name = this.type.name;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.content.size)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            name += "(" + this.content.toStringInner() + ")";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return wrapMarks(this.marks, name);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the content match in this node at the given index.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    contentMatchAt(index) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let match = this.type.contentMatch.matchFragment(this.content, 0, index);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!match)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new Error("Called contentMatchAt on a node with invalid content");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return match;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Test whether replacing the range between `from` and `to` (by
 | 
						
						
						
						
							 | 
							
								 | 
							
							    child index) with the given replacement fragment (which defaults
 | 
						
						
						
						
							 | 
							
								 | 
							
							    to the empty fragment) would leave the node's content valid. You
 | 
						
						
						
						
							 | 
							
								 | 
							
							    can optionally pass `start` and `end` indices into the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    replacement fragment.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    canReplace(from, to, replacement = Fragment.empty, start = 0, end = replacement.childCount) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let one = this.contentMatchAt(from).matchFragment(replacement, start, end);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let two = one && one.matchFragment(this.content, to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!two || !two.validEnd)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = start; i < end; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!this.type.allowsMarks(replacement.child(i).marks))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Test whether replacing the range `from` to `to` (by index) with
 | 
						
						
						
						
							 | 
							
								 | 
							
							    a node of the given type would leave the node's content valid.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    canReplaceWith(from, to, type, marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (marks && !this.type.allowsMarks(marks))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let start = this.contentMatchAt(from).matchType(type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let end = start && start.matchFragment(this.content, to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return end ? end.validEnd : false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Test whether the given node's content could be appended to this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node. If that node is empty, this will only return true if there
 | 
						
						
						
						
							 | 
							
								 | 
							
							    is at least one node type that can appear in both nodes (to avoid
 | 
						
						
						
						
							 | 
							
								 | 
							
							    merging completely incompatible nodes).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    canAppend(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (other.content.size)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.canReplace(this.childCount, this.childCount, other.content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.type.compatibleContent(other.type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Check whether this node and its descendants conform to the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    schema, and raise error when they do not.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    check() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.type.checkContent(this.content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let copy = Mark.none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < this.marks.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            copy = this.marks[i].addToSet(copy);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!Mark.sameSet(copy, this.marks))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map(m => m.type.name)}`);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.content.forEach(node => node.check());
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Return a JSON-serializeable representation of this node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toJSON() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let obj = { type: this.type.name };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let _ in this.attrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            obj.attrs = this.attrs;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.content.size)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            obj.content = this.content.toJSON();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.marks.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            obj.marks = this.marks.map(n => n.toJSON());
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return obj;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Deserialize a node from its JSON representation.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static fromJSON(schema, json) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!json)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Invalid input for Node.fromJSON");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let marks = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (json.marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!Array.isArray(json.marks))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                throw new RangeError("Invalid mark data for Node.fromJSON");
 | 
						
						
						
						
							 | 
							
								 | 
							
							            marks = json.marks.map(schema.markFromJSON);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (json.type == "text") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (typeof json.text != "string")
 | 
						
						
						
						
							 | 
							
								 | 
							
							                throw new RangeError("Invalid text node in JSON");
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return schema.text(json.text, marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let content = Fragment.fromJSON(schema, json.content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return schema.nodeType(json.type).create(json.attrs, content, marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							Node.prototype.text = undefined;
 | 
						
						
						
						
							 | 
							
								 | 
							
							class TextNode extends Node {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(type, attrs, content, marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        super(type, attrs, null, marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!content)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Empty text nodes are not allowed");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.text = content;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toString() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.type.spec.toDebugString)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.type.spec.toDebugString(this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return wrapMarks(this.marks, JSON.stringify(this.text));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get textContent() { return this.text; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    textBetween(from, to) { return this.text.slice(from, to); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get nodeSize() { return this.text.length; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    mark(marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return marks == this.marks ? this : new TextNode(this.type, this.attrs, this.text, marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    withText(text) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (text == this.text)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new TextNode(this.type, this.attrs, text, this.marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    cut(from = 0, to = this.text.length) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (from == 0 && to == this.text.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.withText(this.text.slice(from, to));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    eq(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.sameMarkup(other) && this.text == other.text;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toJSON() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let base = super.toJSON();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        base.text = this.text;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return base;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function wrapMarks(marks, str) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let i = marks.length - 1; i >= 0; i--)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        str = marks[i].type.name + "(" + str + ")";
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return str;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							Instances of this class represent a match state of a node type's
 | 
						
						
						
						
							 | 
							
								 | 
							
							[content expression](https://prosemirror.net/docs/ref/#model.NodeSpec.content), and can be used to
 | 
						
						
						
						
							 | 
							
								 | 
							
							find out whether further content matches here, and whether a given
 | 
						
						
						
						
							 | 
							
								 | 
							
							position is a valid end of the node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class ContentMatch {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True when this match state represents a valid end of the node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    validEnd) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.validEnd = validEnd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							        @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							        */
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.next = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							        @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							        */
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.wrapCache = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static parse(string, nodeTypes) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let stream = new TokenStream(string, nodeTypes);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (stream.next == null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return ContentMatch.empty;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let expr = parseExpr(stream);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (stream.next)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            stream.err("Unexpected trailing text");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let match = dfa(nfa(expr));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        checkForDeadEnds(match, stream);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return match;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Match a node type, returning a match after that node if
 | 
						
						
						
						
							 | 
							
								 | 
							
							    successful.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    matchType(type) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < this.next.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (this.next[i].type == type)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return this.next[i].next;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Try to match a fragment. Returns the resulting match when
 | 
						
						
						
						
							 | 
							
								 | 
							
							    successful.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    matchFragment(frag, start = 0, end = frag.childCount) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let cur = this;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = start; cur && i < end; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            cur = cur.matchType(frag.child(i).type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return cur;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get inlineContent() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.next.length != 0 && this.next[0].type.isInline;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the first matching node type at this match position that can
 | 
						
						
						
						
							 | 
							
								 | 
							
							    be generated.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get defaultType() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < this.next.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let { type } = this.next[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!(type.isText || type.hasRequiredAttrs()))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return type;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    compatible(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < this.next.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let j = 0; j < other.next.length; j++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (this.next[i].type == other.next[j].type)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Try to match the given fragment, and if that fails, see if it can
 | 
						
						
						
						
							 | 
							
								 | 
							
							    be made to match by inserting nodes in front of it. When
 | 
						
						
						
						
							 | 
							
								 | 
							
							    successful, return a fragment of inserted nodes (which may be
 | 
						
						
						
						
							 | 
							
								 | 
							
							    empty if nothing had to be inserted). When `toEnd` is true, only
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return a fragment if the resulting match goes to the end of the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    content expression.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    fillBefore(after, toEnd = false, startIndex = 0) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let seen = [this];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function search(match, types) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let finished = match.matchFragment(after, startIndex);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (finished && (!toEnd || finished.validEnd))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return Fragment.from(types.map(tp => tp.createAndFill()));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < match.next.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let { type, next } = match.next[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    seen.push(next);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let found = search(next, types.concat(type));
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (found)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        return found;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return search(this, []);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Find a set of wrapping node types that would allow a node of the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    given type to appear at this position. The result may be empty
 | 
						
						
						
						
							 | 
							
								 | 
							
							    (when it fits directly) and will be null when no such wrapping
 | 
						
						
						
						
							 | 
							
								 | 
							
							    exists.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findWrapping(target) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < this.wrapCache.length; i += 2)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (this.wrapCache[i] == target)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return this.wrapCache[i + 1];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let computed = this.computeWrapping(target);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.wrapCache.push(target, computed);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return computed;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    computeWrapping(target) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let seen = Object.create(null), active = [{ match: this, type: null, via: null }];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        while (active.length) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let current = active.shift(), match = current.match;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (match.matchType(target)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let result = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                for (let obj = current; obj.type; obj = obj.via)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    result.push(obj.type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return result.reverse();
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < match.next.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let { type, next } = match.next[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next.validEnd)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    active.push({ match: type.contentMatch, type, via: current });
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    seen[type.name] = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The number of outgoing edges this node has in the finite
 | 
						
						
						
						
							 | 
							
								 | 
							
							    automaton that describes the content expression.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get edgeCount() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.next.length;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Get the _n_th outgoing edge from this node in the finite
 | 
						
						
						
						
							 | 
							
								 | 
							
							    automaton that describes the content expression.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    edge(n) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (n >= this.next.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError(`There's no ${n}th edge in this content match`);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.next[n];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    toString() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let seen = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function scan(m) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            seen.push(m);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < m.next.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (seen.indexOf(m.next[i].next) == -1)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    scan(m.next[i].next);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        scan(this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return seen.map((m, i) => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let out = i + (m.validEnd ? "*" : " ") + " ";
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < m.next.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                out += (i ? ", " : "") + m.next[i].type.name + "->" + seen.indexOf(m.next[i].next);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return out;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }).join("\n");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							@internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							ContentMatch.empty = new ContentMatch(true);
 | 
						
						
						
						
							 | 
							
								 | 
							
							class TokenStream {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(string, nodeTypes) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.string = string;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.nodeTypes = nodeTypes;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.inline = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.pos = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.tokens = string.split(/\s*(?=\b|\W|$)/);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.tokens[this.tokens.length - 1] == "")
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.tokens.pop();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.tokens[0] == "")
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.tokens.shift();
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get next() { return this.tokens[this.pos]; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    eat(tok) { return this.next == tok && (this.pos++ || true); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    err(str) { throw new SyntaxError(str + " (in content expression '" + this.string + "')"); }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function parseExpr(stream) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let exprs = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    do {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        exprs.push(parseExprSeq(stream));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    } while (stream.eat("|"));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return exprs.length == 1 ? exprs[0] : { type: "choice", exprs };
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function parseExprSeq(stream) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let exprs = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    do {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        exprs.push(parseExprSubscript(stream));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    } while (stream.next && stream.next != ")" && stream.next != "|");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return exprs.length == 1 ? exprs[0] : { type: "seq", exprs };
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function parseExprSubscript(stream) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let expr = parseExprAtom(stream);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (;;) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (stream.eat("+"))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            expr = { type: "plus", expr };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (stream.eat("*"))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            expr = { type: "star", expr };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (stream.eat("?"))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            expr = { type: "opt", expr };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (stream.eat("{"))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            expr = parseExprRange(stream, expr);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else
 | 
						
						
						
						
							 | 
							
								 | 
							
							            break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return expr;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function parseNum(stream) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (/\D/.test(stream.next))
 | 
						
						
						
						
							 | 
							
								 | 
							
							        stream.err("Expected number, got '" + stream.next + "'");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let result = Number(stream.next);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    stream.pos++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function parseExprRange(stream, expr) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let min = parseNum(stream), max = min;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (stream.eat(",")) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (stream.next != "}")
 | 
						
						
						
						
							 | 
							
								 | 
							
							            max = parseNum(stream);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else
 | 
						
						
						
						
							 | 
							
								 | 
							
							            max = -1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!stream.eat("}"))
 | 
						
						
						
						
							 | 
							
								 | 
							
							        stream.err("Unclosed braced range");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return { type: "range", min, max, expr };
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function resolveName(stream, name) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let types = stream.nodeTypes, type = types[name];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (type)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return [type];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let result = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let typeName in types) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let type = types[typeName];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (type.groups.indexOf(name) > -1)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            result.push(type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (result.length == 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        stream.err("No node type or group '" + name + "' found");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function parseExprAtom(stream) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (stream.eat("(")) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let expr = parseExpr(stream);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!stream.eat(")"))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            stream.err("Missing closing paren");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return expr;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if (!/\W/.test(stream.next)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let exprs = resolveName(stream, stream.next).map(type => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (stream.inline == null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                stream.inline = type.isInline;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (stream.inline != type.isInline)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                stream.err("Mixing inline and block content");
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return { type: "name", value: type };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        stream.pos++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return exprs.length == 1 ? exprs[0] : { type: "choice", exprs };
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        stream.err("Unexpected token '" + stream.next + "'");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							Construct an NFA from an expression as returned by the parser. The
 | 
						
						
						
						
							 | 
							
								 | 
							
							NFA is represented as an array of states, which are themselves
 | 
						
						
						
						
							 | 
							
								 | 
							
							arrays of edges, which are `{term, to}` objects. The first state is
 | 
						
						
						
						
							 | 
							
								 | 
							
							the entry state and the last node is the success state.
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							Note that unlike typical NFAs, the edge ordering in this one is
 | 
						
						
						
						
							 | 
							
								 | 
							
							significant, in that it is used to contruct filler content when
 | 
						
						
						
						
							 | 
							
								 | 
							
							necessary.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							function nfa(expr) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let nfa = [[]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    connect(compile(expr, 0), node());
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return nfa;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    function node() { return nfa.push([]) - 1; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    function edge(from, to, term) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let edge = { term, to };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        nfa[from].push(edge);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return edge;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    function connect(edges, to) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        edges.forEach(edge => edge.to = to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    function compile(expr, from) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (expr.type == "choice") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return expr.exprs.reduce((out, expr) => out.concat(compile(expr, from)), []);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (expr.type == "seq") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0;; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let next = compile(expr.exprs[i], from);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (i == expr.exprs.length - 1)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return next;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                connect(next, from = node());
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (expr.type == "star") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let loop = node();
 | 
						
						
						
						
							 | 
							
								 | 
							
							            edge(from, loop);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            connect(compile(expr.expr, loop), loop);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return [edge(loop)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (expr.type == "plus") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let loop = node();
 | 
						
						
						
						
							 | 
							
								 | 
							
							            connect(compile(expr.expr, from), loop);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            connect(compile(expr.expr, loop), loop);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return [edge(loop)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (expr.type == "opt") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return [edge(from)].concat(compile(expr.expr, from));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (expr.type == "range") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let cur = from;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < expr.min; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let next = node();
 | 
						
						
						
						
							 | 
							
								 | 
							
							                connect(compile(expr.expr, cur), next);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                cur = next;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (expr.max == -1) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                connect(compile(expr.expr, cur), cur);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                for (let i = expr.min; i < expr.max; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let next = node();
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    edge(cur, next);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    connect(compile(expr.expr, cur), next);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    cur = next;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return [edge(cur)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (expr.type == "name") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return [edge(from, undefined, expr.value)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new Error("Unknown expr type");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function cmp(a, b) { return b - a; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Get the set of nodes reachable by null edges from `node`. Omit
 | 
						
						
						
						
							 | 
							
								 | 
							
							// nodes with only a single null-out-edge, since they may lead to
 | 
						
						
						
						
							 | 
							
								 | 
							
							// needless duplicated nodes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							function nullFrom(nfa, node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let result = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    scan(node);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return result.sort(cmp);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    function scan(node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let edges = nfa[node];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (edges.length == 1 && !edges[0].term)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return scan(edges[0].to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        result.push(node);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < edges.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let { term, to } = edges[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!term && result.indexOf(to) == -1)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                scan(to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Compiles an NFA as produced by `nfa` into a DFA, modeled as a set
 | 
						
						
						
						
							 | 
							
								 | 
							
							// of state objects (`ContentMatch` instances) with transitions
 | 
						
						
						
						
							 | 
							
								 | 
							
							// between them.
 | 
						
						
						
						
							 | 
							
								 | 
							
							function dfa(nfa) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let labeled = Object.create(null);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return explore(nullFrom(nfa, 0));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    function explore(states) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let out = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        states.forEach(node => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            nfa[node].forEach(({ term, to }) => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!term)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let set;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                for (let i = 0; i < out.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (out[i][0] == term)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        set = out[i][1];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                nullFrom(nfa, to).forEach(node => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (!set)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        out.push([term, set = []]);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (set.indexOf(node) == -1)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        set.push(node);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                });
 | 
						
						
						
						
							 | 
							
								 | 
							
							            });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa.length - 1) > -1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < out.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let states = out[i][1].sort(cmp);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            state.next.push({ type: out[i][0], next: labeled[states.join(",")] || explore(states) });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return state;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function checkForDeadEnds(match, stream) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let i = 0, work = [match]; i < work.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let state = work[i], dead = !state.validEnd, nodes = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let j = 0; j < state.next.length; j++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let { type, next } = state.next[j];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            nodes.push(type.name);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (dead && !(type.isText || type.hasRequiredAttrs()))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                dead = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (work.indexOf(next) == -1)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                work.push(next);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (dead)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							// For node types where all attrs have a default value (or which don't
 | 
						
						
						
						
							 | 
							
								 | 
							
							// have any attributes), build up a single reusable default attribute
 | 
						
						
						
						
							 | 
							
								 | 
							
							// object, and use it for all nodes that don't specify specific
 | 
						
						
						
						
							 | 
							
								 | 
							
							// attributes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							function defaultAttrs(attrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let defaults = Object.create(null);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let attrName in attrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let attr = attrs[attrName];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!attr.hasDefault)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        defaults[attrName] = attr.default;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return defaults;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function computeAttrs(attrs, value) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let built = Object.create(null);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let name in attrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let given = value && value[name];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (given === undefined) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let attr = attrs[name];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (attr.hasDefault)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                given = attr.default;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else
 | 
						
						
						
						
							 | 
							
								 | 
							
							                throw new RangeError("No value supplied for attribute " + name);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        built[name] = given;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return built;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function initAttrs(attrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let result = Object.create(null);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (attrs)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let name in attrs)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            result[name] = new Attribute(attrs[name]);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							Node types are objects allocated once per `Schema` and used to
 | 
						
						
						
						
							 | 
							
								 | 
							
							[tag](https://prosemirror.net/docs/ref/#model.Node.type) `Node` instances. They contain information
 | 
						
						
						
						
							 | 
							
								 | 
							
							about the node type, such as its name and what kind of node it
 | 
						
						
						
						
							 | 
							
								 | 
							
							represents.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class NodeType {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The name the node type has in this schema.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    name, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    A link back to the `Schema` the node type belongs to.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    schema, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The spec that this type is based on
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    spec) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.name = name;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.schema = schema;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.spec = spec;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							        The set of marks allowed in this node. `null` means all marks
 | 
						
						
						
						
							 | 
							
								 | 
							
							        are allowed.
 | 
						
						
						
						
							 | 
							
								 | 
							
							        */
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.markSet = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.groups = spec.group ? spec.group.split(" ") : [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.attrs = initAttrs(spec.attrs);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.defaultAttrs = defaultAttrs(this.attrs);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.contentMatch = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.inlineContent = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.isBlock = !(spec.inline || name == "text");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.isText = name == "text";
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True if this is an inline type.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isInline() { return !this.isBlock; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True if this is a textblock type, a block that contains inline
 | 
						
						
						
						
							 | 
							
								 | 
							
							    content.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isTextblock() { return this.isBlock && this.inlineContent; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True for node types that allow no content.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isLeaf() { return this.contentMatch == ContentMatch.empty; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    True when this node is an atom, i.e. when it does not have
 | 
						
						
						
						
							 | 
							
								 | 
							
							    directly editable content.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isAtom() { return this.isLeaf || !!this.spec.atom; }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The node type's [whitespace](https://prosemirror.net/docs/ref/#model.NodeSpec.whitespace) option.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get whitespace() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.spec.whitespace || (this.spec.code ? "pre" : "normal");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Tells you whether this node type has any required attributes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    hasRequiredAttrs() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let n in this.attrs)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (this.attrs[n].isRequired)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Indicates whether this node allows some of the same content as
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the given node type.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    compatibleContent(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this == other || this.contentMatch.compatible(other.contentMatch);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    computeAttrs(attrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!attrs && this.defaultAttrs)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.defaultAttrs;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return computeAttrs(this.attrs, attrs);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a `Node` of this type. The given attributes are
 | 
						
						
						
						
							 | 
							
								 | 
							
							    checked and defaulted (you can pass `null` to use the type's
 | 
						
						
						
						
							 | 
							
								 | 
							
							    defaults entirely, if no required attributes exist). `content`
 | 
						
						
						
						
							 | 
							
								 | 
							
							    may be a `Fragment`, a node, an array of nodes, or
 | 
						
						
						
						
							 | 
							
								 | 
							
							    `null`. Similarly `marks` may be `null` to default to the empty
 | 
						
						
						
						
							 | 
							
								 | 
							
							    set of marks.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    create(attrs = null, content, marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.isText)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new Error("NodeType.create can't construct text nodes");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Node(this, this.computeAttrs(attrs), Fragment.from(content), Mark.setFrom(marks));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but check the given content
 | 
						
						
						
						
							 | 
							
								 | 
							
							    against the node type's content restrictions, and throw an error
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if it doesn't match.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    createChecked(attrs = null, content, marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        content = Fragment.from(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.checkContent(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Node(this, this.computeAttrs(attrs), content, Mark.setFrom(marks));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but see if it is
 | 
						
						
						
						
							 | 
							
								 | 
							
							    necessary to add nodes to the start or end of the given fragment
 | 
						
						
						
						
							 | 
							
								 | 
							
							    to make it fit the node. If no fitting wrapping can be found,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return null. Note that, due to the fact that required nodes can
 | 
						
						
						
						
							 | 
							
								 | 
							
							    always be created, this will always succeed if you pass null or
 | 
						
						
						
						
							 | 
							
								 | 
							
							    `Fragment.empty` as content.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    createAndFill(attrs = null, content, marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        attrs = this.computeAttrs(attrs);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        content = Fragment.from(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (content.size) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let before = this.contentMatch.fillBefore(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!before)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content = before.append(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let matched = this.contentMatch.matchFragment(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let after = matched && matched.fillBefore(Fragment.empty, true);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!after)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Node(this, attrs, content.append(after), Mark.setFrom(marks));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Returns true if the given fragment is valid content for this node
 | 
						
						
						
						
							 | 
							
								 | 
							
							    type with the given attributes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    validContent(content) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let result = this.contentMatch.matchFragment(content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!result || !result.validEnd)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < content.childCount; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!this.allowsMarks(content.child(i).marks))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Throws a RangeError if the given fragment is not valid content for this
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node type.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    checkContent(content) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!this.validContent(content))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Check whether the given mark type is allowed in this node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    allowsMarkType(markType) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.markSet == null || this.markSet.indexOf(markType) > -1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Test whether the given set of marks are allowed in this node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    allowsMarks(marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.markSet == null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < marks.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!this.allowsMarkType(marks[i].type))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Removes the marks that are not allowed in this node from the given set.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    allowedMarks(marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.markSet == null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let copy;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < marks.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!this.allowsMarkType(marks[i].type)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!copy)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    copy = marks.slice(0, i);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (copy) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                copy.push(marks[i]);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return !copy ? marks : copy.length ? copy : Mark.none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static compile(nodes, schema) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let result = Object.create(null);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        nodes.forEach((name, spec) => result[name] = new NodeType(name, schema, spec));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let topType = schema.spec.topNode || "doc";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!result[topType])
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Schema is missing its top node type ('" + topType + "')");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!result.text)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Every schema needs a 'text' type");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let _ in result.text.attrs)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("The text node type should not have attributes");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Attribute descriptors
 | 
						
						
						
						
							 | 
							
								 | 
							
							class Attribute {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(options) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.hasDefault = Object.prototype.hasOwnProperty.call(options, "default");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.default = options.default;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get isRequired() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return !this.hasDefault;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Marks
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							Like nodes, marks (which are associated with nodes to signify
 | 
						
						
						
						
							 | 
							
								 | 
							
							things like emphasis or being part of a link) are
 | 
						
						
						
						
							 | 
							
								 | 
							
							[tagged](https://prosemirror.net/docs/ref/#model.Mark.type) with type objects, which are
 | 
						
						
						
						
							 | 
							
								 | 
							
							instantiated once per `Schema`.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class MarkType {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The name of the mark type.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    name, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    rank, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The schema that this mark type instance is part of.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    schema, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The spec on which the type is based.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    spec) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.name = name;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.rank = rank;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.schema = schema;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.spec = spec;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.attrs = initAttrs(spec.attrs);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.excluded = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let defaults = defaultAttrs(this.attrs);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.instance = defaults ? new Mark(this, defaults) : null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a mark of this type. `attrs` may be `null` or an object
 | 
						
						
						
						
							 | 
							
								 | 
							
							    containing only some of the mark's attributes. The others, if
 | 
						
						
						
						
							 | 
							
								 | 
							
							    they have defaults, will be added.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    create(attrs = null) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!attrs && this.instance)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.instance;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new Mark(this, computeAttrs(this.attrs, attrs));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static compile(marks, schema) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let result = Object.create(null), rank = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        marks.forEach((name, spec) => result[name] = new MarkType(name, rank++, schema, spec));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    When there is a mark of this type in the given set, a new set
 | 
						
						
						
						
							 | 
							
								 | 
							
							    without it is returned. Otherwise, the input set is returned.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    removeFromSet(set) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (var i = 0; i < set.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (set[i].type == this) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                set = set.slice(0, i).concat(set.slice(i + 1));
 | 
						
						
						
						
							 | 
							
								 | 
							
							                i--;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return set;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Tests whether there is a mark of this type in the given set.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    isInSet(set) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < set.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (set[i].type == this)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return set[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Queries whether a given mark type is
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    excludes(other) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.excluded.indexOf(other) > -1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							A document schema. Holds [node](https://prosemirror.net/docs/ref/#model.NodeType) and [mark
 | 
						
						
						
						
							 | 
							
								 | 
							
							type](https://prosemirror.net/docs/ref/#model.MarkType) objects for the nodes and marks that may
 | 
						
						
						
						
							 | 
							
								 | 
							
							occur in conforming documents, and provides functionality for
 | 
						
						
						
						
							 | 
							
								 | 
							
							creating and deserializing such documents.
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							When given, the type parameters provide the names of the nodes and
 | 
						
						
						
						
							 | 
							
								 | 
							
							marks in this schema.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class Schema {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Construct a schema from a schema [specification](https://prosemirror.net/docs/ref/#model.SchemaSpec).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(spec) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							        An object for storing whatever values modules may want to
 | 
						
						
						
						
							 | 
							
								 | 
							
							        compute and cache per schema. (If you want to store something
 | 
						
						
						
						
							 | 
							
								 | 
							
							        in it, try to use property names unlikely to clash.)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        */
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.cached = Object.create(null);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let instanceSpec = this.spec = {};
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let prop in spec)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            instanceSpec[prop] = spec[prop];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        instanceSpec.nodes = OrderedMap.from(spec.nodes),
 | 
						
						
						
						
							 | 
							
								 | 
							
							            instanceSpec.marks = OrderedMap.from(spec.marks || {}),
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.nodes = NodeType.compile(this.spec.nodes, this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.marks = MarkType.compile(this.spec.marks, this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let contentExprCache = Object.create(null);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let prop in this.nodes) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (prop in this.marks)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                throw new RangeError(prop + " can not be both a node and a mark");
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let type = this.nodes[prop], contentExpr = type.spec.content || "", markExpr = type.spec.marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            type.contentMatch = contentExprCache[contentExpr] ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							                (contentExprCache[contentExpr] = ContentMatch.parse(contentExpr, this.nodes));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            type.inlineContent = type.contentMatch.inlineContent;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            type.markSet = markExpr == "_" ? null :
 | 
						
						
						
						
							 | 
							
								 | 
							
							                markExpr ? gatherMarks(this, markExpr.split(" ")) :
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    markExpr == "" || !type.inlineContent ? [] : null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let prop in this.marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let type = this.marks[prop], excl = type.spec.excludes;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" "));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.nodeFromJSON = this.nodeFromJSON.bind(this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.markFromJSON = this.markFromJSON.bind(this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.topNodeType = this.nodes[this.spec.topNode || "doc"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.cached.wrappings = Object.create(null);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a node in this schema. The `type` may be a string or a
 | 
						
						
						
						
							 | 
							
								 | 
							
							    `NodeType` instance. Attributes will be extended with defaults,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    `content` may be a `Fragment`, `null`, a `Node`, or an array of
 | 
						
						
						
						
							 | 
							
								 | 
							
							    nodes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node(type, attrs = null, content, marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (typeof type == "string")
 | 
						
						
						
						
							 | 
							
								 | 
							
							            type = this.nodeType(type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (!(type instanceof NodeType))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Invalid node type: " + type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (type.schema != this)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Node type from different schema used (" + type.name + ")");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return type.createChecked(attrs, content, marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a text node in the schema. Empty text nodes are not
 | 
						
						
						
						
							 | 
							
								 | 
							
							    allowed.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    text(text, marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let type = this.nodes.text;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return new TextNode(type, type.defaultAttrs, text, Mark.setFrom(marks));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a mark with the given type and attributes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    mark(type, attrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (typeof type == "string")
 | 
						
						
						
						
							 | 
							
								 | 
							
							            type = this.marks[type];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return type.create(attrs);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Deserialize a node from its JSON representation. This method is
 | 
						
						
						
						
							 | 
							
								 | 
							
							    bound.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    nodeFromJSON(json) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return Node.fromJSON(this, json);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Deserialize a mark from its JSON representation. This method is
 | 
						
						
						
						
							 | 
							
								 | 
							
							    bound.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    markFromJSON(json) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return Mark.fromJSON(this, json);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    nodeType(name) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let found = this.nodes[name];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!found)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new RangeError("Unknown node type: " + name);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return found;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function gatherMarks(schema, marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let found = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let i = 0; i < marks.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let name = marks[i], mark = schema.marks[name], ok = mark;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (mark) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            found.push(mark);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let prop in schema.marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let mark = schema.marks[prop];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (name == "_" || (mark.spec.group && mark.spec.group.split(" ").indexOf(name) > -1))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    found.push(ok = mark);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!ok)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            throw new SyntaxError("Unknown mark type: '" + marks[i] + "'");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return found;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							A DOM parser represents a strategy for parsing DOM content into a
 | 
						
						
						
						
							 | 
							
								 | 
							
							ProseMirror document conforming to a given schema. Its behavior is
 | 
						
						
						
						
							 | 
							
								 | 
							
							defined by an array of [rules](https://prosemirror.net/docs/ref/#model.ParseRule).
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class DOMParser {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a parser that targets the given schema, using the given
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parsing rules.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The schema into which the parser parses.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    schema, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The set of [parse rules](https://prosemirror.net/docs/ref/#model.ParseRule) that the parser
 | 
						
						
						
						
							 | 
							
								 | 
							
							    uses, in order of precedence.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    rules) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.schema = schema;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.rules = rules;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							        @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							        */
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.tags = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							        @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							        */
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.styles = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        rules.forEach(rule => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (rule.tag)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.tags.push(rule);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (rule.style)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.styles.push(rule);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // Only normalize list elements when lists in the schema can't directly contain themselves
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.normalizeLists = !this.tags.some(r => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!/^(ul|ol)\b/.test(r.tag) || !r.node)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let node = schema.nodes[r.node];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return node.contentMatch.matchType(node);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        });
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Parse a document from the content of a DOM node.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parse(dom, options = {}) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let context = new ParseContext(this, options, false);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        context.addAll(dom, options.from, options.to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return context.finish();
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Parses the content of the given DOM node, like
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [`parse`](https://prosemirror.net/docs/ref/#model.DOMParser.parse), and takes the same set of
 | 
						
						
						
						
							 | 
							
								 | 
							
							    options. But unlike that method, which produces a whole node,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    this one returns a slice that is open at the sides, meaning that
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the schema constraints aren't applied to the start of nodes to
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the left of the input and the end of nodes at the end.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parseSlice(dom, options = {}) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let context = new ParseContext(this, options, true);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        context.addAll(dom, options.from, options.to);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return Slice.maxOpen(context.finish());
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    matchTag(dom, context, after) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = after ? this.tags.indexOf(after) + 1 : 0; i < this.tags.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let rule = this.tags[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (matches(dom, rule.tag) &&
 | 
						
						
						
						
							 | 
							
								 | 
							
							                (rule.namespace === undefined || dom.namespaceURI == rule.namespace) &&
 | 
						
						
						
						
							 | 
							
								 | 
							
							                (!rule.context || context.matchesContext(rule.context))) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (rule.getAttrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let result = rule.getAttrs(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (result === false)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        continue;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    rule.attrs = result || undefined;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return rule;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    matchStyle(prop, value, context, after) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = after ? this.styles.indexOf(after) + 1 : 0; i < this.styles.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let rule = this.styles[i], style = rule.style;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (style.indexOf(prop) != 0 ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							                rule.context && !context.matchesContext(rule.context) ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // Test that the style string either precisely matches the prop,
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // or has an '=' sign after the prop, followed by the given
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // value.
 | 
						
						
						
						
							 | 
							
								 | 
							
							                style.length > prop.length &&
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    (style.charCodeAt(prop.length) != 61 || style.slice(prop.length + 1) != value))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                continue;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (rule.getAttrs) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let result = rule.getAttrs(value);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (result === false)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    continue;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                rule.attrs = result || undefined;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return rule;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static schemaRules(schema) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let result = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function insert(rule) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let priority = rule.priority == null ? 50 : rule.priority, i = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (; i < result.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let next = result[i], nextPriority = next.priority == null ? 50 : next.priority;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (nextPriority < priority)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            result.splice(i, 0, rule);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let name in schema.marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let rules = schema.marks[name].spec.parseDOM;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (rules)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                rules.forEach(rule => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    insert(rule = copy(rule));
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    rule.mark = name;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let name in schema.nodes) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let rules = schema.nodes[name].spec.parseDOM;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (rules)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                rules.forEach(rule => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    insert(rule = copy(rule));
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    rule.node = name;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Construct a DOM parser using the parsing rules listed in a
 | 
						
						
						
						
							 | 
							
								 | 
							
							    schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static fromSchema(schema) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return schema.cached.domParser ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							            (schema.cached.domParser = new DOMParser(schema, DOMParser.schemaRules(schema)));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							const blockTags = {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    address: true, article: true, aside: true, blockquote: true, canvas: true,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    dd: true, div: true, dl: true, fieldset: true, figcaption: true, figure: true,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    footer: true, form: true, h1: true, h2: true, h3: true, h4: true, h5: true,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    h6: true, header: true, hgroup: true, hr: true, li: true, noscript: true, ol: true,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    output: true, p: true, pre: true, section: true, table: true, tfoot: true, ul: true
 | 
						
						
						
						
							 | 
							
								 | 
							
							};
 | 
						
						
						
						
							 | 
							
								 | 
							
							const ignoreTags = {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    head: true, noscript: true, object: true, script: true, style: true, title: true
 | 
						
						
						
						
							 | 
							
								 | 
							
							};
 | 
						
						
						
						
							 | 
							
								 | 
							
							const listTags = { ol: true, ul: true };
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Using a bitfield for node context options
 | 
						
						
						
						
							 | 
							
								 | 
							
							const OPT_PRESERVE_WS = 1, OPT_PRESERVE_WS_FULL = 2, OPT_OPEN_LEFT = 4;
 | 
						
						
						
						
							 | 
							
								 | 
							
							function wsOptionsFor(type, preserveWhitespace, base) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (preserveWhitespace != null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return (preserveWhitespace ? OPT_PRESERVE_WS : 0) |
 | 
						
						
						
						
							 | 
							
								 | 
							
							            (preserveWhitespace === "full" ? OPT_PRESERVE_WS_FULL : 0);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & ~OPT_OPEN_LEFT;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							class NodeContext {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(type, attrs, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Marks applied to this node itself
 | 
						
						
						
						
							 | 
							
								 | 
							
							    marks, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Marks that can't apply here, but will be used in children if possible
 | 
						
						
						
						
							 | 
							
								 | 
							
							    pendingMarks, solid, match, options) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.type = type;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.attrs = attrs;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.marks = marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.pendingMarks = pendingMarks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.solid = solid;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.options = options;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.content = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // Marks applied to the node's children
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.activeMarks = Mark.none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // Nested Marks with same type
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.stashMarks = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.match = match || (options & OPT_OPEN_LEFT ? null : type.contentMatch);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findWrapping(node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!this.match) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!this.type)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let fill = this.type.contentMatch.fillBefore(Fragment.from(node));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (fill) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.match = this.type.contentMatch.matchFragment(fill);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let start = this.type.contentMatch, wrap;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (wrap = start.findWrapping(node.type)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.match = start;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return wrap;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.match.findWrapping(node.type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    finish(openEnd) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!(this.options & OPT_PRESERVE_WS)) { // Strip trailing whitespace
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let last = this.content[this.content.length - 1], m;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (last && last.isText && (m = /[ \t\r\n\u000c]+$/.exec(last.text))) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let text = last;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (last.text.length == m[0].length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.content.pop();
 | 
						
						
						
						
							 | 
							
								 | 
							
							                else
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.content[this.content.length - 1] = text.withText(text.text.slice(0, text.text.length - m[0].length));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let content = Fragment.from(this.content);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!openEnd && this.match)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content = content.append(this.match.fillBefore(Fragment.empty, true));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.type ? this.type.create(this.attrs, content, this.marks) : content;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    popFromStashMark(mark) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = this.stashMarks.length - 1; i >= 0; i--)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (mark.eq(this.stashMarks[i]))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return this.stashMarks.splice(i, 1)[0];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    applyPending(nextType) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0, pending = this.pendingMarks; i < pending.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let mark = pending[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if ((this.type ? this.type.allowsMarkType(mark.type) : markMayApply(mark.type, nextType)) &&
 | 
						
						
						
						
							 | 
							
								 | 
							
							                !mark.isInSet(this.activeMarks)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.activeMarks = mark.addToSet(this.activeMarks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.pendingMarks = mark.removeFromSet(this.pendingMarks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    inlineContext(node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.type)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.type.inlineContent;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.content.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return this.content[0].isInline;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return node.parentNode && !blockTags.hasOwnProperty(node.parentNode.nodeName.toLowerCase());
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							class ParseContext {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // The parser we are using.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    parser, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // The options passed to this parse.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    options, isOpen) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.parser = parser;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.options = options;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.isOpen = isOpen;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.open = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let topNode = options.topNode, topContext;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (topNode)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none, Mark.none, true, options.topMatch || topNode.type.contentMatch, topOptions);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (isOpen)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            topContext = new NodeContext(null, null, Mark.none, Mark.none, true, null, topOptions);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else
 | 
						
						
						
						
							 | 
							
								 | 
							
							            topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none, Mark.none, true, null, topOptions);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.nodes = [topContext];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.find = options.findPositions;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.needsBlock = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get top() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.nodes[this.open];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Add a DOM node to the content. Text is inserted as text node,
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // otherwise, the node is passed to `addElement` or, if it has a
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // `style` attribute, `addElementWithStyles`.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addDOM(dom) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (dom.nodeType == 3) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.addTextNode(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (dom.nodeType == 1) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let style = dom.getAttribute("style");
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let marks = style ? this.readStyles(parseStyles(style)) : null, top = this.top;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (marks != null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                for (let i = 0; i < marks.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.addPendingMark(marks[i]);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.addElement(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (marks != null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                for (let i = 0; i < marks.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.removePendingMark(marks[i], top);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addTextNode(dom) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let value = dom.nodeValue;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let top = this.top;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (top.options & OPT_PRESERVE_WS_FULL ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							            top.inlineContext(dom) ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							            /[^ \t\r\n\u000c]/.test(value)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!(top.options & OPT_PRESERVE_WS)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                value = value.replace(/[ \t\r\n\u000c]+/g, " ");
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // If this starts with whitespace, and there is no node before it, or
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // a hard break, or a text node that ends with whitespace, strip the
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // leading space.
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (/^[ \t\r\n\u000c]/.test(value) && this.open == this.nodes.length - 1) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let nodeBefore = top.content[top.content.length - 1];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let domNodeBefore = dom.previousSibling;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (!nodeBefore ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        (domNodeBefore && domNodeBefore.nodeName == 'BR') ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        (nodeBefore.isText && /[ \t\r\n\u000c]$/.test(nodeBefore.text)))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        value = value.slice(1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (!(top.options & OPT_PRESERVE_WS_FULL)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                value = value.replace(/\r?\n|\r/g, " ");
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                value = value.replace(/\r\n?/g, "\n");
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (value)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.insertNode(this.parser.schema.text(value));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.findInText(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.findInside(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Try to find a handler for the given tag and use that to parse. If
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // none is found, the element's content nodes are added directly.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addElement(dom, matchAfter) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let name = dom.nodeName.toLowerCase(), ruleID;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (listTags.hasOwnProperty(name) && this.parser.normalizeLists)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            normalizeList(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let rule = (this.options.ruleFromNode && this.options.ruleFromNode(dom)) ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							            (ruleID = this.parser.matchTag(dom, this, matchAfter));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.findInside(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.ignoreFallback(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (!rule || rule.skip || rule.closeParent) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (rule && rule.closeParent)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.open = Math.max(0, this.open - 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (rule && rule.skip.nodeType)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                dom = rule.skip;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let sync, top = this.top, oldNeedsBlock = this.needsBlock;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (blockTags.hasOwnProperty(name)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (top.content.length && top.content[0].isInline && this.open) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.open--;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    top = this.top;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                sync = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!top.type)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.needsBlock = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (!dom.firstChild) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.leafFallback(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.addAll(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (sync)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.sync(top);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.needsBlock = oldNeedsBlock;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.addElementByRule(dom, rule, rule.consuming === false ? ruleID : undefined);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Called for leaf DOM nodes that would otherwise be ignored
 | 
						
						
						
						
							 | 
							
								 | 
							
							    leafFallback(dom) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (dom.nodeName == "BR" && this.top.type && this.top.type.inlineContent)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.addTextNode(dom.ownerDocument.createTextNode("\n"));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Called for ignored nodes
 | 
						
						
						
						
							 | 
							
								 | 
							
							    ignoreFallback(dom) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // Ignored BR nodes should at least create an inline context
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.findPlace(this.parser.schema.text("-"));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Run any style parser associated with the node's styles. Either
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // return an array of marks, or null to indicate some of the styles
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // had a rule with `ignore` set.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    readStyles(styles) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let marks = Mark.none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        style: for (let i = 0; i < styles.length; i += 2) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let after = undefined;;) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let rule = this.parser.matchStyle(styles[i], styles[i + 1], this, after);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!rule)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    continue style;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (rule.ignore)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                marks = this.parser.schema.marks[rule.mark].create(rule.attrs).addToSet(marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (rule.consuming === false)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    after = rule;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                else
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Look up a handler for the given node. If none are found, return
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // false. Otherwise, apply it, use its return value to drive the way
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // the node's content is wrapped, and return true.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addElementByRule(dom, rule, continueAfter) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let sync, nodeType, mark;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (rule.node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            nodeType = this.parser.schema.nodes[rule.node];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!nodeType.isLeaf) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                sync = this.enter(nodeType, rule.attrs || null, rule.preserveWhitespace);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (!this.insertNode(nodeType.create(rule.attrs))) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.leafFallback(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let markType = this.parser.schema.marks[rule.mark];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            mark = markType.create(rule.attrs);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.addPendingMark(mark);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let startIn = this.top;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (nodeType && nodeType.isLeaf) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.findInside(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (continueAfter) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.addElement(dom, continueAfter);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (rule.getContent) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.findInside(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let contentDOM = dom;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (typeof rule.contentElement == "string")
 | 
						
						
						
						
							 | 
							
								 | 
							
							                contentDOM = dom.querySelector(rule.contentElement);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (typeof rule.contentElement == "function")
 | 
						
						
						
						
							 | 
							
								 | 
							
							                contentDOM = rule.contentElement(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else if (rule.contentElement)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                contentDOM = rule.contentElement;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.findAround(dom, contentDOM, true);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.addAll(contentDOM);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (sync && this.sync(startIn))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.open--;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (mark)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.removePendingMark(mark, startIn);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Add all child nodes between `startIndex` and `endIndex` (or the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // whole node, if not given). If `sync` is passed, use it to
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // synchronize after every block element.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addAll(parent, startIndex, endIndex) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let index = startIndex || 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let dom = startIndex ? parent.childNodes[startIndex] : parent.firstChild, end = endIndex == null ? null : parent.childNodes[endIndex]; dom != end; dom = dom.nextSibling, ++index) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.findAtPoint(parent, index);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.addDOM(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.findAtPoint(parent, index);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Try to find a way to fit the given node type into the current
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // context. May add intermediate wrappers and/or leave non-solid
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // nodes that we're in.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findPlace(node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let route, sync;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let depth = this.open; depth >= 0; depth--) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let cx = this.nodes[depth];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let found = cx.findWrapping(node);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (found && (!route || route.length > found.length)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                route = found;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                sync = cx;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!found.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (cx.solid)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!route)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.sync(sync);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = 0; i < route.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.enterInner(route[i], null, false);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Try to insert the given node, adjusting the context when needed.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    insertNode(node) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (node.isInline && this.needsBlock && !this.top.type) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let block = this.textblockFromContext();
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (block)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.enterInner(block);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.findPlace(node)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.closeExtra();
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let top = this.top;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            top.applyPending(node.type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (top.match)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                top.match = top.match.matchType(node.type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let marks = top.activeMarks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < node.marks.length; i++)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!top.type || top.type.allowsMarkType(node.marks[i].type))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    marks = node.marks[i].addToSet(marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            top.content.push(node.mark(marks));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Try to start a node of the given type, adjusting the context when
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // necessary.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    enter(type, attrs, preserveWS) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let ok = this.findPlace(type.create(attrs));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (ok)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.enterInner(type, attrs, true, preserveWS);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return ok;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Open a node of the given type
 | 
						
						
						
						
							 | 
							
								 | 
							
							    enterInner(type, attrs = null, solid = false, preserveWS) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.closeExtra();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let top = this.top;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        top.applyPending(type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        top.match = top.match && top.match.matchType(type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let options = wsOptionsFor(type, preserveWS, top.options);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ((top.options & OPT_OPEN_LEFT) && top.content.length == 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            options |= OPT_OPEN_LEFT;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.nodes.push(new NodeContext(type, attrs, top.activeMarks, top.pendingMarks, solid, null, options));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.open++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Make sure all nodes above this.open are finished and added to
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // their parents
 | 
						
						
						
						
							 | 
							
								 | 
							
							    closeExtra(openEnd = false) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let i = this.nodes.length - 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (i > this.open) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (; i > this.open; i--)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.nodes[i - 1].content.push(this.nodes[i].finish(openEnd));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.nodes.length = this.open + 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    finish() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.open = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.closeExtra(this.isOpen);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return this.nodes[0].finish(this.isOpen || this.options.topOpen);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    sync(to) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = this.open; i >= 0; i--)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (this.nodes[i] == to) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                this.open = i;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    get currentPos() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.closeExtra();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let pos = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = this.open; i >= 0; i--) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let content = this.nodes[i].content;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let j = content.length - 1; j >= 0; j--)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                pos += content[j].nodeSize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (i)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                pos++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return pos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findAtPoint(parent, offset) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.find)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < this.find.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (this.find[i].node == parent && this.find[i].offset == offset)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.find[i].pos = this.currentPos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findInside(parent) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.find)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < this.find.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (this.find[i].pos == null && parent.nodeType == 1 && parent.contains(this.find[i].node))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.find[i].pos = this.currentPos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findAround(parent, content, before) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (parent != content && this.find)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < this.find.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (this.find[i].pos == null && parent.nodeType == 1 && parent.contains(this.find[i].node)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let pos = content.compareDocumentPosition(this.find[i].node);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (pos & (before ? 2 : 4))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        this.find[i].pos = this.currentPos;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    findInText(textNode) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (this.find)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < this.find.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (this.find[i].node == textNode)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    this.find[i].pos = this.currentPos - (textNode.nodeValue.length - this.find[i].offset);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Determines whether the given context string matches this context.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    matchesContext(context) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (context.indexOf("|") > -1)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return context.split(/\s*\|\s*/).some(this.matchesContext, this);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let parts = context.split("/");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let option = this.options.context;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let useRoot = !this.isOpen && (!option || option.parent.type == this.nodes[0].type);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let minDepth = -(option ? option.depth + 1 : 0) + (useRoot ? 0 : 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let match = (i, depth) => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (; i >= 0; i--) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let part = parts[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (part == "") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (i == parts.length - 1 || i == 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        continue;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    for (; depth >= minDepth; depth--)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (match(i - 1, depth))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let next = depth > 0 || (depth == 0 && useRoot) ? this.nodes[depth].type
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        : option && depth >= minDepth ? option.node(depth - minDepth).type
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            : null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (!next || (next.name != part && next.groups.indexOf(part) == -1))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        return false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    depth--;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return match(parts.length - 1, this.open);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    textblockFromContext() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let $context = this.options.context;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ($context)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let d = $context.depth; d >= 0; d--) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let deflt = $context.node(d).contentMatchAt($context.indexAfter(d)).defaultType;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (deflt && deflt.isTextblock && deflt.defaultAttrs)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return deflt;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let name in this.parser.schema.nodes) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let type = this.parser.schema.nodes[name];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (type.isTextblock && type.defaultAttrs)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return type;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    addPendingMark(mark) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let found = findSameMarkInSet(mark, this.top.pendingMarks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (found)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.top.stashMarks.push(found);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.top.pendingMarks = mark.addToSet(this.top.pendingMarks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    removePendingMark(mark, upto) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let depth = this.open; depth >= 0; depth--) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let level = this.nodes[depth];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let found = level.pendingMarks.lastIndexOf(mark);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (found > -1) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                level.pendingMarks = mark.removeFromSet(level.pendingMarks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                level.activeMarks = mark.removeFromSet(level.activeMarks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let stashMark = level.popFromStashMark(mark);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (stashMark && level.type && level.type.allowsMarkType(stashMark.type))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    level.activeMarks = stashMark.addToSet(level.activeMarks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (level == upto)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Kludge to work around directly nested list nodes produced by some
 | 
						
						
						
						
							 | 
							
								 | 
							
							// tools and allowed by browsers to mean that the nested list is
 | 
						
						
						
						
							 | 
							
								 | 
							
							// actually part of the list item above it.
 | 
						
						
						
						
							 | 
							
								 | 
							
							function normalizeList(dom) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let child = dom.firstChild, prevItem = null; child; child = child.nextSibling) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let name = child.nodeType == 1 ? child.nodeName.toLowerCase() : null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (name && listTags.hasOwnProperty(name) && prevItem) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            prevItem.appendChild(child);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            child = prevItem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (name == "li") {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            prevItem = child;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        else if (name) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            prevItem = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Apply a CSS selector.
 | 
						
						
						
						
							 | 
							
								 | 
							
							function matches(dom, selector) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return (dom.matches || dom.msMatchesSelector || dom.webkitMatchesSelector || dom.mozMatchesSelector).call(dom, selector);
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Tokenize a style attribute into property/value pairs.
 | 
						
						
						
						
							 | 
							
								 | 
							
							function parseStyles(style) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let re = /\s*([\w-]+)\s*:\s*([^;]+)/g, m, result = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    while (m = re.exec(style))
 | 
						
						
						
						
							 | 
							
								 | 
							
							        result.push(m[1], m[2].trim());
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function copy(obj) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let copy = {};
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let prop in obj)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        copy[prop] = obj[prop];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return copy;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Used when finding a mark at the top level of a fragment parse.
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Checks whether it would be reasonable to apply a given mark type to
 | 
						
						
						
						
							 | 
							
								 | 
							
							// a given node, by looking at the way the mark occurs in the schema.
 | 
						
						
						
						
							 | 
							
								 | 
							
							function markMayApply(markType, nodeType) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let nodes = nodeType.schema.nodes;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let name in nodes) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let parent = nodes[name];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!parent.allowsMarkType(markType))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            continue;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let seen = [], scan = (match) => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            seen.push(match);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let i = 0; i < match.edgeCount; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let { type, next } = match.edge(i);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (type == nodeType)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (seen.indexOf(next) < 0 && scan(next))
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (scan(parent.contentMatch))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function findSameMarkInSet(mark, set) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let i = 0; i < set.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (mark.eq(set[i]))
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return set[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							/**
 | 
						
						
						
						
							 | 
							
								 | 
							
							A DOM serializer knows how to convert ProseMirror nodes and
 | 
						
						
						
						
							 | 
							
								 | 
							
							marks of various types to DOM nodes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							*/
 | 
						
						
						
						
							 | 
							
								 | 
							
							class DOMSerializer {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Create a serializer. `nodes` should map node names to functions
 | 
						
						
						
						
							 | 
							
								 | 
							
							    that take a node and return a description of the corresponding
 | 
						
						
						
						
							 | 
							
								 | 
							
							    DOM. `marks` does the same for mark names, but also gets an
 | 
						
						
						
						
							 | 
							
								 | 
							
							    argument that tells it whether the mark's content is block or
 | 
						
						
						
						
							 | 
							
								 | 
							
							    inline content (for typical use, it'll always be inline). A mark
 | 
						
						
						
						
							 | 
							
								 | 
							
							    serializer may be `null` to indicate that marks of that type
 | 
						
						
						
						
							 | 
							
								 | 
							
							    should not be serialized.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    constructor(
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The node serialization functions.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    nodes, 
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    The mark serialization functions.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    marks) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.nodes = nodes;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        this.marks = marks;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Serialize the content of this fragment to a DOM fragment. When
 | 
						
						
						
						
							 | 
							
								 | 
							
							    not in the browser, the `document` option, containing a DOM
 | 
						
						
						
						
							 | 
							
								 | 
							
							    document, should be passed so that the serializer can create
 | 
						
						
						
						
							 | 
							
								 | 
							
							    nodes.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    serializeFragment(fragment, options = {}, target) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!target)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            target = doc(options).createDocumentFragment();
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let top = target, active = [];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        fragment.forEach(node => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (active.length || node.marks.length) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let keep = 0, rendered = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                while (keep < active.length && rendered < node.marks.length) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let next = node.marks[rendered];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (!this.marks[next.type.name]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        rendered++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        continue;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (!next.eq(active[keep][0]) || next.type.spec.spanning === false)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    keep++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    rendered++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                while (keep < active.length)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    top = active.pop()[1];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                while (rendered < node.marks.length) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let add = node.marks[rendered++];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let markDOM = this.serializeMark(add, node.isInline, options);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (markDOM) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        active.push([add, top]);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        top.appendChild(markDOM.dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        top = markDOM.contentDOM || markDOM.dom;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            top.appendChild(this.serializeNodeInner(node, options));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return target;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    serializeNodeInner(node, options) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let { dom, contentDOM } = DOMSerializer.renderSpec(doc(options), this.nodes[node.type.name](node));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (contentDOM) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (node.isLeaf)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                throw new RangeError("Content hole not allowed in a leaf node spec");
 | 
						
						
						
						
							 | 
							
								 | 
							
							            this.serializeFragment(node.content, options, contentDOM);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return dom;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Serialize this node to a DOM node. This can be useful when you
 | 
						
						
						
						
							 | 
							
								 | 
							
							    need to serialize a part of a document, as opposed to the whole
 | 
						
						
						
						
							 | 
							
								 | 
							
							    document. To serialize a whole document, use
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [`serializeFragment`](https://prosemirror.net/docs/ref/#model.DOMSerializer.serializeFragment) on
 | 
						
						
						
						
							 | 
							
								 | 
							
							    its [content](https://prosemirror.net/docs/ref/#model.Node.content).
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    serializeNode(node, options = {}) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let dom = this.serializeNodeInner(node, options);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = node.marks.length - 1; i >= 0; i--) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let wrap = this.serializeMark(node.marks[i], node.isInline, options);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (wrap) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                (wrap.contentDOM || wrap.dom).appendChild(dom);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                dom = wrap.dom;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return dom;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @internal
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    serializeMark(mark, inline, options = {}) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let toDOM = this.marks[mark.type.name];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return toDOM && DOMSerializer.renderSpec(doc(options), toDOM(mark, inline));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Render an [output spec](https://prosemirror.net/docs/ref/#model.DOMOutputSpec) to a DOM node. If
 | 
						
						
						
						
							 | 
							
								 | 
							
							    the spec has a hole (zero) in it, `contentDOM` will point at the
 | 
						
						
						
						
							 | 
							
								 | 
							
							    node with the hole.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static renderSpec(doc, structure, xmlNS = null) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (typeof structure == "string")
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return { dom: doc.createTextNode(structure) };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (structure.nodeType != null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return { dom: structure };
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (structure.dom && structure.dom.nodeType != null)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return structure;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let tagName = structure[0], space = tagName.indexOf(" ");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (space > 0) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            xmlNS = tagName.slice(0, space);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            tagName = tagName.slice(space + 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let contentDOM;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let dom = (xmlNS ? doc.createElementNS(xmlNS, tagName) : doc.createElement(tagName));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let attrs = structure[1], start = 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            start = 2;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            for (let name in attrs)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (attrs[name] != null) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let space = name.indexOf(" ");
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (space > 0)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    else
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        dom.setAttribute(name, attrs[name]);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        for (let i = start; i < structure.length; i++) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            let child = structure[i];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (child === 0) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (i < structure.length - 1 || i > start)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    throw new RangeError("Content hole must be the only child of its parent node");
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return { dom, contentDOM: dom };
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                let { dom: inner, contentDOM: innerContent } = DOMSerializer.renderSpec(doc, child, xmlNS);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                dom.appendChild(inner);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (innerContent) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (contentDOM)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        throw new RangeError("Multiple content holes");
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    contentDOM = innerContent;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return { dom, contentDOM };
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Build a serializer using the [`toDOM`](https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    properties in a schema's node and mark specs.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static fromSchema(schema) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return schema.cached.domSerializer ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							            (schema.cached.domSerializer = new DOMSerializer(this.nodesFromSchema(schema), this.marksFromSchema(schema)));
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Gather the serializers in a schema's node specs into an object.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    This can be useful as a base to build a custom serializer from.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static nodesFromSchema(schema) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let result = gatherToDOM(schema.nodes);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!result.text)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            result.text = node => node.text;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    /**
 | 
						
						
						
						
							 | 
							
								 | 
							
							    Gather the serializers in a schema's mark specs into an object.
 | 
						
						
						
						
							 | 
							
								 | 
							
							    */
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static marksFromSchema(schema) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return gatherToDOM(schema.marks);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function gatherToDOM(obj) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    let result = {};
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (let name in obj) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let toDOM = obj[name].spec.toDOM;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (toDOM)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            result[name] = toDOM;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return result;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							function doc(options) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return options.document || window.document;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							export { ContentMatch, DOMParser, DOMSerializer, Fragment, Mark, MarkType, Node, NodeRange, NodeType, ReplaceError, ResolvedPos, Schema, Slice };
 |