{"version":3,"sources":["jsdelivr-header.js","/npm/@tiptap/core@2.11.7/src/helpers/createChainableState.ts","/npm/@tiptap/core@2.11.7/src/CommandManager.ts","/npm/@tiptap/core@2.11.7/src/EventEmitter.ts","/npm/@tiptap/core@2.11.7/src/helpers/getExtensionField.ts","/npm/@tiptap/core@2.11.7/src/helpers/splitExtensions.ts","/npm/@tiptap/core@2.11.7/src/helpers/getAttributesFromExtensions.ts","/npm/@tiptap/core@2.11.7/src/helpers/getNodeType.ts","/npm/@tiptap/core@2.11.7/src/utilities/mergeAttributes.ts","/npm/@tiptap/core@2.11.7/src/helpers/getRenderedAttributes.ts","/npm/@tiptap/core@2.11.7/src/utilities/isFunction.ts","/npm/@tiptap/core@2.11.7/src/utilities/callOrReturn.ts","/npm/@tiptap/core@2.11.7/src/utilities/isEmptyObject.ts","/npm/@tiptap/core@2.11.7/src/utilities/fromString.ts","/npm/@tiptap/core@2.11.7/src/helpers/injectExtensionAttributesToParseRule.ts","/npm/@tiptap/core@2.11.7/src/helpers/getSchemaByResolvedExtensions.ts","/npm/@tiptap/core@2.11.7/src/helpers/getSchemaTypeByName.ts","/npm/@tiptap/core@2.11.7/src/helpers/isExtensionRulesEnabled.ts","/npm/@tiptap/core@2.11.7/src/helpers/getHTMLFromFragment.ts","/npm/@tiptap/core@2.11.7/src/helpers/getTextContentFromNodes.ts","/npm/@tiptap/core@2.11.7/src/utilities/isRegExp.ts","/npm/@tiptap/core@2.11.7/src/InputRule.ts","/npm/@tiptap/core@2.11.7/src/utilities/isPlainObject.ts","/npm/@tiptap/core@2.11.7/src/utilities/mergeDeep.ts","/npm/@tiptap/core@2.11.7/src/Mark.ts","/npm/@tiptap/core@2.11.7/src/utilities/isNumber.ts","/npm/@tiptap/core@2.11.7/src/PasteRule.ts","/npm/@tiptap/core@2.11.7/src/utilities/findDuplicates.ts","/npm/@tiptap/core@2.11.7/src/ExtensionManager.ts","/npm/@tiptap/core@2.11.7/src/Extension.ts","/npm/@tiptap/core@2.11.7/src/helpers/getTextBetween.ts","/npm/@tiptap/core@2.11.7/src/helpers/getTextSerializersFromSchema.ts","/npm/@tiptap/core@2.11.7/src/extensions/clipboardTextSerializer.ts","/npm/@tiptap/core@2.11.7/src/utilities/objectIncludes.ts","/npm/@tiptap/core@2.11.7/src/helpers/getMarkRange.ts","/npm/@tiptap/core@2.11.7/src/helpers/getMarkType.ts","/npm/@tiptap/core@2.11.7/src/helpers/isTextSelection.ts","/npm/@tiptap/core@2.11.7/src/utilities/minMax.ts","/npm/@tiptap/core@2.11.7/src/helpers/resolveFocusPosition.ts","/npm/@tiptap/core@2.11.7/src/utilities/isAndroid.ts","/npm/@tiptap/core@2.11.7/src/utilities/isiOS.ts","/npm/@tiptap/core@2.11.7/src/commands/focus.ts","/npm/@tiptap/core@2.11.7/src/utilities/elementFromString.ts","/npm/@tiptap/core@2.11.7/src/helpers/createNodeFromContent.ts","/npm/@tiptap/core@2.11.7/src/helpers/selectionToInsertionEnd.ts","/npm/@tiptap/core@2.11.7/src/utilities/isMacOS.ts","/npm/@tiptap/core@2.11.7/src/helpers/isNodeActive.ts","/npm/@tiptap/core@2.11.7/src/helpers/getSchemaTypeNameByName.ts","/npm/@tiptap/core@2.11.7/src/utilities/deleteProps.ts","/npm/@tiptap/core@2.11.7/src/helpers/createDocument.ts","/npm/@tiptap/core@2.11.7/src/helpers/getMarkAttributes.ts","/npm/@tiptap/core@2.11.7/src/helpers/defaultBlockAt.ts","/npm/@tiptap/core@2.11.7/src/helpers/findParentNodeClosestToPos.ts","/npm/@tiptap/core@2.11.7/src/helpers/findParentNode.ts","/npm/@tiptap/core@2.11.7/src/helpers/getSchema.ts","/npm/@tiptap/core@2.11.7/src/helpers/getText.ts","/npm/@tiptap/core@2.11.7/src/helpers/getNodeAttributes.ts","/npm/@tiptap/core@2.11.7/src/helpers/getAttributes.ts","/npm/@tiptap/core@2.11.7/src/utilities/removeDuplicates.ts","/npm/@tiptap/core@2.11.7/src/helpers/getMarksBetween.ts","/npm/@tiptap/core@2.11.7/src/helpers/getSplittedAttributes.ts","/npm/@tiptap/core@2.11.7/src/helpers/isMarkActive.ts","/npm/@tiptap/core@2.11.7/src/helpers/isActive.ts","/npm/@tiptap/core@2.11.7/src/helpers/isList.ts","/npm/@tiptap/core@2.11.7/src/helpers/isNodeEmpty.ts","/npm/@tiptap/core@2.11.7/src/helpers/rewriteUnknownContent.ts","/npm/@tiptap/core@2.11.7/src/commands/splitBlock.ts","/npm/@tiptap/core@2.11.7/src/commands/toggleList.ts","/npm/@tiptap/core@2.11.7/src/commands/blur.ts","/npm/@tiptap/core@2.11.7/src/commands/clearContent.ts","/npm/@tiptap/core@2.11.7/src/commands/clearNodes.ts","/npm/@tiptap/core@2.11.7/src/commands/command.ts","/npm/@tiptap/core@2.11.7/src/commands/createParagraphNear.ts","/npm/@tiptap/core@2.11.7/src/commands/cut.ts","/npm/@tiptap/core@2.11.7/src/commands/deleteCurrentNode.ts","/npm/@tiptap/core@2.11.7/src/commands/deleteNode.ts","/npm/@tiptap/core@2.11.7/src/commands/deleteRange.ts","/npm/@tiptap/core@2.11.7/src/commands/deleteSelection.ts","/npm/@tiptap/core@2.11.7/src/commands/enter.ts","/npm/@tiptap/core@2.11.7/src/commands/exitCode.ts","/npm/@tiptap/core@2.11.7/src/commands/extendMarkRange.ts","/npm/@tiptap/core@2.11.7/src/commands/first.ts","/npm/@tiptap/core@2.11.7/src/commands/forEach.ts","/npm/@tiptap/core@2.11.7/src/commands/insertContent.ts","/npm/@tiptap/core@2.11.7/src/commands/insertContentAt.ts","/npm/@tiptap/core@2.11.7/src/commands/join.ts","/npm/@tiptap/core@2.11.7/src/commands/joinItemBackward.ts","/npm/@tiptap/core@2.11.7/src/commands/joinItemForward.ts","/npm/@tiptap/core@2.11.7/src/commands/joinTextblockBackward.ts","/npm/@tiptap/core@2.11.7/src/commands/joinTextblockForward.ts","/npm/@tiptap/core@2.11.7/src/commands/keyboardShortcut.ts","/npm/@tiptap/core@2.11.7/src/commands/lift.ts","/npm/@tiptap/core@2.11.7/src/commands/liftEmptyBlock.ts","/npm/@tiptap/core@2.11.7/src/commands/liftListItem.ts","/npm/@tiptap/core@2.11.7/src/commands/newlineInCode.ts","/npm/@tiptap/core@2.11.7/src/commands/resetAttributes.ts","/npm/@tiptap/core@2.11.7/src/commands/scrollIntoView.ts","/npm/@tiptap/core@2.11.7/src/commands/selectAll.ts","/npm/@tiptap/core@2.11.7/src/commands/selectNodeBackward.ts","/npm/@tiptap/core@2.11.7/src/commands/selectNodeForward.ts","/npm/@tiptap/core@2.11.7/src/commands/selectParentNode.ts","/npm/@tiptap/core@2.11.7/src/commands/selectTextblockEnd.ts","/npm/@tiptap/core@2.11.7/src/commands/selectTextblockStart.ts","/npm/@tiptap/core@2.11.7/src/commands/setContent.ts","/npm/@tiptap/core@2.11.7/src/commands/setMark.ts","/npm/@tiptap/core@2.11.7/src/commands/setMeta.ts","/npm/@tiptap/core@2.11.7/src/commands/setNode.ts","/npm/@tiptap/core@2.11.7/src/commands/setNodeSelection.ts","/npm/@tiptap/core@2.11.7/src/commands/setTextSelection.ts","/npm/@tiptap/core@2.11.7/src/commands/sinkListItem.ts","/npm/@tiptap/core@2.11.7/src/commands/splitListItem.ts","/npm/@tiptap/core@2.11.7/src/commands/toggleMark.ts","/npm/@tiptap/core@2.11.7/src/commands/toggleNode.ts","/npm/@tiptap/core@2.11.7/src/commands/toggleWrap.ts","/npm/@tiptap/core@2.11.7/src/commands/undoInputRule.ts","/npm/@tiptap/core@2.11.7/src/commands/unsetAllMarks.ts","/npm/@tiptap/core@2.11.7/src/commands/unsetMark.ts","/npm/@tiptap/core@2.11.7/src/commands/updateAttributes.ts","/npm/@tiptap/core@2.11.7/src/commands/wrapIn.ts","/npm/@tiptap/core@2.11.7/src/commands/wrapInList.ts","/npm/@tiptap/core@2.11.7/src/extensions/commands.ts","/npm/@tiptap/core@2.11.7/src/extensions/drop.ts","/npm/@tiptap/core@2.11.7/src/extensions/editable.ts","/npm/@tiptap/core@2.11.7/src/extensions/focusEvents.ts","/npm/@tiptap/core@2.11.7/src/extensions/keymap.ts","/npm/@tiptap/core@2.11.7/src/extensions/paste.ts","/npm/@tiptap/core@2.11.7/src/extensions/tabindex.ts","/npm/@tiptap/core@2.11.7/src/NodePos.ts","/npm/@tiptap/core@2.11.7/src/utilities/createStyleTag.ts","/npm/@tiptap/core@2.11.7/src/Node.ts","/npm/@tiptap/core@2.11.7/src/Editor.ts","/npm/@tiptap/core@2.11.7/src/style.ts","/npm/@tiptap/core@2.11.7/src/NodeView.ts","/npm/@tiptap/core@2.11.7/src/Tracker.ts","/npm/@tiptap/core@2.11.7/src/helpers/combineTransactionSteps.ts","/npm/@tiptap/core@2.11.7/src/utilities/escapeForRegEx.ts","/npm/@tiptap/core@2.11.7/src/helpers/findChildren.ts","/npm/@tiptap/core@2.11.7/src/helpers/findChildrenInRange.ts","/npm/@tiptap/core@2.11.7/src/helpers/generateHTML.ts","/npm/@tiptap/core@2.11.7/src/helpers/generateJSON.ts","/npm/@tiptap/core@2.11.7/src/helpers/generateText.ts","/npm/@tiptap/core@2.11.7/src/helpers/getChangedRanges.ts","/npm/@tiptap/core@2.11.7/src/helpers/getDebugJSON.ts","/npm/@tiptap/core@2.11.7/src/helpers/getNodeAtPosition.ts","/npm/@tiptap/core@2.11.7/src/helpers/isAtEndOfNode.ts","/npm/@tiptap/core@2.11.7/src/helpers/isAtStartOfNode.ts","/npm/@tiptap/core@2.11.7/src/helpers/isNodeSelection.ts","/npm/@tiptap/core@2.11.7/src/utilities/isString.ts","/npm/@tiptap/core@2.11.7/src/inputRules/markInputRule.ts","/npm/@tiptap/core@2.11.7/src/pasteRules/markPasteRule.ts","/npm/@tiptap/core@2.11.7/src/inputRules/nodeInputRule.ts","/npm/@tiptap/core@2.11.7/src/pasteRules/nodePasteRule.ts","/npm/@tiptap/core@2.11.7/src/helpers/posToDOMRect.ts","/npm/@tiptap/core@2.11.7/src/inputRules/textInputRule.ts","/npm/@tiptap/core@2.11.7/src/pasteRules/textPasteRule.ts","/npm/@tiptap/core@2.11.7/src/inputRules/textblockTypeInputRule.ts","/npm/@tiptap/core@2.11.7/src/inputRules/wrappingInputRule.ts"],"names":[],"mappings":"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","file":"/npm/@tiptap/core@2.11.7/dist/index.umd.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@tiptap/core@2.11.7/dist/index.umd.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import { EditorState, Transaction } from '@tiptap/pm/state'\n\n/**\n * Takes a Transaction & Editor State and turns it into a chainable state object\n * @param config The transaction and state to create the chainable state from\n * @returns A chainable Editor state object\n */\nexport function createChainableState(config: {\n  transaction: Transaction\n  state: EditorState\n}): EditorState {\n  const { state, transaction } = config\n  let { selection } = transaction\n  let { doc } = transaction\n  let { storedMarks } = transaction\n\n  return {\n    ...state,\n    apply: state.apply.bind(state),\n    applyTransaction: state.applyTransaction.bind(state),\n    plugins: state.plugins,\n    schema: state.schema,\n    reconfigure: state.reconfigure.bind(state),\n    toJSON: state.toJSON.bind(state),\n    get storedMarks() {\n      return storedMarks\n    },\n    get selection() {\n      return selection\n    },\n    get doc() {\n      return doc\n    },\n    get tr() {\n      selection = transaction.selection\n      doc = transaction.doc\n      storedMarks = transaction.storedMarks\n\n      return transaction\n    },\n  }\n}\n","import { EditorState, Transaction } from '@tiptap/pm/state'\n\nimport { Editor } from './Editor.js'\nimport { createChainableState } from './helpers/createChainableState.js'\nimport {\n  AnyCommands, CanCommands, ChainedCommands, CommandProps, SingleCommands,\n} from './types.js'\n\nexport class CommandManager {\n  editor: Editor\n\n  rawCommands: AnyCommands\n\n  customState?: EditorState\n\n  constructor(props: { editor: Editor; state?: EditorState }) {\n    this.editor = props.editor\n    this.rawCommands = this.editor.extensionManager.commands\n    this.customState = props.state\n  }\n\n  get hasCustomState(): boolean {\n    return !!this.customState\n  }\n\n  get state(): EditorState {\n    return this.customState || this.editor.state\n  }\n\n  get commands(): SingleCommands {\n    const { rawCommands, editor, state } = this\n    const { view } = editor\n    const { tr } = state\n    const props = this.buildProps(tr)\n\n    return Object.fromEntries(\n      Object.entries(rawCommands).map(([name, command]) => {\n        const method = (...args: any[]) => {\n          const callback = command(...args)(props)\n\n          if (!tr.getMeta('preventDispatch') && !this.hasCustomState) {\n            view.dispatch(tr)\n          }\n\n          return callback\n        }\n\n        return [name, method]\n      }),\n    ) as unknown as SingleCommands\n  }\n\n  get chain(): () => ChainedCommands {\n    return () => this.createChain()\n  }\n\n  get can(): () => CanCommands {\n    return () => this.createCan()\n  }\n\n  public createChain(startTr?: Transaction, shouldDispatch = true): ChainedCommands {\n    const { rawCommands, editor, state } = this\n    const { view } = editor\n    const callbacks: boolean[] = []\n    const hasStartTransaction = !!startTr\n    const tr = startTr || state.tr\n\n    const run = () => {\n      if (\n        !hasStartTransaction\n        && shouldDispatch\n        && !tr.getMeta('preventDispatch')\n        && !this.hasCustomState\n      ) {\n        view.dispatch(tr)\n      }\n\n      return callbacks.every(callback => callback === true)\n    }\n\n    const chain = {\n      ...Object.fromEntries(\n        Object.entries(rawCommands).map(([name, command]) => {\n          const chainedCommand = (...args: never[]) => {\n            const props = this.buildProps(tr, shouldDispatch)\n            const callback = command(...args)(props)\n\n            callbacks.push(callback)\n\n            return chain\n          }\n\n          return [name, chainedCommand]\n        }),\n      ),\n      run,\n    } as unknown as ChainedCommands\n\n    return chain\n  }\n\n  public createCan(startTr?: Transaction): CanCommands {\n    const { rawCommands, state } = this\n    const dispatch = false\n    const tr = startTr || state.tr\n    const props = this.buildProps(tr, dispatch)\n    const formattedCommands = Object.fromEntries(\n      Object.entries(rawCommands).map(([name, command]) => {\n        return [name, (...args: never[]) => command(...args)({ ...props, dispatch: undefined })]\n      }),\n    ) as unknown as SingleCommands\n\n    return {\n      ...formattedCommands,\n      chain: () => this.createChain(tr, dispatch),\n    } as CanCommands\n  }\n\n  public buildProps(tr: Transaction, shouldDispatch = true): CommandProps {\n    const { rawCommands, editor, state } = this\n    const { view } = editor\n\n    const props: CommandProps = {\n      tr,\n      editor,\n      view,\n      state: createChainableState({\n        state,\n        transaction: tr,\n      }),\n      dispatch: shouldDispatch ? () => undefined : undefined,\n      chain: () => this.createChain(tr, shouldDispatch),\n      can: () => this.createCan(tr),\n      get commands() {\n        return Object.fromEntries(\n          Object.entries(rawCommands).map(([name, command]) => {\n            return [name, (...args: never[]) => command(...args)(props)]\n          }),\n        ) as unknown as SingleCommands\n      },\n    }\n\n    return props\n  }\n}\n","type StringKeyOf<T> = Extract<keyof T, string>\ntype CallbackType<\n  T extends Record<string, any>,\n  EventName extends StringKeyOf<T>,\n> = T[EventName] extends any[] ? T[EventName] : [T[EventName]]\ntype CallbackFunction<\n  T extends Record<string, any>,\n  EventName extends StringKeyOf<T>,\n> = (...props: CallbackType<T, EventName>) => any\n\nexport class EventEmitter<T extends Record<string, any>> {\n\n  private callbacks: { [key: string]: Array<(...args: any[])=>void> } = {}\n\n  public on<EventName extends StringKeyOf<T>>(event: EventName, fn: CallbackFunction<T, EventName>): this {\n    if (!this.callbacks[event]) {\n      this.callbacks[event] = []\n    }\n\n    this.callbacks[event].push(fn)\n\n    return this\n  }\n\n  public emit<EventName extends StringKeyOf<T>>(event: EventName, ...args: CallbackType<T, EventName>): this {\n    const callbacks = this.callbacks[event]\n\n    if (callbacks) {\n      callbacks.forEach(callback => callback.apply(this, args))\n    }\n\n    return this\n  }\n\n  public off<EventName extends StringKeyOf<T>>(event: EventName, fn?: CallbackFunction<T, EventName>): this {\n    const callbacks = this.callbacks[event]\n\n    if (callbacks) {\n      if (fn) {\n        this.callbacks[event] = callbacks.filter(callback => callback !== fn)\n      } else {\n        delete this.callbacks[event]\n      }\n    }\n\n    return this\n  }\n\n  public once<EventName extends StringKeyOf<T>>(event: EventName, fn: CallbackFunction<T, EventName>): this {\n    const onceFn = (...args: CallbackType<T, EventName>) => {\n      this.off(event, onceFn)\n      fn.apply(this, args)\n    }\n\n    return this.on(event, onceFn)\n  }\n\n  public removeAllListeners(): void {\n    this.callbacks = {}\n  }\n}\n","import { AnyExtension, MaybeThisParameterType, RemoveThis } from '../types.js'\n\n/**\n * Returns a field from an extension\n * @param extension The Tiptap extension\n * @param field The field, for example `renderHTML` or `priority`\n * @param context The context object that should be passed as `this` into the function\n * @returns The field value\n */\nexport function getExtensionField<T = any>(\n  extension: AnyExtension,\n  field: string,\n  context?: Omit<MaybeThisParameterType<T>, 'parent'>,\n): RemoveThis<T> {\n\n  if (extension.config[field] === undefined && extension.parent) {\n    return getExtensionField(extension.parent, field, context)\n  }\n\n  if (typeof extension.config[field] === 'function') {\n    const value = extension.config[field].bind({\n      ...context,\n      parent: extension.parent\n        ? getExtensionField(extension.parent, field, context)\n        : null,\n    })\n\n    return value\n  }\n\n  return extension.config[field]\n}\n","import { Extension } from '../Extension.js'\nimport { Mark } from '../Mark.js'\nimport { Node } from '../Node.js'\nimport { Extensions } from '../types.js'\n\nexport function splitExtensions(extensions: Extensions) {\n  const baseExtensions = extensions.filter(extension => extension.type === 'extension') as Extension[]\n  const nodeExtensions = extensions.filter(extension => extension.type === 'node') as Node[]\n  const markExtensions = extensions.filter(extension => extension.type === 'mark') as Mark[]\n\n  return {\n    baseExtensions,\n    nodeExtensions,\n    markExtensions,\n  }\n}\n","import { MarkConfig, NodeConfig } from '../index.js'\nimport {\n  AnyConfig,\n  Attribute,\n  Attributes,\n  ExtensionAttribute,\n  Extensions,\n} from '../types.js'\nimport { getExtensionField } from './getExtensionField.js'\nimport { splitExtensions } from './splitExtensions.js'\n\n/**\n * Get a list of all extension attributes defined in `addAttribute` and `addGlobalAttribute`.\n * @param extensions List of extensions\n */\nexport function getAttributesFromExtensions(extensions: Extensions): ExtensionAttribute[] {\n  const extensionAttributes: ExtensionAttribute[] = []\n  const { nodeExtensions, markExtensions } = splitExtensions(extensions)\n  const nodeAndMarkExtensions = [...nodeExtensions, ...markExtensions]\n  const defaultAttribute: Required<Attribute> = {\n    default: null,\n    rendered: true,\n    renderHTML: null,\n    parseHTML: null,\n    keepOnSplit: true,\n    isRequired: false,\n  }\n\n  extensions.forEach(extension => {\n    const context = {\n      name: extension.name,\n      options: extension.options,\n      storage: extension.storage,\n      extensions: nodeAndMarkExtensions,\n    }\n\n    const addGlobalAttributes = getExtensionField<AnyConfig['addGlobalAttributes']>(\n      extension,\n      'addGlobalAttributes',\n      context,\n    )\n\n    if (!addGlobalAttributes) {\n      return\n    }\n\n    const globalAttributes = addGlobalAttributes()\n\n    globalAttributes.forEach(globalAttribute => {\n      globalAttribute.types.forEach(type => {\n        Object\n          .entries(globalAttribute.attributes)\n          .forEach(([name, attribute]) => {\n            extensionAttributes.push({\n              type,\n              name,\n              attribute: {\n                ...defaultAttribute,\n                ...attribute,\n              },\n            })\n          })\n      })\n    })\n  })\n\n  nodeAndMarkExtensions.forEach(extension => {\n    const context = {\n      name: extension.name,\n      options: extension.options,\n      storage: extension.storage,\n    }\n\n    const addAttributes = getExtensionField<NodeConfig['addAttributes'] | MarkConfig['addAttributes']>(\n      extension,\n      'addAttributes',\n      context,\n    )\n\n    if (!addAttributes) {\n      return\n    }\n\n    // TODO: remove `as Attributes`\n    const attributes = addAttributes() as Attributes\n\n    Object\n      .entries(attributes)\n      .forEach(([name, attribute]) => {\n        const mergedAttr = {\n          ...defaultAttribute,\n          ...attribute,\n        }\n\n        if (typeof mergedAttr?.default === 'function') {\n          mergedAttr.default = mergedAttr.default()\n        }\n\n        if (mergedAttr?.isRequired && mergedAttr?.default === undefined) {\n          delete mergedAttr.default\n        }\n\n        extensionAttributes.push({\n          type: extension.name,\n          name,\n          attribute: mergedAttr,\n        })\n      })\n  })\n\n  return extensionAttributes\n}\n","import { NodeType, Schema } from '@tiptap/pm/model'\n\nexport function getNodeType(nameOrType: string | NodeType, schema: Schema): NodeType {\n  if (typeof nameOrType === 'string') {\n    if (!schema.nodes[nameOrType]) {\n      throw Error(\n        `There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`,\n      )\n    }\n\n    return schema.nodes[nameOrType]\n  }\n\n  return nameOrType\n}\n","export function mergeAttributes(...objects: Record<string, any>[]): Record<string, any> {\n  return objects\n    .filter(item => !!item)\n    .reduce((items, item) => {\n      const mergedAttributes = { ...items }\n\n      Object.entries(item).forEach(([key, value]) => {\n        const exists = mergedAttributes[key]\n\n        if (!exists) {\n          mergedAttributes[key] = value\n\n          return\n        }\n\n        if (key === 'class') {\n          const valueClasses: string[] = value ? String(value).split(' ') : []\n          const existingClasses: string[] = mergedAttributes[key] ? mergedAttributes[key].split(' ') : []\n\n          const insertClasses = valueClasses.filter(\n            valueClass => !existingClasses.includes(valueClass),\n          )\n\n          mergedAttributes[key] = [...existingClasses, ...insertClasses].join(' ')\n        } else if (key === 'style') {\n          const newStyles: string[] = value ? value.split(';').map((style: string) => style.trim()).filter(Boolean) : []\n          const existingStyles: string[] = mergedAttributes[key] ? mergedAttributes[key].split(';').map((style: string) => style.trim()).filter(Boolean) : []\n\n          const styleMap = new Map<string, string>()\n\n          existingStyles.forEach(style => {\n            const [property, val] = style.split(':').map(part => part.trim())\n\n            styleMap.set(property, val)\n          })\n\n          newStyles.forEach(style => {\n            const [property, val] = style.split(':').map(part => part.trim())\n\n            styleMap.set(property, val)\n          })\n\n          mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join('; ')\n        } else {\n          mergedAttributes[key] = value\n        }\n      })\n\n      return mergedAttributes\n    }, {})\n}\n","import { Mark, Node } from '@tiptap/pm/model'\n\nimport { ExtensionAttribute } from '../types.js'\nimport { mergeAttributes } from '../utilities/mergeAttributes.js'\n\nexport function getRenderedAttributes(\n  nodeOrMark: Node | Mark,\n  extensionAttributes: ExtensionAttribute[],\n): Record<string, any> {\n  return extensionAttributes\n    .filter(\n      attribute => attribute.type === nodeOrMark.type.name,\n    )\n    .filter(item => item.attribute.rendered)\n    .map(item => {\n      if (!item.attribute.renderHTML) {\n        return {\n          [item.name]: nodeOrMark.attrs[item.name],\n        }\n      }\n\n      return item.attribute.renderHTML(nodeOrMark.attrs) || {}\n    })\n    .reduce((attributes, attribute) => mergeAttributes(attributes, attribute), {})\n}\n","// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function isFunction(value: any): value is Function {\n  return typeof value === 'function'\n}\n","import { MaybeReturnType } from '../types.js'\nimport { isFunction } from './isFunction.js'\n\n/**\n * Optionally calls `value` as a function.\n * Otherwise it is returned directly.\n * @param value Function or any value.\n * @param context Optional context to bind to function.\n * @param props Optional props to pass to function.\n */\nexport function callOrReturn<T>(value: T, context: any = undefined, ...props: any[]): MaybeReturnType<T> {\n  if (isFunction(value)) {\n    if (context) {\n      return value.bind(context)(...props)\n    }\n\n    return value(...props)\n  }\n\n  return value as MaybeReturnType<T>\n}\n","export function isEmptyObject(value = {}): boolean {\n  return Object.keys(value).length === 0 && value.constructor === Object\n}\n","export function fromString(value: any): any {\n  if (typeof value !== 'string') {\n    return value\n  }\n\n  if (value.match(/^[+-]?(?:\\d*\\.)?\\d+$/)) {\n    return Number(value)\n  }\n\n  if (value === 'true') {\n    return true\n  }\n\n  if (value === 'false') {\n    return false\n  }\n\n  return value\n}\n","import { ParseRule } from '@tiptap/pm/model'\n\nimport { ExtensionAttribute } from '../types.js'\nimport { fromString } from '../utilities/fromString.js'\n\n/**\n * This function merges extension attributes into parserule attributes (`attrs` or `getAttrs`).\n * Cancels when `getAttrs` returned `false`.\n * @param parseRule ProseMirror ParseRule\n * @param extensionAttributes List of attributes to inject\n */\nexport function injectExtensionAttributesToParseRule(\n  parseRule: ParseRule,\n  extensionAttributes: ExtensionAttribute[],\n): ParseRule {\n  if ('style' in parseRule) {\n    return parseRule\n  }\n\n  return {\n    ...parseRule,\n    getAttrs: (node: HTMLElement) => {\n      const oldAttributes = parseRule.getAttrs ? parseRule.getAttrs(node) : parseRule.attrs\n\n      if (oldAttributes === false) {\n        return false\n      }\n\n      const newAttributes = extensionAttributes.reduce((items, item) => {\n        const value = item.attribute.parseHTML\n          ? item.attribute.parseHTML(node)\n          : fromString((node).getAttribute(item.name))\n\n        if (value === null || value === undefined) {\n          return items\n        }\n\n        return {\n          ...items,\n          [item.name]: value,\n        }\n      }, {})\n\n      return { ...oldAttributes, ...newAttributes }\n    },\n  }\n}\n","import {\n  MarkSpec, NodeSpec, Schema, TagParseRule,\n} from '@tiptap/pm/model'\n\nimport { Editor, MarkConfig, NodeConfig } from '../index.js'\nimport { AnyConfig, Extensions } from '../types.js'\nimport { callOrReturn } from '../utilities/callOrReturn.js'\nimport { isEmptyObject } from '../utilities/isEmptyObject.js'\nimport { getAttributesFromExtensions } from './getAttributesFromExtensions.js'\nimport { getExtensionField } from './getExtensionField.js'\nimport { getRenderedAttributes } from './getRenderedAttributes.js'\nimport { injectExtensionAttributesToParseRule } from './injectExtensionAttributesToParseRule.js'\nimport { splitExtensions } from './splitExtensions.js'\n\nfunction cleanUpSchemaItem<T>(data: T) {\n  return Object.fromEntries(\n    // @ts-ignore\n    Object.entries(data).filter(([key, value]) => {\n      if (key === 'attrs' && isEmptyObject(value as object | undefined)) {\n        return false\n      }\n\n      return value !== null && value !== undefined\n    }),\n  ) as T\n}\n\n/**\n * Creates a new Prosemirror schema based on the given extensions.\n * @param extensions An array of Tiptap extensions\n * @param editor The editor instance\n * @returns A Prosemirror schema\n */\nexport function getSchemaByResolvedExtensions(extensions: Extensions, editor?: Editor): Schema {\n  const allAttributes = getAttributesFromExtensions(extensions)\n  const { nodeExtensions, markExtensions } = splitExtensions(extensions)\n  const topNode = nodeExtensions.find(extension => getExtensionField(extension, 'topNode'))?.name\n\n  const nodes = Object.fromEntries(\n    nodeExtensions.map(extension => {\n      const extensionAttributes = allAttributes.filter(\n        attribute => attribute.type === extension.name,\n      )\n      const context = {\n        name: extension.name,\n        options: extension.options,\n        storage: extension.storage,\n        editor,\n      }\n\n      const extraNodeFields = extensions.reduce((fields, e) => {\n        const extendNodeSchema = getExtensionField<AnyConfig['extendNodeSchema']>(\n          e,\n          'extendNodeSchema',\n          context,\n        )\n\n        return {\n          ...fields,\n          ...(extendNodeSchema ? extendNodeSchema(extension) : {}),\n        }\n      }, {})\n\n      const schema: NodeSpec = cleanUpSchemaItem({\n        ...extraNodeFields,\n        content: callOrReturn(\n          getExtensionField<NodeConfig['content']>(extension, 'content', context),\n        ),\n        marks: callOrReturn(getExtensionField<NodeConfig['marks']>(extension, 'marks', context)),\n        group: callOrReturn(getExtensionField<NodeConfig['group']>(extension, 'group', context)),\n        inline: callOrReturn(getExtensionField<NodeConfig['inline']>(extension, 'inline', context)),\n        atom: callOrReturn(getExtensionField<NodeConfig['atom']>(extension, 'atom', context)),\n        selectable: callOrReturn(\n          getExtensionField<NodeConfig['selectable']>(extension, 'selectable', context),\n        ),\n        draggable: callOrReturn(\n          getExtensionField<NodeConfig['draggable']>(extension, 'draggable', context),\n        ),\n        code: callOrReturn(getExtensionField<NodeConfig['code']>(extension, 'code', context)),\n        whitespace: callOrReturn(getExtensionField<NodeConfig['whitespace']>(extension, 'whitespace', context)),\n        linebreakReplacement: callOrReturn(getExtensionField<NodeConfig['linebreakReplacement']>(extension, 'linebreakReplacement', context)),\n        defining: callOrReturn(\n          getExtensionField<NodeConfig['defining']>(extension, 'defining', context),\n        ),\n        isolating: callOrReturn(\n          getExtensionField<NodeConfig['isolating']>(extension, 'isolating', context),\n        ),\n        attrs: Object.fromEntries(\n          extensionAttributes.map(extensionAttribute => {\n            return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]\n          }),\n        ),\n      })\n\n      const parseHTML = callOrReturn(\n        getExtensionField<NodeConfig['parseHTML']>(extension, 'parseHTML', context),\n      )\n\n      if (parseHTML) {\n        schema.parseDOM = parseHTML.map(parseRule => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)) as TagParseRule[]\n      }\n\n      const renderHTML = getExtensionField<NodeConfig['renderHTML']>(\n        extension,\n        'renderHTML',\n        context,\n      )\n\n      if (renderHTML) {\n        schema.toDOM = node => renderHTML({\n          node,\n          HTMLAttributes: getRenderedAttributes(node, extensionAttributes),\n        })\n      }\n\n      const renderText = getExtensionField<NodeConfig['renderText']>(\n        extension,\n        'renderText',\n        context,\n      )\n\n      if (renderText) {\n        schema.toText = renderText\n      }\n\n      return [extension.name, schema]\n    }),\n  )\n\n  const marks = Object.fromEntries(\n    markExtensions.map(extension => {\n      const extensionAttributes = allAttributes.filter(\n        attribute => attribute.type === extension.name,\n      )\n      const context = {\n        name: extension.name,\n        options: extension.options,\n        storage: extension.storage,\n        editor,\n      }\n\n      const extraMarkFields = extensions.reduce((fields, e) => {\n        const extendMarkSchema = getExtensionField<AnyConfig['extendMarkSchema']>(\n          e,\n          'extendMarkSchema',\n          context,\n        )\n\n        return {\n          ...fields,\n          ...(extendMarkSchema ? extendMarkSchema(extension as any) : {}),\n        }\n      }, {})\n\n      const schema: MarkSpec = cleanUpSchemaItem({\n        ...extraMarkFields,\n        inclusive: callOrReturn(\n          getExtensionField<MarkConfig['inclusive']>(extension, 'inclusive', context),\n        ),\n        excludes: callOrReturn(\n          getExtensionField<MarkConfig['excludes']>(extension, 'excludes', context),\n        ),\n        group: callOrReturn(getExtensionField<MarkConfig['group']>(extension, 'group', context)),\n        spanning: callOrReturn(\n          getExtensionField<MarkConfig['spanning']>(extension, 'spanning', context),\n        ),\n        code: callOrReturn(getExtensionField<MarkConfig['code']>(extension, 'code', context)),\n        attrs: Object.fromEntries(\n          extensionAttributes.map(extensionAttribute => {\n            return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]\n          }),\n        ),\n      })\n\n      const parseHTML = callOrReturn(\n        getExtensionField<MarkConfig['parseHTML']>(extension, 'parseHTML', context),\n      )\n\n      if (parseHTML) {\n        schema.parseDOM = parseHTML.map(parseRule => injectExtensionAttributesToParseRule(parseRule, extensionAttributes))\n      }\n\n      const renderHTML = getExtensionField<MarkConfig['renderHTML']>(\n        extension,\n        'renderHTML',\n        context,\n      )\n\n      if (renderHTML) {\n        schema.toDOM = mark => renderHTML({\n          mark,\n          HTMLAttributes: getRenderedAttributes(mark, extensionAttributes),\n        })\n      }\n\n      return [extension.name, schema]\n    }),\n  )\n\n  return new Schema({\n    topNode,\n    nodes,\n    marks,\n  })\n}\n","import { MarkType, NodeType, Schema } from '@tiptap/pm/model'\n\n/**\n * Tries to get a node or mark type by its name.\n * @param name The name of the node or mark type\n * @param schema The Prosemiror schema to search in\n * @returns The node or mark type, or null if it doesn't exist\n */\nexport function getSchemaTypeByName(name: string, schema: Schema): NodeType | MarkType | null {\n  return schema.nodes[name] || schema.marks[name] || null\n}\n","import { AnyExtension, EnableRules } from '../types.js'\n\nexport function isExtensionRulesEnabled(extension: AnyExtension, enabled: EnableRules): boolean {\n  if (Array.isArray(enabled)) {\n    return enabled.some(enabledExtension => {\n      const name = typeof enabledExtension === 'string'\n        ? enabledExtension\n        : enabledExtension.name\n\n      return name === extension.name\n    })\n  }\n\n  return enabled\n}\n","import { DOMSerializer, Fragment, Schema } from '@tiptap/pm/model'\n\nexport function getHTMLFromFragment(fragment: Fragment, schema: Schema): string {\n  const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment)\n\n  const temporaryDocument = document.implementation.createHTMLDocument()\n  const container = temporaryDocument.createElement('div')\n\n  container.appendChild(documentFragment)\n\n  return container.innerHTML\n}\n","import { ResolvedPos } from '@tiptap/pm/model'\n\n/**\n * Returns the text content of a resolved prosemirror position\n * @param $from The resolved position to get the text content from\n * @param maxMatch The maximum number of characters to match\n * @returns The text content\n */\nexport const getTextContentFromNodes = ($from: ResolvedPos, maxMatch = 500) => {\n  let textBefore = ''\n\n  const sliceEndPos = $from.parentOffset\n\n  $from.parent.nodesBetween(\n    Math.max(0, sliceEndPos - maxMatch),\n    sliceEndPos,\n    (node, pos, parent, index) => {\n      const chunk = node.type.spec.toText?.({\n        node,\n        pos,\n        parent,\n        index,\n      })\n        || node.textContent\n        || '%leaf%'\n\n      textBefore += node.isAtom && !node.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos))\n    },\n  )\n\n  return textBefore\n}\n","export function isRegExp(value: any): value is RegExp {\n  return Object.prototype.toString.call(value) === '[object RegExp]'\n}\n","import { Fragment, Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { EditorState, Plugin, TextSelection } from '@tiptap/pm/state'\n\nimport { CommandManager } from './CommandManager.js'\nimport { Editor } from './Editor.js'\nimport { createChainableState } from './helpers/createChainableState.js'\nimport { getHTMLFromFragment } from './helpers/getHTMLFromFragment.js'\nimport { getTextContentFromNodes } from './helpers/getTextContentFromNodes.js'\nimport {\n  CanCommands,\n  ChainedCommands,\n  ExtendedRegExpMatchArray,\n  Range,\n  SingleCommands,\n} from './types.js'\nimport { isRegExp } from './utilities/isRegExp.js'\n\nexport type InputRuleMatch = {\n  index: number;\n  text: string;\n  replaceWith?: string;\n  match?: RegExpMatchArray;\n  data?: Record<string, any>;\n};\n\nexport type InputRuleFinder = RegExp | ((text: string) => InputRuleMatch | null);\n\nexport class InputRule {\n  find: InputRuleFinder\n\n  handler: (props: {\n    state: EditorState;\n    range: Range;\n    match: ExtendedRegExpMatchArray;\n    commands: SingleCommands;\n    chain: () => ChainedCommands;\n    can: () => CanCommands;\n  }) => void | null\n\n  constructor(config: {\n    find: InputRuleFinder;\n    handler: (props: {\n      state: EditorState;\n      range: Range;\n      match: ExtendedRegExpMatchArray;\n      commands: SingleCommands;\n      chain: () => ChainedCommands;\n      can: () => CanCommands;\n    }) => void | null;\n  }) {\n    this.find = config.find\n    this.handler = config.handler\n  }\n}\n\nconst inputRuleMatcherHandler = (\n  text: string,\n  find: InputRuleFinder,\n): ExtendedRegExpMatchArray | null => {\n  if (isRegExp(find)) {\n    return find.exec(text)\n  }\n\n  const inputRuleMatch = find(text)\n\n  if (!inputRuleMatch) {\n    return null\n  }\n\n  const result: ExtendedRegExpMatchArray = [inputRuleMatch.text]\n\n  result.index = inputRuleMatch.index\n  result.input = text\n  result.data = inputRuleMatch.data\n\n  if (inputRuleMatch.replaceWith) {\n    if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) {\n      console.warn(\n        '[tiptap warn]: \"inputRuleMatch.replaceWith\" must be part of \"inputRuleMatch.text\".',\n      )\n    }\n\n    result.push(inputRuleMatch.replaceWith)\n  }\n\n  return result\n}\n\nfunction run(config: {\n  editor: Editor;\n  from: number;\n  to: number;\n  text: string;\n  rules: InputRule[];\n  plugin: Plugin;\n}): boolean {\n  const {\n    editor, from, to, text, rules, plugin,\n  } = config\n  const { view } = editor\n\n  if (view.composing) {\n    return false\n  }\n\n  const $from = view.state.doc.resolve(from)\n\n  if (\n    // check for code node\n    $from.parent.type.spec.code\n    // check for code mark\n    || !!($from.nodeBefore || $from.nodeAfter)?.marks.find(mark => mark.type.spec.code)\n  ) {\n    return false\n  }\n\n  let matched = false\n\n  const textBefore = getTextContentFromNodes($from) + text\n\n  rules.forEach(rule => {\n    if (matched) {\n      return\n    }\n\n    const match = inputRuleMatcherHandler(textBefore, rule.find)\n\n    if (!match) {\n      return\n    }\n\n    const tr = view.state.tr\n    const state = createChainableState({\n      state: view.state,\n      transaction: tr,\n    })\n    const range = {\n      from: from - (match[0].length - text.length),\n      to,\n    }\n\n    const { commands, chain, can } = new CommandManager({\n      editor,\n      state,\n    })\n\n    const handler = rule.handler({\n      state,\n      range,\n      match,\n      commands,\n      chain,\n      can,\n    })\n\n    // stop if there are no changes\n    if (handler === null || !tr.steps.length) {\n      return\n    }\n\n    // store transform as meta data\n    // so we can undo input rules within the `undoInputRules` command\n    tr.setMeta(plugin, {\n      transform: tr,\n      from,\n      to,\n      text,\n    })\n\n    view.dispatch(tr)\n    matched = true\n  })\n\n  return matched\n}\n\n/**\n * Create an input rules plugin. When enabled, it will cause text\n * input that matches any of the given rules to trigger the rule’s\n * action.\n */\nexport function inputRulesPlugin(props: { editor: Editor; rules: InputRule[] }): Plugin {\n  const { editor, rules } = props\n  const plugin = new Plugin({\n    state: {\n      init() {\n        return null\n      },\n      apply(tr, prev, state) {\n        const stored = tr.getMeta(plugin)\n\n        if (stored) {\n          return stored\n        }\n\n        // if InputRule is triggered by insertContent()\n        const simulatedInputMeta = tr.getMeta('applyInputRules') as\n          | undefined\n          | {\n              from: number;\n              text: string | ProseMirrorNode | Fragment;\n            }\n        const isSimulatedInput = !!simulatedInputMeta\n\n        if (isSimulatedInput) {\n          setTimeout(() => {\n            let { text } = simulatedInputMeta\n\n            if (typeof text === 'string') {\n              text = text as string\n            } else {\n              text = getHTMLFromFragment(Fragment.from(text), state.schema)\n            }\n\n            const { from } = simulatedInputMeta\n            const to = from + text.length\n\n            run({\n              editor,\n              from,\n              to,\n              text,\n              rules,\n              plugin,\n            })\n          })\n        }\n\n        return tr.selectionSet || tr.docChanged ? null : prev\n      },\n    },\n\n    props: {\n      handleTextInput(view, from, to, text) {\n        return run({\n          editor,\n          from,\n          to,\n          text,\n          rules,\n          plugin,\n        })\n      },\n\n      handleDOMEvents: {\n        compositionend: view => {\n          setTimeout(() => {\n            const { $cursor } = view.state.selection as TextSelection\n\n            if ($cursor) {\n              run({\n                editor,\n                from: $cursor.pos,\n                to: $cursor.pos,\n                text: '',\n                rules,\n                plugin,\n              })\n            }\n          })\n\n          return false\n        },\n      },\n\n      // add support for input rules to trigger on enter\n      // this is useful for example for code blocks\n      handleKeyDown(view, event) {\n        if (event.key !== 'Enter') {\n          return false\n        }\n\n        const { $cursor } = view.state.selection as TextSelection\n\n        if ($cursor) {\n          return run({\n            editor,\n            from: $cursor.pos,\n            to: $cursor.pos,\n            text: '\\n',\n            rules,\n            plugin,\n          })\n        }\n\n        return false\n      },\n    },\n\n    // @ts-ignore\n    isInputRules: true,\n  }) as Plugin\n\n  return plugin\n}\n","// see: https://github.com/mesqueeb/is-what/blob/88d6e4ca92fb2baab6003c54e02eedf4e729e5ab/src/index.ts\n\nfunction getType(value: any): string {\n  return Object.prototype.toString.call(value).slice(8, -1)\n}\n\nexport function isPlainObject(value: any): value is Record<string, any> {\n  if (getType(value) !== 'Object') {\n    return false\n  }\n\n  return value.constructor === Object && Object.getPrototypeOf(value) === Object.prototype\n}\n","import { isPlainObject } from './isPlainObject.js'\n\nexport function mergeDeep(target: Record<string, any>, source: Record<string, any>): Record<string, any> {\n  const output = { ...target }\n\n  if (isPlainObject(target) && isPlainObject(source)) {\n    Object.keys(source).forEach(key => {\n      if (isPlainObject(source[key]) && isPlainObject(target[key])) {\n        output[key] = mergeDeep(target[key], source[key])\n      } else {\n        output[key] = source[key]\n      }\n    })\n  }\n\n  return output\n}\n","import {\n  DOMOutputSpec, Mark as ProseMirrorMark, MarkSpec, MarkType,\n} from '@tiptap/pm/model'\nimport { Plugin, Transaction } from '@tiptap/pm/state'\n\nimport { Editor } from './Editor.js'\nimport { getExtensionField } from './helpers/getExtensionField.js'\nimport { MarkConfig } from './index.js'\nimport { InputRule } from './InputRule.js'\nimport { Node } from './Node.js'\nimport { PasteRule } from './PasteRule.js'\nimport {\n  AnyConfig,\n  Attributes,\n  Extensions,\n  GlobalAttributes,\n  KeyboardShortcutCommand,\n  ParentConfig,\n  RawCommands,\n} from './types.js'\nimport { callOrReturn } from './utilities/callOrReturn.js'\nimport { mergeDeep } from './utilities/mergeDeep.js'\n\ndeclare module '@tiptap/core' {\n  export interface MarkConfig<Options = any, Storage = any> {\n    // @ts-ignore - this is a dynamic key\n    [key: string]: any\n\n    /**\n     * The extension name - this must be unique.\n     * It will be used to identify the extension.\n     *\n     * @example 'myExtension'\n     */\n    name: string\n\n    /**\n     * The priority of your extension. The higher, the earlier it will be called\n     * and will take precedence over other extensions with a lower priority.\n     * @default 100\n     * @example 101\n     */\n    priority?: number\n\n    /**\n     * The default options for this extension.\n     * @example\n     * defaultOptions: {\n     *   myOption: 'foo',\n     *   myOtherOption: 10,\n     * }\n     */\n    defaultOptions?: Options\n\n    /**\n     * This method will add options to this extension\n     * @see https://tiptap.dev/guide/custom-extensions#settings\n     * @example\n     * addOptions() {\n     *  return {\n     *    myOption: 'foo',\n     *    myOtherOption: 10,\n     * }\n     */\n    addOptions?: (this: {\n      name: string\n      parent: Exclude<ParentConfig<MarkConfig<Options, Storage>>['addOptions'], undefined>\n    }) => Options\n\n    /**\n     * The default storage this extension can save data to.\n     * @see https://tiptap.dev/guide/custom-extensions#storage\n     * @example\n     * defaultStorage: {\n     *   prefetchedUsers: [],\n     *   loading: false,\n     * }\n     */\n    addStorage?: (this: {\n      name: string\n      options: Options\n      parent: Exclude<ParentConfig<MarkConfig<Options, Storage>>['addStorage'], undefined>\n    }) => Storage\n\n    /**\n     * This function adds globalAttributes to specific nodes.\n     * @see https://tiptap.dev/guide/custom-extensions#global-attributes\n     * @example\n     * addGlobalAttributes() {\n     *   return [\n     *     {\n             // Extend the following extensions\n     *       types: [\n     *         'heading',\n     *         'paragraph',\n     *       ],\n     *       // … with those attributes\n     *       attributes: {\n     *         textAlign: {\n     *           default: 'left',\n     *           renderHTML: attributes => ({\n     *             style: `text-align: ${attributes.textAlign}`,\n     *           }),\n     *           parseHTML: element => element.style.textAlign || 'left',\n     *         },\n     *       },\n     *     },\n     *   ]\n     * }\n     */\n    addGlobalAttributes?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      extensions: (Node | Mark)[]\n      parent: ParentConfig<MarkConfig<Options, Storage>>['addGlobalAttributes']\n    }) => GlobalAttributes\n\n    /**\n     * This function adds commands to the editor\n     * @see https://tiptap.dev/guide/custom-extensions#keyboard-shortcuts\n     * @example\n     * addCommands() {\n     *   return {\n     *     myCommand: () => ({ chain }) => chain().setMark('type', 'foo').run(),\n     *   }\n     * }\n     */\n    addCommands?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: MarkType\n      parent: ParentConfig<MarkConfig<Options, Storage>>['addCommands']\n    }) => Partial<RawCommands>\n\n    /**\n     * This function registers keyboard shortcuts.\n     * @see https://tiptap.dev/guide/custom-extensions#keyboard-shortcuts\n     * @example\n     * addKeyboardShortcuts() {\n     *   return {\n     *     'Mod-l': () => this.editor.commands.toggleBulletList(),\n     *   }\n     * },\n     */\n    addKeyboardShortcuts?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: MarkType\n      parent: ParentConfig<MarkConfig<Options, Storage>>['addKeyboardShortcuts']\n    }) => {\n      [key: string]: KeyboardShortcutCommand\n    }\n\n    /**\n     * This function adds input rules to the editor.\n     * @see https://tiptap.dev/guide/custom-extensions#input-rules\n     * @example\n     * addInputRules() {\n     *   return [\n     *     markInputRule({\n     *       find: inputRegex,\n     *       type: this.type,\n     *     }),\n     *   ]\n     * },\n     */\n    addInputRules?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: MarkType\n      parent: ParentConfig<MarkConfig<Options, Storage>>['addInputRules']\n    }) => InputRule[]\n\n    /**\n     * This function adds paste rules to the editor.\n     * @see https://tiptap.dev/guide/custom-extensions#paste-rules\n     * @example\n     * addPasteRules() {\n     *   return [\n     *     markPasteRule({\n     *       find: pasteRegex,\n     *       type: this.type,\n     *     }),\n     *   ]\n     * },\n     */\n    addPasteRules?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: MarkType\n      parent: ParentConfig<MarkConfig<Options, Storage>>['addPasteRules']\n    }) => PasteRule[]\n\n    /**\n     * This function adds Prosemirror plugins to the editor\n     * @see https://tiptap.dev/guide/custom-extensions#prosemirror-plugins\n     * @example\n     * addProseMirrorPlugins() {\n     *   return [\n     *     customPlugin(),\n     *   ]\n     * }\n     */\n    addProseMirrorPlugins?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: MarkType\n      parent: ParentConfig<MarkConfig<Options, Storage>>['addProseMirrorPlugins']\n    }) => Plugin[]\n\n    /**\n     * This function adds additional extensions to the editor. This is useful for\n     * building extension kits.\n     * @example\n     * addExtensions() {\n     *   return [\n     *     BulletList,\n     *     OrderedList,\n     *     ListItem\n     *   ]\n     * }\n     */\n    addExtensions?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      parent: ParentConfig<MarkConfig<Options, Storage>>['addExtensions']\n    }) => Extensions\n\n    /**\n     * This function extends the schema of the node.\n     * @example\n     * extendNodeSchema() {\n     *   return {\n     *     group: 'inline',\n     *     selectable: false,\n     *   }\n     * }\n     */\n    extendNodeSchema?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            parent: ParentConfig<MarkConfig<Options, Storage>>['extendNodeSchema']\n          },\n          extension: Node,\n        ) => Record<string, any>)\n      | null\n\n    /**\n     * This function extends the schema of the mark.\n     * @example\n     * extendMarkSchema() {\n     *   return {\n     *     group: 'inline',\n     *     selectable: false,\n     *   }\n     * }\n     */\n    extendMarkSchema?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            parent: ParentConfig<MarkConfig<Options, Storage>>['extendMarkSchema']\n          },\n          extension: Mark,\n        ) => Record<string, any>)\n      | null\n\n    /**\n     * The editor is not ready yet.\n     */\n    onBeforeCreate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: MarkType\n          parent: ParentConfig<MarkConfig<Options, Storage>>['onBeforeCreate']\n        }) => void)\n      | null\n\n    /**\n     * The editor is ready.\n     */\n    onCreate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: MarkType\n          parent: ParentConfig<MarkConfig<Options, Storage>>['onCreate']\n        }) => void)\n      | null\n\n    /**\n     * The content has changed.\n     */\n    onUpdate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: MarkType\n          parent: ParentConfig<MarkConfig<Options, Storage>>['onUpdate']\n        }) => void)\n      | null\n\n    /**\n     * The selection has changed.\n     */\n    onSelectionUpdate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: MarkType\n          parent: ParentConfig<MarkConfig<Options, Storage>>['onSelectionUpdate']\n        }) => void)\n      | null\n\n    /**\n     * The editor state has changed.\n     */\n    onTransaction?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            editor: Editor\n            type: MarkType\n            parent: ParentConfig<MarkConfig<Options, Storage>>['onTransaction']\n          },\n          props: {\n            editor: Editor\n            transaction: Transaction\n          },\n        ) => void)\n      | null\n\n    /**\n     * The editor is focused.\n     */\n    onFocus?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            editor: Editor\n            type: MarkType\n            parent: ParentConfig<MarkConfig<Options, Storage>>['onFocus']\n          },\n          props: {\n            event: FocusEvent\n          },\n        ) => void)\n      | null\n\n    /**\n     * The editor isn’t focused anymore.\n     */\n    onBlur?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            editor: Editor\n            type: MarkType\n            parent: ParentConfig<MarkConfig<Options, Storage>>['onBlur']\n          },\n          props: {\n            event: FocusEvent\n          },\n        ) => void)\n      | null\n\n    /**\n     * The editor is destroyed.\n     */\n    onDestroy?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: MarkType\n          parent: ParentConfig<MarkConfig<Options, Storage>>['onDestroy']\n        }) => void)\n      | null\n\n    /**\n     * Keep mark after split node\n     */\n    keepOnSplit?: boolean | (() => boolean)\n\n    /**\n     * Inclusive\n     */\n    inclusive?:\n      | MarkSpec['inclusive']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<MarkConfig<Options, Storage>>['inclusive']\n          editor?: Editor\n        }) => MarkSpec['inclusive'])\n\n    /**\n     * Excludes\n     */\n    excludes?:\n      | MarkSpec['excludes']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<MarkConfig<Options, Storage>>['excludes']\n          editor?: Editor\n        }) => MarkSpec['excludes'])\n\n    /**\n     * Marks this Mark as exitable\n     */\n    exitable?: boolean | (() => boolean)\n\n    /**\n     * Group\n     */\n    group?:\n      | MarkSpec['group']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<MarkConfig<Options, Storage>>['group']\n          editor?: Editor\n        }) => MarkSpec['group'])\n\n    /**\n     * Spanning\n     */\n    spanning?:\n      | MarkSpec['spanning']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<MarkConfig<Options, Storage>>['spanning']\n          editor?: Editor\n        }) => MarkSpec['spanning'])\n\n    /**\n     * Code\n     */\n    code?:\n      | boolean\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<MarkConfig<Options, Storage>>['code']\n          editor?: Editor\n        }) => boolean)\n\n    /**\n     * Parse HTML\n     */\n    parseHTML?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      parent: ParentConfig<MarkConfig<Options, Storage>>['parseHTML']\n      editor?: Editor\n    }) => MarkSpec['parseDOM']\n\n    /**\n     * Render HTML\n     */\n    renderHTML?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            parent: ParentConfig<MarkConfig<Options, Storage>>['renderHTML']\n            editor?: Editor\n          },\n          props: {\n            mark: ProseMirrorMark\n            HTMLAttributes: Record<string, any>\n          },\n        ) => DOMOutputSpec)\n      | null\n\n    /**\n     * Attributes\n     */\n    addAttributes?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      parent: ParentConfig<MarkConfig<Options, Storage>>['addAttributes']\n      editor?: Editor\n    // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n    }) => Attributes | {}\n  }\n}\n\n/**\n * The Mark class is used to create custom mark extensions.\n * @see https://tiptap.dev/api/extensions#create-a-new-extension\n */\nexport class Mark<Options = any, Storage = any> {\n  type = 'mark'\n\n  name = 'mark'\n\n  parent: Mark | null = null\n\n  child: Mark | null = null\n\n  options: Options\n\n  storage: Storage\n\n  config: MarkConfig = {\n    name: this.name,\n    defaultOptions: {},\n  }\n\n  constructor(config: Partial<MarkConfig<Options, Storage>> = {}) {\n    this.config = {\n      ...this.config,\n      ...config,\n    }\n\n    this.name = this.config.name\n\n    if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) {\n      console.warn(\n        `[tiptap warn]: BREAKING CHANGE: \"defaultOptions\" is deprecated. Please use \"addOptions\" instead. Found in extension: \"${this.name}\".`,\n      )\n    }\n\n    // TODO: remove `addOptions` fallback\n    this.options = this.config.defaultOptions\n\n    if (this.config.addOptions) {\n      this.options = callOrReturn(\n        getExtensionField<AnyConfig['addOptions']>(this, 'addOptions', {\n          name: this.name,\n        }),\n      )\n    }\n\n    this.storage = callOrReturn(\n      getExtensionField<AnyConfig['addStorage']>(this, 'addStorage', {\n        name: this.name,\n        options: this.options,\n      }),\n    ) || {}\n  }\n\n  static create<O = any, S = any>(config: Partial<MarkConfig<O, S>> = {}) {\n    return new Mark<O, S>(config)\n  }\n\n  configure(options: Partial<Options> = {}) {\n    // return a new instance so we can use the same extension\n    // with different calls of `configure`\n    const extension = this.extend<Options, Storage>({\n      ...this.config,\n      addOptions: () => {\n        return mergeDeep(this.options as Record<string, any>, options) as Options\n      },\n    })\n\n    // Always preserve the current name\n    extension.name = this.name\n    // Set the parent to be our parent\n    extension.parent = this.parent\n\n    return extension\n  }\n\n  extend<ExtendedOptions = Options, ExtendedStorage = Storage>(\n    extendedConfig: Partial<MarkConfig<ExtendedOptions, ExtendedStorage>> = {},\n  ) {\n    const extension = new Mark<ExtendedOptions, ExtendedStorage>(extendedConfig)\n\n    extension.parent = this\n\n    this.child = extension\n\n    extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name\n\n    if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) {\n      console.warn(\n        `[tiptap warn]: BREAKING CHANGE: \"defaultOptions\" is deprecated. Please use \"addOptions\" instead. Found in extension: \"${extension.name}\".`,\n      )\n    }\n\n    extension.options = callOrReturn(\n      getExtensionField<AnyConfig['addOptions']>(extension, 'addOptions', {\n        name: extension.name,\n      }),\n    )\n\n    extension.storage = callOrReturn(\n      getExtensionField<AnyConfig['addStorage']>(extension, 'addStorage', {\n        name: extension.name,\n        options: extension.options,\n      }),\n    )\n\n    return extension\n  }\n\n  static handleExit({ editor, mark }: { editor: Editor; mark: Mark }) {\n    const { tr } = editor.state\n    const currentPos = editor.state.selection.$from\n    const isAtEnd = currentPos.pos === currentPos.end()\n\n    if (isAtEnd) {\n      const currentMarks = currentPos.marks()\n      const isInMark = !!currentMarks.find(m => m?.type.name === mark.name)\n\n      if (!isInMark) {\n        return false\n      }\n\n      const removeMark = currentMarks.find(m => m?.type.name === mark.name)\n\n      if (removeMark) {\n        tr.removeStoredMark(removeMark)\n      }\n      tr.insertText(' ', currentPos.pos)\n\n      editor.view.dispatch(tr)\n\n      return true\n    }\n\n    return false\n  }\n}\n","export function isNumber(value: any): value is number {\n  return typeof value === 'number'\n}\n","import { Fragment, Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { EditorState, Plugin } from '@tiptap/pm/state'\n\nimport { CommandManager } from './CommandManager.js'\nimport { Editor } from './Editor.js'\nimport { createChainableState } from './helpers/createChainableState.js'\nimport { getHTMLFromFragment } from './helpers/getHTMLFromFragment.js'\nimport {\n  CanCommands,\n  ChainedCommands,\n  ExtendedRegExpMatchArray,\n  Range,\n  SingleCommands,\n} from './types.js'\nimport { isNumber } from './utilities/isNumber.js'\nimport { isRegExp } from './utilities/isRegExp.js'\n\nexport type PasteRuleMatch = {\n  index: number;\n  text: string;\n  replaceWith?: string;\n  match?: RegExpMatchArray;\n  data?: Record<string, any>;\n};\n\nexport type PasteRuleFinder =\n  | RegExp\n  | ((text: string, event?: ClipboardEvent | null) => PasteRuleMatch[] | null | undefined);\n\n/**\n * Paste rules are used to react to pasted content.\n * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules\n */\nexport class PasteRule {\n  find: PasteRuleFinder\n\n  handler: (props: {\n    state: EditorState;\n    range: Range;\n    match: ExtendedRegExpMatchArray;\n    commands: SingleCommands;\n    chain: () => ChainedCommands;\n    can: () => CanCommands;\n    pasteEvent: ClipboardEvent | null;\n    dropEvent: DragEvent | null;\n  }) => void | null\n\n  constructor(config: {\n    find: PasteRuleFinder;\n    handler: (props: {\n      can: () => CanCommands;\n      chain: () => ChainedCommands;\n      commands: SingleCommands;\n      dropEvent: DragEvent | null;\n      match: ExtendedRegExpMatchArray;\n      pasteEvent: ClipboardEvent | null;\n      range: Range;\n      state: EditorState;\n    }) => void | null;\n  }) {\n    this.find = config.find\n    this.handler = config.handler\n  }\n}\n\nconst pasteRuleMatcherHandler = (\n  text: string,\n  find: PasteRuleFinder,\n  event?: ClipboardEvent | null,\n): ExtendedRegExpMatchArray[] => {\n  if (isRegExp(find)) {\n    return [...text.matchAll(find)]\n  }\n\n  const matches = find(text, event)\n\n  if (!matches) {\n    return []\n  }\n\n  return matches.map(pasteRuleMatch => {\n    const result: ExtendedRegExpMatchArray = [pasteRuleMatch.text]\n\n    result.index = pasteRuleMatch.index\n    result.input = text\n    result.data = pasteRuleMatch.data\n\n    if (pasteRuleMatch.replaceWith) {\n      if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) {\n        console.warn(\n          '[tiptap warn]: \"pasteRuleMatch.replaceWith\" must be part of \"pasteRuleMatch.text\".',\n        )\n      }\n\n      result.push(pasteRuleMatch.replaceWith)\n    }\n\n    return result\n  })\n}\n\nfunction run(config: {\n  editor: Editor;\n  state: EditorState;\n  from: number;\n  to: number;\n  rule: PasteRule;\n  pasteEvent: ClipboardEvent | null;\n  dropEvent: DragEvent | null;\n}): boolean {\n  const {\n    editor, state, from, to, rule, pasteEvent, dropEvent,\n  } = config\n\n  const { commands, chain, can } = new CommandManager({\n    editor,\n    state,\n  })\n\n  const handlers: (void | null)[] = []\n\n  state.doc.nodesBetween(from, to, (node, pos) => {\n    if (!node.isTextblock || node.type.spec.code) {\n      return\n    }\n\n    const resolvedFrom = Math.max(from, pos)\n    const resolvedTo = Math.min(to, pos + node.content.size)\n    const textToMatch = node.textBetween(resolvedFrom - pos, resolvedTo - pos, undefined, '\\ufffc')\n\n    const matches = pasteRuleMatcherHandler(textToMatch, rule.find, pasteEvent)\n\n    matches.forEach(match => {\n      if (match.index === undefined) {\n        return\n      }\n\n      const start = resolvedFrom + match.index + 1\n      const end = start + match[0].length\n      const range = {\n        from: state.tr.mapping.map(start),\n        to: state.tr.mapping.map(end),\n      }\n\n      const handler = rule.handler({\n        state,\n        range,\n        match,\n        commands,\n        chain,\n        can,\n        pasteEvent,\n        dropEvent,\n      })\n\n      handlers.push(handler)\n    })\n  })\n\n  const success = handlers.every(handler => handler !== null)\n\n  return success\n}\n\n// When dragging across editors, must get another editor instance to delete selection content.\nlet tiptapDragFromOtherEditor: Editor | null = null\n\nconst createClipboardPasteEvent = (text: string) => {\n  const event = new ClipboardEvent('paste', {\n    clipboardData: new DataTransfer(),\n  })\n\n  event.clipboardData?.setData('text/html', text)\n\n  return event\n}\n\n/**\n * Create an paste rules plugin. When enabled, it will cause pasted\n * text that matches any of the given rules to trigger the rule’s\n * action.\n */\nexport function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }): Plugin[] {\n  const { editor, rules } = props\n  let dragSourceElement: Element | null = null\n  let isPastedFromProseMirror = false\n  let isDroppedFromProseMirror = false\n  let pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null\n  let dropEvent: DragEvent | null\n\n  try {\n    dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null\n  } catch {\n    dropEvent = null\n  }\n\n  const processEvent = ({\n    state,\n    from,\n    to,\n    rule,\n    pasteEvt,\n  }: {\n    state: EditorState;\n    from: number;\n    to: { b: number };\n    rule: PasteRule;\n    pasteEvt: ClipboardEvent | null;\n  }) => {\n    const tr = state.tr\n    const chainableState = createChainableState({\n      state,\n      transaction: tr,\n    })\n\n    const handler = run({\n      editor,\n      state: chainableState,\n      from: Math.max(from - 1, 0),\n      to: to.b - 1,\n      rule,\n      pasteEvent: pasteEvt,\n      dropEvent,\n    })\n\n    if (!handler || !tr.steps.length) {\n      return\n    }\n\n    try {\n      dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null\n    } catch {\n      dropEvent = null\n    }\n    pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null\n\n    return tr\n  }\n\n  const plugins = rules.map(rule => {\n    return new Plugin({\n      // we register a global drag handler to track the current drag source element\n      view(view) {\n        const handleDragstart = (event: DragEvent) => {\n          dragSourceElement = view.dom.parentElement?.contains(event.target as Element)\n            ? view.dom.parentElement\n            : null\n\n          if (dragSourceElement) {\n            tiptapDragFromOtherEditor = editor\n          }\n        }\n\n        const handleDragend = () => {\n          if (tiptapDragFromOtherEditor) {\n            tiptapDragFromOtherEditor = null\n          }\n        }\n\n        window.addEventListener('dragstart', handleDragstart)\n        window.addEventListener('dragend', handleDragend)\n\n        return {\n          destroy() {\n            window.removeEventListener('dragstart', handleDragstart)\n            window.removeEventListener('dragend', handleDragend)\n          },\n        }\n      },\n\n      props: {\n        handleDOMEvents: {\n          drop: (view, event: Event) => {\n            isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement\n            dropEvent = event as DragEvent\n\n            if (!isDroppedFromProseMirror) {\n              const dragFromOtherEditor = tiptapDragFromOtherEditor\n\n              if (dragFromOtherEditor) {\n                // setTimeout to avoid the wrong content after drop, timeout arg can't be empty or 0\n                setTimeout(() => {\n                  const selection = dragFromOtherEditor.state.selection\n\n                  if (selection) {\n                    dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to })\n                  }\n                }, 10)\n              }\n            }\n            return false\n          },\n\n          paste: (_view, event: Event) => {\n            const html = (event as ClipboardEvent).clipboardData?.getData('text/html')\n\n            pasteEvent = event as ClipboardEvent\n\n            isPastedFromProseMirror = !!html?.includes('data-pm-slice')\n\n            return false\n          },\n        },\n      },\n\n      appendTransaction: (transactions, oldState, state) => {\n        const transaction = transactions[0]\n        const isPaste = transaction.getMeta('uiEvent') === 'paste' && !isPastedFromProseMirror\n        const isDrop = transaction.getMeta('uiEvent') === 'drop' && !isDroppedFromProseMirror\n\n        // if PasteRule is triggered by insertContent()\n        const simulatedPasteMeta = transaction.getMeta('applyPasteRules') as\n          | undefined\n          | { from: number; text: string | ProseMirrorNode | Fragment }\n        const isSimulatedPaste = !!simulatedPasteMeta\n\n        if (!isPaste && !isDrop && !isSimulatedPaste) {\n          return\n        }\n\n        // Handle simulated paste\n        if (isSimulatedPaste) {\n          let { text } = simulatedPasteMeta\n\n          if (typeof text === 'string') {\n            text = text as string\n          } else {\n            text = getHTMLFromFragment(Fragment.from(text), state.schema)\n          }\n\n          const { from } = simulatedPasteMeta\n          const to = from + text.length\n\n          const pasteEvt = createClipboardPasteEvent(text)\n\n          return processEvent({\n            rule,\n            state,\n            from,\n            to: { b: to },\n            pasteEvt,\n          })\n        }\n\n        // handle actual paste/drop\n        const from = oldState.doc.content.findDiffStart(state.doc.content)\n        const to = oldState.doc.content.findDiffEnd(state.doc.content)\n\n        // stop if there is no changed range\n        if (!isNumber(from) || !to || from === to.b) {\n          return\n        }\n\n        return processEvent({\n          rule,\n          state,\n          from,\n          to,\n          pasteEvt: pasteEvent,\n        })\n      },\n    })\n  })\n\n  return plugins\n}\n","export function findDuplicates(items: any[]): any[] {\n  const filtered = items.filter((el, index) => items.indexOf(el) !== index)\n\n  return Array.from(new Set(filtered))\n}\n","import { keymap } from '@tiptap/pm/keymap'\nimport { Schema } from '@tiptap/pm/model'\nimport { Plugin } from '@tiptap/pm/state'\nimport { NodeViewConstructor } from '@tiptap/pm/view'\n\nimport type { Editor } from './Editor.js'\nimport { getAttributesFromExtensions } from './helpers/getAttributesFromExtensions.js'\nimport { getExtensionField } from './helpers/getExtensionField.js'\nimport { getNodeType } from './helpers/getNodeType.js'\nimport { getRenderedAttributes } from './helpers/getRenderedAttributes.js'\nimport { getSchemaByResolvedExtensions } from './helpers/getSchemaByResolvedExtensions.js'\nimport { getSchemaTypeByName } from './helpers/getSchemaTypeByName.js'\nimport { isExtensionRulesEnabled } from './helpers/isExtensionRulesEnabled.js'\nimport { splitExtensions } from './helpers/splitExtensions.js'\nimport type { NodeConfig } from './index.js'\nimport { InputRule, inputRulesPlugin } from './InputRule.js'\nimport { Mark } from './Mark.js'\nimport { PasteRule, pasteRulesPlugin } from './PasteRule.js'\nimport { AnyConfig, Extensions, RawCommands } from './types.js'\nimport { callOrReturn } from './utilities/callOrReturn.js'\nimport { findDuplicates } from './utilities/findDuplicates.js'\n\nexport class ExtensionManager {\n  editor: Editor\n\n  schema: Schema\n\n  extensions: Extensions\n\n  splittableMarks: string[] = []\n\n  constructor(extensions: Extensions, editor: Editor) {\n    this.editor = editor\n    this.extensions = ExtensionManager.resolve(extensions)\n    this.schema = getSchemaByResolvedExtensions(this.extensions, editor)\n    this.setupExtensions()\n  }\n\n  /**\n   * Returns a flattened and sorted extension list while\n   * also checking for duplicated extensions and warns the user.\n   * @param extensions An array of Tiptap extensions\n   * @returns An flattened and sorted array of Tiptap extensions\n   */\n  static resolve(extensions: Extensions): Extensions {\n    const resolvedExtensions = ExtensionManager.sort(ExtensionManager.flatten(extensions))\n    const duplicatedNames = findDuplicates(resolvedExtensions.map(extension => extension.name))\n\n    if (duplicatedNames.length) {\n      console.warn(\n        `[tiptap warn]: Duplicate extension names found: [${duplicatedNames\n          .map(item => `'${item}'`)\n          .join(', ')}]. This can lead to issues.`,\n      )\n    }\n\n    return resolvedExtensions\n  }\n\n  /**\n   * Create a flattened array of extensions by traversing the `addExtensions` field.\n   * @param extensions An array of Tiptap extensions\n   * @returns A flattened array of Tiptap extensions\n   */\n  static flatten(extensions: Extensions): Extensions {\n    return (\n      extensions\n        .map(extension => {\n          const context = {\n            name: extension.name,\n            options: extension.options,\n            storage: extension.storage,\n          }\n\n          const addExtensions = getExtensionField<AnyConfig['addExtensions']>(\n            extension,\n            'addExtensions',\n            context,\n          )\n\n          if (addExtensions) {\n            return [extension, ...this.flatten(addExtensions())]\n          }\n\n          return extension\n        })\n        // `Infinity` will break TypeScript so we set a number that is probably high enough\n        .flat(10)\n    )\n  }\n\n  /**\n   * Sort extensions by priority.\n   * @param extensions An array of Tiptap extensions\n   * @returns A sorted array of Tiptap extensions by priority\n   */\n  static sort(extensions: Extensions): Extensions {\n    const defaultPriority = 100\n\n    return extensions.sort((a, b) => {\n      const priorityA = getExtensionField<AnyConfig['priority']>(a, 'priority') || defaultPriority\n      const priorityB = getExtensionField<AnyConfig['priority']>(b, 'priority') || defaultPriority\n\n      if (priorityA > priorityB) {\n        return -1\n      }\n\n      if (priorityA < priorityB) {\n        return 1\n      }\n\n      return 0\n    })\n  }\n\n  /**\n   * Get all commands from the extensions.\n   * @returns An object with all commands where the key is the command name and the value is the command function\n   */\n  get commands(): RawCommands {\n    return this.extensions.reduce((commands, extension) => {\n      const context = {\n        name: extension.name,\n        options: extension.options,\n        storage: extension.storage,\n        editor: this.editor,\n        type: getSchemaTypeByName(extension.name, this.schema),\n      }\n\n      const addCommands = getExtensionField<AnyConfig['addCommands']>(\n        extension,\n        'addCommands',\n        context,\n      )\n\n      if (!addCommands) {\n        return commands\n      }\n\n      return {\n        ...commands,\n        ...addCommands(),\n      }\n    }, {} as RawCommands)\n  }\n\n  /**\n   * Get all registered Prosemirror plugins from the extensions.\n   * @returns An array of Prosemirror plugins\n   */\n  get plugins(): Plugin[] {\n    const { editor } = this\n\n    // With ProseMirror, first plugins within an array are executed first.\n    // In Tiptap, we provide the ability to override plugins,\n    // so it feels more natural to run plugins at the end of an array first.\n    // That’s why we have to reverse the `extensions` array and sort again\n    // based on the `priority` option.\n    const extensions = ExtensionManager.sort([...this.extensions].reverse())\n\n    const inputRules: InputRule[] = []\n    const pasteRules: PasteRule[] = []\n\n    const allPlugins = extensions\n      .map(extension => {\n        const context = {\n          name: extension.name,\n          options: extension.options,\n          storage: extension.storage,\n          editor,\n          type: getSchemaTypeByName(extension.name, this.schema),\n        }\n\n        const plugins: Plugin[] = []\n\n        const addKeyboardShortcuts = getExtensionField<AnyConfig['addKeyboardShortcuts']>(\n          extension,\n          'addKeyboardShortcuts',\n          context,\n        )\n\n        let defaultBindings: Record<string, () => boolean> = {}\n\n        // bind exit handling\n        if (extension.type === 'mark' && getExtensionField<AnyConfig['exitable']>(extension, 'exitable', context)) {\n          defaultBindings.ArrowRight = () => Mark.handleExit({ editor, mark: extension as Mark })\n        }\n\n        if (addKeyboardShortcuts) {\n          const bindings = Object.fromEntries(\n            Object.entries(addKeyboardShortcuts()).map(([shortcut, method]) => {\n              return [shortcut, () => method({ editor })]\n            }),\n          )\n\n          defaultBindings = { ...defaultBindings, ...bindings }\n        }\n\n        const keyMapPlugin = keymap(defaultBindings)\n\n        plugins.push(keyMapPlugin)\n\n        const addInputRules = getExtensionField<AnyConfig['addInputRules']>(\n          extension,\n          'addInputRules',\n          context,\n        )\n\n        if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) {\n          inputRules.push(...addInputRules())\n        }\n\n        const addPasteRules = getExtensionField<AnyConfig['addPasteRules']>(\n          extension,\n          'addPasteRules',\n          context,\n        )\n\n        if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) {\n          pasteRules.push(...addPasteRules())\n        }\n\n        const addProseMirrorPlugins = getExtensionField<AnyConfig['addProseMirrorPlugins']>(\n          extension,\n          'addProseMirrorPlugins',\n          context,\n        )\n\n        if (addProseMirrorPlugins) {\n          const proseMirrorPlugins = addProseMirrorPlugins()\n\n          plugins.push(...proseMirrorPlugins)\n        }\n\n        return plugins\n      })\n      .flat()\n\n    return [\n      inputRulesPlugin({\n        editor,\n        rules: inputRules,\n      }),\n      ...pasteRulesPlugin({\n        editor,\n        rules: pasteRules,\n      }),\n      ...allPlugins,\n    ]\n  }\n\n  /**\n   * Get all attributes from the extensions.\n   * @returns An array of attributes\n   */\n  get attributes() {\n    return getAttributesFromExtensions(this.extensions)\n  }\n\n  /**\n   * Get all node views from the extensions.\n   * @returns An object with all node views where the key is the node name and the value is the node view function\n   */\n  get nodeViews(): Record<string, NodeViewConstructor> {\n    const { editor } = this\n    const { nodeExtensions } = splitExtensions(this.extensions)\n\n    return Object.fromEntries(\n      nodeExtensions\n        .filter(extension => !!getExtensionField(extension, 'addNodeView'))\n        .map(extension => {\n          const extensionAttributes = this.attributes.filter(\n            attribute => attribute.type === extension.name,\n          )\n          const context = {\n            name: extension.name,\n            options: extension.options,\n            storage: extension.storage,\n            editor,\n            type: getNodeType(extension.name, this.schema),\n          }\n          const addNodeView = getExtensionField<NodeConfig['addNodeView']>(\n            extension,\n            'addNodeView',\n            context,\n          )\n\n          if (!addNodeView) {\n            return []\n          }\n\n          const nodeview: NodeViewConstructor = (\n            node,\n            view,\n            getPos,\n            decorations,\n            innerDecorations,\n          ) => {\n            const HTMLAttributes = getRenderedAttributes(node, extensionAttributes)\n\n            return addNodeView()({\n              // pass-through\n              node,\n              view,\n              getPos: getPos as () => number,\n              decorations,\n              innerDecorations,\n              // tiptap-specific\n              editor,\n              extension,\n              HTMLAttributes,\n            })\n          }\n\n          return [extension.name, nodeview]\n        }),\n    )\n  }\n\n  /**\n   * Go through all extensions, create extension storages & setup marks\n   * & bind editor event listener.\n   */\n  private setupExtensions() {\n    this.extensions.forEach(extension => {\n      // store extension storage in editor\n      this.editor.extensionStorage[extension.name] = extension.storage\n\n      const context = {\n        name: extension.name,\n        options: extension.options,\n        storage: extension.storage,\n        editor: this.editor,\n        type: getSchemaTypeByName(extension.name, this.schema),\n      }\n\n      if (extension.type === 'mark') {\n        const keepOnSplit = callOrReturn(getExtensionField(extension, 'keepOnSplit', context)) ?? true\n\n        if (keepOnSplit) {\n          this.splittableMarks.push(extension.name)\n        }\n      }\n\n      const onBeforeCreate = getExtensionField<AnyConfig['onBeforeCreate']>(\n        extension,\n        'onBeforeCreate',\n        context,\n      )\n      const onCreate = getExtensionField<AnyConfig['onCreate']>(extension, 'onCreate', context)\n      const onUpdate = getExtensionField<AnyConfig['onUpdate']>(extension, 'onUpdate', context)\n      const onSelectionUpdate = getExtensionField<AnyConfig['onSelectionUpdate']>(\n        extension,\n        'onSelectionUpdate',\n        context,\n      )\n      const onTransaction = getExtensionField<AnyConfig['onTransaction']>(\n        extension,\n        'onTransaction',\n        context,\n      )\n      const onFocus = getExtensionField<AnyConfig['onFocus']>(extension, 'onFocus', context)\n      const onBlur = getExtensionField<AnyConfig['onBlur']>(extension, 'onBlur', context)\n      const onDestroy = getExtensionField<AnyConfig['onDestroy']>(extension, 'onDestroy', context)\n\n      if (onBeforeCreate) {\n        this.editor.on('beforeCreate', onBeforeCreate)\n      }\n\n      if (onCreate) {\n        this.editor.on('create', onCreate)\n      }\n\n      if (onUpdate) {\n        this.editor.on('update', onUpdate)\n      }\n\n      if (onSelectionUpdate) {\n        this.editor.on('selectionUpdate', onSelectionUpdate)\n      }\n\n      if (onTransaction) {\n        this.editor.on('transaction', onTransaction)\n      }\n\n      if (onFocus) {\n        this.editor.on('focus', onFocus)\n      }\n\n      if (onBlur) {\n        this.editor.on('blur', onBlur)\n      }\n\n      if (onDestroy) {\n        this.editor.on('destroy', onDestroy)\n      }\n    })\n  }\n}\n","import { Plugin, Transaction } from '@tiptap/pm/state'\n\nimport { Editor } from './Editor.js'\nimport { getExtensionField } from './helpers/getExtensionField.js'\nimport { ExtensionConfig } from './index.js'\nimport { InputRule } from './InputRule.js'\nimport { Mark } from './Mark.js'\nimport { Node } from './Node.js'\nimport { PasteRule } from './PasteRule.js'\nimport {\n  AnyConfig,\n  Extensions,\n  GlobalAttributes,\n  KeyboardShortcutCommand,\n  ParentConfig,\n  RawCommands,\n} from './types.js'\nimport { callOrReturn } from './utilities/callOrReturn.js'\nimport { mergeDeep } from './utilities/mergeDeep.js'\n\ndeclare module '@tiptap/core' {\n  interface ExtensionConfig<Options = any, Storage = any> {\n    // @ts-ignore - this is a dynamic key\n    [key: string]: any\n\n    /**\n     * The extension name - this must be unique.\n     * It will be used to identify the extension.\n     *\n     * @example 'myExtension'\n     */\n    name: string\n\n    /**\n     * The priority of your extension. The higher, the earlier it will be called\n     * and will take precedence over other extensions with a lower priority.\n     * @default 100\n     * @example 101\n     */\n    priority?: number\n\n    /**\n     * The default options for this extension.\n     * @example\n     * defaultOptions: {\n     *   myOption: 'foo',\n     *   myOtherOption: 10,\n     * }\n     */\n    defaultOptions?: Options\n\n    /**\n     * This method will add options to this extension\n     * @see https://tiptap.dev/docs/editor/guide/custom-extensions#settings\n     * @example\n     * addOptions() {\n     *  return {\n     *    myOption: 'foo',\n     *    myOtherOption: 10,\n     * }\n     */\n    addOptions?: (this: {\n      name: string\n      parent: Exclude<ParentConfig<ExtensionConfig<Options, Storage>>['addOptions'], undefined>\n    }) => Options\n\n    /**\n     * The default storage this extension can save data to.\n     * @see https://tiptap.dev/docs/editor/guide/custom-extensions#storage\n     * @example\n     * defaultStorage: {\n     *   prefetchedUsers: [],\n     *   loading: false,\n     * }\n     */\n    addStorage?: (this: {\n      name: string\n      options: Options\n      parent: Exclude<ParentConfig<ExtensionConfig<Options, Storage>>['addStorage'], undefined>\n    }) => Storage\n\n    /**\n     * This function adds globalAttributes to specific nodes.\n     * @see https://tiptap.dev/docs/editor/guide/custom-extensions#global-attributes\n     * @example\n     * addGlobalAttributes() {\n     *   return [\n     *     {\n             // Extend the following extensions\n     *       types: [\n     *         'heading',\n     *         'paragraph',\n     *       ],\n     *       // … with those attributes\n     *       attributes: {\n     *         textAlign: {\n     *           default: 'left',\n     *           renderHTML: attributes => ({\n     *             style: `text-align: ${attributes.textAlign}`,\n     *           }),\n     *           parseHTML: element => element.style.textAlign || 'left',\n     *         },\n     *       },\n     *     },\n     *   ]\n     * }\n     */\n    addGlobalAttributes?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      extensions: (Node | Mark)[]\n      parent: ParentConfig<ExtensionConfig<Options, Storage>>['addGlobalAttributes']\n    }) => GlobalAttributes\n\n    /**\n     * This function adds commands to the editor\n     * @see https://tiptap.dev/docs/editor/guide/custom-extensions#commands\n     * @example\n     * addCommands() {\n     *   return {\n     *     myCommand: () => ({ chain }) => chain().setMark('type', 'foo').run(),\n     *   }\n     * }\n     */\n    addCommands?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      parent: ParentConfig<ExtensionConfig<Options, Storage>>['addCommands']\n    }) => Partial<RawCommands>\n\n    /**\n     * This function registers keyboard shortcuts.\n     * @see https://tiptap.dev/docs/editor/guide/custom-extensions#keyboard-shortcuts\n     * @example\n     * addKeyboardShortcuts() {\n     *   return {\n     *     'Mod-l': () => this.editor.commands.toggleBulletList(),\n     *   }\n     * },\n     */\n    addKeyboardShortcuts?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      parent: ParentConfig<ExtensionConfig<Options, Storage>>['addKeyboardShortcuts']\n    }) => {\n      [key: string]: KeyboardShortcutCommand\n    }\n\n    /**\n     * This function adds input rules to the editor.\n     * @see https://tiptap.dev/docs/editor/guide/custom-extensions#input-rules\n     * @example\n     * addInputRules() {\n     *   return [\n     *     markInputRule({\n     *       find: inputRegex,\n     *       type: this.type,\n     *     }),\n     *   ]\n     * },\n     */\n    addInputRules?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      parent: ParentConfig<ExtensionConfig<Options, Storage>>['addInputRules']\n    }) => InputRule[]\n\n    /**\n     * This function adds paste rules to the editor.\n     * @see https://tiptap.dev/docs/editor/guide/custom-extensions#paste-rules\n     * @example\n     * addPasteRules() {\n     *   return [\n     *     markPasteRule({\n     *       find: pasteRegex,\n     *       type: this.type,\n     *     }),\n     *   ]\n     * },\n     */\n    addPasteRules?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      parent: ParentConfig<ExtensionConfig<Options, Storage>>['addPasteRules']\n    }) => PasteRule[]\n\n    /**\n     * This function adds Prosemirror plugins to the editor\n     * @see https://tiptap.dev/docs/editor/guide/custom-extensions#prosemirror-plugins\n     * @example\n     * addProseMirrorPlugins() {\n     *   return [\n     *     customPlugin(),\n     *   ]\n     * }\n     */\n    addProseMirrorPlugins?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      parent: ParentConfig<ExtensionConfig<Options, Storage>>['addProseMirrorPlugins']\n    }) => Plugin[]\n\n    /**\n     * This function adds additional extensions to the editor. This is useful for\n     * building extension kits.\n     * @example\n     * addExtensions() {\n     *   return [\n     *     BulletList,\n     *     OrderedList,\n     *     ListItem\n     *   ]\n     * }\n     */\n    addExtensions?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      parent: ParentConfig<ExtensionConfig<Options, Storage>>['addExtensions']\n    }) => Extensions\n\n    /**\n     * This function extends the schema of the node.\n     * @example\n     * extendNodeSchema() {\n     *   return {\n     *     group: 'inline',\n     *     selectable: false,\n     *   }\n     * }\n     */\n    extendNodeSchema?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            parent: ParentConfig<ExtensionConfig<Options, Storage>>['extendNodeSchema']\n          },\n          extension: Node,\n        ) => Record<string, any>)\n      | null\n\n    /**\n     * This function extends the schema of the mark.\n     * @example\n     * extendMarkSchema() {\n     *   return {\n     *     group: 'inline',\n     *     selectable: false,\n     *   }\n     * }\n     */\n    extendMarkSchema?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            parent: ParentConfig<ExtensionConfig<Options, Storage>>['extendMarkSchema']\n          },\n          extension: Mark,\n        ) => Record<string, any>)\n      | null\n\n    /**\n     * The editor is not ready yet.\n     */\n    onBeforeCreate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          parent: ParentConfig<ExtensionConfig<Options, Storage>>['onBeforeCreate']\n        }) => void)\n      | null\n\n    /**\n     * The editor is ready.\n     */\n    onCreate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          parent: ParentConfig<ExtensionConfig<Options, Storage>>['onCreate']\n        }) => void)\n      | null\n\n    /**\n     * The content has changed.\n     */\n    onUpdate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          parent: ParentConfig<ExtensionConfig<Options, Storage>>['onUpdate']\n        }) => void)\n      | null\n\n    /**\n     * The selection has changed.\n     */\n    onSelectionUpdate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          parent: ParentConfig<ExtensionConfig<Options, Storage>>['onSelectionUpdate']\n        }) => void)\n      | null\n\n    /**\n     * The editor state has changed.\n     */\n    onTransaction?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            editor: Editor\n            parent: ParentConfig<ExtensionConfig<Options, Storage>>['onTransaction']\n          },\n          props: {\n            editor: Editor\n            transaction: Transaction\n          },\n        ) => void)\n      | null\n\n    /**\n     * The editor is focused.\n     */\n    onFocus?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            editor: Editor\n            parent: ParentConfig<ExtensionConfig<Options, Storage>>['onFocus']\n          },\n          props: {\n            event: FocusEvent\n          },\n        ) => void)\n      | null\n\n    /**\n     * The editor isn’t focused anymore.\n     */\n    onBlur?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            editor: Editor\n            parent: ParentConfig<ExtensionConfig<Options, Storage>>['onBlur']\n          },\n          props: {\n            event: FocusEvent\n          },\n        ) => void)\n      | null\n\n    /**\n     * The editor is destroyed.\n     */\n    onDestroy?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          parent: ParentConfig<ExtensionConfig<Options, Storage>>['onDestroy']\n        }) => void)\n      | null\n  }\n}\n\n/**\n * The Extension class is the base class for all extensions.\n * @see https://tiptap.dev/api/extensions#create-a-new-extension\n */\nexport class Extension<Options = any, Storage = any> {\n  type = 'extension'\n\n  name = 'extension'\n\n  parent: Extension | null = null\n\n  child: Extension | null = null\n\n  options: Options\n\n  storage: Storage\n\n  config: ExtensionConfig = {\n    name: this.name,\n    defaultOptions: {},\n  }\n\n  constructor(config: Partial<ExtensionConfig<Options, Storage>> = {}) {\n    this.config = {\n      ...this.config,\n      ...config,\n    }\n\n    this.name = this.config.name\n\n    if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) {\n      console.warn(\n        `[tiptap warn]: BREAKING CHANGE: \"defaultOptions\" is deprecated. Please use \"addOptions\" instead. Found in extension: \"${this.name}\".`,\n      )\n    }\n\n    // TODO: remove `addOptions` fallback\n    this.options = this.config.defaultOptions\n\n    if (this.config.addOptions) {\n      this.options = callOrReturn(\n        getExtensionField<AnyConfig['addOptions']>(this, 'addOptions', {\n          name: this.name,\n        }),\n      )\n    }\n\n    this.storage = callOrReturn(\n      getExtensionField<AnyConfig['addStorage']>(this, 'addStorage', {\n        name: this.name,\n        options: this.options,\n      }),\n    ) || {}\n  }\n\n  static create<O = any, S = any>(config: Partial<ExtensionConfig<O, S>> = {}) {\n    return new Extension<O, S>(config)\n  }\n\n  configure(options: Partial<Options> = {}) {\n    // return a new instance so we can use the same extension\n    // with different calls of `configure`\n    const extension = this.extend<Options, Storage>({\n      ...this.config,\n      addOptions: () => {\n        return mergeDeep(this.options as Record<string, any>, options) as Options\n      },\n    })\n\n    // Always preserve the current name\n    extension.name = this.name\n    // Set the parent to be our parent\n    extension.parent = this.parent\n\n    return extension\n  }\n\n  extend<ExtendedOptions = Options, ExtendedStorage = Storage>(\n    extendedConfig: Partial<ExtensionConfig<ExtendedOptions, ExtendedStorage>> = {},\n  ) {\n    const extension = new Extension<ExtendedOptions, ExtendedStorage>({ ...this.config, ...extendedConfig })\n\n    extension.parent = this\n\n    this.child = extension\n\n    extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name\n\n    if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) {\n      console.warn(\n        `[tiptap warn]: BREAKING CHANGE: \"defaultOptions\" is deprecated. Please use \"addOptions\" instead. Found in extension: \"${extension.name}\".`,\n      )\n    }\n\n    extension.options = callOrReturn(\n      getExtensionField<AnyConfig['addOptions']>(extension, 'addOptions', {\n        name: extension.name,\n      }),\n    )\n\n    extension.storage = callOrReturn(\n      getExtensionField<AnyConfig['addStorage']>(extension, 'addStorage', {\n        name: extension.name,\n        options: extension.options,\n      }),\n    )\n\n    return extension\n  }\n}\n","import { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nimport { Range, TextSerializer } from '../types.js'\n\n/**\n * Gets the text between two positions in a Prosemirror node\n * and serializes it using the given text serializers and block separator (see getText)\n * @param startNode The Prosemirror node to start from\n * @param range The range of the text to get\n * @param options Options for the text serializer & block separator\n * @returns The text between the two positions\n */\nexport function getTextBetween(\n  startNode: ProseMirrorNode,\n  range: Range,\n  options?: {\n    blockSeparator?: string\n    textSerializers?: Record<string, TextSerializer>\n  },\n): string {\n  const { from, to } = range\n  const { blockSeparator = '\\n\\n', textSerializers = {} } = options || {}\n  let text = ''\n\n  startNode.nodesBetween(from, to, (node, pos, parent, index) => {\n    if (node.isBlock && pos > from) {\n      text += blockSeparator\n    }\n\n    const textSerializer = textSerializers?.[node.type.name]\n\n    if (textSerializer) {\n      if (parent) {\n        text += textSerializer({\n          node,\n          pos,\n          parent,\n          index,\n          range,\n        })\n      }\n      // do not descend into child nodes when there exists a serializer\n      return false\n    }\n\n    if (node.isText) {\n      text += node?.text?.slice(Math.max(from, pos) - pos, to - pos) // eslint-disable-line\n    }\n  })\n\n  return text\n}\n","import { Schema } from '@tiptap/pm/model'\n\nimport { TextSerializer } from '../types.js'\n\n/**\n * Find text serializers `toText` in a Prosemirror schema\n * @param schema The Prosemirror schema to search in\n * @returns A record of text serializers by node name\n */\nexport function getTextSerializersFromSchema(schema: Schema): Record<string, TextSerializer> {\n  return Object.fromEntries(\n    Object.entries(schema.nodes)\n      .filter(([, node]) => node.spec.toText)\n      .map(([name, node]) => [name, node.spec.toText]),\n  )\n}\n","import { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport { Extension } from '../Extension.js'\nimport { getTextBetween } from '../helpers/getTextBetween.js'\nimport { getTextSerializersFromSchema } from '../helpers/getTextSerializersFromSchema.js'\n\nexport type ClipboardTextSerializerOptions = {\n  blockSeparator?: string,\n}\n\nexport const ClipboardTextSerializer = Extension.create<ClipboardTextSerializerOptions>({\n  name: 'clipboardTextSerializer',\n\n  addOptions() {\n    return {\n      blockSeparator: undefined,\n    }\n  },\n\n  addProseMirrorPlugins() {\n    return [\n      new Plugin({\n        key: new PluginKey('clipboardTextSerializer'),\n        props: {\n          clipboardTextSerializer: () => {\n            const { editor } = this\n            const { state, schema } = editor\n            const { doc, selection } = state\n            const { ranges } = selection\n            const from = Math.min(...ranges.map(range => range.$from.pos))\n            const to = Math.max(...ranges.map(range => range.$to.pos))\n            const textSerializers = getTextSerializersFromSchema(schema)\n            const range = { from, to }\n\n            return getTextBetween(doc, range, {\n              ...(this.options.blockSeparator !== undefined\n                ? { blockSeparator: this.options.blockSeparator }\n                : {}),\n              textSerializers,\n            })\n          },\n        },\n      }),\n    ]\n  },\n})\n","import { isRegExp } from './isRegExp.js'\n\n/**\n * Check if object1 includes object2\n * @param object1 Object\n * @param object2 Object\n */\nexport function objectIncludes(\n  object1: Record<string, any>,\n  object2: Record<string, any>,\n  options: { strict: boolean } = { strict: true },\n): boolean {\n  const keys = Object.keys(object2)\n\n  if (!keys.length) {\n    return true\n  }\n\n  return keys.every(key => {\n    if (options.strict) {\n      return object2[key] === object1[key]\n    }\n\n    if (isRegExp(object2[key])) {\n      return object2[key].test(object1[key])\n    }\n\n    return object2[key] === object1[key]\n  })\n}\n","import { Mark as ProseMirrorMark, MarkType, ResolvedPos } from '@tiptap/pm/model'\n\nimport { Range } from '../types.js'\nimport { objectIncludes } from '../utilities/objectIncludes.js'\n\nfunction findMarkInSet(\n  marks: ProseMirrorMark[],\n  type: MarkType,\n  attributes: Record<string, any> = {},\n): ProseMirrorMark | undefined {\n  return marks.find(item => {\n    return (\n      item.type === type\n      && objectIncludes(\n        // Only check equality for the attributes that are provided\n        Object.fromEntries(Object.keys(attributes).map(k => [k, item.attrs[k]])),\n        attributes,\n      )\n    )\n  })\n}\n\nfunction isMarkInSet(\n  marks: ProseMirrorMark[],\n  type: MarkType,\n  attributes: Record<string, any> = {},\n): boolean {\n  return !!findMarkInSet(marks, type, attributes)\n}\n\n/**\n * Get the range of a mark at a resolved position.\n */\nexport function getMarkRange(\n  /**\n   * The position to get the mark range for.\n   */\n  $pos: ResolvedPos,\n  /**\n   * The mark type to get the range for.\n   */\n  type: MarkType,\n  /**\n   * The attributes to match against.\n   * If not provided, only the first mark at the position will be matched.\n   */\n  attributes?: Record<string, any>,\n): Range | void {\n  if (!$pos || !type) {\n    return\n  }\n  let start = $pos.parent.childAfter($pos.parentOffset)\n\n  // If the cursor is at the start of a text node that does not have the mark, look backward\n  if (!start.node || !start.node.marks.some(mark => mark.type === type)) {\n    start = $pos.parent.childBefore($pos.parentOffset)\n  }\n\n  // If there is no text node with the mark even backward, return undefined\n  if (!start.node || !start.node.marks.some(mark => mark.type === type)) {\n    return\n  }\n\n  // Default to only matching against the first mark's attributes\n  attributes = attributes || start.node.marks[0]?.attrs\n\n  // We now know that the cursor is either at the start, middle or end of a text node with the specified mark\n  // so we can look it up on the targeted mark\n  const mark = findMarkInSet([...start.node.marks], type, attributes)\n\n  if (!mark) {\n    return\n  }\n\n  let startIndex = start.index\n  let startPos = $pos.start() + start.offset\n  let endIndex = startIndex + 1\n  let endPos = startPos + start.node.nodeSize\n\n  while (\n    startIndex > 0\n    && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)\n  ) {\n    startIndex -= 1\n    startPos -= $pos.parent.child(startIndex).nodeSize\n  }\n\n  while (\n    endIndex < $pos.parent.childCount\n    && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)\n  ) {\n    endPos += $pos.parent.child(endIndex).nodeSize\n    endIndex += 1\n  }\n\n  return {\n    from: startPos,\n    to: endPos,\n  }\n}\n","import { MarkType, Schema } from '@tiptap/pm/model'\n\nexport function getMarkType(nameOrType: string | MarkType, schema: Schema): MarkType {\n  if (typeof nameOrType === 'string') {\n    if (!schema.marks[nameOrType]) {\n      throw Error(\n        `There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?`,\n      )\n    }\n\n    return schema.marks[nameOrType]\n  }\n\n  return nameOrType\n}\n","import { TextSelection } from '@tiptap/pm/state'\n\nexport function isTextSelection(value: unknown): value is TextSelection {\n  return value instanceof TextSelection\n}\n","export function minMax(value = 0, min = 0, max = 0): number {\n  return Math.min(Math.max(value, min), max)\n}\n","import { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { Selection, TextSelection } from '@tiptap/pm/state'\n\nimport { FocusPosition } from '../types.js'\nimport { minMax } from '../utilities/minMax.js'\n\nexport function resolveFocusPosition(\n  doc: ProseMirrorNode,\n  position: FocusPosition = null,\n): Selection | null {\n  if (!position) {\n    return null\n  }\n\n  const selectionAtStart = Selection.atStart(doc)\n  const selectionAtEnd = Selection.atEnd(doc)\n\n  if (position === 'start' || position === true) {\n    return selectionAtStart\n  }\n\n  if (position === 'end') {\n    return selectionAtEnd\n  }\n\n  const minPos = selectionAtStart.from\n  const maxPos = selectionAtEnd.to\n\n  if (position === 'all') {\n    return TextSelection.create(\n      doc,\n      minMax(0, minPos, maxPos),\n      minMax(doc.content.size, minPos, maxPos),\n    )\n  }\n\n  return TextSelection.create(\n    doc,\n    minMax(position, minPos, maxPos),\n    minMax(position, minPos, maxPos),\n  )\n}\n","export function isAndroid(): boolean {\n  return navigator.platform === 'Android' || /android/i.test(navigator.userAgent)\n}\n","export function isiOS(): boolean {\n  return [\n    'iPad Simulator',\n    'iPhone Simulator',\n    'iPod Simulator',\n    'iPad',\n    'iPhone',\n    'iPod',\n  ].includes(navigator.platform)\n  // iPad on iOS 13 detection\n  || (navigator.userAgent.includes('Mac') && 'ontouchend' in document)\n}\n","import { isTextSelection } from '../helpers/isTextSelection.js'\nimport { resolveFocusPosition } from '../helpers/resolveFocusPosition.js'\nimport { FocusPosition, RawCommands } from '../types.js'\nimport { isAndroid } from '../utilities/isAndroid.js'\nimport { isiOS } from '../utilities/isiOS.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    focus: {\n      /**\n       * Focus the editor at the given position.\n       * @param position The position to focus at.\n       * @param options.scrollIntoView Scroll the focused position into view after focusing\n       * @example editor.commands.focus()\n       * @example editor.commands.focus(32, { scrollIntoView: false })\n       */\n      focus: (\n        /**\n         * The position to focus at.\n         */\n        position?: FocusPosition,\n\n        /**\n         * Optional options\n         * @default { scrollIntoView: true }\n         */\n        options?: {\n          scrollIntoView?: boolean,\n        },\n      ) => ReturnType,\n    }\n  }\n}\n\nexport const focus: RawCommands['focus'] = (position = null, options = {}) => ({\n  editor,\n  view,\n  tr,\n  dispatch,\n}) => {\n  options = {\n    scrollIntoView: true,\n    ...options,\n  }\n\n  const delayedFocus = () => {\n    // focus within `requestAnimationFrame` breaks focus on iOS and Android\n    // so we have to call this\n    if (isiOS() || isAndroid()) {\n      (view.dom as HTMLElement).focus()\n    }\n\n    // For React we have to focus asynchronously. Otherwise wild things happen.\n    // see: https://github.com/ueberdosis/tiptap/issues/1520\n    requestAnimationFrame(() => {\n      if (!editor.isDestroyed) {\n        view.focus()\n\n        if (options?.scrollIntoView) {\n          editor.commands.scrollIntoView()\n        }\n      }\n    })\n  }\n\n  if ((view.hasFocus() && position === null) || position === false) {\n    return true\n  }\n\n  // we don’t try to resolve a NodeSelection or CellSelection\n  if (dispatch && position === null && !isTextSelection(editor.state.selection)) {\n    delayedFocus()\n    return true\n  }\n\n  // pass through tr.doc instead of editor.state.doc\n  // since transactions could change the editors state before this command has been run\n  const selection = resolveFocusPosition(tr.doc, position) || editor.state.selection\n  const isSameSelection = editor.state.selection.eq(selection)\n\n  if (dispatch) {\n    if (!isSameSelection) {\n      tr.setSelection(selection)\n    }\n\n    // `tr.setSelection` resets the stored marks\n    // so we’ll restore them if the selection is the same as before\n    if (isSameSelection && tr.storedMarks) {\n      tr.setStoredMarks(tr.storedMarks)\n    }\n\n    delayedFocus()\n  }\n\n  return true\n}\n","const removeWhitespaces = (node: HTMLElement) => {\n  const children = node.childNodes\n\n  for (let i = children.length - 1; i >= 0; i -= 1) {\n    const child = children[i]\n\n    if (child.nodeType === 3 && child.nodeValue && /^(\\n\\s\\s|\\n)$/.test(child.nodeValue)) {\n      node.removeChild(child)\n    } else if (child.nodeType === 1) {\n      removeWhitespaces(child as HTMLElement)\n    }\n  }\n\n  return node\n}\n\nexport function elementFromString(value: string): HTMLElement {\n  // add a wrapper to preserve leading and trailing whitespace\n  const wrappedValue = `<body>${value}</body>`\n\n  const html = new window.DOMParser().parseFromString(wrappedValue, 'text/html').body\n\n  return removeWhitespaces(html)\n}\n","import {\n  DOMParser,\n  Fragment,\n  Node as ProseMirrorNode,\n  ParseOptions,\n  Schema,\n} from '@tiptap/pm/model'\n\nimport { Content } from '../types.js'\nimport { elementFromString } from '../utilities/elementFromString.js'\n\nexport type CreateNodeFromContentOptions = {\n  slice?: boolean\n  parseOptions?: ParseOptions\n  errorOnInvalidContent?: boolean\n}\n\n/**\n * Takes a JSON or HTML content and creates a Prosemirror node or fragment from it.\n * @param content The JSON or HTML content to create the node from\n * @param schema The Prosemirror schema to use for the node\n * @param options Options for the parser\n * @returns The created Prosemirror node or fragment\n */\nexport function createNodeFromContent(\n  content: Content | ProseMirrorNode | Fragment,\n  schema: Schema,\n  options?: CreateNodeFromContentOptions,\n): ProseMirrorNode | Fragment {\n  if (content instanceof ProseMirrorNode || content instanceof Fragment) {\n    return content\n  }\n  options = {\n    slice: true,\n    parseOptions: {},\n    ...options,\n  }\n\n  const isJSONContent = typeof content === 'object' && content !== null\n  const isTextContent = typeof content === 'string'\n\n  if (isJSONContent) {\n    try {\n      const isArrayContent = Array.isArray(content) && content.length > 0\n\n      // if the JSON Content is an array of nodes, create a fragment for each node\n      if (isArrayContent) {\n        return Fragment.fromArray(content.map(item => schema.nodeFromJSON(item)))\n      }\n\n      const node = schema.nodeFromJSON(content)\n\n      if (options.errorOnInvalidContent) {\n        node.check()\n      }\n\n      return node\n    } catch (error) {\n      if (options.errorOnInvalidContent) {\n        throw new Error('[tiptap error]: Invalid JSON content', { cause: error as Error })\n      }\n\n      console.warn('[tiptap warn]: Invalid content.', 'Passed value:', content, 'Error:', error)\n\n      return createNodeFromContent('', schema, options)\n    }\n  }\n\n  if (isTextContent) {\n\n    // Check for invalid content\n    if (options.errorOnInvalidContent) {\n      let hasInvalidContent = false\n      let invalidContent = ''\n\n      // A copy of the current schema with a catch-all node at the end\n      const contentCheckSchema = new Schema({\n        topNode: schema.spec.topNode,\n        marks: schema.spec.marks,\n        // Prosemirror's schemas are executed such that: the last to execute, matches last\n        // This means that we can add a catch-all node at the end of the schema to catch any content that we don't know how to handle\n        nodes: schema.spec.nodes.append({\n          __tiptap__private__unknown__catch__all__node: {\n            content: 'inline*',\n            group: 'block',\n            parseDOM: [\n              {\n                tag: '*',\n                getAttrs: e => {\n                  // If this is ever called, we know that the content has something that we don't know how to handle in the schema\n                  hasInvalidContent = true\n                  // Try to stringify the element for a more helpful error message\n                  invalidContent = typeof e === 'string' ? e : e.outerHTML\n                  return null\n                },\n              },\n            ],\n          },\n        }),\n      })\n\n      if (options.slice) {\n        DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions)\n      } else {\n        DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions)\n      }\n\n      if (options.errorOnInvalidContent && hasInvalidContent) {\n        throw new Error('[tiptap error]: Invalid HTML content', { cause: new Error(`Invalid element found: ${invalidContent}`) })\n      }\n    }\n\n    const parser = DOMParser.fromSchema(schema)\n\n    if (options.slice) {\n      return parser.parseSlice(elementFromString(content), options.parseOptions).content\n    }\n\n    return parser.parse(elementFromString(content), options.parseOptions)\n\n  }\n\n  return createNodeFromContent('', schema, options)\n}\n","import { Selection, Transaction } from '@tiptap/pm/state'\nimport { ReplaceAroundStep, ReplaceStep } from '@tiptap/pm/transform'\n\n// source: https://github.com/ProseMirror/prosemirror-state/blob/master/src/selection.js#L466\nexport function selectionToInsertionEnd(tr: Transaction, startLen: number, bias: number) {\n  const last = tr.steps.length - 1\n\n  if (last < startLen) {\n    return\n  }\n\n  const step = tr.steps[last]\n\n  if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) {\n    return\n  }\n\n  const map = tr.mapping.maps[last]\n  let end = 0\n\n  map.forEach((_from, _to, _newFrom, newTo) => {\n    if (end === 0) {\n      end = newTo\n    }\n  })\n\n  tr.setSelection(Selection.near(tr.doc.resolve(end), bias))\n}\n","export function isMacOS(): boolean {\n  return typeof navigator !== 'undefined'\n    ? /Mac/.test(navigator.platform)\n    : false\n}\n","import { NodeType } from '@tiptap/pm/model'\nimport { EditorState } from '@tiptap/pm/state'\n\nimport { NodeRange } from '../types.js'\nimport { objectIncludes } from '../utilities/objectIncludes.js'\nimport { getNodeType } from './getNodeType.js'\n\nexport function isNodeActive(\n  state: EditorState,\n  typeOrName: NodeType | string | null,\n  attributes: Record<string, any> = {},\n): boolean {\n  const { from, to, empty } = state.selection\n  const type = typeOrName ? getNodeType(typeOrName, state.schema) : null\n\n  const nodeRanges: NodeRange[] = []\n\n  state.doc.nodesBetween(from, to, (node, pos) => {\n    if (node.isText) {\n      return\n    }\n\n    const relativeFrom = Math.max(from, pos)\n    const relativeTo = Math.min(to, pos + node.nodeSize)\n\n    nodeRanges.push({\n      node,\n      from: relativeFrom,\n      to: relativeTo,\n    })\n  })\n\n  const selectionRange = to - from\n  const matchedNodeRanges = nodeRanges\n    .filter(nodeRange => {\n      if (!type) {\n        return true\n      }\n\n      return type.name === nodeRange.node.type.name\n    })\n    .filter(nodeRange => objectIncludes(nodeRange.node.attrs, attributes, { strict: false }))\n\n  if (empty) {\n    return !!matchedNodeRanges.length\n  }\n\n  const range = matchedNodeRanges.reduce((sum, nodeRange) => sum + nodeRange.to - nodeRange.from, 0)\n\n  return range >= selectionRange\n}\n","import { Schema } from '@tiptap/pm/model'\n\n/**\n * Get the type of a schema item by its name.\n * @param name The name of the schema item\n * @param schema The Prosemiror schema to search in\n * @returns The type of the schema item (`node` or `mark`), or null if it doesn't exist\n */\nexport function getSchemaTypeNameByName(name: string, schema: Schema): 'node' | 'mark' | null {\n  if (schema.nodes[name]) {\n    return 'node'\n  }\n\n  if (schema.marks[name]) {\n    return 'mark'\n  }\n\n  return null\n}\n","/**\n * Remove a property or an array of properties from an object\n * @param obj Object\n * @param key Key to remove\n */\nexport function deleteProps(obj: Record<string, any>, propOrProps: string | string[]): Record<string, any> {\n  const props = typeof propOrProps === 'string'\n    ? [propOrProps]\n    : propOrProps\n\n  return Object\n    .keys(obj)\n    .reduce((newObj: Record<string, any>, prop) => {\n      if (!props.includes(prop)) {\n        newObj[prop] = obj[prop]\n      }\n\n      return newObj\n    }, {})\n}\n","import {\n  Fragment, Node as ProseMirrorNode, ParseOptions, Schema,\n} from '@tiptap/pm/model'\n\nimport { Content } from '../types.js'\nimport { createNodeFromContent } from './createNodeFromContent.js'\n\n/**\n * Create a new Prosemirror document node from content.\n * @param content The JSON or HTML content to create the document from\n * @param schema The Prosemirror schema to use for the document\n * @param parseOptions Options for the parser\n * @returns The created Prosemirror document node\n */\nexport function createDocument(\n  content: Content | ProseMirrorNode | Fragment,\n  schema: Schema,\n  parseOptions: ParseOptions = {},\n  options: { errorOnInvalidContent?: boolean } = {},\n): ProseMirrorNode {\n  return createNodeFromContent(content, schema, {\n    slice: false,\n    parseOptions,\n    errorOnInvalidContent: options.errorOnInvalidContent,\n  }) as ProseMirrorNode\n}\n","import { Mark, MarkType } from '@tiptap/pm/model'\nimport { EditorState } from '@tiptap/pm/state'\n\nimport { getMarkType } from './getMarkType.js'\n\nexport function getMarkAttributes(\n  state: EditorState,\n  typeOrName: string | MarkType,\n): Record<string, any> {\n  const type = getMarkType(typeOrName, state.schema)\n  const { from, to, empty } = state.selection\n  const marks: Mark[] = []\n\n  if (empty) {\n    if (state.storedMarks) {\n      marks.push(...state.storedMarks)\n    }\n\n    marks.push(...state.selection.$head.marks())\n  } else {\n    state.doc.nodesBetween(from, to, node => {\n      marks.push(...node.marks)\n    })\n  }\n\n  const mark = marks.find(markItem => markItem.type.name === type.name)\n\n  if (!mark) {\n    return {}\n  }\n\n  return { ...mark.attrs }\n}\n","import { ContentMatch, NodeType } from '@tiptap/pm/model'\n\n/**\n * Gets the default block type at a given match\n * @param match The content match to get the default block type from\n * @returns The default block type or null\n */\nexport function defaultBlockAt(match: ContentMatch): NodeType | null {\n  for (let i = 0; i < match.edgeCount; i += 1) {\n    const { type } = match.edge(i)\n\n    if (type.isTextblock && !type.hasRequiredAttrs()) {\n      return type\n    }\n  }\n\n  return null\n}\n","import { Node as ProseMirrorNode, ResolvedPos } from '@tiptap/pm/model'\n\nimport { Predicate } from '../types.js'\n\n/**\n * Finds the closest parent node to a resolved position that matches a predicate.\n * @param $pos The resolved position to search from\n * @param predicate The predicate to match\n * @returns The closest parent node to the resolved position that matches the predicate\n * @example ```js\n * findParentNodeClosestToPos($from, node => node.type.name === 'paragraph')\n * ```\n */\nexport function findParentNodeClosestToPos(\n  $pos: ResolvedPos,\n  predicate: Predicate,\n):\n  | {\n      pos: number\n      start: number\n      depth: number\n      node: ProseMirrorNode\n    }\n  | undefined {\n  for (let i = $pos.depth; i > 0; i -= 1) {\n    const node = $pos.node(i)\n\n    if (predicate(node)) {\n      return {\n        pos: i > 0 ? $pos.before(i) : 0,\n        start: $pos.start(i),\n        depth: i,\n        node,\n      }\n    }\n  }\n}\n","import { Selection } from '@tiptap/pm/state'\n\nimport { Predicate } from '../types.js'\nimport { findParentNodeClosestToPos } from './findParentNodeClosestToPos.js'\n\n/**\n * Finds the closest parent node to the current selection that matches a predicate.\n * @param predicate The predicate to match\n * @returns A command that finds the closest parent node to the current selection that matches the predicate\n * @example ```js\n * findParentNode(node => node.type.name === 'paragraph')\n * ```\n */\nexport function findParentNode(predicate: Predicate) {\n  return (selection: Selection) => findParentNodeClosestToPos(selection.$from, predicate)\n}\n","import { Schema } from '@tiptap/pm/model'\n\nimport { Editor } from '../Editor.js'\nimport { ExtensionManager } from '../ExtensionManager.js'\nimport { Extensions } from '../types.js'\nimport { getSchemaByResolvedExtensions } from './getSchemaByResolvedExtensions.js'\n\nexport function getSchema(extensions: Extensions, editor?: Editor): Schema {\n  const resolvedExtensions = ExtensionManager.resolve(extensions)\n\n  return getSchemaByResolvedExtensions(resolvedExtensions, editor)\n}\n","import { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nimport { TextSerializer } from '../types.js'\nimport { getTextBetween } from './getTextBetween.js'\n\n/**\n * Gets the text of a Prosemirror node\n * @param node The Prosemirror node\n * @param options Options for the text serializer & block separator\n * @returns The text of the node\n * @example ```js\n * const text = getText(node, { blockSeparator: '\\n' })\n * ```\n */\nexport function getText(\n  node: ProseMirrorNode,\n  options?: {\n    blockSeparator?: string\n    textSerializers?: Record<string, TextSerializer>\n  },\n) {\n  const range = {\n    from: 0,\n    to: node.content.size,\n  }\n\n  return getTextBetween(node, range, options)\n}\n","import { Node, NodeType } from '@tiptap/pm/model'\nimport { EditorState } from '@tiptap/pm/state'\n\nimport { getNodeType } from './getNodeType.js'\n\nexport function getNodeAttributes(\n  state: EditorState,\n  typeOrName: string | NodeType,\n): Record<string, any> {\n  const type = getNodeType(typeOrName, state.schema)\n  const { from, to } = state.selection\n  const nodes: Node[] = []\n\n  state.doc.nodesBetween(from, to, node => {\n    nodes.push(node)\n  })\n\n  const node = nodes.reverse().find(nodeItem => nodeItem.type.name === type.name)\n\n  if (!node) {\n    return {}\n  }\n\n  return { ...node.attrs }\n}\n","import { MarkType, NodeType } from '@tiptap/pm/model'\nimport { EditorState } from '@tiptap/pm/state'\n\nimport { getMarkAttributes } from './getMarkAttributes.js'\nimport { getNodeAttributes } from './getNodeAttributes.js'\nimport { getSchemaTypeNameByName } from './getSchemaTypeNameByName.js'\n\n/**\n * Get node or mark attributes by type or name on the current editor state\n * @param state The current editor state\n * @param typeOrName The node or mark type or name\n * @returns The attributes of the node or mark or an empty object\n */\nexport function getAttributes(\n  state: EditorState,\n  typeOrName: string | NodeType | MarkType,\n): Record<string, any> {\n  const schemaType = getSchemaTypeNameByName(\n    typeof typeOrName === 'string' ? typeOrName : typeOrName.name,\n    state.schema,\n  )\n\n  if (schemaType === 'node') {\n    return getNodeAttributes(state, typeOrName as NodeType)\n  }\n\n  if (schemaType === 'mark') {\n    return getMarkAttributes(state, typeOrName as MarkType)\n  }\n\n  return {}\n}\n","/**\n * Removes duplicated values within an array.\n * Supports numbers, strings and objects.\n */\nexport function removeDuplicates<T>(array: T[], by = JSON.stringify): T[] {\n  const seen: Record<any, any> = {}\n\n  return array.filter(item => {\n    const key = by(item)\n\n    return Object.prototype.hasOwnProperty.call(seen, key)\n      ? false\n      : (seen[key] = true)\n  })\n}\n","import { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nimport { MarkRange } from '../types.js'\nimport { getMarkRange } from './getMarkRange.js'\n\nexport function getMarksBetween(from: number, to: number, doc: ProseMirrorNode): MarkRange[] {\n  const marks: MarkRange[] = []\n\n  // get all inclusive marks on empty selection\n  if (from === to) {\n    doc\n      .resolve(from)\n      .marks()\n      .forEach(mark => {\n        const $pos = doc.resolve(from)\n        const range = getMarkRange($pos, mark.type)\n\n        if (!range) {\n          return\n        }\n\n        marks.push({\n          mark,\n          ...range,\n        })\n      })\n  } else {\n    doc.nodesBetween(from, to, (node, pos) => {\n      if (!node || node?.nodeSize === undefined) {\n        return\n      }\n\n      marks.push(\n        ...node.marks.map(mark => ({\n          from: pos,\n          to: pos + node.nodeSize,\n          mark,\n        })),\n      )\n    })\n  }\n\n  return marks\n}\n","import { ExtensionAttribute } from '../types.js'\n\n/**\n * Return attributes of an extension that should be splitted by keepOnSplit flag\n * @param extensionAttributes Array of extension attributes\n * @param typeName The type of the extension\n * @param attributes The attributes of the extension\n * @returns The splitted attributes\n */\nexport function getSplittedAttributes(\n  extensionAttributes: ExtensionAttribute[],\n  typeName: string,\n  attributes: Record<string, any>,\n): Record<string, any> {\n  return Object.fromEntries(Object\n    .entries(attributes)\n    .filter(([name]) => {\n      const extensionAttribute = extensionAttributes.find(item => {\n        return item.type === typeName && item.name === name\n      })\n\n      if (!extensionAttribute) {\n        return false\n      }\n\n      return extensionAttribute.attribute.keepOnSplit\n    }))\n}\n","import { MarkType } from '@tiptap/pm/model'\nimport { EditorState } from '@tiptap/pm/state'\n\nimport { MarkRange } from '../types.js'\nimport { objectIncludes } from '../utilities/objectIncludes.js'\nimport { getMarkType } from './getMarkType.js'\n\nexport function isMarkActive(\n  state: EditorState,\n  typeOrName: MarkType | string | null,\n  attributes: Record<string, any> = {},\n): boolean {\n  const { empty, ranges } = state.selection\n  const type = typeOrName ? getMarkType(typeOrName, state.schema) : null\n\n  if (empty) {\n    return !!(state.storedMarks || state.selection.$from.marks())\n      .filter(mark => {\n        if (!type) {\n          return true\n        }\n\n        return type.name === mark.type.name\n      })\n      .find(mark => objectIncludes(mark.attrs, attributes, { strict: false }))\n  }\n\n  let selectionRange = 0\n  const markRanges: MarkRange[] = []\n\n  ranges.forEach(({ $from, $to }) => {\n    const from = $from.pos\n    const to = $to.pos\n\n    state.doc.nodesBetween(from, to, (node, pos) => {\n      if (!node.isText && !node.marks.length) {\n        return\n      }\n\n      const relativeFrom = Math.max(from, pos)\n      const relativeTo = Math.min(to, pos + node.nodeSize)\n      const range = relativeTo - relativeFrom\n\n      selectionRange += range\n\n      markRanges.push(\n        ...node.marks.map(mark => ({\n          mark,\n          from: relativeFrom,\n          to: relativeTo,\n        })),\n      )\n    })\n  })\n\n  if (selectionRange === 0) {\n    return false\n  }\n\n  // calculate range of matched mark\n  const matchedRange = markRanges\n    .filter(markRange => {\n      if (!type) {\n        return true\n      }\n\n      return type.name === markRange.mark.type.name\n    })\n    .filter(markRange => objectIncludes(markRange.mark.attrs, attributes, { strict: false }))\n    .reduce((sum, markRange) => sum + markRange.to - markRange.from, 0)\n\n  // calculate range of marks that excludes the searched mark\n  // for example `code` doesn’t allow any other marks\n  const excludedRange = markRanges\n    .filter(markRange => {\n      if (!type) {\n        return true\n      }\n\n      return markRange.mark.type !== type && markRange.mark.type.excludes(type)\n    })\n    .reduce((sum, markRange) => sum + markRange.to - markRange.from, 0)\n\n  // we only include the result of `excludedRange`\n  // if there is a match at all\n  const range = matchedRange > 0 ? matchedRange + excludedRange : matchedRange\n\n  return range >= selectionRange\n}\n","import { EditorState } from '@tiptap/pm/state'\n\nimport { getSchemaTypeNameByName } from './getSchemaTypeNameByName.js'\nimport { isMarkActive } from './isMarkActive.js'\nimport { isNodeActive } from './isNodeActive.js'\n\nexport function isActive(\n  state: EditorState,\n  name: string | null,\n  attributes: Record<string, any> = {},\n): boolean {\n  if (!name) {\n    return isNodeActive(state, null, attributes) || isMarkActive(state, null, attributes)\n  }\n\n  const schemaType = getSchemaTypeNameByName(name, state.schema)\n\n  if (schemaType === 'node') {\n    return isNodeActive(state, name, attributes)\n  }\n\n  if (schemaType === 'mark') {\n    return isMarkActive(state, name, attributes)\n  }\n\n  return false\n}\n","import { getExtensionField } from '../helpers/getExtensionField.js'\nimport { NodeConfig } from '../index.js'\nimport { Extensions } from '../types.js'\nimport { callOrReturn } from '../utilities/callOrReturn.js'\nimport { splitExtensions } from './splitExtensions.js'\n\nexport function isList(name: string, extensions: Extensions): boolean {\n  const { nodeExtensions } = splitExtensions(extensions)\n  const extension = nodeExtensions.find(item => item.name === name)\n\n  if (!extension) {\n    return false\n  }\n\n  const context = {\n    name: extension.name,\n    options: extension.options,\n    storage: extension.storage,\n  }\n  const group = callOrReturn(getExtensionField<NodeConfig['group']>(extension, 'group', context))\n\n  if (typeof group !== 'string') {\n    return false\n  }\n\n  return group.split(' ').includes('list')\n}\n","import { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\n/**\n * Returns true if the given prosemirror node is empty.\n */\nexport function isNodeEmpty(\n  node: ProseMirrorNode,\n  {\n    checkChildren = true,\n    ignoreWhitespace = false,\n  }: {\n    /**\n     * When true (default), it will also check if all children are empty.\n     */\n    checkChildren?: boolean;\n    /**\n     * When true, it will ignore whitespace when checking for emptiness.\n     */\n    ignoreWhitespace?: boolean;\n  } = {},\n): boolean {\n  if (ignoreWhitespace) {\n    if (node.type.name === 'hardBreak') {\n      // Hard breaks are considered empty\n      return true\n    }\n    if (node.isText) {\n      return /^\\s*$/m.test(node.text ?? '')\n    }\n  }\n\n  if (node.isText) {\n    return !node.text\n  }\n\n  if (node.isAtom || node.isLeaf) {\n    return false\n  }\n\n  if (node.content.childCount === 0) {\n    return true\n  }\n\n  if (checkChildren) {\n    let isContentEmpty = true\n\n    node.content.forEach(childNode => {\n      if (isContentEmpty === false) {\n        // Exit early for perf\n        return\n      }\n\n      if (!isNodeEmpty(childNode, { ignoreWhitespace, checkChildren })) {\n        isContentEmpty = false\n      }\n    })\n\n    return isContentEmpty\n  }\n\n  return false\n}\n","import type { Schema } from '@tiptap/pm/model'\n\nimport type { JSONContent } from '../types.js'\n\ntype RewriteUnknownContentOptions = {\n  /**\n   * If true, unknown nodes will be treated as paragraphs\n   * @default true\n   */\n  fallbackToParagraph?: boolean;\n};\n\ntype RewrittenContent = {\n  /**\n   * The original JSON content that was rewritten\n   */\n  original: JSONContent;\n  /**\n   * The name of the node or mark that was unsupported\n   */\n  unsupported: string;\n}[];\n\n/**\n * The actual implementation of the rewriteUnknownContent function\n */\nfunction rewriteUnknownContentInner({\n  json,\n  validMarks,\n  validNodes,\n  options,\n  rewrittenContent = [],\n}: {\n  json: JSONContent;\n  validMarks: Set<string>;\n  validNodes: Set<string>;\n  options?: RewriteUnknownContentOptions;\n  rewrittenContent?: RewrittenContent;\n}): {\n  /**\n   * The cleaned JSON content\n   */\n  json: JSONContent | null;\n  /**\n   * The array of nodes and marks that were rewritten\n   */\n  rewrittenContent: RewrittenContent;\n} {\n  if (json.marks && Array.isArray(json.marks)) {\n    json.marks = json.marks.filter(mark => {\n      const name = typeof mark === 'string' ? mark : mark.type\n\n      if (validMarks.has(name)) {\n        return true\n      }\n\n      rewrittenContent.push({\n        original: JSON.parse(JSON.stringify(mark)),\n        unsupported: name,\n      })\n      // Just ignore any unknown marks\n      return false\n    })\n  }\n\n  if (json.content && Array.isArray(json.content)) {\n    json.content = json.content\n      .map(\n        value => rewriteUnknownContentInner({\n          json: value,\n          validMarks,\n          validNodes,\n          options,\n          rewrittenContent,\n        }).json,\n      )\n      .filter(a => a !== null && a !== undefined)\n  }\n\n  if (json.type && !validNodes.has(json.type)) {\n    rewrittenContent.push({\n      original: JSON.parse(JSON.stringify(json)),\n      unsupported: json.type,\n    })\n\n    if (json.content && Array.isArray(json.content) && (options?.fallbackToParagraph !== false)) {\n      // Just treat it like a paragraph and hope for the best\n      json.type = 'paragraph'\n\n      return {\n        json,\n        rewrittenContent,\n      }\n    }\n\n    // or just omit it entirely\n    return {\n      json: null,\n      rewrittenContent,\n    }\n  }\n\n  return { json, rewrittenContent }\n}\n\n/**\n * Rewrite unknown nodes and marks within JSON content\n * Allowing for user within the editor\n */\nexport function rewriteUnknownContent(\n  /**\n   * The JSON content to clean of unknown nodes and marks\n   */\n  json: JSONContent,\n  /**\n   * The schema to use for validation\n   */\n  schema: Schema,\n  /**\n   * Options for the cleaning process\n   */\n  options?: RewriteUnknownContentOptions,\n): {\n  /**\n   * The cleaned JSON content\n   */\n  json: JSONContent | null;\n  /**\n   * The array of nodes and marks that were rewritten\n   */\n  rewrittenContent: {\n    /**\n     * The original JSON content that was rewritten\n     */\n    original: JSONContent;\n    /**\n     * The name of the node or mark that was unsupported\n     */\n    unsupported: string;\n  }[];\n} {\n  return rewriteUnknownContentInner({\n    json,\n    validNodes: new Set(Object.keys(schema.nodes)),\n    validMarks: new Set(Object.keys(schema.marks)),\n    options,\n  })\n}\n","import { EditorState, NodeSelection, TextSelection } from '@tiptap/pm/state'\nimport { canSplit } from '@tiptap/pm/transform'\n\nimport { defaultBlockAt } from '../helpers/defaultBlockAt.js'\nimport { getSplittedAttributes } from '../helpers/getSplittedAttributes.js'\nimport { RawCommands } from '../types.js'\n\nfunction ensureMarks(state: EditorState, splittableMarks?: string[]) {\n  const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks())\n\n  if (marks) {\n    const filteredMarks = marks.filter(mark => splittableMarks?.includes(mark.type.name))\n\n    state.tr.ensureMarks(filteredMarks)\n  }\n}\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    splitBlock: {\n      /**\n       * Forks a new node from an existing node.\n       * @param options.keepMarks Keep marks from the previous node.\n       * @example editor.commands.splitBlock()\n       * @example editor.commands.splitBlock({ keepMarks: true })\n       */\n      splitBlock: (options?: { keepMarks?: boolean }) => ReturnType\n    }\n  }\n}\n\nexport const splitBlock: RawCommands['splitBlock'] = ({ keepMarks = true } = {}) => ({\n  tr, state, dispatch, editor,\n}) => {\n  const { selection, doc } = tr\n  const { $from, $to } = selection\n  const extensionAttributes = editor.extensionManager.attributes\n  const newAttributes = getSplittedAttributes(\n    extensionAttributes,\n    $from.node().type.name,\n    $from.node().attrs,\n  )\n\n  if (selection instanceof NodeSelection && selection.node.isBlock) {\n    if (!$from.parentOffset || !canSplit(doc, $from.pos)) {\n      return false\n    }\n\n    if (dispatch) {\n      if (keepMarks) {\n        ensureMarks(state, editor.extensionManager.splittableMarks)\n      }\n\n      tr.split($from.pos).scrollIntoView()\n    }\n\n    return true\n  }\n\n  if (!$from.parent.isBlock) {\n    return false\n  }\n\n  const atEnd = $to.parentOffset === $to.parent.content.size\n\n  const deflt = $from.depth === 0\n    ? undefined\n    : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)))\n\n  let types = atEnd && deflt\n    ? [\n      {\n        type: deflt,\n        attrs: newAttributes,\n      },\n    ]\n    : undefined\n\n  let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types)\n\n  if (\n    !types\n      && !can\n      && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : undefined)\n  ) {\n    can = true\n    types = deflt\n      ? [\n        {\n          type: deflt,\n          attrs: newAttributes,\n        },\n      ]\n      : undefined\n  }\n\n  if (dispatch) {\n    if (can) {\n      if (selection instanceof TextSelection) {\n        tr.deleteSelection()\n      }\n\n      tr.split(tr.mapping.map($from.pos), 1, types)\n\n      if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) {\n        const first = tr.mapping.map($from.before())\n        const $first = tr.doc.resolve(first)\n\n        if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) {\n          tr.setNodeMarkup(tr.mapping.map($from.before()), deflt)\n        }\n      }\n    }\n\n    if (keepMarks) {\n      ensureMarks(state, editor.extensionManager.splittableMarks)\n    }\n\n    tr.scrollIntoView()\n  }\n\n  return can\n}\n","import { NodeType } from '@tiptap/pm/model'\nimport { Transaction } from '@tiptap/pm/state'\nimport { canJoin } from '@tiptap/pm/transform'\n\nimport { findParentNode } from '../helpers/findParentNode.js'\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { isList } from '../helpers/isList.js'\nimport { RawCommands } from '../types.js'\n\nconst joinListBackwards = (tr: Transaction, listType: NodeType): boolean => {\n  const list = findParentNode(node => node.type === listType)(tr.selection)\n\n  if (!list) {\n    return true\n  }\n\n  const before = tr.doc.resolve(Math.max(0, list.pos - 1)).before(list.depth)\n\n  if (before === undefined) {\n    return true\n  }\n\n  const nodeBefore = tr.doc.nodeAt(before)\n  const canJoinBackwards = list.node.type === nodeBefore?.type && canJoin(tr.doc, list.pos)\n\n  if (!canJoinBackwards) {\n    return true\n  }\n\n  tr.join(list.pos)\n\n  return true\n}\n\nconst joinListForwards = (tr: Transaction, listType: NodeType): boolean => {\n  const list = findParentNode(node => node.type === listType)(tr.selection)\n\n  if (!list) {\n    return true\n  }\n\n  const after = tr.doc.resolve(list.start).after(list.depth)\n\n  if (after === undefined) {\n    return true\n  }\n\n  const nodeAfter = tr.doc.nodeAt(after)\n  const canJoinForwards = list.node.type === nodeAfter?.type && canJoin(tr.doc, after)\n\n  if (!canJoinForwards) {\n    return true\n  }\n\n  tr.join(after)\n\n  return true\n}\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    toggleList: {\n      /**\n       * Toggle between different list types.\n       * @param listTypeOrName The type or name of the list.\n       * @param itemTypeOrName The type or name of the list item.\n       * @param keepMarks Keep marks when toggling.\n       * @param attributes Attributes for the new list.\n       * @example editor.commands.toggleList('bulletList', 'listItem')\n       */\n      toggleList: (listTypeOrName: string | NodeType, itemTypeOrName: string | NodeType, keepMarks?: boolean, attributes?: Record<string, any>) => ReturnType;\n    }\n  }\n}\n\nexport const toggleList: RawCommands['toggleList'] = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) => ({\n  editor, tr, state, dispatch, chain, commands, can,\n}) => {\n  const { extensions, splittableMarks } = editor.extensionManager\n  const listType = getNodeType(listTypeOrName, state.schema)\n  const itemType = getNodeType(itemTypeOrName, state.schema)\n  const { selection, storedMarks } = state\n  const { $from, $to } = selection\n  const range = $from.blockRange($to)\n\n  const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks())\n\n  if (!range) {\n    return false\n  }\n\n  const parentList = findParentNode(node => isList(node.type.name, extensions))(selection)\n\n  if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {\n    // remove list\n    if (parentList.node.type === listType) {\n      return commands.liftListItem(itemType)\n    }\n\n    // change list type\n    if (\n      isList(parentList.node.type.name, extensions)\n        && listType.validContent(parentList.node.content)\n        && dispatch\n    ) {\n      return chain()\n        .command(() => {\n          tr.setNodeMarkup(parentList.pos, listType)\n\n          return true\n        })\n        .command(() => joinListBackwards(tr, listType))\n        .command(() => joinListForwards(tr, listType))\n        .run()\n    }\n  }\n  if (!keepMarks || !marks || !dispatch) {\n\n    return chain()\n      // try to convert node to default node if needed\n      .command(() => {\n        const canWrapInList = can().wrapInList(listType, attributes)\n\n        if (canWrapInList) {\n          return true\n        }\n\n        return commands.clearNodes()\n      })\n      .wrapInList(listType, attributes)\n      .command(() => joinListBackwards(tr, listType))\n      .command(() => joinListForwards(tr, listType))\n      .run()\n  }\n\n  return (\n    chain()\n    // try to convert node to default node if needed\n      .command(() => {\n        const canWrapInList = can().wrapInList(listType, attributes)\n\n        const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name))\n\n        tr.ensureMarks(filteredMarks)\n\n        if (canWrapInList) {\n          return true\n        }\n\n        return commands.clearNodes()\n      })\n      .wrapInList(listType, attributes)\n      .command(() => joinListBackwards(tr, listType))\n      .command(() => joinListForwards(tr, listType))\n      .run()\n  )\n}\n","import { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    blur: {\n      /**\n       * Removes focus from the editor.\n       * @example editor.commands.blur()\n       */\n      blur: () => ReturnType,\n    }\n  }\n}\n\nexport const blur: RawCommands['blur'] = () => ({ editor, view }) => {\n  requestAnimationFrame(() => {\n    if (!editor.isDestroyed) {\n      (view.dom as HTMLElement).blur()\n\n      // Browsers should remove the caret on blur but safari does not.\n      // See: https://github.com/ueberdosis/tiptap/issues/2405\n      window?.getSelection()?.removeAllRanges()\n    }\n  })\n\n  return true\n}\n","import { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    clearContent: {\n      /**\n       * Clear the whole document.\n       * @param emitUpdate Whether to emit an update event.\n       * @example editor.commands.clearContent()\n       */\n      clearContent: (emitUpdate?: boolean) => ReturnType,\n    }\n  }\n}\n\nexport const clearContent: RawCommands['clearContent'] = (emitUpdate = false) => ({ commands }) => {\n  return commands.setContent('', emitUpdate)\n}\n","import { liftTarget } from '@tiptap/pm/transform'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    clearNodes: {\n      /**\n       * Normalize nodes to a simple paragraph.\n       * @example editor.commands.clearNodes()\n       */\n      clearNodes: () => ReturnType,\n    }\n  }\n}\n\nexport const clearNodes: RawCommands['clearNodes'] = () => ({ state, tr, dispatch }) => {\n  const { selection } = tr\n  const { ranges } = selection\n\n  if (!dispatch) {\n    return true\n  }\n\n  ranges.forEach(({ $from, $to }) => {\n    state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {\n      if (node.type.isText) {\n        return\n      }\n\n      const { doc, mapping } = tr\n      const $mappedFrom = doc.resolve(mapping.map(pos))\n      const $mappedTo = doc.resolve(mapping.map(pos + node.nodeSize))\n      const nodeRange = $mappedFrom.blockRange($mappedTo)\n\n      if (!nodeRange) {\n        return\n      }\n\n      const targetLiftDepth = liftTarget(nodeRange)\n\n      if (node.type.isTextblock) {\n        const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index())\n\n        tr.setNodeMarkup(nodeRange.start, defaultType)\n      }\n\n      if (targetLiftDepth || targetLiftDepth === 0) {\n        tr.lift(nodeRange, targetLiftDepth)\n      }\n    })\n  })\n\n  return true\n}\n","import { Command, RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    command: {\n      /**\n       * Define a command inline.\n       * @param fn The command function.\n       * @example\n       * editor.commands.command(({ tr, state }) => {\n       *   ...\n       *   return true\n       * })\n       */\n      command: (fn: (props: Parameters<Command>[0]) => boolean) => ReturnType,\n    }\n  }\n}\n\nexport const command: RawCommands['command'] = fn => props => {\n  return fn(props)\n}\n","import { createParagraphNear as originalCreateParagraphNear } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    createParagraphNear: {\n      /**\n       * Create a paragraph nearby.\n       * @example editor.commands.createParagraphNear()\n       */\n      createParagraphNear: () => ReturnType\n    }\n  }\n}\n\nexport const createParagraphNear: RawCommands['createParagraphNear'] = () => ({ state, dispatch }) => {\n  return originalCreateParagraphNear(state, dispatch)\n}\n","import { TextSelection } from '@tiptap/pm/state'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    cut: {\n      /**\n       * Cuts content from a range and inserts it at a given position.\n       * @param range The range to cut.\n       * @param range.from The start position of the range.\n       * @param range.to The end position of the range.\n       * @param targetPos The position to insert the content at.\n       * @example editor.commands.cut({ from: 1, to: 3 }, 5)\n       */\n      cut: ({ from, to }: { from: number, to: number }, targetPos: number) => ReturnType,\n    }\n  }\n}\n\nexport const cut: RawCommands['cut'] = (originRange, targetPos) => ({ editor, tr }) => {\n  const { state } = editor\n\n  const contentSlice = state.doc.slice(originRange.from, originRange.to)\n\n  tr.deleteRange(originRange.from, originRange.to)\n  const newPos = tr.mapping.map(targetPos)\n\n  tr.insert(newPos, contentSlice.content)\n\n  tr.setSelection(new TextSelection(tr.doc.resolve(newPos - 1)))\n\n  return true\n}\n","import { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    deleteCurrentNode: {\n      /**\n       * Delete the node that currently has the selection anchor.\n       * @example editor.commands.deleteCurrentNode()\n       */\n      deleteCurrentNode: () => ReturnType,\n    }\n  }\n}\n\nexport const deleteCurrentNode: RawCommands['deleteCurrentNode'] = () => ({ tr, dispatch }) => {\n  const { selection } = tr\n  const currentNode = selection.$anchor.node()\n\n  // if there is content inside the current node, break out of this command\n  if (currentNode.content.size > 0) {\n    return false\n  }\n\n  const $pos = tr.selection.$anchor\n\n  for (let depth = $pos.depth; depth > 0; depth -= 1) {\n    const node = $pos.node(depth)\n\n    if (node.type === currentNode.type) {\n      if (dispatch) {\n        const from = $pos.before(depth)\n        const to = $pos.after(depth)\n\n        tr.delete(from, to).scrollIntoView()\n      }\n\n      return true\n    }\n  }\n\n  return false\n}\n","import { NodeType } from '@tiptap/pm/model'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    deleteNode: {\n      /**\n       * Delete a node with a given type or name.\n       * @param typeOrName The type or name of the node.\n       * @example editor.commands.deleteNode('paragraph')\n       */\n      deleteNode: (typeOrName: string | NodeType) => ReturnType,\n    }\n  }\n}\n\nexport const deleteNode: RawCommands['deleteNode'] = typeOrName => ({ tr, state, dispatch }) => {\n  const type = getNodeType(typeOrName, state.schema)\n  const $pos = tr.selection.$anchor\n\n  for (let depth = $pos.depth; depth > 0; depth -= 1) {\n    const node = $pos.node(depth)\n\n    if (node.type === type) {\n      if (dispatch) {\n        const from = $pos.before(depth)\n        const to = $pos.after(depth)\n\n        tr.delete(from, to).scrollIntoView()\n      }\n\n      return true\n    }\n  }\n\n  return false\n}\n","import { Range, RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    deleteRange: {\n      /**\n       * Delete a given range.\n       * @param range The range to delete.\n       * @example editor.commands.deleteRange({ from: 1, to: 3 })\n       */\n      deleteRange: (range: Range) => ReturnType,\n    }\n  }\n}\n\nexport const deleteRange: RawCommands['deleteRange'] = range => ({ tr, dispatch }) => {\n  const { from, to } = range\n\n  if (dispatch) {\n    tr.delete(from, to)\n  }\n\n  return true\n}\n","import { deleteSelection as originalDeleteSelection } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    deleteSelection: {\n      /**\n       * Delete the selection, if there is one.\n       * @example editor.commands.deleteSelection()\n       */\n      deleteSelection: () => ReturnType\n    }\n  }\n}\n\nexport const deleteSelection: RawCommands['deleteSelection'] = () => ({ state, dispatch }) => {\n  return originalDeleteSelection(state, dispatch)\n}\n","import { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    enter: {\n      /**\n       * Trigger enter.\n       * @example editor.commands.enter()\n       */\n      enter: () => ReturnType,\n    }\n  }\n}\n\nexport const enter: RawCommands['enter'] = () => ({ commands }) => {\n  return commands.keyboardShortcut('Enter')\n}\n","import { exitCode as originalExitCode } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    exitCode: {\n      /**\n       * Exit from a code block.\n       * @example editor.commands.exitCode()\n       */\n      exitCode: () => ReturnType\n    }\n  }\n}\n\nexport const exitCode: RawCommands['exitCode'] = () => ({ state, dispatch }) => {\n  return originalExitCode(state, dispatch)\n}\n","import { MarkType } from '@tiptap/pm/model'\nimport { TextSelection } from '@tiptap/pm/state'\n\nimport { getMarkRange } from '../helpers/getMarkRange.js'\nimport { getMarkType } from '../helpers/getMarkType.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    extendMarkRange: {\n      /**\n       * Extends the text selection to the current mark by type or name.\n       * @param typeOrName The type or name of the mark.\n       * @param attributes The attributes of the mark.\n       * @example editor.commands.extendMarkRange('bold')\n       * @example editor.commands.extendMarkRange('mention', { userId: \"1\" })\n       */\n      extendMarkRange: (\n        /**\n         * The type or name of the mark.\n         */\n        typeOrName: string | MarkType,\n\n        /**\n         * The attributes of the mark.\n         */\n        attributes?: Record<string, any>,\n      ) => ReturnType\n    }\n  }\n}\n\nexport const extendMarkRange: RawCommands['extendMarkRange'] = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {\n  const type = getMarkType(typeOrName, state.schema)\n  const { doc, selection } = tr\n  const { $from, from, to } = selection\n\n  if (dispatch) {\n    const range = getMarkRange($from, type, attributes)\n\n    if (range && range.from <= from && range.to >= to) {\n      const newSelection = TextSelection.create(doc, range.from, range.to)\n\n      tr.setSelection(newSelection)\n    }\n  }\n\n  return true\n}\n","import { Command, CommandProps, RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    first: {\n      /**\n       * Runs one command after the other and stops at the first which returns true.\n       * @param commands The commands to run.\n       * @example editor.commands.first([command1, command2])\n       */\n      first: (commands: Command[] | ((props: CommandProps) => Command[])) => ReturnType,\n    }\n  }\n}\n\nexport const first: RawCommands['first'] = commands => props => {\n  const items = typeof commands === 'function'\n    ? commands(props)\n    : commands\n\n  for (let i = 0; i < items.length; i += 1) {\n    if (items[i](props)) {\n      return true\n    }\n  }\n\n  return false\n}\n","import { CommandProps, RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    forEach: {\n      /**\n       * Loop through an array of items.\n       */\n      forEach: <T>(\n        items: T[],\n        fn: (\n          item: T,\n          props: CommandProps & {\n            index: number,\n          },\n        ) => boolean,\n      ) => ReturnType,\n    }\n  }\n}\n\nexport const forEach: RawCommands['forEach'] = (items, fn) => props => {\n  return items.every((item, index) => fn(item, { ...props, index }))\n}\n","import { Fragment, Node as ProseMirrorNode, ParseOptions } from '@tiptap/pm/model'\n\nimport { Content, RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    insertContent: {\n      /**\n       * Insert a node or string of HTML at the current position.\n       * @example editor.commands.insertContent('<h1>Example</h1>')\n       * @example editor.commands.insertContent('<h1>Example</h1>', { updateSelection: false })\n       */\n      insertContent: (\n        /**\n         * The ProseMirror content to insert.\n         */\n        value: Content | ProseMirrorNode | Fragment,\n\n        /**\n         * Optional options\n         */\n        options?: {\n          /**\n           * Options for parsing the content.\n           */\n          parseOptions?: ParseOptions;\n\n          /**\n           * Whether to update the selection after inserting the content.\n           */\n          updateSelection?: boolean;\n          applyInputRules?: boolean;\n          applyPasteRules?: boolean;\n        }\n      ) => ReturnType;\n    };\n  }\n}\n\nexport const insertContent: RawCommands['insertContent'] = (value, options) => ({ tr, commands }) => {\n  return commands.insertContentAt(\n    { from: tr.selection.from, to: tr.selection.to },\n    value,\n    options,\n  )\n}\n","import { Fragment, Node as ProseMirrorNode, ParseOptions } from '@tiptap/pm/model'\n\nimport { createNodeFromContent } from '../helpers/createNodeFromContent.js'\nimport { selectionToInsertionEnd } from '../helpers/selectionToInsertionEnd.js'\nimport { Content, Range, RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    insertContentAt: {\n      /**\n       * Insert a node or string of HTML at a specific position.\n       * @example editor.commands.insertContentAt(0, '<h1>Example</h1>')\n       */\n      insertContentAt: (\n        /**\n         * The position to insert the content at.\n         */\n        position: number | Range,\n\n        /**\n         * The ProseMirror content to insert.\n         */\n        value: Content | ProseMirrorNode | Fragment,\n\n        /**\n         * Optional options\n         */\n        options?: {\n          /**\n           * Options for parsing the content.\n           */\n          parseOptions?: ParseOptions\n\n          /**\n           * Whether to update the selection after inserting the content.\n           */\n          updateSelection?: boolean\n\n          /**\n           * Whether to apply input rules after inserting the content.\n           */\n          applyInputRules?: boolean\n\n          /**\n           * Whether to apply paste rules after inserting the content.\n           */\n          applyPasteRules?: boolean\n\n          /**\n           * Whether to throw an error if the content is invalid.\n           */\n          errorOnInvalidContent?: boolean\n        },\n      ) => ReturnType\n    }\n  }\n}\n\nconst isFragment = (nodeOrFragment: ProseMirrorNode | Fragment): nodeOrFragment is Fragment => {\n  return !('type' in nodeOrFragment)\n}\n\nexport const insertContentAt: RawCommands['insertContentAt'] = (position, value, options) => ({ tr, dispatch, editor }) => {\n  if (dispatch) {\n    options = {\n      parseOptions: editor.options.parseOptions,\n      updateSelection: true,\n      applyInputRules: false,\n      applyPasteRules: false,\n      ...options,\n    }\n\n    let content: Fragment | ProseMirrorNode\n\n    try {\n      content = createNodeFromContent(value, editor.schema, {\n        parseOptions: {\n          preserveWhitespace: 'full',\n          ...options.parseOptions,\n        },\n        errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,\n      })\n    } catch (e) {\n      editor.emit('contentError', {\n        editor,\n        error: e as Error,\n        disableCollaboration: () => {\n          if (editor.storage.collaboration) {\n            editor.storage.collaboration.isDisabled = true\n          }\n        },\n      })\n      return false\n    }\n\n    let { from, to } = typeof position === 'number' ? { from: position, to: position } : { from: position.from, to: position.to }\n\n    let isOnlyTextContent = true\n    let isOnlyBlockContent = true\n    const nodes = isFragment(content) ? content : [content]\n\n    nodes.forEach(node => {\n      // check if added node is valid\n      node.check()\n\n      isOnlyTextContent = isOnlyTextContent ? node.isText && node.marks.length === 0 : false\n\n      isOnlyBlockContent = isOnlyBlockContent ? node.isBlock : false\n    })\n\n    // check if we can replace the wrapping node by\n    // the newly inserted content\n    // example:\n    // replace an empty paragraph by an inserted image\n    // instead of inserting the image below the paragraph\n    if (from === to && isOnlyBlockContent) {\n      const { parent } = tr.doc.resolve(from)\n      const isEmptyTextBlock = parent.isTextblock && !parent.type.spec.code && !parent.childCount\n\n      if (isEmptyTextBlock) {\n        from -= 1\n        to += 1\n      }\n    }\n\n    let newContent\n\n    // if there is only plain text we have to use `insertText`\n    // because this will keep the current marks\n    if (isOnlyTextContent) {\n      // if value is string, we can use it directly\n      // otherwise if it is an array, we have to join it\n      if (Array.isArray(value)) {\n        newContent = value.map(v => v.text || '').join('')\n      } else if (value instanceof Fragment) {\n        let text = ''\n\n        value.forEach(node => {\n          if (node.text) {\n            text += node.text\n          }\n        })\n\n        newContent = text\n      } else if (typeof value === 'object' && !!value && !!value.text) {\n        newContent = value.text\n      } else {\n        newContent = value as string\n      }\n\n      tr.insertText(newContent, from, to)\n    } else {\n      newContent = content\n\n      tr.replaceWith(from, to, newContent)\n    }\n\n    // set cursor at end of inserted content\n    if (options.updateSelection) {\n      selectionToInsertionEnd(tr, tr.steps.length - 1, -1)\n    }\n\n    if (options.applyInputRules) {\n      tr.setMeta('applyInputRules', { from, text: newContent })\n    }\n\n    if (options.applyPasteRules) {\n      tr.setMeta('applyPasteRules', { from, text: newContent })\n    }\n  }\n\n  return true\n}\n","import {\n  joinBackward as originalJoinBackward,\n  joinDown as originalJoinDown,\n  joinForward as originalJoinForward,\n  joinUp as originalJoinUp,\n} from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    joinUp: {\n      /**\n       * Join the selected block or, if there is a text selection, the closest ancestor block of the selection that can be joined, with the sibling above it.\n       * @example editor.commands.joinUp()\n       */\n      joinUp: () => ReturnType\n    }\n    joinDown: {\n      /**\n       * Join the selected block, or the closest ancestor of the selection that can be joined, with the sibling after it.\n       * @example editor.commands.joinDown()\n       */\n      joinDown: () => ReturnType\n    }\n    joinBackward: {\n      /**\n       * If the selection is empty and at the start of a textblock, try to reduce the distance between that block and the one before it—if there's a block directly before it that can be joined, join them.\n       * If not, try to move the selected block closer to the next one in the document structure by lifting it out of its\n       * parent or moving it into a parent of the previous block. Will use the view for accurate (bidi-aware) start-of-textblock detection if given.\n       * @example editor.commands.joinBackward()\n       */\n      joinBackward: () => ReturnType\n    }\n    joinForward: {\n      /**\n       * If the selection is empty and the cursor is at the end of a textblock, try to reduce or remove the boundary between that block and the one after it,\n       * either by joining them or by moving the other block closer to this one in the tree structure.\n       * Will use the view for accurate start-of-textblock detection if given.\n       * @example editor.commands.joinForward()\n       */\n      joinForward: () => ReturnType\n    }\n  }\n}\n\nexport const joinUp: RawCommands['joinUp'] = () => ({ state, dispatch }) => {\n  return originalJoinUp(state, dispatch)\n}\n\nexport const joinDown: RawCommands['joinDown'] = () => ({ state, dispatch }) => {\n  return originalJoinDown(state, dispatch)\n}\n\nexport const joinBackward: RawCommands['joinBackward'] = () => ({ state, dispatch }) => {\n  return originalJoinBackward(state, dispatch)\n}\n\nexport const joinForward: RawCommands['joinForward'] = () => ({ state, dispatch }) => {\n  return originalJoinForward(state, dispatch)\n}\n","import { joinPoint } from '@tiptap/pm/transform'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    joinItemBackward: {\n      /**\n       * Join two items backward.\n       * @example editor.commands.joinItemBackward()\n       */\n      joinItemBackward: () => ReturnType\n    }\n  }\n}\n\nexport const joinItemBackward: RawCommands['joinItemBackward'] = () => ({\n  state,\n  dispatch,\n  tr,\n}) => {\n  try {\n    const point = joinPoint(state.doc, state.selection.$from.pos, -1)\n\n    if (point === null || point === undefined) {\n      return false\n    }\n\n    tr.join(point, 2)\n\n    if (dispatch) {\n      dispatch(tr)\n    }\n\n    return true\n  } catch {\n    return false\n  }\n}\n","import { joinPoint } from '@tiptap/pm/transform'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    joinItemForward: {\n      /**\n       * Join two items Forwards.\n       * @example editor.commands.joinItemForward()\n       */\n      joinItemForward: () => ReturnType\n    }\n  }\n}\n\nexport const joinItemForward: RawCommands['joinItemForward'] = () => ({\n  state,\n  dispatch,\n  tr,\n}) => {\n  try {\n    const point = joinPoint(state.doc, state.selection.$from.pos, +1)\n\n    if (point === null || point === undefined) {\n      return false\n    }\n\n    tr.join(point, 2)\n\n    if (dispatch) {\n      dispatch(tr)\n    }\n\n    return true\n  } catch {\n    return false\n  }\n}\n","import { joinTextblockBackward as originalCommand } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    joinTextblockBackward: {\n      /**\n       * A more limited form of joinBackward that only tries to join the current textblock to the one before it, if the cursor is at the start of a textblock.\n       */\n      joinTextblockBackward: () => ReturnType\n    }\n  }\n}\n\nexport const joinTextblockBackward: RawCommands['joinTextblockBackward'] = () => ({ state, dispatch }) => {\n  return originalCommand(state, dispatch)\n}\n","import { joinTextblockForward as originalCommand } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    joinTextblockForward: {\n      /**\n       * A more limited form of joinForward that only tries to join the current textblock to the one after it, if the cursor is at the end of a textblock.\n       */\n      joinTextblockForward: () => ReturnType\n    }\n  }\n}\n\nexport const joinTextblockForward: RawCommands['joinTextblockForward'] = () => ({ state, dispatch }) => {\n  return originalCommand(state, dispatch)\n}\n","import { RawCommands } from '../types.js'\nimport { isiOS } from '../utilities/isiOS.js'\nimport { isMacOS } from '../utilities/isMacOS.js'\n\nfunction normalizeKeyName(name: string) {\n  const parts = name.split(/-(?!$)/)\n  let result = parts[parts.length - 1]\n\n  if (result === 'Space') {\n    result = ' '\n  }\n\n  let alt\n  let ctrl\n  let shift\n  let meta\n\n  for (let i = 0; i < parts.length - 1; i += 1) {\n    const mod = parts[i]\n\n    if (/^(cmd|meta|m)$/i.test(mod)) {\n      meta = true\n    } else if (/^a(lt)?$/i.test(mod)) {\n      alt = true\n    } else if (/^(c|ctrl|control)$/i.test(mod)) {\n      ctrl = true\n    } else if (/^s(hift)?$/i.test(mod)) {\n      shift = true\n    } else if (/^mod$/i.test(mod)) {\n      if (isiOS() || isMacOS()) {\n        meta = true\n      } else {\n        ctrl = true\n      }\n    } else {\n      throw new Error(`Unrecognized modifier name: ${mod}`)\n    }\n  }\n\n  if (alt) {\n    result = `Alt-${result}`\n  }\n\n  if (ctrl) {\n    result = `Ctrl-${result}`\n  }\n\n  if (meta) {\n    result = `Meta-${result}`\n  }\n\n  if (shift) {\n    result = `Shift-${result}`\n  }\n\n  return result\n}\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    keyboardShortcut: {\n      /**\n       * Trigger a keyboard shortcut.\n       * @param name The name of the keyboard shortcut.\n       * @example editor.commands.keyboardShortcut('Mod-b')\n       */\n      keyboardShortcut: (name: string) => ReturnType,\n    }\n  }\n}\n\nexport const keyboardShortcut: RawCommands['keyboardShortcut'] = name => ({\n  editor,\n  view,\n  tr,\n  dispatch,\n}) => {\n  const keys = normalizeKeyName(name).split(/-(?!$)/)\n  const key = keys.find(item => !['Alt', 'Ctrl', 'Meta', 'Shift'].includes(item))\n  const event = new KeyboardEvent('keydown', {\n    key: key === 'Space'\n      ? ' '\n      : key,\n    altKey: keys.includes('Alt'),\n    ctrlKey: keys.includes('Ctrl'),\n    metaKey: keys.includes('Meta'),\n    shiftKey: keys.includes('Shift'),\n    bubbles: true,\n    cancelable: true,\n  })\n\n  const capturedTransaction = editor.captureTransaction(() => {\n    view.someProp('handleKeyDown', f => f(view, event))\n  })\n\n  capturedTransaction?.steps.forEach(step => {\n    const newStep = step.map(tr.mapping)\n\n    if (newStep && dispatch) {\n      tr.maybeStep(newStep)\n    }\n  })\n\n  return true\n}\n","import { lift as originalLift } from '@tiptap/pm/commands'\nimport { NodeType } from '@tiptap/pm/model'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { isNodeActive } from '../helpers/isNodeActive.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    lift: {\n      /**\n       * Removes an existing wrap if possible lifting the node out of it\n       * @param typeOrName The type or name of the node.\n       * @param attributes The attributes of the node.\n       * @example editor.commands.lift('paragraph')\n       * @example editor.commands.lift('heading', { level: 1 })\n       */\n      lift: (typeOrName: string | NodeType, attributes?: Record<string, any>) => ReturnType\n    }\n  }\n}\n\nexport const lift: RawCommands['lift'] = (typeOrName, attributes = {}) => ({ state, dispatch }) => {\n  const type = getNodeType(typeOrName, state.schema)\n  const isActive = isNodeActive(state, type, attributes)\n\n  if (!isActive) {\n    return false\n  }\n\n  return originalLift(state, dispatch)\n}\n","import { liftEmptyBlock as originalLiftEmptyBlock } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    liftEmptyBlock: {\n      /**\n       * If the cursor is in an empty textblock that can be lifted, lift the block.\n       * @example editor.commands.liftEmptyBlock()\n       */\n      liftEmptyBlock: () => ReturnType,\n    }\n  }\n}\n\nexport const liftEmptyBlock: RawCommands['liftEmptyBlock'] = () => ({ state, dispatch }) => {\n  return originalLiftEmptyBlock(state, dispatch)\n}\n","import { NodeType } from '@tiptap/pm/model'\nimport { liftListItem as originalLiftListItem } from '@tiptap/pm/schema-list'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    liftListItem: {\n      /**\n       * Create a command to lift the list item around the selection up into a wrapping list.\n       * @param typeOrName The type or name of the node.\n       * @example editor.commands.liftListItem('listItem')\n       */\n      liftListItem: (typeOrName: string | NodeType) => ReturnType\n    }\n  }\n}\n\nexport const liftListItem: RawCommands['liftListItem'] = typeOrName => ({ state, dispatch }) => {\n  const type = getNodeType(typeOrName, state.schema)\n\n  return originalLiftListItem(type)(state, dispatch)\n}\n","import { newlineInCode as originalNewlineInCode } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    newlineInCode: {\n      /**\n       * Add a newline character in code.\n       * @example editor.commands.newlineInCode()\n       */\n      newlineInCode: () => ReturnType\n    }\n  }\n}\n\nexport const newlineInCode: RawCommands['newlineInCode'] = () => ({ state, dispatch }) => {\n  return originalNewlineInCode(state, dispatch)\n}\n","import { MarkType, NodeType } from '@tiptap/pm/model'\n\nimport { getMarkType } from '../helpers/getMarkType.js'\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { getSchemaTypeNameByName } from '../helpers/getSchemaTypeNameByName.js'\nimport { RawCommands } from '../types.js'\nimport { deleteProps } from '../utilities/deleteProps.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    resetAttributes: {\n      /**\n       * Resets some node attributes to the default value.\n       * @param typeOrName The type or name of the node.\n       * @param attributes The attributes of the node to reset.\n       * @example editor.commands.resetAttributes('heading', 'level')\n       */\n      resetAttributes: (\n        typeOrName: string | NodeType | MarkType,\n        attributes: string | string[],\n      ) => ReturnType\n    }\n  }\n}\n\nexport const resetAttributes: RawCommands['resetAttributes'] = (typeOrName, attributes) => ({ tr, state, dispatch }) => {\n  let nodeType: NodeType | null = null\n  let markType: MarkType | null = null\n\n  const schemaType = getSchemaTypeNameByName(\n    typeof typeOrName === 'string' ? typeOrName : typeOrName.name,\n    state.schema,\n  )\n\n  if (!schemaType) {\n    return false\n  }\n\n  if (schemaType === 'node') {\n    nodeType = getNodeType(typeOrName as NodeType, state.schema)\n  }\n\n  if (schemaType === 'mark') {\n    markType = getMarkType(typeOrName as MarkType, state.schema)\n  }\n\n  if (dispatch) {\n    tr.selection.ranges.forEach(range => {\n      state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => {\n        if (nodeType && nodeType === node.type) {\n          tr.setNodeMarkup(pos, undefined, deleteProps(node.attrs, attributes))\n        }\n\n        if (markType && node.marks.length) {\n          node.marks.forEach(mark => {\n            if (markType === mark.type) {\n              tr.addMark(\n                pos,\n                pos + node.nodeSize,\n                markType.create(deleteProps(mark.attrs, attributes)),\n              )\n            }\n          })\n        }\n      })\n    })\n  }\n\n  return true\n}\n","import { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    scrollIntoView: {\n      /**\n       * Scroll the selection into view.\n       * @example editor.commands.scrollIntoView()\n       */\n      scrollIntoView: () => ReturnType,\n    }\n  }\n}\n\nexport const scrollIntoView: RawCommands['scrollIntoView'] = () => ({ tr, dispatch }) => {\n  if (dispatch) {\n    tr.scrollIntoView()\n  }\n\n  return true\n}\n","import { AllSelection } from '@tiptap/pm/state'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    selectAll: {\n      /**\n       * Select the whole document.\n       * @example editor.commands.selectAll()\n       */\n      selectAll: () => ReturnType,\n    }\n  }\n}\n\nexport const selectAll: RawCommands['selectAll'] = () => ({ tr, dispatch }) => {\n  if (dispatch) {\n    const selection = new AllSelection(tr.doc)\n\n    tr.setSelection(selection)\n  }\n\n  return true\n}\n","import { selectNodeBackward as originalSelectNodeBackward } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    selectNodeBackward: {\n      /**\n       * Select a node backward.\n       * @example editor.commands.selectNodeBackward()\n       */\n      selectNodeBackward: () => ReturnType\n    }\n  }\n}\n\nexport const selectNodeBackward: RawCommands['selectNodeBackward'] = () => ({ state, dispatch }) => {\n  return originalSelectNodeBackward(state, dispatch)\n}\n","import { selectNodeForward as originalSelectNodeForward } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    selectNodeForward: {\n      /**\n       * Select a node forward.\n       * @example editor.commands.selectNodeForward()\n       */\n      selectNodeForward: () => ReturnType\n    }\n  }\n}\n\nexport const selectNodeForward: RawCommands['selectNodeForward'] = () => ({ state, dispatch }) => {\n  return originalSelectNodeForward(state, dispatch)\n}\n","import { selectParentNode as originalSelectParentNode } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    selectParentNode: {\n      /**\n       * Select the parent node.\n       * @example editor.commands.selectParentNode()\n       */\n      selectParentNode: () => ReturnType\n    }\n  }\n}\n\nexport const selectParentNode: RawCommands['selectParentNode'] = () => ({ state, dispatch }) => {\n  return originalSelectParentNode(state, dispatch)\n}\n","// @ts-ignore\n// TODO: add types to @types/prosemirror-commands\nimport { selectTextblockEnd as originalSelectTextblockEnd } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    selectTextblockEnd: {\n      /**\n       * Moves the cursor to the end of current text block.\n       * @example editor.commands.selectTextblockEnd()\n       */\n      selectTextblockEnd: () => ReturnType\n    }\n  }\n}\n\nexport const selectTextblockEnd: RawCommands['selectTextblockEnd'] = () => ({ state, dispatch }) => {\n  return originalSelectTextblockEnd(state, dispatch)\n}\n","// @ts-ignore\n// TODO: add types to @types/prosemirror-commands\nimport { selectTextblockStart as originalSelectTextblockStart } from '@tiptap/pm/commands'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    selectTextblockStart: {\n      /**\n       * Moves the cursor to the start of current text block.\n       * @example editor.commands.selectTextblockStart()\n       */\n      selectTextblockStart: () => ReturnType\n    }\n  }\n}\n\nexport const selectTextblockStart: RawCommands['selectTextblockStart'] = () => ({ state, dispatch }) => {\n  return originalSelectTextblockStart(state, dispatch)\n}\n","import { Fragment, Node as ProseMirrorNode, ParseOptions } from '@tiptap/pm/model'\n\nimport { createDocument } from '../helpers/createDocument.js'\nimport { Content, RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    setContent: {\n      /**\n       * Replace the whole document with new content.\n       * @param content The new content.\n       * @param emitUpdate Whether to emit an update event.\n       * @param parseOptions Options for parsing the content.\n       * @example editor.commands.setContent('<p>Example text</p>')\n       */\n      setContent: (\n        /**\n         * The new content.\n         */\n        content: Content | Fragment | ProseMirrorNode,\n\n        /**\n         * Whether to emit an update event.\n         * @default false\n         */\n        emitUpdate?: boolean,\n\n        /**\n         * Options for parsing the content.\n         * @default {}\n         */\n        parseOptions?: ParseOptions,\n        /**\n         * Options for `setContent`.\n         */\n        options?: {\n          /**\n           * Whether to throw an error if the content is invalid.\n           */\n          errorOnInvalidContent?: boolean;\n        }\n      ) => ReturnType;\n    };\n  }\n}\n\nexport const setContent: RawCommands['setContent'] = (content, emitUpdate = false, parseOptions = {}, options = {}) => ({\n  editor, tr, dispatch, commands,\n}) => {\n  const { doc } = tr\n\n  // This is to keep backward compatibility with the previous behavior\n  // TODO remove this in the next major version\n  if (parseOptions.preserveWhitespace !== 'full') {\n    const document = createDocument(content, editor.schema, parseOptions, {\n      errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,\n    })\n\n    if (dispatch) {\n      tr.replaceWith(0, doc.content.size, document).setMeta('preventUpdate', !emitUpdate)\n    }\n    return true\n  }\n\n  if (dispatch) {\n    tr.setMeta('preventUpdate', !emitUpdate)\n  }\n\n  return commands.insertContentAt({ from: 0, to: doc.content.size }, content, {\n    parseOptions,\n    errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,\n  })\n}\n","import { MarkType, ResolvedPos } from '@tiptap/pm/model'\nimport { EditorState, Transaction } from '@tiptap/pm/state'\n\nimport { getMarkAttributes } from '../helpers/getMarkAttributes.js'\nimport { getMarkType } from '../helpers/getMarkType.js'\nimport { isTextSelection } from '../helpers/index.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    setMark: {\n      /**\n       * Add a mark with new attributes.\n       * @param typeOrName The mark type or name.\n       * @example editor.commands.setMark('bold', { level: 1 })\n       */\n      setMark: (typeOrName: string | MarkType, attributes?: Record<string, any>) => ReturnType\n    }\n  }\n}\n\nfunction canSetMark(state: EditorState, tr: Transaction, newMarkType: MarkType) {\n  const { selection } = tr\n  let cursor: ResolvedPos | null = null\n\n  if (isTextSelection(selection)) {\n    cursor = selection.$cursor\n  }\n\n  if (cursor) {\n    const currentMarks = state.storedMarks ?? cursor.marks()\n\n    // There can be no current marks that exclude the new mark\n    return (\n      !!newMarkType.isInSet(currentMarks)\n      || !currentMarks.some(mark => mark.type.excludes(newMarkType))\n    )\n  }\n\n  const { ranges } = selection\n\n  return ranges.some(({ $from, $to }) => {\n    let someNodeSupportsMark = $from.depth === 0\n      ? state.doc.inlineContent && state.doc.type.allowsMarkType(newMarkType)\n      : false\n\n    state.doc.nodesBetween($from.pos, $to.pos, (node, _pos, parent) => {\n      // If we already found a mark that we can enable, return false to bypass the remaining search\n      if (someNodeSupportsMark) {\n        return false\n      }\n\n      if (node.isInline) {\n        const parentAllowsMarkType = !parent || parent.type.allowsMarkType(newMarkType)\n        const currentMarksAllowMarkType = !!newMarkType.isInSet(node.marks)\n          || !node.marks.some(otherMark => otherMark.type.excludes(newMarkType))\n\n        someNodeSupportsMark = parentAllowsMarkType && currentMarksAllowMarkType\n      }\n      return !someNodeSupportsMark\n    })\n\n    return someNodeSupportsMark\n  })\n}\nexport const setMark: RawCommands['setMark'] = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {\n  const { selection } = tr\n  const { empty, ranges } = selection\n  const type = getMarkType(typeOrName, state.schema)\n\n  if (dispatch) {\n    if (empty) {\n      const oldAttributes = getMarkAttributes(state, type)\n\n      tr.addStoredMark(\n        type.create({\n          ...oldAttributes,\n          ...attributes,\n        }),\n      )\n    } else {\n      ranges.forEach(range => {\n        const from = range.$from.pos\n        const to = range.$to.pos\n\n        state.doc.nodesBetween(from, to, (node, pos) => {\n          const trimmedFrom = Math.max(pos, from)\n          const trimmedTo = Math.min(pos + node.nodeSize, to)\n          const someHasMark = node.marks.find(mark => mark.type === type)\n\n          // if there is already a mark of this type\n          // we know that we have to merge its attributes\n          // otherwise we add a fresh new mark\n          if (someHasMark) {\n            node.marks.forEach(mark => {\n              if (type === mark.type) {\n                tr.addMark(\n                  trimmedFrom,\n                  trimmedTo,\n                  type.create({\n                    ...mark.attrs,\n                    ...attributes,\n                  }),\n                )\n              }\n            })\n          } else {\n            tr.addMark(trimmedFrom, trimmedTo, type.create(attributes))\n          }\n        })\n      })\n    }\n  }\n\n  return canSetMark(state, tr, type)\n}\n","import type { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    setMeta: {\n      /**\n       * Store a metadata property in the current transaction.\n       * @param key The key of the metadata property.\n       * @param value The value to store.\n       * @example editor.commands.setMeta('foo', 'bar')\n       */\n      setMeta: (key: string | Plugin | PluginKey, value: any) => ReturnType,\n    }\n  }\n}\n\nexport const setMeta: RawCommands['setMeta'] = (key, value) => ({ tr }) => {\n  tr.setMeta(key, value)\n\n  return true\n}\n","import { setBlockType } from '@tiptap/pm/commands'\nimport { NodeType } from '@tiptap/pm/model'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    setNode: {\n      /**\n       * Replace a given range with a node.\n       * @param typeOrName The type or name of the node\n       * @param attributes The attributes of the node\n       * @example editor.commands.setNode('paragraph')\n       */\n      setNode: (typeOrName: string | NodeType, attributes?: Record<string, any>) => ReturnType\n    }\n  }\n}\n\nexport const setNode: RawCommands['setNode'] = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => {\n  const type = getNodeType(typeOrName, state.schema)\n\n  let attributesToCopy: Record<string, any> | undefined\n\n  if (state.selection.$anchor.sameParent(state.selection.$head)) {\n    // only copy attributes if the selection is pointing to a node of the same type\n    attributesToCopy = state.selection.$anchor.parent.attrs\n  }\n\n  // TODO: use a fallback like insertContent?\n  if (!type.isTextblock) {\n    console.warn('[tiptap warn]: Currently \"setNode()\" only supports text block nodes.')\n\n    return false\n  }\n\n  return (\n    chain()\n    // try to convert node to default node if needed\n      .command(({ commands }) => {\n        const canSetBlock = setBlockType(type, { ...attributesToCopy, ...attributes })(state)\n\n        if (canSetBlock) {\n          return true\n        }\n\n        return commands.clearNodes()\n      })\n      .command(({ state: updatedState }) => {\n        return setBlockType(type, { ...attributesToCopy, ...attributes })(updatedState, dispatch)\n      })\n      .run()\n  )\n}\n","import { NodeSelection } from '@tiptap/pm/state'\n\nimport { RawCommands } from '../types.js'\nimport { minMax } from '../utilities/minMax.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    setNodeSelection: {\n      /**\n       * Creates a NodeSelection.\n       * @param position - Position of the node.\n       * @example editor.commands.setNodeSelection(10)\n       */\n      setNodeSelection: (position: number) => ReturnType\n    }\n  }\n}\n\nexport const setNodeSelection: RawCommands['setNodeSelection'] = position => ({ tr, dispatch }) => {\n  if (dispatch) {\n    const { doc } = tr\n    const from = minMax(position, 0, doc.content.size)\n    const selection = NodeSelection.create(doc, from)\n\n    tr.setSelection(selection)\n  }\n\n  return true\n}\n","import { TextSelection } from '@tiptap/pm/state'\n\nimport { Range, RawCommands } from '../types.js'\nimport { minMax } from '../utilities/minMax.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    setTextSelection: {\n      /**\n       * Creates a TextSelection.\n       * @param position The position of the selection.\n       * @example editor.commands.setTextSelection(10)\n       */\n      setTextSelection: (position: number | Range) => ReturnType\n    }\n  }\n}\n\nexport const setTextSelection: RawCommands['setTextSelection'] = position => ({ tr, dispatch }) => {\n  if (dispatch) {\n    const { doc } = tr\n    const { from, to } = typeof position === 'number' ? { from: position, to: position } : position\n    const minPos = TextSelection.atStart(doc).from\n    const maxPos = TextSelection.atEnd(doc).to\n    const resolvedFrom = minMax(from, minPos, maxPos)\n    const resolvedEnd = minMax(to, minPos, maxPos)\n    const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd)\n\n    tr.setSelection(selection)\n  }\n\n  return true\n}\n","import { NodeType } from '@tiptap/pm/model'\nimport { sinkListItem as originalSinkListItem } from '@tiptap/pm/schema-list'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    sinkListItem: {\n      /**\n       * Sink the list item down into an inner list.\n       * @param typeOrName The type or name of the node.\n       * @example editor.commands.sinkListItem('listItem')\n       */\n      sinkListItem: (typeOrName: string | NodeType) => ReturnType\n    }\n  }\n}\n\nexport const sinkListItem: RawCommands['sinkListItem'] = typeOrName => ({ state, dispatch }) => {\n  const type = getNodeType(typeOrName, state.schema)\n\n  return originalSinkListItem(type)(state, dispatch)\n}\n","import {\n  Fragment, Node as ProseMirrorNode, NodeType, Slice,\n} from '@tiptap/pm/model'\nimport { TextSelection } from '@tiptap/pm/state'\nimport { canSplit } from '@tiptap/pm/transform'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { getSplittedAttributes } from '../helpers/getSplittedAttributes.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    splitListItem: {\n      /**\n       * Splits one list item into two list items.\n       * @param typeOrName The type or name of the node.\n       * @param overrideAttrs The attributes to ensure on the new node.\n       * @example editor.commands.splitListItem('listItem')\n       */\n      splitListItem: (typeOrName: string | NodeType, overrideAttrs?: Record<string, any>) => ReturnType\n    }\n  }\n}\n\nexport const splitListItem: RawCommands['splitListItem'] = (typeOrName, overrideAttrs = {}) => ({\n  tr, state, dispatch, editor,\n}) => {\n  const type = getNodeType(typeOrName, state.schema)\n  const { $from, $to } = state.selection\n\n  // @ts-ignore\n  // eslint-disable-next-line\n    const node: ProseMirrorNode = state.selection.node\n\n  if ((node && node.isBlock) || $from.depth < 2 || !$from.sameParent($to)) {\n    return false\n  }\n\n  const grandParent = $from.node(-1)\n\n  if (grandParent.type !== type) {\n    return false\n  }\n\n  const extensionAttributes = editor.extensionManager.attributes\n\n  if ($from.parent.content.size === 0 && $from.node(-1).childCount === $from.indexAfter(-1)) {\n    // In an empty block. If this is a nested list, the wrapping\n    // list item should be split. Otherwise, bail out and let next\n    // command handle lifting.\n    if (\n      $from.depth === 2\n        || $from.node(-3).type !== type\n        || $from.index(-2) !== $from.node(-2).childCount - 1\n    ) {\n      return false\n    }\n\n    if (dispatch) {\n      let wrap = Fragment.empty\n      // eslint-disable-next-line\n        const depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3\n\n      // Build a fragment containing empty versions of the structure\n      // from the outer list item to the parent node of the cursor\n      for (let d = $from.depth - depthBefore; d >= $from.depth - 3; d -= 1) {\n        wrap = Fragment.from($from.node(d).copy(wrap))\n      }\n\n      // eslint-disable-next-line\n        const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3\n\n      // Add a second list item with an empty default start node\n      const newNextTypeAttributes = {\n        ...getSplittedAttributes(\n          extensionAttributes,\n          $from.node().type.name,\n          $from.node().attrs,\n        ),\n        ...overrideAttrs,\n      }\n      const nextType = type.contentMatch.defaultType?.createAndFill(newNextTypeAttributes) || undefined\n\n      wrap = wrap.append(Fragment.from(type.createAndFill(null, nextType) || undefined))\n\n      const start = $from.before($from.depth - (depthBefore - 1))\n\n      tr.replace(start, $from.after(-depthAfter), new Slice(wrap, 4 - depthBefore, 0))\n\n      let sel = -1\n\n      tr.doc.nodesBetween(start, tr.doc.content.size, (n, pos) => {\n        if (sel > -1) {\n          return false\n        }\n\n        if (n.isTextblock && n.content.size === 0) {\n          sel = pos + 1\n        }\n      })\n\n      if (sel > -1) {\n        tr.setSelection(TextSelection.near(tr.doc.resolve(sel)))\n      }\n\n      tr.scrollIntoView()\n    }\n\n    return true\n  }\n\n  const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null\n\n  const newTypeAttributes = {\n    ...getSplittedAttributes(\n      extensionAttributes,\n      grandParent.type.name,\n      grandParent.attrs,\n    ),\n    ...overrideAttrs,\n  }\n  const newNextTypeAttributes = {\n    ...getSplittedAttributes(\n      extensionAttributes,\n      $from.node().type.name,\n      $from.node().attrs,\n    ),\n    ...overrideAttrs,\n  }\n\n  tr.delete($from.pos, $to.pos)\n\n  const types = nextType\n    ? [\n      { type, attrs: newTypeAttributes },\n      { type: nextType, attrs: newNextTypeAttributes },\n    ]\n    : [{ type, attrs: newTypeAttributes }]\n\n  if (!canSplit(tr.doc, $from.pos, 2)) {\n    return false\n  }\n\n  if (dispatch) {\n    const { selection, storedMarks } = state\n    const { splittableMarks } = editor.extensionManager\n    const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks())\n\n    tr.split($from.pos, 2, types).scrollIntoView()\n\n    if (!marks || !dispatch) {\n      return true\n    }\n\n    const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name))\n\n    tr.ensureMarks(filteredMarks)\n  }\n\n  return true\n}\n","import { MarkType } from '@tiptap/pm/model'\n\nimport { getMarkType } from '../helpers/getMarkType.js'\nimport { isMarkActive } from '../helpers/isMarkActive.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    toggleMark: {\n      /**\n       * Toggle a mark on and off.\n       * @param typeOrName The mark type or name.\n       * @param attributes The attributes of the mark.\n       * @param options.extendEmptyMarkRange Removes the mark even across the current selection. Defaults to `false`.\n       * @example editor.commands.toggleMark('bold')\n       */\n      toggleMark: (\n        /**\n         * The mark type or name.\n         */\n        typeOrName: string | MarkType,\n\n        /**\n         * The attributes of the mark.\n         */\n        attributes?: Record<string, any>,\n\n        options?: {\n          /**\n           * Removes the mark even across the current selection. Defaults to `false`.\n           */\n          extendEmptyMarkRange?: boolean\n        },\n      ) => ReturnType\n    }\n  }\n}\n\nexport const toggleMark: RawCommands['toggleMark'] = (typeOrName, attributes = {}, options = {}) => ({ state, commands }) => {\n  const { extendEmptyMarkRange = false } = options\n  const type = getMarkType(typeOrName, state.schema)\n  const isActive = isMarkActive(state, type, attributes)\n\n  if (isActive) {\n    return commands.unsetMark(type, { extendEmptyMarkRange })\n  }\n\n  return commands.setMark(type, attributes)\n}\n","import { NodeType } from '@tiptap/pm/model'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { isNodeActive } from '../helpers/isNodeActive.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    toggleNode: {\n      /**\n       * Toggle a node with another node.\n       * @param typeOrName The type or name of the node.\n       * @param toggleTypeOrName The type or name of the node to toggle.\n       * @param attributes The attributes of the node.\n       * @example editor.commands.toggleNode('heading', 'paragraph')\n       */\n      toggleNode: (\n        typeOrName: string | NodeType,\n        toggleTypeOrName: string | NodeType,\n        attributes?: Record<string, any>,\n      ) => ReturnType\n    }\n  }\n}\n\nexport const toggleNode: RawCommands['toggleNode'] = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state, commands }) => {\n  const type = getNodeType(typeOrName, state.schema)\n  const toggleType = getNodeType(toggleTypeOrName, state.schema)\n  const isActive = isNodeActive(state, type, attributes)\n\n  let attributesToCopy: Record<string, any> | undefined\n\n  if (state.selection.$anchor.sameParent(state.selection.$head)) {\n    // only copy attributes if the selection is pointing to a node of the same type\n    attributesToCopy = state.selection.$anchor.parent.attrs\n  }\n\n  if (isActive) {\n    return commands.setNode(toggleType, attributesToCopy)\n  }\n\n  // If the node is not active, we want to set the new node type with the given attributes\n  // Copying over the attributes from the current node if the selection is pointing to a node of the same type\n  return commands.setNode(type, { ...attributesToCopy, ...attributes })\n}\n","import { NodeType } from '@tiptap/pm/model'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { isNodeActive } from '../helpers/isNodeActive.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    toggleWrap: {\n      /**\n       * Wraps nodes in another node, or removes an existing wrap.\n       * @param typeOrName The type or name of the node.\n       * @param attributes The attributes of the node.\n       * @example editor.commands.toggleWrap('blockquote')\n       */\n      toggleWrap: (typeOrName: string | NodeType, attributes?: Record<string, any>) => ReturnType\n    }\n  }\n}\n\nexport const toggleWrap: RawCommands['toggleWrap'] = (typeOrName, attributes = {}) => ({ state, commands }) => {\n  const type = getNodeType(typeOrName, state.schema)\n  const isActive = isNodeActive(state, type, attributes)\n\n  if (isActive) {\n    return commands.lift(type)\n  }\n\n  return commands.wrapIn(type, attributes)\n}\n","import { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    undoInputRule: {\n      /**\n       * Undo an input rule.\n       * @example editor.commands.undoInputRule()\n       */\n      undoInputRule: () => ReturnType,\n    }\n  }\n}\n\nexport const undoInputRule: RawCommands['undoInputRule'] = () => ({ state, dispatch }) => {\n  const plugins = state.plugins\n\n  for (let i = 0; i < plugins.length; i += 1) {\n    const plugin = plugins[i]\n    let undoable\n\n    // @ts-ignore\n    // eslint-disable-next-line\n    if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) {\n      if (dispatch) {\n        const tr = state.tr\n        const toUndo = undoable.transform\n\n        for (let j = toUndo.steps.length - 1; j >= 0; j -= 1) {\n          tr.step(toUndo.steps[j].invert(toUndo.docs[j]))\n        }\n\n        if (undoable.text) {\n          const marks = tr.doc.resolve(undoable.from).marks()\n\n          tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks))\n        } else {\n          tr.delete(undoable.from, undoable.to)\n        }\n      }\n\n      return true\n    }\n  }\n\n  return false\n}\n","import { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    unsetAllMarks: {\n      /**\n       * Remove all marks in the current selection.\n       * @example editor.commands.unsetAllMarks()\n       */\n      unsetAllMarks: () => ReturnType,\n    }\n  }\n}\n\nexport const unsetAllMarks: RawCommands['unsetAllMarks'] = () => ({ tr, dispatch }) => {\n  const { selection } = tr\n  const { empty, ranges } = selection\n\n  if (empty) {\n    return true\n  }\n\n  if (dispatch) {\n    ranges.forEach(range => {\n      tr.removeMark(range.$from.pos, range.$to.pos)\n    })\n  }\n\n  return true\n}\n","import { MarkType } from '@tiptap/pm/model'\n\nimport { getMarkRange } from '../helpers/getMarkRange.js'\nimport { getMarkType } from '../helpers/getMarkType.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    unsetMark: {\n      /**\n       * Remove all marks in the current selection.\n       * @param typeOrName The mark type or name.\n       * @param options.extendEmptyMarkRange Removes the mark even across the current selection. Defaults to `false`.\n       * @example editor.commands.unsetMark('bold')\n       */\n      unsetMark: (\n        /**\n         * The mark type or name.\n         */\n        typeOrName: string | MarkType,\n\n        options?: {\n          /**\n           * Removes the mark even across the current selection. Defaults to `false`.\n           */\n          extendEmptyMarkRange?: boolean\n        },\n      ) => ReturnType\n    }\n  }\n}\n\nexport const unsetMark: RawCommands['unsetMark'] = (typeOrName, options = {}) => ({ tr, state, dispatch }) => {\n  const { extendEmptyMarkRange = false } = options\n  const { selection } = tr\n  const type = getMarkType(typeOrName, state.schema)\n  const { $from, empty, ranges } = selection\n\n  if (!dispatch) {\n    return true\n  }\n\n  if (empty && extendEmptyMarkRange) {\n    let { from, to } = selection\n    const attrs = $from.marks().find(mark => mark.type === type)?.attrs\n    const range = getMarkRange($from, type, attrs)\n\n    if (range) {\n      from = range.from\n      to = range.to\n    }\n\n    tr.removeMark(from, to, type)\n  } else {\n    ranges.forEach(range => {\n      tr.removeMark(range.$from.pos, range.$to.pos, type)\n    })\n  }\n\n  tr.removeStoredMark(type)\n\n  return true\n}\n","import {\n  Mark, MarkType, Node, NodeType,\n} from '@tiptap/pm/model'\nimport { SelectionRange } from '@tiptap/pm/state'\n\nimport { getMarkType } from '../helpers/getMarkType.js'\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { getSchemaTypeNameByName } from '../helpers/getSchemaTypeNameByName.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    updateAttributes: {\n      /**\n       * Update attributes of a node or mark.\n       * @param typeOrName The type or name of the node or mark.\n       * @param attributes The attributes of the node or mark.\n       * @example editor.commands.updateAttributes('mention', { userId: \"2\" })\n       */\n      updateAttributes: (\n        /**\n         * The type or name of the node or mark.\n         */\n        typeOrName: string | NodeType | MarkType,\n\n        /**\n         * The attributes of the node or mark.\n         */\n        attributes: Record<string, any>,\n      ) => ReturnType\n    }\n  }\n}\n\nexport const updateAttributes: RawCommands['updateAttributes'] = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {\n\n  let nodeType: NodeType | null = null\n  let markType: MarkType | null = null\n\n  const schemaType = getSchemaTypeNameByName(\n    typeof typeOrName === 'string' ? typeOrName : typeOrName.name,\n    state.schema,\n  )\n\n  if (!schemaType) {\n    return false\n  }\n\n  if (schemaType === 'node') {\n    nodeType = getNodeType(typeOrName as NodeType, state.schema)\n  }\n\n  if (schemaType === 'mark') {\n    markType = getMarkType(typeOrName as MarkType, state.schema)\n  }\n\n  if (dispatch) {\n    tr.selection.ranges.forEach((range: SelectionRange) => {\n\n      const from = range.$from.pos\n      const to = range.$to.pos\n\n      let lastPos: number | undefined\n      let lastNode: Node | undefined\n      let trimmedFrom: number\n      let trimmedTo: number\n\n      if (tr.selection.empty) {\n        state.doc.nodesBetween(from, to, (node: Node, pos: number) => {\n\n          if (nodeType && nodeType === node.type) {\n            trimmedFrom = Math.max(pos, from)\n            trimmedTo = Math.min(pos + node.nodeSize, to)\n            lastPos = pos\n            lastNode = node\n          }\n        })\n      } else {\n        state.doc.nodesBetween(from, to, (node: Node, pos: number) => {\n\n          if (pos < from && nodeType && nodeType === node.type) {\n            trimmedFrom = Math.max(pos, from)\n            trimmedTo = Math.min(pos + node.nodeSize, to)\n            lastPos = pos\n            lastNode = node\n          }\n\n          if (pos >= from && pos <= to) {\n\n            if (nodeType && nodeType === node.type) {\n              tr.setNodeMarkup(pos, undefined, {\n                ...node.attrs,\n                ...attributes,\n              })\n            }\n\n            if (markType && node.marks.length) {\n              node.marks.forEach((mark: Mark) => {\n\n                if (markType === mark.type) {\n                  const trimmedFrom2 = Math.max(pos, from)\n                  const trimmedTo2 = Math.min(pos + node.nodeSize, to)\n\n                  tr.addMark(\n                    trimmedFrom2,\n                    trimmedTo2,\n                    markType.create({\n                      ...mark.attrs,\n                      ...attributes,\n                    }),\n                  )\n                }\n              })\n            }\n          }\n        })\n      }\n\n      if (lastNode) {\n\n        if (lastPos !== undefined) {\n          tr.setNodeMarkup(lastPos, undefined, {\n            ...lastNode.attrs,\n            ...attributes,\n          })\n        }\n\n        if (markType && lastNode.marks.length) {\n          lastNode.marks.forEach((mark: Mark) => {\n\n            if (markType === mark.type) {\n              tr.addMark(\n                trimmedFrom,\n                trimmedTo,\n                markType.create({\n                  ...mark.attrs,\n                  ...attributes,\n                }),\n              )\n            }\n          })\n        }\n      }\n    })\n  }\n\n  return true\n}\n","import { wrapIn as originalWrapIn } from '@tiptap/pm/commands'\nimport { NodeType } from '@tiptap/pm/model'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    wrapIn: {\n      /**\n       * Wraps nodes in another node.\n       * @param typeOrName The type or name of the node.\n       * @param attributes The attributes of the node.\n       * @example editor.commands.wrapIn('blockquote')\n       */\n      wrapIn: (typeOrName: string | NodeType, attributes?: Record<string, any>) => ReturnType\n    }\n  }\n}\n\nexport const wrapIn: RawCommands['wrapIn'] = (typeOrName, attributes = {}) => ({ state, dispatch }) => {\n  const type = getNodeType(typeOrName, state.schema)\n\n  return originalWrapIn(type, attributes)(state, dispatch)\n}\n","import { NodeType } from '@tiptap/pm/model'\nimport { wrapInList as originalWrapInList } from '@tiptap/pm/schema-list'\n\nimport { getNodeType } from '../helpers/getNodeType.js'\nimport { RawCommands } from '../types.js'\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    wrapInList: {\n      /**\n       * Wrap a node in a list.\n       * @param typeOrName The type or name of the node.\n       * @param attributes The attributes of the node.\n       * @example editor.commands.wrapInList('bulletList')\n       */\n      wrapInList: (typeOrName: string | NodeType, attributes?: Record<string, any>) => ReturnType\n    }\n  }\n}\n\nexport const wrapInList: RawCommands['wrapInList'] = (typeOrName, attributes = {}) => ({ state, dispatch }) => {\n  const type = getNodeType(typeOrName, state.schema)\n\n  return originalWrapInList(type, attributes)(state, dispatch)\n}\n","import * as commands from '../commands/index.js'\nimport { Extension } from '../Extension.js'\n\nexport * from '../commands/index.js'\n\nexport const Commands = Extension.create({\n  name: 'commands',\n\n  addCommands() {\n    return {\n      ...commands,\n    }\n  },\n})\n","import { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport { Extension } from '../Extension.js'\n\nexport const Drop = Extension.create({\n  name: 'drop',\n\n  addProseMirrorPlugins() {\n    return [\n      new Plugin({\n        key: new PluginKey('tiptapDrop'),\n\n        props: {\n          handleDrop: (_, e, slice, moved) => {\n            this.editor.emit('drop', {\n              editor: this.editor,\n              event: e,\n              slice,\n              moved,\n            })\n          },\n        },\n      }),\n    ]\n  },\n})\n","import { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport { Extension } from '../Extension.js'\n\nexport const Editable = Extension.create({\n  name: 'editable',\n\n  addProseMirrorPlugins() {\n    return [\n      new Plugin({\n        key: new PluginKey('editable'),\n        props: {\n          editable: () => this.editor.options.editable,\n        },\n      }),\n    ]\n  },\n})\n","import { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport { Extension } from '../Extension.js'\n\nexport const focusEventsPluginKey = new PluginKey('focusEvents')\n\nexport const FocusEvents = Extension.create({\n  name: 'focusEvents',\n\n  addProseMirrorPlugins() {\n    const { editor } = this\n\n    return [\n      new Plugin({\n        key: focusEventsPluginKey,\n        props: {\n          handleDOMEvents: {\n            focus: (view, event: Event) => {\n              editor.isFocused = true\n\n              const transaction = editor.state.tr\n                .setMeta('focus', { event })\n                .setMeta('addToHistory', false)\n\n              view.dispatch(transaction)\n\n              return false\n            },\n            blur: (view, event: Event) => {\n              editor.isFocused = false\n\n              const transaction = editor.state.tr\n                .setMeta('blur', { event })\n                .setMeta('addToHistory', false)\n\n              view.dispatch(transaction)\n\n              return false\n            },\n          },\n        },\n      }),\n    ]\n  },\n})\n","import { Plugin, PluginKey, Selection } from '@tiptap/pm/state'\n\nimport { CommandManager } from '../CommandManager.js'\nimport { Extension } from '../Extension.js'\nimport { createChainableState } from '../helpers/createChainableState.js'\nimport { isNodeEmpty } from '../helpers/isNodeEmpty.js'\nimport { isiOS } from '../utilities/isiOS.js'\nimport { isMacOS } from '../utilities/isMacOS.js'\n\nexport const Keymap = Extension.create({\n  name: 'keymap',\n\n  addKeyboardShortcuts() {\n    const handleBackspace = () => this.editor.commands.first(({ commands }) => [\n      () => commands.undoInputRule(),\n\n      // maybe convert first text block node to default node\n      () => commands.command(({ tr }) => {\n        const { selection, doc } = tr\n        const { empty, $anchor } = selection\n        const { pos, parent } = $anchor\n        const $parentPos = $anchor.parent.isTextblock && pos > 0 ? tr.doc.resolve(pos - 1) : $anchor\n        const parentIsIsolating = $parentPos.parent.type.spec.isolating\n\n        const parentPos = $anchor.pos - $anchor.parentOffset\n\n        const isAtStart = (parentIsIsolating && $parentPos.parent.childCount === 1)\n          ? parentPos === $anchor.pos\n          : Selection.atStart(doc).from === pos\n\n        if (\n          !empty\n          || !parent.type.isTextblock\n          || parent.textContent.length\n          || !isAtStart\n          || (isAtStart && $anchor.parent.type.name === 'paragraph') // prevent clearNodes when no nodes to clear, otherwise history stack is appended\n        ) {\n          return false\n        }\n\n        return commands.clearNodes()\n      }),\n\n      () => commands.deleteSelection(),\n      () => commands.joinBackward(),\n      () => commands.selectNodeBackward(),\n    ])\n\n    const handleDelete = () => this.editor.commands.first(({ commands }) => [\n      () => commands.deleteSelection(),\n      () => commands.deleteCurrentNode(),\n      () => commands.joinForward(),\n      () => commands.selectNodeForward(),\n    ])\n\n    const handleEnter = () => this.editor.commands.first(({ commands }) => [\n      () => commands.newlineInCode(),\n      () => commands.createParagraphNear(),\n      () => commands.liftEmptyBlock(),\n      () => commands.splitBlock(),\n    ])\n\n    const baseKeymap = {\n      Enter: handleEnter,\n      'Mod-Enter': () => this.editor.commands.exitCode(),\n      Backspace: handleBackspace,\n      'Mod-Backspace': handleBackspace,\n      'Shift-Backspace': handleBackspace,\n      Delete: handleDelete,\n      'Mod-Delete': handleDelete,\n      'Mod-a': () => this.editor.commands.selectAll(),\n    }\n\n    const pcKeymap = {\n      ...baseKeymap,\n    }\n\n    const macKeymap = {\n      ...baseKeymap,\n      'Ctrl-h': handleBackspace,\n      'Alt-Backspace': handleBackspace,\n      'Ctrl-d': handleDelete,\n      'Ctrl-Alt-Backspace': handleDelete,\n      'Alt-Delete': handleDelete,\n      'Alt-d': handleDelete,\n      'Ctrl-a': () => this.editor.commands.selectTextblockStart(),\n      'Ctrl-e': () => this.editor.commands.selectTextblockEnd(),\n    }\n\n    if (isiOS() || isMacOS()) {\n      return macKeymap\n    }\n\n    return pcKeymap\n  },\n\n  addProseMirrorPlugins() {\n    return [\n      // With this plugin we check if the whole document was selected and deleted.\n      // In this case we will additionally call `clearNodes()` to convert e.g. a heading\n      // to a paragraph if necessary.\n      // This is an alternative to ProseMirror's `AllSelection`, which doesn’t work well\n      // with many other commands.\n      new Plugin({\n        key: new PluginKey('clearDocument'),\n        appendTransaction: (transactions, oldState, newState) => {\n          if (transactions.some(tr => tr.getMeta('composition'))) {\n            return\n          }\n\n          const docChanges = transactions.some(transaction => transaction.docChanged)\n            && !oldState.doc.eq(newState.doc)\n\n          const ignoreTr = transactions.some(transaction => transaction.getMeta('preventClearDocument'))\n\n          if (!docChanges || ignoreTr) {\n            return\n          }\n\n          const { empty, from, to } = oldState.selection\n          const allFrom = Selection.atStart(oldState.doc).from\n          const allEnd = Selection.atEnd(oldState.doc).to\n          const allWasSelected = from === allFrom && to === allEnd\n\n          if (empty || !allWasSelected) {\n            return\n          }\n\n          const isEmpty = isNodeEmpty(newState.doc)\n\n          if (!isEmpty) {\n            return\n          }\n\n          const tr = newState.tr\n          const state = createChainableState({\n            state: newState,\n            transaction: tr,\n          })\n          const { commands } = new CommandManager({\n            editor: this.editor,\n            state,\n          })\n\n          commands.clearNodes()\n\n          if (!tr.steps.length) {\n            return\n          }\n\n          return tr\n        },\n      }),\n    ]\n  },\n})\n","import { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport { Extension } from '../Extension.js'\n\nexport const Paste = Extension.create({\n  name: 'paste',\n\n  addProseMirrorPlugins() {\n\n    return [\n      new Plugin({\n        key: new PluginKey('tiptapPaste'),\n\n        props: {\n          handlePaste: (_view, e, slice) => {\n            this.editor.emit('paste', {\n              editor: this.editor,\n              event: e,\n              slice,\n            })\n          },\n        },\n      }),\n    ]\n  },\n})\n","import { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport { Extension } from '../Extension.js'\n\nexport const Tabindex = Extension.create({\n  name: 'tabindex',\n\n  addProseMirrorPlugins() {\n    return [\n      new Plugin({\n        key: new PluginKey('tabindex'),\n        props: {\n          attributes: (): { [name: string]: string; } => (this.editor.isEditable ? { tabindex: '0' } : {}),\n        },\n      }),\n    ]\n  },\n})\n","import {\n  Fragment, Node, ResolvedPos,\n} from '@tiptap/pm/model'\n\nimport { Editor } from './Editor.js'\nimport { Content, Range } from './types.js'\n\nexport class NodePos {\n  private resolvedPos: ResolvedPos\n\n  private isBlock: boolean\n\n  private editor: Editor\n\n  private get name(): string {\n    return this.node.type.name\n  }\n\n  constructor(pos: ResolvedPos, editor: Editor, isBlock = false, node: Node | null = null) {\n    this.isBlock = isBlock\n    this.resolvedPos = pos\n    this.editor = editor\n    this.currentNode = node\n  }\n\n  private currentNode: Node | null = null\n\n  get node(): Node {\n    return this.currentNode || this.resolvedPos.node()\n  }\n\n  get element(): HTMLElement {\n    return this.editor.view.domAtPos(this.pos).node as HTMLElement\n  }\n\n  public actualDepth: number | null = null\n\n  get depth(): number {\n    return this.actualDepth ?? this.resolvedPos.depth\n  }\n\n  get pos(): number {\n    return this.resolvedPos.pos\n  }\n\n  get content(): Fragment {\n    return this.node.content\n  }\n\n  set content(content: Content) {\n    let from = this.from\n    let to = this.to\n\n    if (this.isBlock) {\n      if (this.content.size === 0) {\n        console.error(`You can’t set content on a block node. Tried to set content on ${this.name} at ${this.pos}`)\n        return\n      }\n\n      from = this.from + 1\n      to = this.to - 1\n    }\n\n    this.editor.commands.insertContentAt({ from, to }, content)\n  }\n\n  get attributes(): { [key: string]: any } {\n    return this.node.attrs\n  }\n\n  get textContent(): string {\n    return this.node.textContent\n  }\n\n  get size(): number {\n    return this.node.nodeSize\n  }\n\n  get from(): number {\n    if (this.isBlock) {\n      return this.pos\n    }\n\n    return this.resolvedPos.start(this.resolvedPos.depth)\n  }\n\n  get range(): Range {\n    return {\n      from: this.from,\n      to: this.to,\n    }\n  }\n\n  get to(): number {\n    if (this.isBlock) {\n      return this.pos + this.size\n    }\n\n    return this.resolvedPos.end(this.resolvedPos.depth) + (this.node.isText ? 0 : 1)\n  }\n\n  get parent(): NodePos | null {\n    if (this.depth === 0) {\n      return null\n    }\n\n    const parentPos = this.resolvedPos.start(this.resolvedPos.depth - 1)\n    const $pos = this.resolvedPos.doc.resolve(parentPos)\n\n    return new NodePos($pos, this.editor)\n  }\n\n  get before(): NodePos | null {\n    let $pos = this.resolvedPos.doc.resolve(this.from - (this.isBlock ? 1 : 2))\n\n    if ($pos.depth !== this.depth) {\n      $pos = this.resolvedPos.doc.resolve(this.from - 3)\n    }\n\n    return new NodePos($pos, this.editor)\n  }\n\n  get after(): NodePos | null {\n    let $pos = this.resolvedPos.doc.resolve(this.to + (this.isBlock ? 2 : 1))\n\n    if ($pos.depth !== this.depth) {\n      $pos = this.resolvedPos.doc.resolve(this.to + 3)\n    }\n\n    return new NodePos($pos, this.editor)\n  }\n\n  get children(): NodePos[] {\n    const children: NodePos[] = []\n\n    this.node.content.forEach((node, offset) => {\n      const isBlock = node.isBlock && !node.isTextblock\n      const isNonTextAtom = node.isAtom && !node.isText\n\n      const targetPos = this.pos + offset + (isNonTextAtom ? 0 : 1)\n      const $pos = this.resolvedPos.doc.resolve(targetPos)\n\n      if (!isBlock && $pos.depth <= this.depth) {\n        return\n      }\n\n      const childNodePos = new NodePos($pos, this.editor, isBlock, isBlock ? node : null)\n\n      if (isBlock) {\n        childNodePos.actualDepth = this.depth + 1\n      }\n\n      children.push(new NodePos($pos, this.editor, isBlock, isBlock ? node : null))\n    })\n\n    return children\n  }\n\n  get firstChild(): NodePos | null {\n    return this.children[0] || null\n  }\n\n  get lastChild(): NodePos | null {\n    const children = this.children\n\n    return children[children.length - 1] || null\n  }\n\n  closest(selector: string, attributes: { [key: string]: any } = {}): NodePos | null {\n    let node: NodePos | null = null\n    let currentNode = this.parent\n\n    while (currentNode && !node) {\n      if (currentNode.node.type.name === selector) {\n        if (Object.keys(attributes).length > 0) {\n          const nodeAttributes = currentNode.node.attrs\n          const attrKeys = Object.keys(attributes)\n\n          for (let index = 0; index < attrKeys.length; index += 1) {\n            const key = attrKeys[index]\n\n            if (nodeAttributes[key] !== attributes[key]) {\n              break\n            }\n          }\n        } else {\n          node = currentNode\n        }\n      }\n\n      currentNode = currentNode.parent\n    }\n\n    return node\n  }\n\n  querySelector(selector: string, attributes: { [key: string]: any } = {}): NodePos | null {\n    return this.querySelectorAll(selector, attributes, true)[0] || null\n  }\n\n  querySelectorAll(selector: string, attributes: { [key: string]: any } = {}, firstItemOnly = false): NodePos[] {\n    let nodes: NodePos[] = []\n\n    if (!this.children || this.children.length === 0) {\n      return nodes\n    }\n    const attrKeys = Object.keys(attributes)\n\n    /**\n     * Finds all children recursively that match the selector and attributes\n     * If firstItemOnly is true, it will return the first item found\n     */\n    this.children.forEach(childPos => {\n      // If we already found a node and we only want the first item, we dont need to keep going\n      if (firstItemOnly && nodes.length > 0) {\n        return\n      }\n\n      if (childPos.node.type.name === selector) {\n        const doesAllAttributesMatch = attrKeys.every(key => attributes[key] === childPos.node.attrs[key])\n\n        if (doesAllAttributesMatch) {\n          nodes.push(childPos)\n        }\n      }\n\n      // If we already found a node and we only want the first item, we can stop here and skip the recursion\n      if (firstItemOnly && nodes.length > 0) {\n        return\n      }\n\n      nodes = nodes.concat(childPos.querySelectorAll(selector, attributes, firstItemOnly))\n    })\n\n    return nodes\n  }\n\n  setAttribute(attributes: { [key: string]: any }) {\n    const { tr } = this.editor.state\n\n    tr.setNodeMarkup(this.from, undefined, {\n      ...this.node.attrs,\n      ...attributes,\n    })\n\n    this.editor.view.dispatch(tr)\n  }\n}\n","export function createStyleTag(style: string, nonce?: string, suffix?: string): HTMLStyleElement {\n  const tiptapStyleTag = (<HTMLStyleElement>document.querySelector(`style[data-tiptap-style${suffix ? `-${suffix}` : ''}]`))\n\n  if (tiptapStyleTag !== null) {\n    return tiptapStyleTag\n  }\n\n  const styleNode = document.createElement('style')\n\n  if (nonce) {\n    styleNode.setAttribute('nonce', nonce)\n  }\n\n  styleNode.setAttribute(`data-tiptap-style${suffix ? `-${suffix}` : ''}`, '')\n  styleNode.innerHTML = style\n  document.getElementsByTagName('head')[0].appendChild(styleNode)\n\n  return styleNode\n}\n","import {\n  DOMOutputSpec, Node as ProseMirrorNode, NodeSpec, NodeType,\n} from '@tiptap/pm/model'\nimport { Plugin, Transaction } from '@tiptap/pm/state'\n\nimport { Editor } from './Editor.js'\nimport { getExtensionField } from './helpers/getExtensionField.js'\nimport { NodeConfig } from './index.js'\nimport { InputRule } from './InputRule.js'\nimport { Mark } from './Mark.js'\nimport { PasteRule } from './PasteRule.js'\nimport {\n  AnyConfig,\n  Attributes,\n  Extensions,\n  GlobalAttributes,\n  KeyboardShortcutCommand,\n  NodeViewRenderer,\n  ParentConfig,\n  RawCommands,\n} from './types.js'\nimport { callOrReturn } from './utilities/callOrReturn.js'\nimport { mergeDeep } from './utilities/mergeDeep.js'\n\ndeclare module '@tiptap/core' {\n  interface NodeConfig<Options = any, Storage = any> {\n    // @ts-ignore - this is a dynamic key\n    [key: string]: any\n\n    /**\n     * The extension name - this must be unique.\n     * It will be used to identify the extension.\n     *\n     * @example 'myExtension'\n     */\n    name: string\n\n    /**\n     * The priority of your extension. The higher, the earlier it will be called\n     * and will take precedence over other extensions with a lower priority.\n     * @default 100\n     * @example 101\n     */\n    priority?: number\n\n    /**\n     * The default options for this extension.\n     * @example\n     * defaultOptions: {\n     *   myOption: 'foo',\n     *   myOtherOption: 10,\n     * }\n     */\n    defaultOptions?: Options\n\n    /**\n     * This method will add options to this extension\n     * @see https://tiptap.dev/guide/custom-extensions#settings\n     * @example\n     * addOptions() {\n     *  return {\n     *    myOption: 'foo',\n     *    myOtherOption: 10,\n     * }\n     */\n    addOptions?: (this: {\n      name: string\n      parent: Exclude<ParentConfig<NodeConfig<Options, Storage>>['addOptions'], undefined>\n    }) => Options\n\n    /**\n     * The default storage this extension can save data to.\n     * @see https://tiptap.dev/guide/custom-extensions#storage\n     * @example\n     * defaultStorage: {\n     *   prefetchedUsers: [],\n     *   loading: false,\n     * }\n     */\n    addStorage?: (this: {\n      name: string\n      options: Options\n      parent: Exclude<ParentConfig<NodeConfig<Options, Storage>>['addStorage'], undefined>\n    }) => Storage\n\n    /**\n     * This function adds globalAttributes to specific nodes.\n     * @see https://tiptap.dev/guide/custom-extensions#global-attributes\n     * @example\n     * addGlobalAttributes() {\n     *   return [\n     *     {\n             // Extend the following extensions\n     *       types: [\n     *         'heading',\n     *         'paragraph',\n     *       ],\n     *       // … with those attributes\n     *       attributes: {\n     *         textAlign: {\n     *           default: 'left',\n     *           renderHTML: attributes => ({\n     *             style: `text-align: ${attributes.textAlign}`,\n     *           }),\n     *           parseHTML: element => element.style.textAlign || 'left',\n     *         },\n     *       },\n     *     },\n     *   ]\n     * }\n     */\n    addGlobalAttributes?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      extensions: (Node | Mark)[]\n      parent: ParentConfig<NodeConfig<Options, Storage>>['addGlobalAttributes']\n    }) => GlobalAttributes\n\n    /**\n     * This function adds commands to the editor\n     * @see https://tiptap.dev/guide/custom-extensions#keyboard-shortcuts\n     * @example\n     * addCommands() {\n     *   return {\n     *     myCommand: () => ({ chain }) => chain().setMark('type', 'foo').run(),\n     *   }\n     * }\n     */\n    addCommands?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: NodeType\n      parent: ParentConfig<NodeConfig<Options, Storage>>['addCommands']\n    }) => Partial<RawCommands>\n\n    /**\n     * This function registers keyboard shortcuts.\n     * @see https://tiptap.dev/guide/custom-extensions#keyboard-shortcuts\n     * @example\n     * addKeyboardShortcuts() {\n     *   return {\n     *     'Mod-l': () => this.editor.commands.toggleBulletList(),\n     *   }\n     * },\n     */\n    addKeyboardShortcuts?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: NodeType\n      parent: ParentConfig<NodeConfig<Options, Storage>>['addKeyboardShortcuts']\n    }) => {\n      [key: string]: KeyboardShortcutCommand\n    }\n\n    /**\n     * This function adds input rules to the editor.\n     * @see https://tiptap.dev/guide/custom-extensions#input-rules\n     * @example\n     * addInputRules() {\n     *   return [\n     *     markInputRule({\n     *       find: inputRegex,\n     *       type: this.type,\n     *     }),\n     *   ]\n     * },\n     */\n    addInputRules?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: NodeType\n      parent: ParentConfig<NodeConfig<Options, Storage>>['addInputRules']\n    }) => InputRule[]\n\n    /**\n     * This function adds paste rules to the editor.\n     * @see https://tiptap.dev/guide/custom-extensions#paste-rules\n     * @example\n     * addPasteRules() {\n     *   return [\n     *     markPasteRule({\n     *       find: pasteRegex,\n     *       type: this.type,\n     *     }),\n     *   ]\n     * },\n     */\n    addPasteRules?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: NodeType\n      parent: ParentConfig<NodeConfig<Options, Storage>>['addPasteRules']\n    }) => PasteRule[]\n\n    /**\n     * This function adds Prosemirror plugins to the editor\n     * @see https://tiptap.dev/guide/custom-extensions#prosemirror-plugins\n     * @example\n     * addProseMirrorPlugins() {\n     *   return [\n     *     customPlugin(),\n     *   ]\n     * }\n     */\n    addProseMirrorPlugins?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      editor: Editor\n      type: NodeType\n      parent: ParentConfig<NodeConfig<Options, Storage>>['addProseMirrorPlugins']\n    }) => Plugin[]\n\n    /**\n     * This function adds additional extensions to the editor. This is useful for\n     * building extension kits.\n     * @example\n     * addExtensions() {\n     *   return [\n     *     BulletList,\n     *     OrderedList,\n     *     ListItem\n     *   ]\n     * }\n     */\n    addExtensions?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      parent: ParentConfig<NodeConfig<Options, Storage>>['addExtensions']\n    }) => Extensions\n\n    /**\n     * This function extends the schema of the node.\n     * @example\n     * extendNodeSchema() {\n     *   return {\n     *     group: 'inline',\n     *     selectable: false,\n     *   }\n     * }\n     */\n    extendNodeSchema?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            parent: ParentConfig<NodeConfig<Options, Storage>>['extendNodeSchema']\n          },\n          extension: Node,\n        ) => Record<string, any>)\n      | null\n\n    /**\n     * This function extends the schema of the mark.\n     * @example\n     * extendMarkSchema() {\n     *   return {\n     *     group: 'inline',\n     *     selectable: false,\n     *   }\n     * }\n     */\n    extendMarkSchema?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            parent: ParentConfig<NodeConfig<Options, Storage>>['extendMarkSchema']\n            editor?: Editor\n          },\n          extension: Node,\n        ) => Record<string, any>)\n      | null\n\n    /**\n     * The editor is not ready yet.\n     */\n    onBeforeCreate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: NodeType\n          parent: ParentConfig<NodeConfig<Options, Storage>>['onBeforeCreate']\n        }) => void)\n      | null\n\n    /**\n     * The editor is ready.\n     */\n    onCreate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: NodeType\n          parent: ParentConfig<NodeConfig<Options, Storage>>['onCreate']\n        }) => void)\n      | null\n\n    /**\n     * The content has changed.\n     */\n    onUpdate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: NodeType\n          parent: ParentConfig<NodeConfig<Options, Storage>>['onUpdate']\n        }) => void)\n      | null\n\n    /**\n     * The selection has changed.\n     */\n    onSelectionUpdate?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: NodeType\n          parent: ParentConfig<NodeConfig<Options, Storage>>['onSelectionUpdate']\n        }) => void)\n      | null\n\n    /**\n     * The editor state has changed.\n     */\n    onTransaction?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            editor: Editor\n            type: NodeType\n            parent: ParentConfig<NodeConfig<Options, Storage>>['onTransaction']\n          },\n          props: {\n            editor: Editor\n            transaction: Transaction\n          },\n        ) => void)\n      | null\n\n    /**\n     * The editor is focused.\n     */\n    onFocus?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            editor: Editor\n            type: NodeType\n            parent: ParentConfig<NodeConfig<Options, Storage>>['onFocus']\n          },\n          props: {\n            event: FocusEvent\n          },\n        ) => void)\n      | null\n\n    /**\n     * The editor isn’t focused anymore.\n     */\n    onBlur?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            editor: Editor\n            type: NodeType\n            parent: ParentConfig<NodeConfig<Options, Storage>>['onBlur']\n          },\n          props: {\n            event: FocusEvent\n          },\n        ) => void)\n      | null\n\n    /**\n     * The editor is destroyed.\n     */\n    onDestroy?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: NodeType\n          parent: ParentConfig<NodeConfig<Options, Storage>>['onDestroy']\n        }) => void)\n      | null\n\n    /**\n     * Node View\n     */\n    addNodeView?:\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          editor: Editor\n          type: NodeType\n          parent: ParentConfig<NodeConfig<Options, Storage>>['addNodeView']\n        }) => NodeViewRenderer)\n      | null\n\n    /**\n     * Defines if this node should be a top level node (doc)\n     * @default false\n     * @example true\n     */\n    topNode?: boolean\n\n    /**\n     * The content expression for this node, as described in the [schema\n     * guide](/docs/guide/#schema.content_expressions). When not given,\n     * the node does not allow any content.\n     *\n     * You can read more about it on the Prosemirror documentation here\n     * @see https://prosemirror.net/docs/guide/#schema.content_expressions\n     * @default undefined\n     * @example content: 'block+'\n     * @example content: 'headline paragraph block*'\n     */\n    content?:\n      | NodeSpec['content']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['content']\n          editor?: Editor\n        }) => NodeSpec['content'])\n\n    /**\n     * The marks that are allowed inside of this node. May be a\n     * space-separated string referring to mark names or groups, `\"_\"`\n     * to explicitly allow all marks, or `\"\"` to disallow marks. When\n     * not given, nodes with inline content default to allowing all\n     * marks, other nodes default to not allowing marks.\n     *\n     * @example marks: 'strong em'\n     */\n    marks?:\n      | NodeSpec['marks']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['marks']\n          editor?: Editor\n        }) => NodeSpec['marks'])\n\n    /**\n     * The group or space-separated groups to which this node belongs,\n     * which can be referred to in the content expressions for the\n     * schema.\n     *\n     * By default Tiptap uses the groups 'block' and 'inline' for nodes. You\n     * can also use custom groups if you want to group specific nodes together\n     * and handle them in your schema.\n     * @example group: 'block'\n     * @example group: 'inline'\n     * @example group: 'customBlock' // this uses a custom group\n     */\n    group?:\n      | NodeSpec['group']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['group']\n          editor?: Editor\n        }) => NodeSpec['group'])\n\n    /**\n     * Should be set to true for inline nodes. (Implied for text nodes.)\n     */\n    inline?:\n      | NodeSpec['inline']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['inline']\n          editor?: Editor\n        }) => NodeSpec['inline'])\n\n    /**\n     * Can be set to true to indicate that, though this isn't a [leaf\n     * node](https://prosemirror.net/docs/ref/#model.NodeType.isLeaf), it doesn't have directly editable\n     * content and should be treated as a single unit in the view.\n     *\n     * @example atom: true\n     */\n    atom?:\n      | NodeSpec['atom']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['atom']\n          editor?: Editor\n        }) => NodeSpec['atom'])\n\n    /**\n     * Controls whether nodes of this type can be selected as a [node\n     * selection](https://prosemirror.net/docs/ref/#state.NodeSelection). Defaults to true for non-text\n     * nodes.\n     *\n     * @default true\n     * @example selectable: false\n     */\n    selectable?:\n      | NodeSpec['selectable']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['selectable']\n          editor?: Editor\n        }) => NodeSpec['selectable'])\n\n    /**\n     * Determines whether nodes of this type can be dragged without\n     * being selected. Defaults to false.\n     *\n     * @default: false\n     * @example: draggable: true\n     */\n    draggable?:\n      | NodeSpec['draggable']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['draggable']\n          editor?: Editor\n        }) => NodeSpec['draggable'])\n\n    /**\n     * Can be used to indicate that this node contains code, which\n     * causes some commands to behave differently.\n     */\n    code?:\n      | NodeSpec['code']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['code']\n          editor?: Editor\n        }) => NodeSpec['code'])\n\n    /**\n     * Controls way whitespace in this a node is parsed. The default is\n     * `\"normal\"`, which causes the [DOM parser](https://prosemirror.net/docs/ref/#model.DOMParser) to\n     * collapse whitespace in normal mode, and normalize it (replacing\n     * newlines and such with spaces) otherwise. `\"pre\"` causes the\n     * parser to preserve spaces inside the node. When this option isn't\n     * given, but [`code`](https://prosemirror.net/docs/ref/#model.NodeSpec.code) is true, `whitespace`\n     * will default to `\"pre\"`. Note that this option doesn't influence\n     * the way the node is rendered—that should be handled by `toDOM`\n     * and/or styling.\n     */\n    whitespace?:\n      | NodeSpec['whitespace']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['whitespace']\n          editor?: Editor\n        }) => NodeSpec['whitespace'])\n\n    /**\n     * Allows a **single** node to be set as linebreak equivalent (e.g. hardBreak).\n     * When converting between block types that have whitespace set to \"pre\"\n     * and don't support the linebreak node (e.g. codeBlock) and other block types\n     * that do support the linebreak node (e.g. paragraphs) - this node will be used\n     * as the linebreak instead of stripping the newline.\n     *\n     * See [linebreakReplacement](https://prosemirror.net/docs/ref/#model.NodeSpec.linebreakReplacement).\n     */\n    linebreakReplacement?:\n      | NodeSpec['linebreakReplacement']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['linebreakReplacement']\n          editor?: Editor\n        }) => NodeSpec['linebreakReplacement'])\n\n    /**\n     * When enabled, enables both\n     * [`definingAsContext`](https://prosemirror.net/docs/ref/#model.NodeSpec.definingAsContext) and\n     * [`definingForContent`](https://prosemirror.net/docs/ref/#model.NodeSpec.definingForContent).\n     *\n     * @default false\n     * @example isolating: true\n     */\n    defining?:\n      | NodeSpec['defining']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['defining']\n          editor?: Editor\n        }) => NodeSpec['defining'])\n\n    /**\n     * When enabled (default is false), the sides of nodes of this type\n     * count as boundaries that regular editing operations, like\n     * backspacing or lifting, won't cross. An example of a node that\n     * should probably have this enabled is a table cell.\n     */\n    isolating?:\n      | NodeSpec['isolating']\n      | ((this: {\n          name: string\n          options: Options\n          storage: Storage\n          parent: ParentConfig<NodeConfig<Options, Storage>>['isolating']\n          editor?: Editor\n        }) => NodeSpec['isolating'])\n\n    /**\n     * Associates DOM parser information with this node, which can be\n     * used by [`DOMParser.fromSchema`](https://prosemirror.net/docs/ref/#model.DOMParser^fromSchema) to\n     * automatically derive a parser. The `node` field in the rules is\n     * implied (the name of this node will be filled in automatically).\n     * If you supply your own parser, you do not need to also specify\n     * parsing rules in your schema.\n     *\n     * @example parseHTML: [{ tag: 'div', attrs: { 'data-id': 'my-block' } }]\n     */\n    parseHTML?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      parent: ParentConfig<NodeConfig<Options, Storage>>['parseHTML']\n      editor?: Editor\n    }) => NodeSpec['parseDOM']\n\n    /**\n     * A description of a DOM structure. Can be either a string, which is\n     * interpreted as a text node, a DOM node, which is interpreted as\n     * itself, a `{dom, contentDOM}` object, or an array.\n     *\n     * An array describes a DOM element. The first value in the array\n     * should be a string—the name of the DOM element, optionally prefixed\n     * by a namespace URL and a space. If the second element is plain\n     * object, it is interpreted as a set of attributes for the element.\n     * Any elements after that (including the 2nd if it's not an attribute\n     * object) are interpreted as children of the DOM elements, and must\n     * either be valid `DOMOutputSpec` values, or the number zero.\n     *\n     * The number zero (pronounced “hole”) is used to indicate the place\n     * where a node's child nodes should be inserted. If it occurs in an\n     * output spec, it should be the only child element in its parent\n     * node.\n     *\n     * @example toDOM: ['div[data-id=\"my-block\"]', { class: 'my-block' }, 0]\n     */\n    renderHTML?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            parent: ParentConfig<NodeConfig<Options, Storage>>['renderHTML']\n            editor?: Editor\n          },\n          props: {\n            node: ProseMirrorNode\n            HTMLAttributes: Record<string, any>\n          },\n        ) => DOMOutputSpec)\n      | null\n\n    /**\n     * renders the node as text\n     * @example renderText: () => 'foo\n     */\n    renderText?:\n      | ((\n          this: {\n            name: string\n            options: Options\n            storage: Storage\n            parent: ParentConfig<NodeConfig<Options, Storage>>['renderText']\n            editor?: Editor\n          },\n          props: {\n            node: ProseMirrorNode\n            pos: number\n            parent: ProseMirrorNode\n            index: number\n          },\n        ) => string)\n      | null\n\n    /**\n     * Add attributes to the node\n     * @example addAttributes: () => ({ class: 'foo' })\n     */\n    addAttributes?: (this: {\n      name: string\n      options: Options\n      storage: Storage\n      parent: ParentConfig<NodeConfig<Options, Storage>>['addAttributes']\n      editor?: Editor\n    // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n    }) => Attributes | {}\n  }\n}\n\n/**\n * The Node class is used to create custom node extensions.\n * @see https://tiptap.dev/api/extensions#create-a-new-extension\n */\nexport class Node<Options = any, Storage = any> {\n  type = 'node'\n\n  name = 'node'\n\n  parent: Node | null = null\n\n  child: Node | null = null\n\n  options: Options\n\n  storage: Storage\n\n  config: NodeConfig = {\n    name: this.name,\n    defaultOptions: {},\n  }\n\n  constructor(config: Partial<NodeConfig<Options, Storage>> = {}) {\n    this.config = {\n      ...this.config,\n      ...config,\n    }\n\n    this.name = this.config.name\n\n    if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) {\n      console.warn(\n        `[tiptap warn]: BREAKING CHANGE: \"defaultOptions\" is deprecated. Please use \"addOptions\" instead. Found in extension: \"${this.name}\".`,\n      )\n    }\n\n    // TODO: remove `addOptions` fallback\n    this.options = this.config.defaultOptions\n\n    if (this.config.addOptions) {\n      this.options = callOrReturn(\n        getExtensionField<AnyConfig['addOptions']>(this, 'addOptions', {\n          name: this.name,\n        }),\n      )\n    }\n\n    this.storage = callOrReturn(\n      getExtensionField<AnyConfig['addStorage']>(this, 'addStorage', {\n        name: this.name,\n        options: this.options,\n      }),\n    ) || {}\n  }\n\n  static create<O = any, S = any>(config: Partial<NodeConfig<O, S>> = {}) {\n    return new Node<O, S>(config)\n  }\n\n  configure(options: Partial<Options> = {}) {\n    // return a new instance so we can use the same extension\n    // with different calls of `configure`\n    const extension = this.extend<Options, Storage>({\n      ...this.config,\n      addOptions: () => {\n        return mergeDeep(this.options as Record<string, any>, options) as Options\n      },\n    })\n\n    // Always preserve the current name\n    extension.name = this.name\n    // Set the parent to be our parent\n    extension.parent = this.parent\n\n    return extension\n  }\n\n  extend<ExtendedOptions = Options, ExtendedStorage = Storage>(\n    extendedConfig: Partial<NodeConfig<ExtendedOptions, ExtendedStorage>> = {},\n  ) {\n    const extension = new Node<ExtendedOptions, ExtendedStorage>(extendedConfig)\n\n    extension.parent = this\n\n    this.child = extension\n\n    extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name\n\n    if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) {\n      console.warn(\n        `[tiptap warn]: BREAKING CHANGE: \"defaultOptions\" is deprecated. Please use \"addOptions\" instead. Found in extension: \"${extension.name}\".`,\n      )\n    }\n\n    extension.options = callOrReturn(\n      getExtensionField<AnyConfig['addOptions']>(extension, 'addOptions', {\n        name: extension.name,\n      }),\n    )\n\n    extension.storage = callOrReturn(\n      getExtensionField<AnyConfig['addStorage']>(extension, 'addStorage', {\n        name: extension.name,\n        options: extension.options,\n      }),\n    )\n\n    return extension\n  }\n}\n","/* eslint-disable @typescript-eslint/no-empty-object-type */\nimport {\n  MarkType,\n  Node as ProseMirrorNode,\n  NodeType,\n  Schema,\n} from '@tiptap/pm/model'\nimport {\n  EditorState, Plugin, PluginKey, Transaction,\n} from '@tiptap/pm/state'\nimport { EditorView } from '@tiptap/pm/view'\n\nimport { CommandManager } from './CommandManager.js'\nimport { EventEmitter } from './EventEmitter.js'\nimport { ExtensionManager } from './ExtensionManager.js'\nimport {\n  ClipboardTextSerializer, Commands, Drop, Editable, FocusEvents, Keymap, Paste,\n  Tabindex,\n} from './extensions/index.js'\nimport { createDocument } from './helpers/createDocument.js'\nimport { getAttributes } from './helpers/getAttributes.js'\nimport { getHTMLFromFragment } from './helpers/getHTMLFromFragment.js'\nimport { getText } from './helpers/getText.js'\nimport { getTextSerializersFromSchema } from './helpers/getTextSerializersFromSchema.js'\nimport { isActive } from './helpers/isActive.js'\nimport { isNodeEmpty } from './helpers/isNodeEmpty.js'\nimport { resolveFocusPosition } from './helpers/resolveFocusPosition.js'\nimport { NodePos } from './NodePos.js'\nimport { style } from './style.js'\nimport {\n  CanCommands,\n  ChainedCommands,\n  EditorEvents,\n  EditorOptions,\n  JSONContent,\n  SingleCommands,\n  TextSerializer,\n} from './types.js'\nimport { createStyleTag } from './utilities/createStyleTag.js'\nimport { isFunction } from './utilities/isFunction.js'\n\nexport * as extensions from './extensions/index.js'\n\n// @ts-ignore\nexport interface TiptapEditorHTMLElement extends HTMLElement {\n  editor?: Editor\n}\n\nexport class Editor extends EventEmitter<EditorEvents> {\n  private commandManager!: CommandManager\n\n  public extensionManager!: ExtensionManager\n\n  private css!: HTMLStyleElement\n\n  public schema!: Schema\n\n  public view!: EditorView\n\n  public isFocused = false\n\n  /**\n   * The editor is considered initialized after the `create` event has been emitted.\n   */\n  public isInitialized = false\n\n  public extensionStorage: Record<string, any> = {}\n\n  public options: EditorOptions = {\n    element: document.createElement('div'),\n    content: '',\n    injectCSS: true,\n    injectNonce: undefined,\n    extensions: [],\n    autofocus: false,\n    editable: true,\n    editorProps: {},\n    parseOptions: {},\n    coreExtensionOptions: {},\n    enableInputRules: true,\n    enablePasteRules: true,\n    enableCoreExtensions: true,\n    enableContentCheck: false,\n    onBeforeCreate: () => null,\n    onCreate: () => null,\n    onUpdate: () => null,\n    onSelectionUpdate: () => null,\n    onTransaction: () => null,\n    onFocus: () => null,\n    onBlur: () => null,\n    onDestroy: () => null,\n    onContentError: ({ error }) => { throw error },\n    onPaste: () => null,\n    onDrop: () => null,\n  }\n\n  constructor(options: Partial<EditorOptions> = {}) {\n    super()\n    this.setOptions(options)\n    this.createExtensionManager()\n    this.createCommandManager()\n    this.createSchema()\n    this.on('beforeCreate', this.options.onBeforeCreate)\n    this.emit('beforeCreate', { editor: this })\n    this.on('contentError', this.options.onContentError)\n    this.createView()\n    this.injectCSS()\n    this.on('create', this.options.onCreate)\n    this.on('update', this.options.onUpdate)\n    this.on('selectionUpdate', this.options.onSelectionUpdate)\n    this.on('transaction', this.options.onTransaction)\n    this.on('focus', this.options.onFocus)\n    this.on('blur', this.options.onBlur)\n    this.on('destroy', this.options.onDestroy)\n    this.on('drop', ({ event, slice, moved }) => this.options.onDrop(event, slice, moved))\n    this.on('paste', ({ event, slice }) => this.options.onPaste(event, slice))\n\n    window.setTimeout(() => {\n      if (this.isDestroyed) {\n        return\n      }\n\n      this.commands.focus(this.options.autofocus)\n      this.emit('create', { editor: this })\n      this.isInitialized = true\n    }, 0)\n  }\n\n  /**\n   * Returns the editor storage.\n   */\n  public get storage(): Record<string, any> {\n    return this.extensionStorage\n  }\n\n  /**\n   * An object of all registered commands.\n   */\n  public get commands(): SingleCommands {\n    return this.commandManager.commands\n  }\n\n  /**\n   * Create a command chain to call multiple commands at once.\n   */\n  public chain(): ChainedCommands {\n    return this.commandManager.chain()\n  }\n\n  /**\n   * Check if a command or a command chain can be executed. Without executing it.\n   */\n  public can(): CanCommands {\n    return this.commandManager.can()\n  }\n\n  /**\n   * Inject CSS styles.\n   */\n  private injectCSS(): void {\n    if (this.options.injectCSS && document) {\n      this.css = createStyleTag(style, this.options.injectNonce)\n    }\n  }\n\n  /**\n   * Update editor options.\n   *\n   * @param options A list of options\n   */\n  public setOptions(options: Partial<EditorOptions> = {}): void {\n    this.options = {\n      ...this.options,\n      ...options,\n    }\n\n    if (!this.view || !this.state || this.isDestroyed) {\n      return\n    }\n\n    if (this.options.editorProps) {\n      this.view.setProps(this.options.editorProps)\n    }\n\n    this.view.updateState(this.state)\n  }\n\n  /**\n   * Update editable state of the editor.\n   */\n  public setEditable(editable: boolean, emitUpdate = true): void {\n    this.setOptions({ editable })\n\n    if (emitUpdate) {\n      this.emit('update', { editor: this, transaction: this.state.tr })\n    }\n  }\n\n  /**\n   * Returns whether the editor is editable.\n   */\n  public get isEditable(): boolean {\n    // since plugins are applied after creating the view\n    // `editable` is always `true` for one tick.\n    // that’s why we also have to check for `options.editable`\n    return this.options.editable && this.view && this.view.editable\n  }\n\n  /**\n   * Returns the editor state.\n   */\n  public get state(): EditorState {\n    return this.view.state\n  }\n\n  /**\n   * Register a ProseMirror plugin.\n   *\n   * @param plugin A ProseMirror plugin\n   * @param handlePlugins Control how to merge the plugin into the existing plugins.\n   * @returns The new editor state\n   */\n  public registerPlugin(\n    plugin: Plugin,\n    handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[],\n  ): EditorState {\n    const plugins = isFunction(handlePlugins)\n      ? handlePlugins(plugin, [...this.state.plugins])\n      : [...this.state.plugins, plugin]\n\n    const state = this.state.reconfigure({ plugins })\n\n    this.view.updateState(state)\n\n    return state\n  }\n\n  /**\n   * Unregister a ProseMirror plugin.\n   *\n   * @param nameOrPluginKeyToRemove The plugins name\n   * @returns The new editor state or undefined if the editor is destroyed\n   */\n  public unregisterPlugin(nameOrPluginKeyToRemove: string | PluginKey | (string | PluginKey)[]): EditorState | undefined {\n    if (this.isDestroyed) {\n      return undefined\n    }\n\n    const prevPlugins = this.state.plugins\n    let plugins = prevPlugins;\n\n    ([] as (string | PluginKey)[]).concat(nameOrPluginKeyToRemove).forEach(nameOrPluginKey => {\n      // @ts-ignore\n      const name = typeof nameOrPluginKey === 'string' ? `${nameOrPluginKey}$` : nameOrPluginKey.key\n\n      // @ts-ignore\n      plugins = prevPlugins.filter(plugin => !plugin.key.startsWith(name))\n    })\n\n    if (prevPlugins.length === plugins.length) {\n      // No plugin was removed, so we don’t need to update the state\n      return undefined\n    }\n\n    const state = this.state.reconfigure({\n      plugins,\n    })\n\n    this.view.updateState(state)\n\n    return state\n  }\n\n  /**\n   * Creates an extension manager.\n   */\n  private createExtensionManager(): void {\n\n    const coreExtensions = this.options.enableCoreExtensions ? [\n      Editable,\n      ClipboardTextSerializer.configure({\n        blockSeparator: this.options.coreExtensionOptions?.clipboardTextSerializer?.blockSeparator,\n      }),\n      Commands,\n      FocusEvents,\n      Keymap,\n      Tabindex,\n      Drop,\n      Paste,\n    ].filter(ext => {\n      if (typeof this.options.enableCoreExtensions === 'object') {\n        return this.options.enableCoreExtensions[ext.name as keyof typeof this.options.enableCoreExtensions] !== false\n      }\n      return true\n    }) : []\n    const allExtensions = [...coreExtensions, ...this.options.extensions].filter(extension => {\n      return ['extension', 'node', 'mark'].includes(extension?.type)\n    })\n\n    this.extensionManager = new ExtensionManager(allExtensions, this)\n  }\n\n  /**\n   * Creates an command manager.\n   */\n  private createCommandManager(): void {\n    this.commandManager = new CommandManager({\n      editor: this,\n    })\n  }\n\n  /**\n   * Creates a ProseMirror schema.\n   */\n  private createSchema(): void {\n    this.schema = this.extensionManager.schema\n  }\n\n  /**\n   * Creates a ProseMirror view.\n   */\n  private createView(): void {\n    let doc: ProseMirrorNode\n\n    try {\n      doc = createDocument(\n        this.options.content,\n        this.schema,\n        this.options.parseOptions,\n        { errorOnInvalidContent: this.options.enableContentCheck },\n      )\n    } catch (e) {\n      if (!(e instanceof Error) || !['[tiptap error]: Invalid JSON content', '[tiptap error]: Invalid HTML content'].includes(e.message)) {\n        // Not the content error we were expecting\n        throw e\n      }\n      this.emit('contentError', {\n        editor: this,\n        error: e as Error,\n        disableCollaboration: () => {\n          if (this.storage.collaboration) {\n            this.storage.collaboration.isDisabled = true\n          }\n          // To avoid syncing back invalid content, reinitialize the extensions without the collaboration extension\n          this.options.extensions = this.options.extensions.filter(extension => extension.name !== 'collaboration')\n\n          // Restart the initialization process by recreating the extension manager with the new set of extensions\n          this.createExtensionManager()\n        },\n      })\n\n      // Content is invalid, but attempt to create it anyway, stripping out the invalid parts\n      doc = createDocument(\n        this.options.content,\n        this.schema,\n        this.options.parseOptions,\n        { errorOnInvalidContent: false },\n      )\n    }\n    const selection = resolveFocusPosition(doc, this.options.autofocus)\n\n    this.view = new EditorView(this.options.element, {\n      ...this.options.editorProps,\n      attributes: {\n        // add `role=\"textbox\"` to the editor element\n        role: 'textbox',\n        ...this.options.editorProps?.attributes,\n      },\n      dispatchTransaction: this.dispatchTransaction.bind(this),\n      state: EditorState.create({\n        doc,\n        selection: selection || undefined,\n      }),\n    })\n\n    // `editor.view` is not yet available at this time.\n    // Therefore we will add all plugins and node views directly afterwards.\n    const newState = this.state.reconfigure({\n      plugins: this.extensionManager.plugins,\n    })\n\n    this.view.updateState(newState)\n\n    this.createNodeViews()\n    this.prependClass()\n\n    // Let’s store the editor instance in the DOM element.\n    // So we’ll have access to it for tests.\n    // @ts-ignore\n    const dom = this.view.dom as TiptapEditorHTMLElement\n\n    dom.editor = this\n  }\n\n  /**\n   * Creates all node views.\n   */\n  public createNodeViews(): void {\n    if (this.view.isDestroyed) {\n      return\n    }\n\n    this.view.setProps({\n      nodeViews: this.extensionManager.nodeViews,\n    })\n  }\n\n  /**\n   * Prepend class name to element.\n   */\n  public prependClass(): void {\n    this.view.dom.className = `tiptap ${this.view.dom.className}`\n  }\n\n  public isCapturingTransaction = false\n\n  private capturedTransaction: Transaction | null = null\n\n  public captureTransaction(fn: () => void) {\n    this.isCapturingTransaction = true\n    fn()\n    this.isCapturingTransaction = false\n\n    const tr = this.capturedTransaction\n\n    this.capturedTransaction = null\n\n    return tr\n  }\n\n  /**\n   * The callback over which to send transactions (state updates) produced by the view.\n   *\n   * @param transaction An editor state transaction\n   */\n  private dispatchTransaction(transaction: Transaction): void {\n    // if the editor / the view of the editor was destroyed\n    // the transaction should not be dispatched as there is no view anymore.\n    if (this.view.isDestroyed) {\n      return\n    }\n\n    if (this.isCapturingTransaction) {\n      if (!this.capturedTransaction) {\n        this.capturedTransaction = transaction\n\n        return\n      }\n\n      transaction.steps.forEach(step => this.capturedTransaction?.step(step))\n\n      return\n    }\n\n    const state = this.state.apply(transaction)\n    const selectionHasChanged = !this.state.selection.eq(state.selection)\n\n    this.emit('beforeTransaction', {\n      editor: this,\n      transaction,\n      nextState: state,\n    })\n    this.view.updateState(state)\n    this.emit('transaction', {\n      editor: this,\n      transaction,\n    })\n\n    if (selectionHasChanged) {\n      this.emit('selectionUpdate', {\n        editor: this,\n        transaction,\n      })\n    }\n\n    const focus = transaction.getMeta('focus')\n    const blur = transaction.getMeta('blur')\n\n    if (focus) {\n      this.emit('focus', {\n        editor: this,\n        event: focus.event,\n        transaction,\n      })\n    }\n\n    if (blur) {\n      this.emit('blur', {\n        editor: this,\n        event: blur.event,\n        transaction,\n      })\n    }\n\n    if (!transaction.docChanged || transaction.getMeta('preventUpdate')) {\n      return\n    }\n\n    this.emit('update', {\n      editor: this,\n      transaction,\n    })\n  }\n\n  /**\n   * Get attributes of the currently selected node or mark.\n   */\n  public getAttributes(nameOrType: string | NodeType | MarkType): Record<string, any> {\n    return getAttributes(this.state, nameOrType)\n  }\n\n  /**\n   * Returns if the currently selected node or mark is active.\n   *\n   * @param name Name of the node or mark\n   * @param attributes Attributes of the node or mark\n   */\n  public isActive(name: string, attributes?: {}): boolean\n  public isActive(attributes: {}): boolean\n  public isActive(nameOrAttributes: string, attributesOrUndefined?: {}): boolean {\n    const name = typeof nameOrAttributes === 'string' ? nameOrAttributes : null\n\n    const attributes = typeof nameOrAttributes === 'string' ? attributesOrUndefined : nameOrAttributes\n\n    return isActive(this.state, name, attributes)\n  }\n\n  /**\n   * Get the document as JSON.\n   */\n  public getJSON(): JSONContent {\n    return this.state.doc.toJSON()\n  }\n\n  /**\n   * Get the document as HTML.\n   */\n  public getHTML(): string {\n    return getHTMLFromFragment(this.state.doc.content, this.schema)\n  }\n\n  /**\n   * Get the document as text.\n   */\n  public getText(options?: {\n    blockSeparator?: string\n    textSerializers?: Record<string, TextSerializer>\n  }): string {\n    const { blockSeparator = '\\n\\n', textSerializers = {} } = options || {}\n\n    return getText(this.state.doc, {\n      blockSeparator,\n      textSerializers: {\n        ...getTextSerializersFromSchema(this.schema),\n        ...textSerializers,\n      },\n    })\n  }\n\n  /**\n   * Check if there is no content.\n   */\n  public get isEmpty(): boolean {\n    return isNodeEmpty(this.state.doc)\n  }\n\n  /**\n   * Get the number of characters for the current document.\n   *\n   * @deprecated\n   */\n  public getCharacterCount(): number {\n    console.warn(\n      '[tiptap warn]: \"editor.getCharacterCount()\" is deprecated. Please use \"editor.storage.characterCount.characters()\" instead.',\n    )\n\n    return this.state.doc.content.size - 2\n  }\n\n  /**\n   * Destroy the editor.\n   */\n  public destroy(): void {\n    this.emit('destroy')\n\n    if (this.view) {\n      // Cleanup our reference to prevent circular references which caused memory leaks\n      // @ts-ignore\n      const dom = this.view.dom as TiptapEditorHTMLElement\n\n      if (dom && dom.editor) {\n        delete dom.editor\n      }\n      this.view.destroy()\n    }\n\n    this.removeAllListeners()\n  }\n\n  /**\n   * Check if the editor is already destroyed.\n   */\n  public get isDestroyed(): boolean {\n    // @ts-ignore\n    return !this.view?.docView\n  }\n\n  public $node(selector: string, attributes?: { [key: string]: any }): NodePos | null {\n    return this.$doc?.querySelector(selector, attributes) || null\n  }\n\n  public $nodes(selector: string, attributes?: { [key: string]: any }): NodePos[] | null {\n    return this.$doc?.querySelectorAll(selector, attributes) || null\n  }\n\n  public $pos(pos: number) {\n    const $pos = this.state.doc.resolve(pos)\n\n    return new NodePos($pos, this)\n  }\n\n  get $doc() {\n    return this.$pos(0)\n  }\n}\n","export const style = `.ProseMirror {\n  position: relative;\n}\n\n.ProseMirror {\n  word-wrap: break-word;\n  white-space: pre-wrap;\n  white-space: break-spaces;\n  -webkit-font-variant-ligatures: none;\n  font-variant-ligatures: none;\n  font-feature-settings: \"liga\" 0; /* the above doesn't seem to work in Edge */\n}\n\n.ProseMirror [contenteditable=\"false\"] {\n  white-space: normal;\n}\n\n.ProseMirror [contenteditable=\"false\"] [contenteditable=\"true\"] {\n  white-space: pre-wrap;\n}\n\n.ProseMirror pre {\n  white-space: pre-wrap;\n}\n\nimg.ProseMirror-separator {\n  display: inline !important;\n  border: none !important;\n  margin: 0 !important;\n  width: 0 !important;\n  height: 0 !important;\n}\n\n.ProseMirror-gapcursor {\n  display: none;\n  pointer-events: none;\n  position: absolute;\n  margin: 0;\n}\n\n.ProseMirror-gapcursor:after {\n  content: \"\";\n  display: block;\n  position: absolute;\n  top: -2px;\n  width: 20px;\n  border-top: 1px solid black;\n  animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;\n}\n\n@keyframes ProseMirror-cursor-blink {\n  to {\n    visibility: hidden;\n  }\n}\n\n.ProseMirror-hideselection *::selection {\n  background: transparent;\n}\n\n.ProseMirror-hideselection *::-moz-selection {\n  background: transparent;\n}\n\n.ProseMirror-hideselection * {\n  caret-color: transparent;\n}\n\n.ProseMirror-focused .ProseMirror-gapcursor {\n  display: block;\n}\n\n.tippy-box[data-animation=fade][data-state=hidden] {\n  opacity: 0\n}`\n","import { NodeSelection } from '@tiptap/pm/state'\nimport { NodeView as ProseMirrorNodeView, ViewMutationRecord } from '@tiptap/pm/view'\n\nimport { Editor as CoreEditor } from './Editor.js'\nimport { DecorationWithType, NodeViewRendererOptions, NodeViewRendererProps } from './types.js'\nimport { isAndroid } from './utilities/isAndroid.js'\nimport { isiOS } from './utilities/isiOS.js'\n\n/**\n * Node views are used to customize the rendered DOM structure of a node.\n * @see https://tiptap.dev/guide/node-views\n */\nexport class NodeView<\n  Component,\n  NodeEditor extends CoreEditor = CoreEditor,\n  Options extends NodeViewRendererOptions = NodeViewRendererOptions,\n> implements ProseMirrorNodeView {\n  component: Component\n\n  editor: NodeEditor\n\n  options: Options\n\n  extension: NodeViewRendererProps['extension']\n\n  node: NodeViewRendererProps['node']\n\n  decorations: NodeViewRendererProps['decorations']\n\n  innerDecorations: NodeViewRendererProps['innerDecorations']\n\n  view: NodeViewRendererProps['view']\n\n  getPos: NodeViewRendererProps['getPos']\n\n  HTMLAttributes: NodeViewRendererProps['HTMLAttributes']\n\n  isDragging = false\n\n  constructor(component: Component, props: NodeViewRendererProps, options?: Partial<Options>) {\n    this.component = component\n    this.editor = props.editor as NodeEditor\n    this.options = {\n      stopEvent: null,\n      ignoreMutation: null,\n      ...options,\n    } as Options\n    this.extension = props.extension\n    this.node = props.node\n    this.decorations = props.decorations as DecorationWithType[]\n    this.innerDecorations = props.innerDecorations\n    this.view = props.view\n    this.HTMLAttributes = props.HTMLAttributes\n    this.getPos = props.getPos\n    this.mount()\n  }\n\n  mount() {\n    // eslint-disable-next-line\n    return\n  }\n\n  get dom(): HTMLElement {\n    return this.editor.view.dom as HTMLElement\n  }\n\n  get contentDOM(): HTMLElement | null {\n    return null\n  }\n\n  onDragStart(event: DragEvent) {\n    const { view } = this.editor\n    const target = event.target as HTMLElement\n\n    // get the drag handle element\n    // `closest` is not available for text nodes so we may have to use its parent\n    const dragHandle = target.nodeType === 3\n      ? target.parentElement?.closest('[data-drag-handle]')\n      : target.closest('[data-drag-handle]')\n\n    if (!this.dom || this.contentDOM?.contains(target) || !dragHandle) {\n      return\n    }\n\n    let x = 0\n    let y = 0\n\n    // calculate offset for drag element if we use a different drag handle element\n    if (this.dom !== dragHandle) {\n      const domBox = this.dom.getBoundingClientRect()\n      const handleBox = dragHandle.getBoundingClientRect()\n\n      // In React, we have to go through nativeEvent to reach offsetX/offsetY.\n      const offsetX = event.offsetX ?? (event as any).nativeEvent?.offsetX\n      const offsetY = event.offsetY ?? (event as any).nativeEvent?.offsetY\n\n      x = handleBox.x - domBox.x + offsetX\n      y = handleBox.y - domBox.y + offsetY\n    }\n\n    const clonedNode = this.dom.cloneNode(true) as HTMLElement\n\n    event.dataTransfer?.setDragImage(clonedNode, x, y)\n\n    const pos = this.getPos()\n\n    if (typeof pos !== 'number') {\n      return\n    }\n    // we need to tell ProseMirror that we want to move the whole node\n    // so we create a NodeSelection\n    const selection = NodeSelection.create(view.state.doc, pos)\n    const transaction = view.state.tr.setSelection(selection)\n\n    view.dispatch(transaction)\n  }\n\n  stopEvent(event: Event) {\n    if (!this.dom) {\n      return false\n    }\n\n    if (typeof this.options.stopEvent === 'function') {\n      return this.options.stopEvent({ event })\n    }\n\n    const target = event.target as HTMLElement\n    const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target)\n\n    // any event from child nodes should be handled by ProseMirror\n    if (!isInElement) {\n      return false\n    }\n\n    const isDragEvent = event.type.startsWith('drag')\n    const isDropEvent = event.type === 'drop'\n    const isInput = ['INPUT', 'BUTTON', 'SELECT', 'TEXTAREA'].includes(target.tagName) || target.isContentEditable\n\n    // any input event within node views should be ignored by ProseMirror\n    if (isInput && !isDropEvent && !isDragEvent) {\n      return true\n    }\n\n    const { isEditable } = this.editor\n    const { isDragging } = this\n    const isDraggable = !!this.node.type.spec.draggable\n    const isSelectable = NodeSelection.isSelectable(this.node)\n    const isCopyEvent = event.type === 'copy'\n    const isPasteEvent = event.type === 'paste'\n    const isCutEvent = event.type === 'cut'\n    const isClickEvent = event.type === 'mousedown'\n\n    // ProseMirror tries to drag selectable nodes\n    // even if `draggable` is set to `false`\n    // this fix prevents that\n    if (!isDraggable && isSelectable && isDragEvent && event.target === this.dom) {\n      event.preventDefault()\n    }\n\n    if (isDraggable && isDragEvent && !isDragging && event.target === this.dom) {\n      event.preventDefault()\n      return false\n    }\n\n    // we have to store that dragging started\n    if (isDraggable && isEditable && !isDragging && isClickEvent) {\n      const dragHandle = target.closest('[data-drag-handle]')\n      const isValidDragHandle = dragHandle && (this.dom === dragHandle || this.dom.contains(dragHandle))\n\n      if (isValidDragHandle) {\n        this.isDragging = true\n\n        document.addEventListener(\n          'dragend',\n          () => {\n            this.isDragging = false\n          },\n          { once: true },\n        )\n\n        document.addEventListener(\n          'drop',\n          () => {\n            this.isDragging = false\n          },\n          { once: true },\n        )\n\n        document.addEventListener(\n          'mouseup',\n          () => {\n            this.isDragging = false\n          },\n          { once: true },\n        )\n      }\n    }\n\n    // these events are handled by prosemirror\n    if (\n      isDragging\n      || isDropEvent\n      || isCopyEvent\n      || isPasteEvent\n      || isCutEvent\n      || (isClickEvent && isSelectable)\n    ) {\n      return false\n    }\n\n    return true\n  }\n\n  /**\n   * Called when a DOM [mutation](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) or a selection change happens within the view.\n   * @return `false` if the editor should re-read the selection or re-parse the range around the mutation\n   * @return `true` if it can safely be ignored.\n   */\n  ignoreMutation(mutation: ViewMutationRecord) {\n    if (!this.dom || !this.contentDOM) {\n      return true\n    }\n\n    if (typeof this.options.ignoreMutation === 'function') {\n      return this.options.ignoreMutation({ mutation })\n    }\n\n    // a leaf/atom node is like a black box for ProseMirror\n    // and should be fully handled by the node view\n    if (this.node.isLeaf || this.node.isAtom) {\n      return true\n    }\n\n    // ProseMirror should handle any selections\n    if (mutation.type === 'selection') {\n      return false\n    }\n\n    // try to prevent a bug on iOS and Android that will break node views on enter\n    // this is because ProseMirror can’t preventDispatch on enter\n    // this will lead to a re-render of the node view on enter\n    // see: https://github.com/ueberdosis/tiptap/issues/1214\n    // see: https://github.com/ueberdosis/tiptap/issues/2534\n    if (\n      this.dom.contains(mutation.target)\n      && mutation.type === 'childList'\n      && (isiOS() || isAndroid())\n      && this.editor.isFocused\n    ) {\n      const changedNodes = [\n        ...Array.from(mutation.addedNodes),\n        ...Array.from(mutation.removedNodes),\n      ] as HTMLElement[]\n\n      // we’ll check if every changed node is contentEditable\n      // to make sure it’s probably mutated by ProseMirror\n      if (changedNodes.every(node => node.isContentEditable)) {\n        return false\n      }\n    }\n\n    // we will allow mutation contentDOM with attributes\n    // so we can for example adding classes within our node view\n    if (this.contentDOM === mutation.target && mutation.type === 'attributes') {\n      return true\n    }\n\n    // ProseMirror should handle any changes within contentDOM\n    if (this.contentDOM.contains(mutation.target)) {\n      return false\n    }\n\n    return true\n  }\n\n  /**\n   * Update the attributes of the prosemirror node.\n   */\n  updateAttributes(attributes: Record<string, any>): void {\n    this.editor.commands.command(({ tr }) => {\n      const pos = this.getPos()\n\n      if (typeof pos !== 'number') {\n        return false\n      }\n\n      tr.setNodeMarkup(pos, undefined, {\n        ...this.node.attrs,\n        ...attributes,\n      })\n\n      return true\n    })\n  }\n\n  /**\n   * Delete the node.\n   */\n  deleteNode(): void {\n    const from = this.getPos()\n\n    if (typeof from !== 'number') {\n      return\n    }\n    const to = from + this.node.nodeSize\n\n    this.editor.commands.deleteRange({ from, to })\n  }\n}\n","import { Transaction } from '@tiptap/pm/state'\n\nexport interface TrackerResult {\n  position: number\n  deleted: boolean\n}\n\nexport class Tracker {\n  transaction: Transaction\n\n  currentStep: number\n\n  constructor(transaction: Transaction) {\n    this.transaction = transaction\n    this.currentStep = this.transaction.steps.length\n  }\n\n  map(position: number): TrackerResult {\n    let deleted = false\n\n    const mappedPosition = this.transaction.steps\n      .slice(this.currentStep)\n      .reduce((newPosition, step) => {\n        const mapResult = step.getMap().mapResult(newPosition)\n\n        if (mapResult.deleted) {\n          deleted = true\n        }\n\n        return mapResult.pos\n      }, position)\n\n    return {\n      position: mappedPosition,\n      deleted,\n    }\n  }\n}\n","import { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { Transaction } from '@tiptap/pm/state'\nimport { Transform } from '@tiptap/pm/transform'\n\n/**\n * Returns a new `Transform` based on all steps of the passed transactions.\n * @param oldDoc The Prosemirror node to start from\n * @param transactions The transactions to combine\n * @returns A new `Transform` with all steps of the passed transactions\n */\nexport function combineTransactionSteps(\n  oldDoc: ProseMirrorNode,\n  transactions: Transaction[],\n): Transform {\n  const transform = new Transform(oldDoc)\n\n  transactions.forEach(transaction => {\n    transaction.steps.forEach(step => {\n      transform.step(step)\n    })\n  })\n\n  return transform\n}\n","// source: https://stackoverflow.com/a/6969486\nexport function escapeForRegEx(string: string): string {\n  return string.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&')\n}\n","import { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nimport { NodeWithPos, Predicate } from '../types.js'\n\n/**\n * Find children inside a Prosemirror node that match a predicate.\n * @param node The Prosemirror node to search in\n * @param predicate The predicate to match\n * @returns An array of nodes with their positions\n */\nexport function findChildren(node: ProseMirrorNode, predicate: Predicate): NodeWithPos[] {\n  const nodesWithPos: NodeWithPos[] = []\n\n  node.descendants((child, pos) => {\n    if (predicate(child)) {\n      nodesWithPos.push({\n        node: child,\n        pos,\n      })\n    }\n  })\n\n  return nodesWithPos\n}\n","import { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nimport { NodeWithPos, Predicate, Range } from '../types.js'\n\n/**\n * Same as `findChildren` but searches only within a `range`.\n * @param node The Prosemirror node to search in\n * @param range The range to search in\n * @param predicate The predicate to match\n * @returns An array of nodes with their positions\n */\nexport function findChildrenInRange(\n  node: ProseMirrorNode,\n  range: Range,\n  predicate: Predicate,\n): NodeWithPos[] {\n  const nodesWithPos: NodeWithPos[] = []\n\n  // if (range.from === range.to) {\n  //   const nodeAt = node.nodeAt(range.from)\n\n  //   if (nodeAt) {\n  //     nodesWithPos.push({\n  //       node: nodeAt,\n  //       pos: range.from,\n  //     })\n  //   }\n  // }\n\n  node.nodesBetween(range.from, range.to, (child, pos) => {\n    if (predicate(child)) {\n      nodesWithPos.push({\n        node: child,\n        pos,\n      })\n    }\n  })\n\n  return nodesWithPos\n}\n","import { Node } from '@tiptap/pm/model'\n\nimport { Extensions, JSONContent } from '../types.js'\nimport { getHTMLFromFragment } from './getHTMLFromFragment.js'\nimport { getSchema } from './getSchema.js'\n\n/**\n * Generate HTML from a JSONContent\n * @param doc The JSONContent to generate HTML from\n * @param extensions The extensions to use for the schema\n * @returns The generated HTML\n */\nexport function generateHTML(doc: JSONContent, extensions: Extensions): string {\n  const schema = getSchema(extensions)\n  const contentNode = Node.fromJSON(schema, doc)\n\n  return getHTMLFromFragment(contentNode.content, schema)\n}\n","import { DOMParser } from '@tiptap/pm/model'\n\nimport { Extensions } from '../types.js'\nimport { elementFromString } from '../utilities/elementFromString.js'\nimport { getSchema } from './getSchema.js'\n\n/**\n * Generate JSONContent from HTML\n * @param html The HTML to generate JSONContent from\n * @param extensions The extensions to use for the schema\n * @returns The generated JSONContent\n */\nexport function generateJSON(html: string, extensions: Extensions): Record<string, any> {\n  const schema = getSchema(extensions)\n  const dom = elementFromString(html)\n\n  return DOMParser.fromSchema(schema).parse(dom).toJSON()\n}\n","import { Node } from '@tiptap/pm/model'\n\nimport { Extensions, JSONContent, TextSerializer } from '../types.js'\nimport { getSchema } from './getSchema.js'\nimport { getText } from './getText.js'\nimport { getTextSerializersFromSchema } from './getTextSerializersFromSchema.js'\n\n/**\n * Generate raw text from a JSONContent\n * @param doc The JSONContent to generate text from\n * @param extensions The extensions to use for the schema\n * @param options Options for the text generation f.e. blockSeparator or textSerializers\n * @returns The generated text\n */\nexport function generateText(\n  doc: JSONContent,\n  extensions: Extensions,\n  options?: {\n    blockSeparator?: string\n    textSerializers?: Record<string, TextSerializer>\n  },\n): string {\n  const { blockSeparator = '\\n\\n', textSerializers = {} } = options || {}\n  const schema = getSchema(extensions)\n  const contentNode = Node.fromJSON(schema, doc)\n\n  return getText(contentNode, {\n    blockSeparator,\n    textSerializers: {\n      ...getTextSerializersFromSchema(schema),\n      ...textSerializers,\n    },\n  })\n}\n","import { Step, Transform } from '@tiptap/pm/transform'\n\nimport { Range } from '../types.js'\nimport { removeDuplicates } from '../utilities/removeDuplicates.js'\n\nexport type ChangedRange = {\n  oldRange: Range,\n  newRange: Range,\n}\n\n/**\n * Removes duplicated ranges and ranges that are\n * fully captured by other ranges.\n */\nfunction simplifyChangedRanges(changes: ChangedRange[]): ChangedRange[] {\n  const uniqueChanges = removeDuplicates(changes)\n\n  return uniqueChanges.length === 1\n    ? uniqueChanges\n    : uniqueChanges.filter((change, index) => {\n      const rest = uniqueChanges.filter((_, i) => i !== index)\n\n      return !rest.some(otherChange => {\n        return change.oldRange.from >= otherChange.oldRange.from\n          && change.oldRange.to <= otherChange.oldRange.to\n          && change.newRange.from >= otherChange.newRange.from\n          && change.newRange.to <= otherChange.newRange.to\n      })\n    })\n}\n\n/**\n * Returns a list of changed ranges\n * based on the first and last state of all steps.\n */\nexport function getChangedRanges(transform: Transform): ChangedRange[] {\n  const { mapping, steps } = transform\n  const changes: ChangedRange[] = []\n\n  mapping.maps.forEach((stepMap, index) => {\n    const ranges: Range[] = []\n\n    // This accounts for step changes where no range was actually altered\n    // e.g. when setting a mark, node attribute, etc.\n    // @ts-ignore\n    if (!stepMap.ranges.length) {\n      const { from, to } = steps[index] as Step & {\n        from?: number,\n        to?: number,\n      }\n\n      if (from === undefined || to === undefined) {\n        return\n      }\n\n      ranges.push({ from, to })\n    } else {\n      stepMap.forEach((from, to) => {\n        ranges.push({ from, to })\n      })\n    }\n\n    ranges.forEach(({ from, to }) => {\n      const newStart = mapping.slice(index).map(from, -1)\n      const newEnd = mapping.slice(index).map(to)\n      const oldStart = mapping.invert().map(newStart, -1)\n      const oldEnd = mapping.invert().map(newEnd)\n\n      changes.push({\n        oldRange: {\n          from: oldStart,\n          to: oldEnd,\n        },\n        newRange: {\n          from: newStart,\n          to: newEnd,\n        },\n      })\n    })\n  })\n\n  return simplifyChangedRanges(changes)\n}\n","import { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nimport { JSONContent } from '../types.js'\n\ninterface DebugJSONContent extends JSONContent {\n  from: number\n  to: number\n}\n\nexport function getDebugJSON(node: ProseMirrorNode, startOffset = 0): DebugJSONContent {\n  const isTopNode = node.type === node.type.schema.topNodeType\n  const increment = isTopNode ? 0 : 1\n  const from = startOffset\n  const to = from + node.nodeSize\n  const marks = node.marks.map(mark => {\n    const output: { type: string; attrs?: Record<string, any> } = {\n      type: mark.type.name,\n    }\n\n    if (Object.keys(mark.attrs).length) {\n      output.attrs = { ...mark.attrs }\n    }\n\n    return output\n  })\n  const attrs = { ...node.attrs }\n  const output: DebugJSONContent = {\n    type: node.type.name,\n    from,\n    to,\n  }\n\n  if (Object.keys(attrs).length) {\n    output.attrs = attrs\n  }\n\n  if (marks.length) {\n    output.marks = marks\n  }\n\n  if (node.content.childCount) {\n    output.content = []\n\n    node.forEach((child, offset) => {\n      output.content?.push(getDebugJSON(child, startOffset + offset + increment))\n    })\n  }\n\n  if (node.text) {\n    output.text = node.text\n  }\n\n  return output\n}\n","import { Node, NodeType } from '@tiptap/pm/model'\nimport { EditorState } from '@tiptap/pm/state'\n\n/**\n * Finds the first node of a given type or name in the current selection.\n * @param state The editor state.\n * @param typeOrName The node type or name.\n * @param pos The position to start searching from.\n * @param maxDepth The maximum depth to search.\n * @returns The node and the depth as an array.\n */\nexport const getNodeAtPosition = (state: EditorState, typeOrName: string | NodeType, pos: number, maxDepth = 20) => {\n  const $pos = state.doc.resolve(pos)\n\n  let currentDepth = maxDepth\n  let node: Node | null = null\n\n  while (currentDepth > 0 && node === null) {\n    const currentNode = $pos.node(currentDepth)\n\n    if (currentNode?.type.name === typeOrName) {\n      node = currentNode\n    } else {\n      currentDepth -= 1\n    }\n  }\n\n  return [node, currentDepth] as [Node | null, number]\n}\n","import { EditorState } from '@tiptap/pm/state'\n\nimport { findParentNode } from './findParentNode.js'\n\nexport const isAtEndOfNode = (state: EditorState, nodeType?: string) => {\n  const { $from, $to, $anchor } = state.selection\n\n  if (nodeType) {\n    const parentNode = findParentNode(node => node.type.name === nodeType)(state.selection)\n\n    if (!parentNode) {\n      return false\n    }\n\n    const $parentPos = state.doc.resolve(parentNode.pos + 1)\n\n    if ($anchor.pos + 1 === $parentPos.end()) {\n      return true\n    }\n\n    return false\n  }\n\n  if ($to.parentOffset < $to.parent.nodeSize - 2 || $from.pos !== $to.pos) {\n    return false\n  }\n\n  return true\n}\n","import { EditorState } from '@tiptap/pm/state'\n\nexport const isAtStartOfNode = (state: EditorState) => {\n  const { $from, $to } = state.selection\n\n  if ($from.parentOffset > 0 || $from.pos !== $to.pos) {\n    return false\n  }\n\n  return true\n}\n","import { NodeSelection } from '@tiptap/pm/state'\n\nexport function isNodeSelection(value: unknown): value is NodeSelection {\n  return value instanceof NodeSelection\n}\n","export function isString(value: any): value is string {\n  return typeof value === 'string'\n}\n","import { MarkType } from '@tiptap/pm/model'\n\nimport { getMarksBetween } from '../helpers/getMarksBetween.js'\nimport { InputRule, InputRuleFinder } from '../InputRule.js'\nimport { ExtendedRegExpMatchArray } from '../types.js'\nimport { callOrReturn } from '../utilities/callOrReturn.js'\n\n/**\n * Build an input rule that adds a mark when the\n * matched text is typed into it.\n * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules\n */\nexport function markInputRule(config: {\n  find: InputRuleFinder\n  type: MarkType\n  getAttributes?:\n    | Record<string, any>\n    | ((match: ExtendedRegExpMatchArray) => Record<string, any>)\n    | false\n    | null\n}) {\n  return new InputRule({\n    find: config.find,\n    handler: ({ state, range, match }) => {\n      const attributes = callOrReturn(config.getAttributes, undefined, match)\n\n      if (attributes === false || attributes === null) {\n        return null\n      }\n\n      const { tr } = state\n      const captureGroup = match[match.length - 1]\n      const fullMatch = match[0]\n\n      if (captureGroup) {\n        const startSpaces = fullMatch.search(/\\S/)\n        const textStart = range.from + fullMatch.indexOf(captureGroup)\n        const textEnd = textStart + captureGroup.length\n\n        const excludedMarks = getMarksBetween(range.from, range.to, state.doc)\n          .filter(item => {\n            // @ts-ignore\n            const excluded = item.mark.type.excluded as MarkType[]\n\n            return excluded.find(type => type === config.type && type !== item.mark.type)\n          })\n          .filter(item => item.to > textStart)\n\n        if (excludedMarks.length) {\n          return null\n        }\n\n        if (textEnd < range.to) {\n          tr.delete(textEnd, range.to)\n        }\n\n        if (textStart > range.from) {\n          tr.delete(range.from + startSpaces, textStart)\n        }\n\n        const markEnd = range.from + startSpaces + captureGroup.length\n\n        tr.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {}))\n\n        tr.removeStoredMark(config.type)\n      }\n    },\n  })\n}\n","import { MarkType } from '@tiptap/pm/model'\n\nimport { getMarksBetween } from '../helpers/getMarksBetween.js'\nimport { PasteRule, PasteRuleFinder } from '../PasteRule.js'\nimport { ExtendedRegExpMatchArray } from '../types.js'\nimport { callOrReturn } from '../utilities/callOrReturn.js'\n\n/**\n * Build an paste rule that adds a mark when the\n * matched text is pasted into it.\n * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules\n */\nexport function markPasteRule(config: {\n  find: PasteRuleFinder\n  type: MarkType\n  getAttributes?:\n    | Record<string, any>\n    | ((match: ExtendedRegExpMatchArray, event: ClipboardEvent) => Record<string, any>)\n    | false\n    | null\n}) {\n  return new PasteRule({\n    find: config.find,\n    handler: ({\n      state, range, match, pasteEvent,\n    }) => {\n      const attributes = callOrReturn(config.getAttributes, undefined, match, pasteEvent)\n\n      if (attributes === false || attributes === null) {\n        return null\n      }\n\n      const { tr } = state\n      const captureGroup = match[match.length - 1]\n      const fullMatch = match[0]\n      let markEnd = range.to\n\n      if (captureGroup) {\n        const startSpaces = fullMatch.search(/\\S/)\n        const textStart = range.from + fullMatch.indexOf(captureGroup)\n        const textEnd = textStart + captureGroup.length\n\n        const excludedMarks = getMarksBetween(range.from, range.to, state.doc)\n          .filter(item => {\n            // @ts-ignore\n            const excluded = item.mark.type.excluded as MarkType[]\n\n            return excluded.find(type => type === config.type && type !== item.mark.type)\n          })\n          .filter(item => item.to > textStart)\n\n        if (excludedMarks.length) {\n          return null\n        }\n\n        if (textEnd < range.to) {\n          tr.delete(textEnd, range.to)\n        }\n\n        if (textStart > range.from) {\n          tr.delete(range.from + startSpaces, textStart)\n        }\n\n        markEnd = range.from + startSpaces + captureGroup.length\n\n        tr.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {}))\n\n        tr.removeStoredMark(config.type)\n      }\n    },\n  })\n}\n","import { NodeType } from '@tiptap/pm/model'\n\nimport { InputRule, InputRuleFinder } from '../InputRule.js'\nimport { ExtendedRegExpMatchArray } from '../types.js'\nimport { callOrReturn } from '../utilities/callOrReturn.js'\n\n/**\n * Build an input rule that adds a node when the\n * matched text is typed into it.\n * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules\n */\nexport function nodeInputRule(config: {\n  /**\n   * The regex to match.\n   */\n  find: InputRuleFinder\n\n  /**\n   * The node type to add.\n   */\n  type: NodeType\n\n  /**\n   * A function that returns the attributes for the node\n   * can also be an object of attributes\n   */\n  getAttributes?:\n    | Record<string, any>\n    | ((match: ExtendedRegExpMatchArray) => Record<string, any>)\n    | false\n    | null\n}) {\n  return new InputRule({\n    find: config.find,\n    handler: ({ state, range, match }) => {\n      const attributes = callOrReturn(config.getAttributes, undefined, match) || {}\n      const { tr } = state\n      const start = range.from\n      let end = range.to\n\n      const newNode = config.type.create(attributes)\n\n      if (match[1]) {\n        const offset = match[0].lastIndexOf(match[1])\n        let matchStart = start + offset\n\n        if (matchStart > end) {\n          matchStart = end\n        } else {\n          end = matchStart + match[1].length\n        }\n\n        // insert last typed character\n        const lastChar = match[0][match[0].length - 1]\n\n        tr.insertText(lastChar, start + match[0].length - 1)\n\n        // insert node from input rule\n        tr.replaceWith(matchStart, end, newNode)\n      } else if (match[0]) {\n        const insertionStart = config.type.isInline ? start : start - 1\n\n        tr.insert(insertionStart, config.type.create(attributes)).delete(\n          tr.mapping.map(start),\n          tr.mapping.map(end),\n        )\n      }\n\n      tr.scrollIntoView()\n    },\n  })\n}\n","import { NodeType } from '@tiptap/pm/model'\n\nimport { PasteRule, PasteRuleFinder } from '../PasteRule.js'\nimport { ExtendedRegExpMatchArray, JSONContent } from '../types.js'\nimport { callOrReturn } from '../utilities/index.js'\n\n/**\n * Build an paste rule that adds a node when the\n * matched text is pasted into it.\n * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules\n */\nexport function nodePasteRule(config: {\n  find: PasteRuleFinder\n  type: NodeType\n  getAttributes?:\n    | Record<string, any>\n    | ((match: ExtendedRegExpMatchArray, event: ClipboardEvent) => Record<string, any>)\n    | false\n    | null\n  getContent?:\n    | JSONContent[]\n    | ((attrs: Record<string, any>) => JSONContent[])\n    | false\n    | null\n}) {\n  return new PasteRule({\n    find: config.find,\n    handler({\n      match, chain, range, pasteEvent,\n    }) {\n      const attributes = callOrReturn(config.getAttributes, undefined, match, pasteEvent)\n      const content = callOrReturn(config.getContent, undefined, attributes)\n\n      if (attributes === false || attributes === null) {\n        return null\n      }\n\n      const node = { type: config.type.name, attrs: attributes } as JSONContent\n\n      if (content) {\n        node.content = content\n      }\n\n      if (match.input) {\n        chain().deleteRange(range).insertContentAt(range.from, node)\n      }\n    },\n  })\n}\n","import { EditorView } from '@tiptap/pm/view'\n\nimport { minMax } from '../utilities/minMax.js'\n\nexport function posToDOMRect(view: EditorView, from: number, to: number): DOMRect {\n  const minPos = 0\n  const maxPos = view.state.doc.content.size\n  const resolvedFrom = minMax(from, minPos, maxPos)\n  const resolvedEnd = minMax(to, minPos, maxPos)\n  const start = view.coordsAtPos(resolvedFrom)\n  const end = view.coordsAtPos(resolvedEnd, -1)\n  const top = Math.min(start.top, end.top)\n  const bottom = Math.max(start.bottom, end.bottom)\n  const left = Math.min(start.left, end.left)\n  const right = Math.max(start.right, end.right)\n  const width = right - left\n  const height = bottom - top\n  const x = left\n  const y = top\n  const data = {\n    top,\n    bottom,\n    left,\n    right,\n    width,\n    height,\n    x,\n    y,\n  }\n\n  return {\n    ...data,\n    toJSON: () => data,\n  }\n}\n","import { InputRule, InputRuleFinder } from '../InputRule.js'\n\n/**\n * Build an input rule that replaces text when the\n * matched text is typed into it.\n * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules\n */\nexport function textInputRule(config: {\n  find: InputRuleFinder,\n  replace: string,\n}) {\n  return new InputRule({\n    find: config.find,\n    handler: ({ state, range, match }) => {\n      let insert = config.replace\n      let start = range.from\n      const end = range.to\n\n      if (match[1]) {\n        const offset = match[0].lastIndexOf(match[1])\n\n        insert += match[0].slice(offset + match[1].length)\n        start += offset\n\n        const cutOff = start - end\n\n        if (cutOff > 0) {\n          insert = match[0].slice(offset - cutOff, offset) + insert\n          start = end\n        }\n      }\n\n      state.tr.insertText(insert, start, end)\n    },\n  })\n}\n","import { PasteRule, PasteRuleFinder } from '../PasteRule.js'\n\n/**\n * Build an paste rule that replaces text when the\n * matched text is pasted into it.\n * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#paste-rules\n */\nexport function textPasteRule(config: {\n  find: PasteRuleFinder,\n  replace: string,\n}) {\n  return new PasteRule({\n    find: config.find,\n    handler: ({ state, range, match }) => {\n      let insert = config.replace\n      let start = range.from\n      const end = range.to\n\n      if (match[1]) {\n        const offset = match[0].lastIndexOf(match[1])\n\n        insert += match[0].slice(offset + match[1].length)\n        start += offset\n\n        const cutOff = start - end\n\n        if (cutOff > 0) {\n          insert = match[0].slice(offset - cutOff, offset) + insert\n          start = end\n        }\n      }\n\n      state.tr.insertText(insert, start, end)\n    },\n  })\n}\n","import { NodeType } from '@tiptap/pm/model'\n\nimport { InputRule, InputRuleFinder } from '../InputRule.js'\nimport { ExtendedRegExpMatchArray } from '../types.js'\nimport { callOrReturn } from '../utilities/callOrReturn.js'\n\n/**\n * Build an input rule that changes the type of a textblock when the\n * matched text is typed into it. When using a regular expresion you’ll\n * probably want the regexp to start with `^`, so that the pattern can\n * only occur at the start of a textblock.\n * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules\n */\nexport function textblockTypeInputRule(config: {\n  find: InputRuleFinder\n  type: NodeType\n  getAttributes?:\n    | Record<string, any>\n    | ((match: ExtendedRegExpMatchArray) => Record<string, any>)\n    | false\n    | null\n}) {\n  return new InputRule({\n    find: config.find,\n    handler: ({ state, range, match }) => {\n      const $start = state.doc.resolve(range.from)\n      const attributes = callOrReturn(config.getAttributes, undefined, match) || {}\n\n      if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), config.type)) {\n        return null\n      }\n\n      state.tr\n        .delete(range.from, range.to)\n        .setBlockType(range.from, range.from, config.type, attributes)\n    },\n  })\n}\n","import { Node as ProseMirrorNode, NodeType } from '@tiptap/pm/model'\nimport { canJoin, findWrapping } from '@tiptap/pm/transform'\n\nimport { Editor } from '../Editor.js'\nimport { InputRule, InputRuleFinder } from '../InputRule.js'\nimport { ExtendedRegExpMatchArray } from '../types.js'\nimport { callOrReturn } from '../utilities/callOrReturn.js'\n\n/**\n * Build an input rule for automatically wrapping a textblock when a\n * given string is typed. When using a regular expresion you’ll\n * probably want the regexp to start with `^`, so that the pattern can\n * only occur at the start of a textblock.\n *\n * `type` is the type of node to wrap in.\n *\n * By default, if there’s a node with the same type above the newly\n * wrapped node, the rule will try to join those\n * two nodes. You can pass a join predicate, which takes a regular\n * expression match and the node before the wrapped node, and can\n * return a boolean to indicate whether a join should happen.\n * @see https://tiptap.dev/docs/editor/extensions/custom-extensions/extend-existing#input-rules\n */\nexport function wrappingInputRule(config: {\n  find: InputRuleFinder,\n  type: NodeType,\n  keepMarks?: boolean,\n  keepAttributes?: boolean,\n  editor?: Editor\n  getAttributes?:\n  | Record<string, any>\n  | ((match: ExtendedRegExpMatchArray) => Record<string, any>)\n  | false\n  | null\n  ,\n  joinPredicate?: (match: ExtendedRegExpMatchArray, node: ProseMirrorNode) => boolean,\n}) {\n  return new InputRule({\n    find: config.find,\n    handler: ({\n      state, range, match, chain,\n    }) => {\n      const attributes = callOrReturn(config.getAttributes, undefined, match) || {}\n      const tr = state.tr.delete(range.from, range.to)\n      const $start = tr.doc.resolve(range.from)\n      const blockRange = $start.blockRange()\n      const wrapping = blockRange && findWrapping(blockRange, config.type, attributes)\n\n      if (!wrapping) {\n        return null\n      }\n\n      tr.wrap(blockRange, wrapping)\n\n      if (config.keepMarks && config.editor) {\n        const { selection, storedMarks } = state\n        const { splittableMarks } = config.editor.extensionManager\n        const marks = storedMarks || (selection.$to.parentOffset && selection.$from.marks())\n\n        if (marks) {\n          const filteredMarks = marks.filter(mark => splittableMarks.includes(mark.type.name))\n\n          tr.ensureMarks(filteredMarks)\n        }\n      }\n      if (config.keepAttributes) {\n        /** If the nodeType is `bulletList` or `orderedList` set the `nodeType` as `listItem` */\n        const nodeType = config.type.name === 'bulletList' || config.type.name === 'orderedList' ? 'listItem' : 'taskList'\n\n        chain().updateAttributes(nodeType, attributes).run()\n      }\n\n      const before = tr.doc.resolve(range.from - 1).nodeBefore\n\n      if (\n        before\n        && before.type === config.type\n        && canJoin(tr.doc, range.from - 1)\n        && (!config.joinPredicate || config.joinPredicate(match, before))\n      ) {\n        tr.join(range.from - 1)\n      }\n    },\n  })\n}\n"]}