{"version":3,"file":"blocknote.umd.cjs","sources":["../src/extensions/UniqueID/UniqueID.ts","../src/api/getBlockInfoFromPos.ts","../src/schema/inlineContent/types.ts","../src/util/typescript.ts","../src/api/nodeConversions/nodeConversions.ts","../src/api/exporters/html/util/sharedHTMLConversion.ts","../src/api/exporters/html/util/simplifyBlocksRehypePlugin.ts","../src/api/exporters/html/externalHTMLExporter.ts","../src/api/exporters/html/internalHTMLSerializer.ts","../src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts","../src/util/browser.ts","../src/blocks/defaultBlockHelpers.ts","../src/blocks/defaultProps.ts","../src/util/string.ts","../src/schema/blocks/internal.ts","../src/schema/blocks/createSpec.ts","../src/schema/inlineContent/internal.ts","../src/schema/inlineContent/createSpec.ts","../src/schema/styles/internal.ts","../src/schema/styles/createSpec.ts","../src/extensions/BackgroundColor/BackgroundColorMark.ts","../src/extensions/TextColor/TextColorMark.ts","../src/blocks/HeadingBlockContent/HeadingBlockContent.ts","../src/util/EventEmitter.ts","../src/extensions/ImageToolbar/ImageToolbarPlugin.ts","../src/blocks/ImageBlockContent/ImageBlockContent.ts","../src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts","../src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts","../src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts","../src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts","../src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts","../src/blocks/TableBlockContent/TableExtension.ts","../src/blocks/TableBlockContent/TableBlockContent.ts","../src/blocks/defaultBlocks.ts","../src/api/nodeUtil.ts","../src/api/blockManipulation/blockManipulation.ts","../src/api/exporters/markdown/removeUnderlinesRehypePlugin.ts","../src/api/exporters/markdown/markdownExporter.ts","../src/api/parsers/html/util/nestedLists.ts","../src/api/parsers/html/parseHTML.ts","../src/api/parsers/markdown/parseMarkdown.ts","../src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts","../src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts","../src/extensions-shared/suggestion/SuggestionPlugin.ts","../src/extensions/SlashMenu/SlashMenuPlugin.ts","../src/extensions/SideMenu/MultipleNodeSelection.ts","../src/util/constants.ts","../src/extensions/SideMenu/SideMenuPlugin.ts","../src/extensions/SlashMenu/defaultSlashMenuItems.ts","../src/extensions/TableHandles/TableHandlesPlugin.ts","../src/api/exporters/copyExtension.ts","../src/api/parsers/pasteExtension.ts","../src/extensions/BackgroundColor/BackgroundColorExtension.ts","../src/extensions/Placeholder/PlaceholderExtension.ts","../src/extensions/TextAlignment/TextAlignmentExtension.ts","../src/extensions/TextColor/TextColorExtension.ts","../src/extensions/TrailingNode/TrailingNodeExtension.ts","../src/extensions/NonEditableBlocks/NonEditableBlockPlugin.ts","../src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts","../src/pm-nodes/BlockContainer.ts","../src/pm-nodes/BlockGroup.ts","../src/pm-nodes/Doc.ts","../src/extensions/CustomMark/CustomMark.ts","../src/editor/BlockNoteExtensions.ts","../src/editor/transformPasted.ts","../src/editor/BlockNoteEditor.ts","../src/api/testUtil/partialBlockTestUtil.ts"],"sourcesContent":["import {\n  combineTransactionSteps,\n  Extension,\n  findChildrenInRange,\n  getChangedRanges,\n} from \"@tiptap/core\";\nimport { Fragment, Slice } from \"prosemirror-model\";\nimport { Plugin, PluginKey } from \"prosemirror-state\";\nimport { v4 } from \"uuid\";\n\n/**\n * Code from Tiptap UniqueID extension (https://tiptap.dev/api/extensions/unique-id)\n * This extension is licensed under MIT (even though it's part of Tiptap pro).\n *\n * If you're a user of BlockNote, we still recommend to support their awesome work and become a sponsor!\n * https://tiptap.dev/pro\n */\n\n/**\n * Removes duplicated values within an array.\n * Supports numbers, strings and objects.\n */\nfunction removeDuplicates(array: any, by = JSON.stringify) {\n  const seen: any = {};\n  return array.filter((item: any) => {\n    const key = by(item);\n    return Object.prototype.hasOwnProperty.call(seen, key)\n      ? false\n      : (seen[key] = true);\n  });\n}\n\n/**\n * Returns a list of duplicated items within an array.\n */\nfunction findDuplicates(items: any) {\n  const filtered = items.filter(\n    (el: any, index: number) => items.indexOf(el) !== index\n  );\n  const duplicates = removeDuplicates(filtered);\n  return duplicates;\n}\n\nconst UniqueID = Extension.create({\n  name: \"uniqueID\",\n  // we’ll set a very high priority to make sure this runs first\n  // and is compatible with `appendTransaction` hooks of other extensions\n  priority: 10000,\n  addOptions() {\n    return {\n      attributeName: \"id\",\n      types: [],\n      generateID: () => {\n        // Use mock ID if tests are running.\n        if (typeof window !== \"undefined\" && (window as any).__TEST_OPTIONS) {\n          const testOptions = (window as any).__TEST_OPTIONS;\n          if (testOptions.mockID === undefined) {\n            testOptions.mockID = 0;\n          } else {\n            testOptions.mockID++;\n          }\n\n          return testOptions.mockID.toString() as string;\n        }\n\n        return v4();\n      },\n      filterTransaction: null,\n    };\n  },\n  addGlobalAttributes() {\n    return [\n      {\n        types: this.options.types,\n        attributes: {\n          [this.options.attributeName]: {\n            default: null,\n            parseHTML: (element) =>\n              element.getAttribute(`data-${this.options.attributeName}`),\n            renderHTML: (attributes) => ({\n              [`data-${this.options.attributeName}`]:\n                attributes[this.options.attributeName],\n            }),\n          },\n        },\n      },\n    ];\n  },\n  // check initial content for missing ids\n  // onCreate() {\n  //   // Don’t do this when the collaboration extension is active\n  //   // because this may update the content, so Y.js tries to merge these changes.\n  //   // This leads to empty block nodes.\n  //   // See: https://github.com/ueberdosis/tiptap/issues/2400\n  //   if (\n  //     this.editor.extensionManager.extensions.find(\n  //       (extension) => extension.name === \"collaboration\"\n  //     )\n  //   ) {\n  //     return;\n  //   }\n  //   const { view, state } = this.editor;\n  //   const { tr, doc } = state;\n  //   const { types, attributeName, generateID } = this.options;\n  //   const nodesWithoutId = findChildren(doc, (node) => {\n  //     return (\n  //       types.includes(node.type.name) && node.attrs[attributeName] === null\n  //     );\n  //   });\n  //   nodesWithoutId.forEach(({ node, pos }) => {\n  //     tr.setNodeMarkup(pos, undefined, {\n  //       ...node.attrs,\n  //       [attributeName]: generateID(),\n  //     });\n  //   });\n  //   tr.setMeta(\"addToHistory\", false);\n  //   view.dispatch(tr);\n  // },\n  addProseMirrorPlugins() {\n    let dragSourceElement: any = null;\n    let transformPasted = false;\n    return [\n      new Plugin({\n        key: new PluginKey(\"uniqueID\"),\n        appendTransaction: (transactions, oldState, newState) => {\n          // console.log(\"appendTransaction\");\n          const docChanges =\n            transactions.some((transaction) => transaction.docChanged) &&\n            !oldState.doc.eq(newState.doc);\n          const filterTransactions =\n            this.options.filterTransaction &&\n            transactions.some((tr) => {\n              let _a, _b;\n              return !((_b = (_a = this.options).filterTransaction) === null ||\n              _b === void 0\n                ? void 0\n                : _b.call(_a, tr));\n            });\n          if (!docChanges || filterTransactions) {\n            return;\n          }\n          const { tr } = newState;\n          const { types, attributeName, generateID } = this.options;\n          const transform = combineTransactionSteps(\n            oldState.doc,\n            transactions as any\n          );\n          const { mapping } = transform;\n          // get changed ranges based on the old state\n          const changes = getChangedRanges(transform);\n\n          changes.forEach(({ newRange }) => {\n            const newNodes = findChildrenInRange(\n              newState.doc,\n              newRange,\n              (node) => {\n                return types.includes(node.type.name);\n              }\n            );\n            const newIds = newNodes\n              .map(({ node }) => node.attrs[attributeName])\n              .filter((id) => id !== null);\n            const duplicatedNewIds = findDuplicates(newIds);\n            newNodes.forEach(({ node, pos }) => {\n              let _a;\n              // instead of checking `node.attrs[attributeName]` directly\n              // we look at the current state of the node within `tr.doc`.\n              // this helps to prevent adding new ids to the same node\n              // if the node changed multiple times within one transaction\n              const id =\n                (_a = tr.doc.nodeAt(pos)) === null || _a === void 0\n                  ? void 0\n                  : _a.attrs[attributeName];\n              if (id === null) {\n                // edge case, when using collaboration, yjs will set the id to null in `_forceRerender`\n                // when loading the editor\n                // this checks for this case and keeps it at initialBlockId so there will be no change\n                const initialDoc = oldState.doc.type.createAndFill()!.content;\n                const wasInitial =\n                  oldState.doc.content.findDiffStart(initialDoc) === null;\n\n                if (wasInitial) {\n                  // the old state was the \"initial content\"\n                  const jsonNode = JSON.parse(\n                    JSON.stringify(newState.doc.toJSON())\n                  );\n                  jsonNode.content[0].content[0].attrs.id = \"initialBlockId\";\n                  // would the new state with the fix also be the \"initial content\"?\n                  if (\n                    JSON.stringify(jsonNode.content) ===\n                    JSON.stringify(initialDoc.toJSON())\n                  ) {\n                    // yes, apply the fix\n                    tr.setNodeMarkup(pos, undefined, {\n                      ...node.attrs,\n                      [attributeName]: \"initialBlockId\",\n                    });\n                    return;\n                  }\n                }\n\n                tr.setNodeMarkup(pos, undefined, {\n                  ...node.attrs,\n                  [attributeName]: generateID(),\n                });\n                return;\n              }\n              // check if the node doesn’t exist in the old state\n              const { deleted } = mapping.invert().mapResult(pos);\n              const newNode = deleted && duplicatedNewIds.includes(id);\n              if (newNode) {\n                tr.setNodeMarkup(pos, undefined, {\n                  ...node.attrs,\n                  [attributeName]: generateID(),\n                });\n              }\n            });\n          });\n          if (!tr.steps.length) {\n            return;\n          }\n          return tr;\n        },\n        // we register a global drag handler to track the current drag source element\n        view(view) {\n          const handleDragstart = (event: any) => {\n            let _a;\n            dragSourceElement = (\n              (_a = view.dom.parentElement) === null || _a === void 0\n                ? void 0\n                : _a.contains(event.target)\n            )\n              ? view.dom.parentElement\n              : null;\n          };\n          window.addEventListener(\"dragstart\", handleDragstart);\n          return {\n            destroy() {\n              window.removeEventListener(\"dragstart\", handleDragstart);\n            },\n          };\n        },\n        props: {\n          // `handleDOMEvents` is called before `transformPasted`\n          // so we can do some checks before\n          handleDOMEvents: {\n            // only create new ids for dropped content while holding `alt`\n            // or content is dragged from another editor\n            drop: (view, event: any) => {\n              let _a;\n              if (\n                dragSourceElement !== view.dom.parentElement ||\n                ((_a = event.dataTransfer) === null || _a === void 0\n                  ? void 0\n                  : _a.effectAllowed) === \"copy\"\n              ) {\n                dragSourceElement = null;\n                transformPasted = true;\n              }\n              return false;\n            },\n            // always create new ids on pasted content\n            paste: () => {\n              transformPasted = true;\n              return false;\n            },\n          },\n          // we’ll remove ids for every pasted node\n          // so we can create a new one within `appendTransaction`\n          transformPasted: (slice) => {\n            if (!transformPasted) {\n              return slice;\n            }\n            const { types, attributeName } = this.options;\n            const removeId = (fragment: any) => {\n              const list: any[] = [];\n              fragment.forEach((node: any) => {\n                // don’t touch text nodes\n                if (node.isText) {\n                  list.push(node);\n                  return;\n                }\n                // check for any other child nodes\n                if (!types.includes(node.type.name)) {\n                  list.push(node.copy(removeId(node.content)));\n                  return;\n                }\n                // remove id\n                const nodeWithoutId = node.type.create(\n                  {\n                    ...node.attrs,\n                    [attributeName]: null,\n                  },\n                  removeId(node.content),\n                  node.marks\n                );\n                list.push(nodeWithoutId);\n              });\n              return Fragment.from(list);\n            };\n            // reset check\n            transformPasted = false;\n            return new Slice(\n              removeId(slice.content),\n              slice.openStart,\n              slice.openEnd\n            );\n          },\n        },\n      }),\n    ];\n  },\n});\n\nexport { UniqueID as default, UniqueID };\n","import { Node, NodeType } from \"prosemirror-model\";\n\nexport type BlockInfoWithoutPositions = {\n  id: string;\n  node: Node;\n  contentNode: Node;\n  contentType: NodeType;\n  numChildBlocks: number;\n};\n\nexport type BlockInfo = BlockInfoWithoutPositions & {\n  startPos: number;\n  endPos: number;\n  depth: number;\n};\n\n/**\n * Helper function for `getBlockInfoFromPos`, returns information regarding\n * provided blockContainer node.\n * @param blockContainer The blockContainer node to retrieve info for.\n */\nexport function getBlockInfo(blockContainer: Node): BlockInfoWithoutPositions {\n  const id = blockContainer.attrs[\"id\"];\n  const contentNode = blockContainer.firstChild!;\n  const contentType = contentNode.type;\n  const numChildBlocks =\n    blockContainer.childCount === 2 ? blockContainer.lastChild!.childCount : 0;\n\n  return {\n    id,\n    node: blockContainer,\n    contentNode,\n    contentType,\n    numChildBlocks,\n  };\n}\n\n/**\n * Retrieves information regarding the nearest blockContainer node in a\n * ProseMirror doc, relative to a position.\n * @param doc The ProseMirror doc.\n * @param pos An integer position.\n * @returns A BlockInfo object for the nearest blockContainer node.\n */\nexport function getBlockInfoFromPos(doc: Node, pos: number): BlockInfo {\n  // If the position is outside the outer block group, we need to move it to the\n  // nearest block. This happens when the collaboration plugin is active, where\n  // the selection is placed at the very end of the doc.\n  const outerBlockGroupStartPos = 1;\n  const outerBlockGroupEndPos = doc.nodeSize - 2;\n  if (pos <= outerBlockGroupStartPos) {\n    pos = outerBlockGroupStartPos + 1;\n\n    while (\n      doc.resolve(pos).parent.type.name !== \"blockContainer\" &&\n      pos < outerBlockGroupEndPos\n    ) {\n      pos++;\n    }\n  } else if (pos >= outerBlockGroupEndPos) {\n    pos = outerBlockGroupEndPos - 1;\n\n    while (\n      doc.resolve(pos).parent.type.name !== \"blockContainer\" &&\n      pos > outerBlockGroupStartPos\n    ) {\n      pos--;\n    }\n  }\n\n  // This gets triggered when a node selection on a block is active, i.e. when\n  // you drag and drop a block.\n  if (doc.resolve(pos).parent.type.name === \"blockGroup\") {\n    pos++;\n  }\n\n  const $pos = doc.resolve(pos);\n\n  const maxDepth = $pos.depth;\n  let node = $pos.node(maxDepth);\n  let depth = maxDepth;\n\n  // eslint-disable-next-line no-constant-condition\n  while (true) {\n    if (depth < 0) {\n      throw new Error(\n        \"Could not find blockContainer node. This can only happen if the underlying BlockNote schema has been edited.\"\n      );\n    }\n\n    if (node.type.name === \"blockContainer\") {\n      break;\n    }\n\n    depth -= 1;\n    node = $pos.node(depth);\n  }\n\n  const { id, contentNode, contentType, numChildBlocks } = getBlockInfo(node);\n\n  const startPos = $pos.start(depth);\n  const endPos = $pos.end(depth);\n\n  return {\n    id,\n    node,\n    contentNode,\n    contentType,\n    numChildBlocks,\n    startPos,\n    endPos,\n    depth,\n  };\n}\n","import { Node } from \"@tiptap/core\";\nimport { PropSchema, Props } from \"../propTypes\";\nimport { StyleSchema, Styles } from \"../styles/types\";\n\nexport type CustomInlineContentConfig = {\n  type: string;\n  content: \"styled\" | \"none\"; // | \"plain\"\n  readonly propSchema: PropSchema;\n  // content: \"inline\" | \"none\" | \"table\";\n};\n// InlineContentConfig contains the \"schema\" info about an InlineContent type\n// i.e. what props it supports, what content it supports, etc.\nexport type InlineContentConfig = CustomInlineContentConfig | \"text\" | \"link\";\n\n// InlineContentImplementation contains the \"implementation\" info about an InlineContent element\n// such as the functions / Nodes required to render and / or serialize it\n// @ts-ignore\nexport type InlineContentImplementation<T extends InlineContentConfig> =\n  T extends \"link\" | \"text\"\n    ? undefined\n    : {\n        node: Node;\n      };\n\n// Container for both the config and implementation of InlineContent,\n// and the type of `implementation` is based on that of the config\nexport type InlineContentSpec<T extends InlineContentConfig> = {\n  config: T;\n  implementation: InlineContentImplementation<T>;\n};\n\n// A Schema contains all the types (Configs) supported in an editor\n// The keys are the \"type\" of InlineContent elements\nexport type InlineContentSchema = Record<string, InlineContentConfig>;\n\nexport type InlineContentSpecs = {\n  text: { config: \"text\"; implementation: undefined };\n  link: { config: \"link\"; implementation: undefined };\n} & Record<string, InlineContentSpec<InlineContentConfig>>;\n\nexport type InlineContentSchemaFromSpecs<T extends InlineContentSpecs> = {\n  [K in keyof T]: T[K][\"config\"];\n};\n\nexport type CustomInlineContentFromConfig<\n  I extends CustomInlineContentConfig,\n  S extends StyleSchema\n> = {\n  type: I[\"type\"];\n  props: Props<I[\"propSchema\"]>;\n  content: I[\"content\"] extends \"styled\"\n    ? StyledText<S>[]\n    : I[\"content\"] extends \"plain\"\n    ? string\n    : I[\"content\"] extends \"none\"\n    ? undefined\n    : never;\n};\n\nexport type InlineContentFromConfig<\n  I extends InlineContentConfig,\n  S extends StyleSchema\n> = I extends \"text\"\n  ? StyledText<S>\n  : I extends \"link\"\n  ? Link<S>\n  : I extends CustomInlineContentConfig\n  ? CustomInlineContentFromConfig<I, S>\n  : never;\n\nexport type PartialCustomInlineContentFromConfig<\n  I extends CustomInlineContentConfig,\n  S extends StyleSchema\n> = {\n  type: I[\"type\"];\n  props?: Props<I[\"propSchema\"]>;\n  content: I[\"content\"] extends \"styled\"\n    ? StyledText<S>[] | string\n    : I[\"content\"] extends \"plain\"\n    ? string\n    : I[\"content\"] extends \"none\"\n    ? undefined\n    : never;\n};\n\nexport type PartialInlineContentFromConfig<\n  I extends InlineContentConfig,\n  S extends StyleSchema\n> = I extends \"text\"\n  ? string | StyledText<S>\n  : I extends \"link\"\n  ? PartialLink<S>\n  : I extends CustomInlineContentConfig\n  ? PartialCustomInlineContentFromConfig<I, S>\n  : never;\n\nexport type CustomContentProps = {\n  customContentProps?: {\n    [key: string]: any;\n  };\n};\n\nexport type StyledText<T extends StyleSchema> = {\n  type: \"text\";\n  text: string;\n  styles: Styles<T>;\n} & CustomContentProps;\n\n// export type StyledText = {\n//   type: \"text\";\n//   text: string;\n//   styles: Styles;\n// } & CustomContentProps;\n\nexport type Link<T extends StyleSchema> = {\n  type: \"link\";\n  href: string;\n  content: StyledText<T>[];\n};\n\nexport type PartialLink<T extends StyleSchema> = Omit<Link<T>, \"content\"> & {\n  content: string | Link<T>[\"content\"];\n};\n\nexport type InlineContent<\n  I extends InlineContentSchema,\n  T extends StyleSchema\n> = InlineContentFromConfig<I[keyof I], T>;\n\ntype PartialInlineContentElement<\n  I extends InlineContentSchema,\n  T extends StyleSchema\n> = PartialInlineContentFromConfig<I[keyof I], T>;\n\nexport type PartialInlineContent<\n  I extends InlineContentSchema,\n  T extends StyleSchema\n> = PartialInlineContentElement<I, T>[] | string;\n\nexport function isLinkInlineContent<T extends StyleSchema>(\n  content: InlineContent<any, T>\n): content is Link<T> {\n  return content.type === \"link\";\n}\n\nexport function isPartialLinkInlineContent<T extends StyleSchema>(\n  content: PartialInlineContentElement<any, T>\n): content is PartialLink<T> {\n  return typeof content !== \"string\" && content.type === \"link\";\n}\n\nexport function isStyledTextInlineContent<T extends StyleSchema>(\n  content: PartialInlineContentElement<any, T>\n): content is StyledText<T> {\n  return typeof content !== \"string\" && content.type === \"text\";\n}\n","export class UnreachableCaseError extends Error {\n    constructor(val: never) {\n        super(`Unreachable case: ${val}`);\n    }\n}","import { Mark, Node, Schema } from \"@tiptap/pm/model\";\n\nimport UniqueID from \"../../extensions/UniqueID/UniqueID\";\nimport type {\n  Block,\n  BlockSchema,\n  CustomContentProps,\n  CustomInlineContentConfig,\n  CustomInlineContentFromConfig,\n  InlineContent,\n  InlineContentFromConfig,\n  InlineContentSchema,\n  PartialBlock,\n  PartialCustomInlineContentFromConfig,\n  PartialInlineContent,\n  PartialLink,\n  PartialTableContent,\n  StyleSchema,\n  StyledText,\n  Styles,\n  TableContent,\n} from \"../../schema\";\nimport { getBlockInfo } from \"../getBlockInfoFromPos\";\n\nimport {\n  isLinkInlineContent,\n  isPartialLinkInlineContent,\n  isStyledTextInlineContent,\n} from \"../../schema/inlineContent/types\";\nimport { UnreachableCaseError } from \"../../util/typescript\";\n// import {\n//   ColorStyle,\n//   ToggledStyle,\n// } from \"../../extensions/Blocks/api/inlineContentTypes\";\n\nconst toggleStyles = new Set([\"bold\", \"italic\", \"underline\", \"strike\", \"code\"]);\nconst colorStyles = new Set([\"textColor\", \"backgroundColor\"]);\n\n/**\n * Convert a StyledText inline element to a\n * prosemirror text node with the appropriate marks\n */\nfunction styledTextToNodes<T extends StyleSchema>(\n  styledText: StyledText<T>,\n  schema: Schema,\n  styleSchema: T\n): Node[] {\n  const marks: Mark[] = [];\n\n  for (const [style, value] of Object.entries(styledText.styles)) {\n    const config = styleSchema[style];\n    if (!config) {\n      throw new Error(`style ${style} not found in styleSchema`);\n    }\n\n    if (config.propSchema === \"boolean\" && toggleStyles.has(style)) {\n      marks.push(schema.mark(style));\n    } else if (config.propSchema === \"string\" && colorStyles.has(style)) {\n      marks.push(schema.mark(style, { stringValue: value }));\n    } else {\n      throw new UnreachableCaseError(config.propSchema as never);\n    }\n  }\n\n  marks.push(\n    schema.mark(\"customContentProps\", {\n      customContentProps: styledText.customContentProps,\n    })\n  );\n\n  return (\n    styledText.text\n      // Splits text & line breaks.\n      .split(/(\\n)/g)\n      // If the content ends with a line break, an empty string is added to the\n      // end, which this removes.\n      .filter((text) => text.length > 0)\n      // Converts text & line breaks to nodes.\n      .map((text) => {\n        if (text === \"\\n\") {\n          return schema.nodes[\"hardBreak\"].create();\n        } else {\n          return schema.text(text, marks);\n        }\n      })\n  );\n}\n\n/**\n * Converts a Link inline content element to\n * prosemirror text nodes with the appropriate marks\n */\nfunction linkToNodes(\n  link: PartialLink<StyleSchema>,\n  schema: Schema,\n  styleSchema: StyleSchema\n): Node[] {\n  const linkMark = schema.marks.link.create({\n    href: link.href,\n  });\n\n  return styledTextArrayToNodes(link.content, schema, styleSchema).map(\n    (node) => {\n      if (node.type.name === \"text\") {\n        return node.mark([...node.marks, linkMark]);\n      }\n\n      if (node.type.name === \"hardBreak\") {\n        return node;\n      }\n      throw new Error(\"unexpected node type\");\n    }\n  );\n}\n\n/**\n * Converts an array of StyledText inline content elements to\n * prosemirror text nodes with the appropriate marks\n */\nfunction styledTextArrayToNodes<S extends StyleSchema>(\n  content: string | StyledText<S>[],\n  schema: Schema,\n  styleSchema: S\n): Node[] {\n  const nodes: Node[] = [];\n\n  if (typeof content === \"string\") {\n    nodes.push(\n      ...styledTextToNodes(\n        { type: \"text\", text: content, styles: {} },\n        schema,\n        styleSchema\n      )\n    );\n    return nodes;\n  }\n\n  for (const styledText of content) {\n    nodes.push(...styledTextToNodes(styledText, schema, styleSchema));\n  }\n  return nodes;\n}\n\n/**\n * converts an array of inline content elements to prosemirror nodes\n */\nexport function inlineContentToNodes<\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  blockContent: PartialInlineContent<I, S>,\n  schema: Schema,\n  styleSchema: S\n): Node[] {\n  const nodes: Node[] = [];\n\n  for (const content of blockContent) {\n    if (typeof content === \"string\") {\n      nodes.push(...styledTextArrayToNodes(content, schema, styleSchema));\n    } else if (isPartialLinkInlineContent(content)) {\n      nodes.push(...linkToNodes(content, schema, styleSchema));\n    } else if (isStyledTextInlineContent(content)) {\n      nodes.push(...styledTextArrayToNodes([content], schema, styleSchema));\n    } else {\n      nodes.push(\n        blockOrInlineContentToContentNode(content, schema, styleSchema)\n      );\n    }\n  }\n  return nodes;\n}\n\n/**\n * converts an array of inline content elements to prosemirror nodes\n */\nexport function tableContentToNodes<\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  tableContent: PartialTableContent<I, S>,\n  schema: Schema,\n  styleSchema: StyleSchema\n): Node[] {\n  const rowNodes: Node[] = [];\n\n  for (const row of tableContent.rows) {\n    const columnNodes: Node[] = [];\n    for (const cell of row.cells) {\n      let pNode: Node;\n      if (!cell) {\n        pNode = schema.nodes[\"tableParagraph\"].create({});\n      } else if (typeof cell === \"string\") {\n        pNode = schema.nodes[\"tableParagraph\"].create({}, schema.text(cell));\n      } else {\n        const textNodes = inlineContentToNodes(cell, schema, styleSchema);\n        pNode = schema.nodes[\"tableParagraph\"].create({}, textNodes);\n      }\n\n      const cellNode = schema.nodes[\"tableCell\"].create({}, pNode);\n      columnNodes.push(cellNode);\n    }\n    const rowNode = schema.nodes[\"tableRow\"].create({}, columnNodes);\n    rowNodes.push(rowNode);\n  }\n  return rowNodes;\n}\n\nfunction blockOrInlineContentToContentNode(\n  block:\n    | PartialBlock<any, any, any>\n    | PartialCustomInlineContentFromConfig<any, any>,\n  schema: Schema,\n  styleSchema: StyleSchema\n) {\n  let contentNode: Node;\n  let type = block.type;\n\n  // TODO: needed? came from previous code\n  if (type === undefined) {\n    type = \"paragraph\";\n  }\n\n  if (!schema.nodes[type]) {\n    throw new Error(`node type ${type} not found in schema`);\n  }\n\n  if (!block.content) {\n    contentNode = schema.nodes[type].create({\n      ...block.props,\n    });\n  } else if (typeof block.content === \"string\") {\n    contentNode = schema.nodes[type].create(\n      { ...block.props },\n      schema.text(block.content)\n    );\n    // <<<<<<< HEAD\n    //   } else {\n    //     const nodes = inlineContentToNodes(block.content, schema);\n    //     contentNode = schema.nodes[type].create(\n    //       { ...block.props, customProps: block.customProps },\n    //       nodes\n    //     );\n    // =======\n  } else if (Array.isArray(block.content)) {\n    const nodes = inlineContentToNodes(block.content, schema, styleSchema);\n    contentNode = schema.nodes[type].create(block.props, nodes);\n  } else if (block.content.type === \"tableContent\") {\n    const nodes = tableContentToNodes(block.content, schema, styleSchema);\n    contentNode = schema.nodes[type].create(block.props, nodes);\n  } else {\n    throw new UnreachableCaseError(block.content.type);\n  }\n  return contentNode;\n}\n/**\n * Converts a BlockNote block to a TipTap node.\n */\nexport function blockToNode(\n  block: PartialBlock<any, any, any>,\n  schema: Schema,\n  styleSchema: StyleSchema\n) {\n  let id = block.id;\n\n  if (id === undefined) {\n    id = UniqueID.options.generateID();\n  }\n\n  const contentNode = blockOrInlineContentToContentNode(\n    block,\n    schema,\n    styleSchema\n  );\n\n  const children: Node[] = [];\n\n  if (block.children) {\n    for (const child of block.children) {\n      children.push(blockToNode(child, schema, styleSchema));\n    }\n  }\n\n  const groupNode = schema.nodes[\"blockGroup\"].create({}, children);\n\n  const blockContainer = schema.nodes[\"blockContainer\"].create(\n    {\n      id: id,\n      ...block.props,\n    },\n    children.length > 0 ? [contentNode, groupNode] : contentNode\n  );\n\n  return blockContainer;\n}\n\n/**\n * Converts an internal (prosemirror) table node contentto a BlockNote Tablecontent\n */\nfunction contentNodeToTableContent<\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(contentNode: Node, inlineContentSchema: I, styleSchema: S) {\n  const ret: TableContent<I, S> = {\n    type: \"tableContent\",\n    rows: [],\n  };\n\n  contentNode.content.forEach((rowNode) => {\n    const row: TableContent<I, S>[\"rows\"][0] = {\n      cells: [],\n    };\n\n    rowNode.content.forEach((cellNode) => {\n      row.cells.push(\n        contentNodeToInlineContent(\n          cellNode.firstChild!,\n          inlineContentSchema,\n          styleSchema\n        )\n      );\n    });\n\n    ret.rows.push(row);\n  });\n\n  return ret;\n}\n\n/**\n * Converts an internal (prosemirror) content node to a BlockNote InlineContent array.\n */\nexport function contentNodeToInlineContent<\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(contentNode: Node, inlineContentSchema: I, styleSchema: S) {\n  const content: InlineContent<any, S>[] = [];\n  let currentContent: InlineContent<any, S> | undefined = undefined;\n\n  // Most of the logic below is for handling links because in ProseMirror links are marks\n  // while in BlockNote links are a type of inline content\n  let customContentProps: any;\n\n  contentNode.content.forEach((node) => {\n    // hardBreak nodes do not have an InlineContent equivalent, instead we\n    // add a newline to the previous node.\n    if (node.type.name === \"hardBreak\") {\n      if (currentContent) {\n        // Current content exists.\n        if (isStyledTextInlineContent(currentContent)) {\n          // Current content is text.\n          currentContent.text += \"\\n\";\n        } else if (isLinkInlineContent(currentContent)) {\n          // Current content is a link.\n          currentContent.content[currentContent.content.length - 1].text +=\n            \"\\n\";\n        } else {\n          throw new Error(\"unexpected\");\n        }\n      } else {\n        // Current content does not exist.\n        currentContent = {\n          type: \"text\",\n          text: \"\\n\",\n          styles: {},\n        };\n      }\n\n      return;\n    }\n\n    if (\n      node.type.name !== \"link\" &&\n      node.type.name !== \"text\" &&\n      inlineContentSchema[node.type.name]\n    ) {\n      if (currentContent) {\n        content.push(currentContent);\n        currentContent = undefined;\n      }\n\n      content.push(\n        nodeToCustomInlineContent(node, inlineContentSchema, styleSchema)\n      );\n\n      return;\n    }\n\n    const styles: Styles<S> = {};\n    let linkMark: Mark | undefined;\n\n    for (const mark of node.marks) {\n      if (mark.type.name === \"link\") {\n        linkMark = mark;\n      } else if (mark.type.name === \"customContentProps\") {\n        customContentProps = mark.attrs.customContentProps;\n      } else {\n        const config = styleSchema[mark.type.name];\n        if (!config) {\n          throw new Error(`style ${mark.type.name} not found in styleSchema`);\n        }\n        if (config.propSchema === \"boolean\") {\n          (styles as any)[config.type] = true;\n        } else if (config.propSchema === \"string\") {\n          (styles as any)[config.type] = mark.attrs.stringValue;\n        } else {\n          throw new UnreachableCaseError(config.propSchema);\n        }\n      }\n    }\n\n    // Parsing links and text.\n    // Current content exists.\n    if (currentContent) {\n      // Current content is text.\n      if (isStyledTextInlineContent(currentContent)) {\n        if (!linkMark) {\n          // Node is text (same type as current content).\n          if (\n            JSON.stringify(currentContent.styles) === JSON.stringify(styles)\n          ) {\n            // Styles are the same.\n            currentContent.text += node.textContent;\n          } else {\n            // Styles are different.\n            content.push(currentContent);\n            currentContent = {\n              type: \"text\",\n              text: node.textContent,\n              styles,\n            };\n          }\n        } else {\n          // Node is a link (different type to current content).\n          content.push(currentContent);\n          currentContent = {\n            type: \"link\",\n            href: linkMark.attrs.href,\n            content: [\n              {\n                type: \"text\",\n                text: node.textContent,\n                styles,\n              },\n            ],\n          };\n        }\n      } else if (isLinkInlineContent(currentContent)) {\n        // Current content is a link.\n        if (linkMark) {\n          // Node is a link (same type as current content).\n          // Link URLs are the same.\n          if (currentContent.href === linkMark.attrs.href) {\n            // Styles are the same.\n            if (\n              JSON.stringify(\n                currentContent.content[currentContent.content.length - 1].styles\n              ) === JSON.stringify(styles)\n            ) {\n              currentContent.content[currentContent.content.length - 1].text +=\n                node.textContent;\n            } else {\n              // Styles are different.\n              currentContent.content.push({\n                type: \"text\",\n                text: node.textContent,\n                styles,\n              });\n            }\n          } else {\n            // Link URLs are different.\n            content.push(currentContent);\n            currentContent = {\n              type: \"link\",\n              href: linkMark.attrs.href,\n              content: [\n                {\n                  type: \"text\",\n                  text: node.textContent,\n                  styles,\n                },\n              ],\n            };\n          }\n        } else {\n          // Node is text (different type to current content).\n          content.push(currentContent);\n          currentContent = {\n            type: \"text\",\n            text: node.textContent,\n            styles,\n          };\n        }\n      } else {\n        // TODO\n      }\n    }\n    // Current content does not exist.\n    else {\n      // Node is text.\n      if (!linkMark) {\n        currentContent = {\n          type: \"text\",\n          text: node.textContent,\n          styles,\n        };\n\n        currentContent.customContentProps = customContentProps;\n      }\n      // Node is a link.\n      else {\n        currentContent = {\n          type: \"link\",\n          href: linkMark.attrs.href,\n          content: [\n            {\n              type: \"text\",\n              text: node.textContent,\n              styles,\n            },\n          ],\n        };\n      }\n    }\n  });\n\n  if (currentContent) {\n    (\n      currentContent as InlineContent<I, S> & CustomContentProps\n    ).customContentProps = customContentProps;\n\n    content.push(currentContent);\n  }\n\n  return content as InlineContent<I, S>[];\n}\n\nexport function nodeToCustomInlineContent<\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(node: Node, inlineContentSchema: I, styleSchema: S): InlineContent<I, S> {\n  if (node.type.name === \"text\" || node.type.name === \"link\") {\n    throw new Error(\"unexpected\");\n  }\n  const props: any = {};\n  const icConfig = inlineContentSchema[\n    node.type.name\n  ] as CustomInlineContentConfig;\n  for (const [attr, value] of Object.entries(node.attrs)) {\n    if (!icConfig) {\n      throw Error(\"ic node is of an unrecognized type: \" + node.type.name);\n    }\n\n    const propSchema = icConfig.propSchema;\n\n    if (attr in propSchema) {\n      props[attr] = value;\n    }\n  }\n\n  let content: CustomInlineContentFromConfig<any, any>[\"content\"];\n\n  if (icConfig.content === \"styled\") {\n    content = contentNodeToInlineContent(\n      node,\n      inlineContentSchema,\n      styleSchema\n    ) as any; // TODO: is this safe? could we have Links here that are undesired?\n  } else {\n    content = undefined;\n  }\n\n  const ic = {\n    type: node.type.name,\n    props,\n    content,\n  } as InlineContentFromConfig<I[keyof I], S>;\n  return ic;\n}\n\n/**\n * Convert a TipTap node to a BlockNote block.\n */\nexport function nodeToBlock<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  node: Node,\n  blockSchema: BSchema,\n  inlineContentSchema: I,\n  styleSchema: S,\n  blockCache?: WeakMap<Node, Block<BSchema, I, S>>\n): Block<BSchema, I, S> {\n  if (node.type.name !== \"blockContainer\") {\n    throw Error(\n      \"Node must be of type blockContainer, but is of type\" +\n        node.type.name +\n        \".\"\n    );\n  }\n\n  const cachedBlock = blockCache?.get(node);\n\n  if (cachedBlock) {\n    return cachedBlock;\n  }\n\n  const blockInfo = getBlockInfo(node);\n\n  let id = blockInfo.id;\n\n  // Only used for blocks converted from other formats.\n  if (id === null) {\n    id = UniqueID.options.generateID();\n  }\n\n  const props: any = {};\n  for (const [attr, value] of Object.entries({\n    ...node.attrs,\n    ...blockInfo.contentNode.attrs,\n  })) {\n    const blockSpec = blockSchema[blockInfo.contentType.name];\n\n    if (!blockSpec) {\n      throw Error(\n        \"Block is of an unrecognized type: \" + blockInfo.contentType.name\n      );\n    }\n\n    const propSchema = blockSpec.propSchema;\n\n    if (attr in propSchema) {\n      props[attr] = value;\n    }\n    // <<<<<<< HEAD\n    //     // Block ids are stored as node attributes the same way props are, so we\n    //     // need to ensure we don't attempt to read block ids as props.\n\n    //     // the second check is for the backgroundColor & textColor props.\n    //     // Since we want them to be inherited by child blocks, we can't put them on the blockContent node,\n    //     // and instead have to put them on the blockContainer node.\n    //     // The blockContainer node is the same for all block types, but some custom blocks might not use backgroundColor & textColor,\n    //     // so these 2 props are technically unexpected but we shouldn't log a warning.\n    //     // (this is a bit hacky)\n    //     else if (\n    //       attr !== \"id\" &&\n    //       attr !== \"customProps\" &&\n    //       !(attr in defaultProps)\n    //     ) {\n    //       console.warn(\"Block has an unrecognized attribute: \" + attr);\n    //     }\n    // =======\n    // >>>>>>> upstream/main\n  }\n\n  const blockConfig = blockSchema[blockInfo.contentType.name];\n\n  const children: Block<BSchema, I, S>[] = [];\n  for (let i = 0; i < blockInfo.numChildBlocks; i++) {\n    children.push(\n      nodeToBlock(\n        node.lastChild!.child(i),\n        blockSchema,\n        inlineContentSchema,\n        styleSchema,\n        blockCache\n      )\n    );\n  }\n\n  let content: Block<any, any, any>[\"content\"];\n\n  if (blockConfig.content === \"inline\") {\n    content = contentNodeToInlineContent(\n      blockInfo.contentNode,\n      inlineContentSchema,\n      styleSchema\n    );\n  } else if (blockConfig.content === \"table\") {\n    content = contentNodeToTableContent(\n      blockInfo.contentNode,\n      inlineContentSchema,\n      styleSchema\n    );\n  } else if (blockConfig.content === \"none\") {\n    content = undefined;\n  } else {\n    throw new UnreachableCaseError(blockConfig.content);\n  }\n\n  const block = {\n    id,\n    type: blockConfig.type,\n    props,\n    // customProps: node.attrs.customProps,\n    content,\n    children,\n  } as Block<BSchema, I, S>;\n\n  blockCache?.set(node, block);\n\n  return block;\n}\n","import { DOMSerializer, Fragment, Node } from \"prosemirror-model\";\n\nimport type { BlockNoteEditor } from \"../../../../editor/BlockNoteEditor\";\nimport {\n  BlockSchema,\n  InlineContentSchema,\n  StyleSchema,\n} from \"../../../../schema\";\nimport { nodeToBlock } from \"../../../nodeConversions/nodeConversions\";\n\nfunction doc(options: { document?: Document }) {\n  return options.document || window.document;\n}\n\n// Used to implement `serializeNodeInner` for the `internalHTMLSerializer` and\n// `externalHTMLExporter`. Changes how the content of `blockContainer` nodes is\n// serialized vs the default `DOMSerializer` implementation. For the\n// `blockContent` node, the `toInternalHTML` or `toExternalHTML` function of its\n// corresponding block is used for serialization instead of the node's\n// `renderHTML` method.\nexport const serializeNodeInner = <\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  node: Node,\n  options: { document?: Document },\n  serializer: DOMSerializer,\n  editor: BlockNoteEditor<BSchema, I, S>,\n  toExternalHTML: boolean\n) => {\n  if (!serializer.nodes[node.type.name]) {\n    throw new Error(\"Serializer is missing a node type: \" + node.type.name);\n  }\n  const { dom, contentDOM } = DOMSerializer.renderSpec(\n    doc(options),\n    serializer.nodes[node.type.name](node)\n  );\n\n  if (contentDOM) {\n    if (node.isLeaf) {\n      throw new RangeError(\"Content hole not allowed in a leaf node spec\");\n    }\n\n    // Handles converting `blockContainer` nodes to HTML.\n    if (node.type.name === \"blockContainer\") {\n      const blockContentNode =\n        node.childCount > 0 &&\n        node.firstChild!.type.spec.group === \"blockContent\"\n          ? node.firstChild!\n          : undefined;\n      const blockGroupNode =\n        node.childCount > 0 && node.lastChild!.type.spec.group === \"blockGroup\"\n          ? node.lastChild!\n          : undefined;\n\n      // Converts `blockContent` node using the custom `blockSpec`'s\n      // `toExternalHTML` or `toInternalHTML` function.\n      // Note: While `blockContainer` nodes should always contain a\n      // `blockContent` node according to the schema, PM Fragments don't always\n      // conform to the schema. This is unintuitive but important as it occurs\n      // when copying only nested blocks.\n      if (blockContentNode !== undefined) {\n        const impl =\n          editor.blockImplementations[blockContentNode.type.name]\n            .implementation;\n        const toHTML = toExternalHTML\n          ? impl.toExternalHTML\n          : impl.toInternalHTML;\n        const blockContent = toHTML(\n          nodeToBlock(\n            node,\n            editor.blockSchema,\n            editor.inlineContentSchema,\n            editor.styleSchema,\n            editor.blockCache\n          ),\n          editor as any\n        );\n\n        // Converts inline nodes in the `blockContent` node's content to HTML\n        // using their `renderHTML` methods.\n        if (blockContent.contentDOM !== undefined) {\n          if (node.isLeaf) {\n            throw new RangeError(\n              \"Content hole not allowed in a leaf node spec\"\n            );\n          }\n\n          blockContent.contentDOM.appendChild(\n            serializer.serializeFragment(blockContentNode.content, options)\n          );\n        }\n\n        contentDOM.appendChild(blockContent.dom);\n      }\n\n      // Converts `blockGroup` node to HTML using its `renderHTML` method.\n      if (blockGroupNode !== undefined) {\n        serializer.serializeFragment(\n          Fragment.from(blockGroupNode),\n          options,\n          contentDOM\n        );\n      }\n    } else {\n      // Converts the node normally, i.e. using its `renderHTML method`.\n      serializer.serializeFragment(node.content, options, contentDOM);\n    }\n  }\n\n  return dom as HTMLElement;\n};\n\n// Used to implement `serializeProseMirrorFragment` for the\n// `internalHTMLSerializer` and `externalHTMLExporter`. Does basically the same\n// thing as `serializer.serializeFragment`, but takes fewer arguments and\n// returns a string instead, to make it easier to use.\nexport const serializeProseMirrorFragment = (\n  fragment: Fragment,\n  serializer: DOMSerializer\n) => {\n  const internalHTML = serializer.serializeFragment(fragment);\n  const parent = document.createElement(\"div\");\n  parent.appendChild(internalHTML);\n\n  return parent.innerHTML;\n};\n","import { Element as HASTElement, Parent as HASTParent } from \"hast\";\nimport { fromDom } from \"hast-util-from-dom\";\n\ntype SimplifyBlocksOptions = {\n  orderedListItemBlockTypes: Set<string>;\n  unorderedListItemBlockTypes: Set<string>;\n};\n\n/**\n * Rehype plugin which converts the HTML output string rendered by BlockNote into a simplified structure which better\n * follows HTML standards. It does several things:\n * - Removes all block related div elements, leaving only the actual content inside the block.\n * - Lifts nested blocks to a higher level for all block types that don't represent list items.\n * - Wraps blocks which represent list items in corresponding ul/ol HTML elements and restructures them to comply\n * with HTML list structure.\n * @param options Options for specifying which block types represent ordered and unordered list items.\n */\nexport function simplifyBlocks(options: SimplifyBlocksOptions) {\n  const listItemBlockTypes = new Set<string>([\n    ...options.orderedListItemBlockTypes,\n    ...options.unorderedListItemBlockTypes,\n  ]);\n\n  const simplifyBlocksHelper = (tree: HASTParent) => {\n    // Checks whether blocks in the tree are wrapped by a parent `blockGroup`\n    // element, in which case the `blockGroup`'s children are lifted out, and it\n    // is removed.\n    if (\n      tree.children.length === 1 &&\n      (tree.children[0] as HASTElement).properties?.[\"dataNodeType\"] ===\n        \"blockGroup\"\n    ) {\n      const blockGroup = tree.children[0] as HASTElement;\n      tree.children.pop();\n      tree.children.push(...blockGroup.children);\n    }\n\n    let numChildElements = tree.children.length;\n    let activeList: HASTElement | undefined;\n\n    for (let i = 0; i < numChildElements; i++) {\n      const blockOuter = tree.children[i] as HASTElement;\n      const blockContainer = blockOuter.children[0] as HASTElement;\n      const blockContent = blockContainer.children[0] as HASTElement;\n      const blockGroup =\n        blockContainer.children.length === 2\n          ? (blockContainer.children[1] as HASTElement)\n          : null;\n\n      const isListItemBlock = listItemBlockTypes.has(\n        blockContent.properties![\"dataContentType\"] as string\n      );\n\n      const listItemBlockType = isListItemBlock\n        ? options.orderedListItemBlockTypes.has(\n            blockContent.properties![\"dataContentType\"] as string\n          )\n          ? \"ol\"\n          : \"ul\"\n        : null;\n\n      // Plugin runs recursively to process nested blocks.\n      if (blockGroup !== null) {\n        simplifyBlocksHelper(blockGroup);\n      }\n\n      // Checks that there is an active list, but the block can't be added to it as it's of a different type.\n      if (activeList && activeList.tagName !== listItemBlockType) {\n        // Blocks that were copied into the list are removed and the list is inserted in their place.\n        tree.children.splice(\n          i - activeList.children.length,\n          activeList.children.length,\n          activeList\n        );\n\n        // Updates the current index and number of child elements.\n        const numElementsRemoved = activeList.children.length - 1;\n        i -= numElementsRemoved;\n        numChildElements -= numElementsRemoved;\n\n        activeList = undefined;\n      }\n\n      // Checks if the block represents a list item.\n      if (isListItemBlock) {\n        // Checks if a list isn't already active. We don't have to check if the block and the list are of the same\n        // type as this was already done earlier.\n        if (!activeList) {\n          // Creates a new list element to represent an active list.\n          activeList = fromDom(\n            document.createElement(listItemBlockType!)\n          ) as HASTElement;\n        }\n\n        // Creates a new list item element to represent the block.\n        const listItemElement = fromDom(\n          document.createElement(\"li\")\n        ) as HASTElement;\n\n        // Adds only the content inside the block to the active list.\n        listItemElement.children.push(blockContent.children[0]);\n        // Nested blocks have already been processed in the recursive function call, so the resulting elements are\n        // also added to the active list.\n        if (blockGroup !== null) {\n          listItemElement.children.push(...blockGroup.children);\n        }\n\n        // Adds the list item representing the block to the active list.\n        activeList.children.push(listItemElement);\n      } else if (blockGroup !== null) {\n        // Lifts all children out of the current block, as only list items should allow nesting.\n        tree.children.splice(i + 1, 0, ...blockGroup.children);\n        // Replaces the block with only the content inside it.\n        tree.children[i] = blockContent.children[0];\n\n        // Updates the current index and number of child elements.\n        const numElementsAdded = blockGroup.children.length;\n        i += numElementsAdded;\n        numChildElements += numElementsAdded;\n      } else {\n        // Replaces the block with only the content inside it.\n        tree.children[i] = blockContent.children[0];\n      }\n    }\n\n    // Since the active list is only inserted after encountering a block which can't be added to it, there are cases\n    // where it remains un-inserted after processing all blocks, which are handled here.\n    if (activeList) {\n      tree.children.splice(\n        numChildElements - activeList.children.length,\n        activeList.children.length,\n        activeList\n      );\n    }\n  };\n\n  return simplifyBlocksHelper;\n}\n","import { DOMSerializer, Fragment, Node, Schema } from \"prosemirror-model\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeStringify from \"rehype-stringify\";\nimport { unified } from \"unified\";\n\nimport type { BlockNoteEditor } from \"../../../editor/BlockNoteEditor\";\nimport {\n  BlockSchema,\n  InlineContentSchema,\n  PartialBlock,\n  StyleSchema,\n} from \"../../../schema\";\nimport { blockToNode } from \"../../nodeConversions/nodeConversions\";\nimport {\n  serializeNodeInner,\n  serializeProseMirrorFragment,\n} from \"./util/sharedHTMLConversion\";\nimport { simplifyBlocks } from \"./util/simplifyBlocksRehypePlugin\";\n\n// Used to export BlockNote blocks and ProseMirror nodes to HTML for use outside\n// the editor. Blocks are exported using the `toExternalHTML` method in their\n// `blockSpec`, or `toInternalHTML` if `toExternalHTML` is not defined.\n//\n// The HTML created by this serializer is different to what's rendered by the\n// editor to the DOM. This also means that data is likely to be lost when\n// converting back to original blocks. The differences in the output HTML are:\n// 1. It doesn't include the `blockGroup` and `blockContainer` wrappers meaning\n// that nesting is not preserved for non-list-item blocks.\n// 2. `li` items in the output HTML are wrapped in `ul` or `ol` elements.\n// 3. While nesting for list items is preserved, other types of blocks nested\n// inside a list are un-nested and a new list is created after them.\n// 4. The HTML is wrapped in a single `div` element.\n//\n// The serializer has 2 main methods:\n// `exportBlocks`: Exports an array of blocks to HTML.\n// `exportFragment`: Exports a ProseMirror fragment to HTML. This is mostly\n// useful if you want to export a selection which may not start/end at the\n// start/end of a block.\nexport interface ExternalHTMLExporter<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> {\n  exportBlocks: (blocks: PartialBlock<BSchema, I, S>[]) => string;\n  exportProseMirrorFragment: (fragment: Fragment) => string;\n}\n\nexport const createExternalHTMLExporter = <\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  schema: Schema,\n  editor: BlockNoteEditor<BSchema, I, S>\n): ExternalHTMLExporter<BSchema, I, S> => {\n  const serializer = DOMSerializer.fromSchema(schema) as DOMSerializer & {\n    serializeNodeInner: (\n      node: Node,\n      options: { document?: Document }\n    ) => HTMLElement;\n    // TODO: Should not be async, but is since we're using a rehype plugin to\n    //  convert internal HTML to external HTML.\n    exportProseMirrorFragment: (fragment: Fragment) => string;\n    exportBlocks: (blocks: PartialBlock<BSchema, I, S>[]) => string;\n  };\n\n  serializer.serializeNodeInner = (\n    node: Node,\n    options: { document?: Document }\n  ) => serializeNodeInner(node, options, serializer, editor, true);\n\n  // Like the `internalHTMLSerializer`, also uses `serializeProseMirrorFragment`\n  // but additionally runs it through the `simplifyBlocks` rehype plugin to\n  // convert the internal HTML to external.\n  serializer.exportProseMirrorFragment = (fragment) => {\n    const externalHTML = unified()\n      .use(rehypeParse, { fragment: true })\n      .use(simplifyBlocks, {\n        orderedListItemBlockTypes: new Set<string>([\"numberedListItem\"]),\n        unorderedListItemBlockTypes: new Set<string>([\"bulletListItem\"]),\n      })\n      .use(rehypeStringify)\n      .processSync(serializeProseMirrorFragment(fragment, serializer));\n\n    return externalHTML.value as string;\n  };\n\n  serializer.exportBlocks = (blocks: PartialBlock<BSchema, I, S>[]) => {\n    const nodes = blocks.map((block) =>\n      blockToNode(block, schema, editor.styleSchema)\n    );\n    const blockGroup = schema.nodes[\"blockGroup\"].create(null, nodes);\n\n    return serializer.exportProseMirrorFragment(Fragment.from(blockGroup));\n  };\n\n  return serializer;\n};\n","import { DOMSerializer, Fragment, Node, Schema } from \"prosemirror-model\";\nimport type { BlockNoteEditor } from \"../../../editor/BlockNoteEditor\";\nimport {\n  BlockSchema,\n  InlineContentSchema,\n  PartialBlock,\n  StyleSchema,\n} from \"../../../schema\";\nimport { blockToNode } from \"../../nodeConversions/nodeConversions\";\nimport {\n  serializeNodeInner,\n  serializeProseMirrorFragment,\n} from \"./util/sharedHTMLConversion\";\n\n// Used to serialize BlockNote blocks and ProseMirror nodes to HTML without\n// losing data. Blocks are exported using the `toInternalHTML` method in their\n// `blockSpec`.\n//\n// The HTML created by this serializer is the same as what's rendered by the\n// editor to the DOM. This means that it retains the same structure as the\n// editor, including the `blockGroup` and `blockContainer` wrappers. This also\n// means that it can be converted back to the original blocks without any data\n// loss.\n//\n// The serializer has 2 main methods:\n// `serializeFragment`: Serializes a ProseMirror fragment to HTML. This is\n// mostly useful if you want to serialize a selection which may not start/end at\n// the start/end of a block.\n// `serializeBlocks`: Serializes an array of blocks to HTML.\nexport interface InternalHTMLSerializer<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> {\n  // TODO: Ideally we would expand the BlockNote API to support partial\n  //  selections so we don't need this.\n  serializeProseMirrorFragment: (fragment: Fragment) => string;\n  serializeBlocks: (blocks: PartialBlock<BSchema, I, S>[]) => string;\n}\n\nexport const createInternalHTMLSerializer = <\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  schema: Schema,\n  editor: BlockNoteEditor<BSchema, I, S>\n): InternalHTMLSerializer<BSchema, I, S> => {\n  const serializer = DOMSerializer.fromSchema(schema) as DOMSerializer & {\n    serializeNodeInner: (\n      node: Node,\n      options: { document?: Document }\n    ) => HTMLElement;\n    serializeBlocks: (blocks: PartialBlock<BSchema, I, S>[]) => string;\n    serializeProseMirrorFragment: (\n      fragment: Fragment,\n      options?: { document?: Document | undefined } | undefined,\n      target?: HTMLElement | DocumentFragment | undefined\n    ) => string;\n  };\n\n  serializer.serializeNodeInner = (\n    node: Node,\n    options: { document?: Document }\n  ) => serializeNodeInner(node, options, serializer, editor, false);\n\n  serializer.serializeProseMirrorFragment = (fragment: Fragment) =>\n    serializeProseMirrorFragment(fragment, serializer);\n\n  serializer.serializeBlocks = (blocks: PartialBlock<BSchema, I, S>[]) => {\n    const nodes = blocks.map((block) =>\n      blockToNode(block, schema, editor.styleSchema)\n    );\n    const blockGroup = schema.nodes[\"blockGroup\"].create(null, nodes);\n\n    return serializer.serializeProseMirrorFragment(Fragment.from(blockGroup));\n  };\n\n  return serializer;\n};\n","export const uploadToTmpFilesDotOrg_DEV_ONLY = async (file: File) => {\n  const body = new FormData();\n  body.append(\"file\", file);\n\n  const ret = await fetch(\"https://tmpfiles.org/api/v1/upload\", {\n    method: \"POST\",\n    body: body,\n  });\n  return (await ret.json()).data.url.replace(\n    \"tmpfiles.org/\",\n    \"tmpfiles.org/dl/\"\n  );\n};\n","export const isAppleOS = () =>\n    typeof navigator !== \"undefined\" &&\n    (/Mac/.test(navigator.platform) ||\n        (/AppleWebKit/.test(navigator.userAgent) &&\n            /Mobile\\/\\w+/.test(navigator.userAgent)));\n\nexport function formatKeyboardShortcut(shortcut: string) {\n  if (isAppleOS()) {\n    return shortcut.replace(\"Mod\", \"⌘\");\n  } else {\n    return shortcut.replace(\"Mod\", \"Ctrl\");\n  }\n}\n\nexport function mergeCSSClasses(...classes: string[]) {\n  return classes.filter((c) => c).join(\" \");\n}\n\n","import { blockToNode } from \"../api/nodeConversions/nodeConversions\";\nimport type { BlockNoteEditor } from \"../editor/BlockNoteEditor\";\nimport type {\n  Block,\n  BlockSchema,\n  InlineContentSchema,\n  StyleSchema,\n} from \"../schema\";\nimport { mergeCSSClasses } from \"../util/browser\";\n\n// Function that creates a ProseMirror `DOMOutputSpec` for a default block.\n// Since all default blocks have the same structure (`blockContent` div with a\n// `inlineContent` element inside), this function only needs the block's name\n// for the `data-content-type` attribute of the `blockContent` element and the\n// HTML tag of the `inlineContent` element, as well as any HTML attributes to\n// add to those.\nexport function createDefaultBlockDOMOutputSpec(\n  blockName: string,\n  htmlTag: string,\n  blockContentHTMLAttributes: Record<string, string>,\n  inlineContentHTMLAttributes: Record<string, string>\n) {\n  const blockContent = document.createElement(\"div\");\n  blockContent.className = mergeCSSClasses(\n    \"bn-block-content\",\n    blockContentHTMLAttributes.class\n  );\n  blockContent.setAttribute(\"data-content-type\", blockName);\n  for (const [attribute, value] of Object.entries(blockContentHTMLAttributes)) {\n    if (attribute !== \"class\") {\n      blockContent.setAttribute(attribute, value);\n    }\n  }\n\n  const inlineContent = document.createElement(htmlTag);\n  inlineContent.className = mergeCSSClasses(\n    \"bn-inline-content\",\n    inlineContentHTMLAttributes.class\n  );\n  for (const [attribute, value] of Object.entries(\n    inlineContentHTMLAttributes\n  )) {\n    if (attribute !== \"class\") {\n      inlineContent.setAttribute(attribute, value);\n    }\n  }\n\n  blockContent.appendChild(inlineContent);\n\n  return {\n    dom: blockContent,\n    contentDOM: inlineContent,\n  };\n}\n\n// Function used to convert default blocks to HTML. It uses the corresponding\n// node's `renderHTML` method to do the conversion by using a default\n// `DOMSerializer`.\nexport const defaultBlockToHTML = <\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  block: Block<BSchema, I, S>,\n  editor: BlockNoteEditor<BSchema, I, S>\n): {\n  dom: HTMLElement;\n  contentDOM?: HTMLElement;\n} => {\n  const node = blockToNode(\n    block,\n    editor._tiptapEditor.schema,\n    editor.styleSchema\n  ).firstChild!;\n  const toDOM = editor._tiptapEditor.schema.nodes[node.type.name].spec.toDOM;\n\n  if (toDOM === undefined) {\n    throw new Error(\n      \"This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.\"\n    );\n  }\n\n  const renderSpec = toDOM(node);\n\n  if (typeof renderSpec !== \"object\" || !(\"dom\" in renderSpec)) {\n    throw new Error(\n      \"Cannot use this block's default HTML serialization as its corresponding TipTap node's `renderHTML` function does not return an object with the `dom` property.\"\n    );\n  }\n\n  return renderSpec as {\n    dom: HTMLElement;\n    contentDOM?: HTMLElement;\n  };\n};\n","import type { Props, PropSchema } from \"../schema\";\n\n// TODO: this system should probably be moved / refactored.\n// The dependency from schema on this file doesn't make sense\n\nexport const defaultProps = {\n  backgroundColor: {\n    default: \"default\" as const,\n  },\n  textColor: {\n    default: \"default\" as const,\n  },\n  textAlignment: {\n    default: \"left\" as const,\n    values: [\"left\", \"center\", \"right\", \"justify\"] as const,\n  },\n} satisfies PropSchema;\n\nexport type DefaultProps = Props<typeof defaultProps>;\n\n// Default props which are set on `blockContainer` nodes rather than\n// `blockContent` nodes. Ensures that they are not redundantly added to\n// a custom block's TipTap node attributes.\nexport const inheritedProps = [\"backgroundColor\", \"textColor\"];\n","export function camelToDataKebab(str: string): string {\n  return \"data-\" + str.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase();\n}\n","import {\n  Attribute,\n  Attributes,\n  Editor,\n  Extension,\n  Node,\n  NodeConfig,\n} from \"@tiptap/core\";\nimport { defaultBlockToHTML } from \"../../blocks/defaultBlockHelpers\";\nimport { inheritedProps } from \"../../blocks/defaultProps\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport { mergeCSSClasses } from \"../../util/browser\";\nimport { camelToDataKebab } from \"../../util/string\";\nimport { InlineContentSchema } from \"../inlineContent/types\";\nimport { PropSchema, Props } from \"../propTypes\";\nimport { StyleSchema } from \"../styles/types\";\nimport {\n  BlockConfig,\n  BlockSchemaFromSpecs,\n  BlockSchemaWithBlock,\n  BlockSpec,\n  BlockSpecs,\n  SpecificBlock,\n  TiptapBlockImplementation,\n} from \"./types\";\n\n// Function that uses the 'propSchema' of a blockConfig to create a TipTap\n// node's `addAttributes` property.\n// TODO: extract function\nexport function propsToAttributes(propSchema: PropSchema): Attributes {\n  const tiptapAttributes: Record<string, Attribute> = {};\n\n  Object.entries(propSchema)\n    .filter(([name, _spec]) => !inheritedProps.includes(name))\n    .forEach(([name, spec]) => {\n      tiptapAttributes[name] = {\n        default: spec.default,\n        keepOnSplit: true,\n        // Props are displayed in kebab-case as HTML attributes. If a prop's\n        // value is the same as its default, we don't display an HTML\n        // attribute for it.\n        parseHTML: (element) => {\n          const value = element.getAttribute(camelToDataKebab(name));\n\n          if (value === null) {\n            return null;\n          }\n\n          if (typeof spec.default === \"boolean\") {\n            if (value === \"true\") {\n              return true;\n            }\n\n            if (value === \"false\") {\n              return false;\n            }\n\n            return null;\n          }\n\n          if (typeof spec.default === \"number\") {\n            const asNumber = parseFloat(value);\n            const isNumeric =\n              !Number.isNaN(asNumber) && Number.isFinite(asNumber);\n\n            if (isNumeric) {\n              return asNumber;\n            }\n\n            return null;\n          }\n\n          return value;\n        },\n        renderHTML: (attributes) =>\n          attributes[name] !== spec.default\n            ? {\n                [camelToDataKebab(name)]: attributes[name],\n              }\n            : {},\n      };\n    });\n\n  return tiptapAttributes;\n}\n\n// Used to figure out which block should be rendered. This block is then used to\n// create the node view.\nexport function getBlockFromPos<\n  BType extends string,\n  Config extends BlockConfig,\n  BSchema extends BlockSchemaWithBlock<BType, Config>,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  getPos: (() => number) | boolean,\n  editor: BlockNoteEditor<BSchema, I, S>,\n  tipTapEditor: Editor,\n  type: BType\n) {\n  // Gets position of the node\n  if (typeof getPos === \"boolean\") {\n    throw new Error(\n      \"Cannot find node position as getPos is a boolean, not a function.\"\n    );\n  }\n  const pos = getPos();\n  // Gets parent blockContainer node\n  const blockContainer = tipTapEditor.state.doc.resolve(pos!).node();\n  // Gets block identifier\n  const blockIdentifier = blockContainer.attrs.id;\n  // Gets the block\n  const block = editor.getBlock(blockIdentifier)! as SpecificBlock<\n    BSchema,\n    BType,\n    I,\n    S\n  >;\n  if (block.type !== type) {\n    throw new Error(\"Block type does not match\");\n  }\n\n  return block;\n}\n\n// Function that wraps the `dom` element returned from 'blockConfig.render' in a\n// `blockContent` div, which contains the block type and props as HTML\n// attributes. If `blockConfig.render` also returns a `contentDOM`, it also adds\n// an `inlineContent` class to it.\nexport function wrapInBlockStructure<\n  BType extends string,\n  PSchema extends PropSchema\n>(\n  element: {\n    dom: HTMLElement;\n    contentDOM?: HTMLElement;\n    destroy?: () => void;\n  },\n  blockType: BType,\n  blockProps: Props<PSchema>,\n  propSchema: PSchema,\n  domAttributes?: Record<string, string>\n): {\n  dom: HTMLElement;\n  contentDOM?: HTMLElement;\n  destroy?: () => void;\n} {\n  // Creates `blockContent` element\n  const blockContent = document.createElement(\"div\");\n\n  // Adds custom HTML attributes\n  if (domAttributes !== undefined) {\n    for (const [attr, value] of Object.entries(domAttributes)) {\n      if (attr !== \"class\") {\n        blockContent.setAttribute(attr, value);\n      }\n    }\n  }\n  // Sets blockContent class\n  blockContent.className = mergeCSSClasses(\n    \"bn-block-content\",\n    domAttributes?.class || \"\"\n  );\n  // Sets content type attribute\n  blockContent.setAttribute(\"data-content-type\", blockType);\n  // Adds props as HTML attributes in kebab-case with \"data-\" prefix. Skips props\n  // which are already added as HTML attributes to the parent `blockContent`\n  // element (inheritedProps) and props set to their default values.\n  for (const [prop, value] of Object.entries(blockProps)) {\n    if (!inheritedProps.includes(prop) && value !== propSchema[prop].default) {\n      blockContent.setAttribute(camelToDataKebab(prop), value);\n    }\n  }\n\n  blockContent.appendChild(element.dom);\n\n  if (element.contentDOM !== undefined) {\n    element.contentDOM.className = mergeCSSClasses(\n      \"bn-inline-content\",\n      element.contentDOM.className\n    );\n    element.contentDOM.setAttribute(\"data-editable\", \"\");\n  }\n\n  return {\n    ...element,\n    dom: blockContent,\n  };\n}\n\n// Helper type to keep track of the `name` and `content` properties after calling Node.create.\ntype StronglyTypedTipTapNode<\n  Name extends string,\n  Content extends \"inline*\" | \"tableRow+\" | \"\"\n> = Node & { name: Name; config: { content: Content } };\n\nexport function createStronglyTypedTiptapNode<\n  Name extends string,\n  Content extends \"inline*\" | \"tableRow+\" | \"\"\n>(config: NodeConfig & { name: Name; content: Content }) {\n  return Node.create(config) as StronglyTypedTipTapNode<Name, Content>; // force re-typing (should be safe as it's type-checked from the config)\n}\n\n// This helper function helps to instantiate a blockspec with a\n// config and implementation that conform to the type of Config\nexport function createInternalBlockSpec<T extends BlockConfig>(\n  config: T,\n  implementation: TiptapBlockImplementation<\n    T,\n    any,\n    InlineContentSchema,\n    StyleSchema\n  >\n) {\n  return {\n    config,\n    implementation,\n  } satisfies BlockSpec<T, any, InlineContentSchema, StyleSchema>;\n}\n\nexport function createBlockSpecFromStronglyTypedTiptapNode<\n  T extends Node,\n  P extends PropSchema\n>(node: T, propSchema: P, requiredExtensions?: Array<Extension | Node>) {\n  return createInternalBlockSpec(\n    {\n      type: node.name as T[\"name\"],\n      content: (node.config.content === \"inline*\"\n        ? \"inline\"\n        : node.config.content === \"tableRow+\"\n        ? \"table\"\n        : \"none\") as T[\"config\"][\"content\"] extends \"inline*\"\n        ? \"inline\"\n        : T[\"config\"][\"content\"] extends \"tableRow+\"\n        ? \"table\"\n        : \"none\",\n      propSchema,\n    },\n    {\n      node,\n      requiredExtensions,\n      toInternalHTML: defaultBlockToHTML,\n      toExternalHTML: defaultBlockToHTML,\n      // parse: () => undefined, // parse rules are in node already\n    }\n  );\n}\n\nexport function getBlockSchemaFromSpecs<T extends BlockSpecs>(specs: T) {\n  return Object.fromEntries(\n    Object.entries(specs).map(([key, value]) => [key, value.config])\n  ) as BlockSchemaFromSpecs<T>;\n}\n","import { ParseRule } from \"@tiptap/pm/model\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport { InlineContentSchema } from \"../inlineContent/types\";\nimport { StyleSchema } from \"../styles/types\";\nimport {\n  createInternalBlockSpec,\n  createStronglyTypedTiptapNode,\n  getBlockFromPos,\n  propsToAttributes,\n  wrapInBlockStructure,\n} from \"./internal\";\nimport {\n  BlockConfig,\n  BlockFromConfig,\n  BlockSchemaWithBlock,\n  PartialBlockFromConfig,\n} from \"./types\";\n\n// restrict content to \"inline\" and \"none\" only\nexport type CustomBlockConfig = BlockConfig & {\n  content: \"inline\" | \"none\";\n};\n\nexport type CustomBlockImplementation<\n  T extends CustomBlockConfig,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> = {\n  render: (\n    /**\n     * The custom block to render\n     */\n    block: BlockFromConfig<T, I, S>,\n    /**\n     * The BlockNote editor instance\n     * This is typed generically. If you want an editor with your custom schema, you need to\n     * cast it manually, e.g.: `const e = editor as BlockNoteEditor<typeof mySchema>;`\n     */\n    editor: BlockNoteEditor<BlockSchemaWithBlock<T[\"type\"], T>, I, S>\n    // (note) if we want to fix the manual cast, we need to prevent circular references and separate block definition and render implementations\n    // or allow manually passing <BSchema>, but that's not possible without passing the other generics because Typescript doesn't support partial inferred generics\n  ) => {\n    dom: HTMLElement;\n    contentDOM?: HTMLElement;\n    destroy?: () => void;\n  };\n  // Exports block to external HTML. If not defined, the output will be the same\n  // as `render(...).dom`. Used to create clipboard data when pasting outside\n  // BlockNote.\n  // TODO: Maybe can return undefined to ignore when serializing?\n  toExternalHTML?: (\n    block: BlockFromConfig<T, I, S>,\n    editor: BlockNoteEditor<BlockSchemaWithBlock<T[\"type\"], T>, I, S>\n  ) => {\n    dom: HTMLElement;\n    contentDOM?: HTMLElement;\n  };\n\n  parse?: (\n    el: HTMLElement\n  ) => PartialBlockFromConfig<T, I, S>[\"props\"] | undefined;\n};\n\n// Function that uses the 'parse' function of a blockConfig to create a\n// TipTap node's `parseHTML` property. This is only used for parsing content\n// from the clipboard.\nexport function getParseRules(\n  config: BlockConfig,\n  customParseFunction: CustomBlockImplementation<any, any, any>[\"parse\"]\n) {\n  const rules: ParseRule[] = [\n    {\n      tag: \"[data-content-type=\" + config.type + \"]\",\n      contentElement: \"[data-editable]\",\n    },\n  ];\n\n  if (customParseFunction) {\n    rules.push({\n      tag: \"*\",\n      getAttrs(node: string | HTMLElement) {\n        if (typeof node === \"string\") {\n          return false;\n        }\n\n        const props = customParseFunction?.(node);\n\n        if (props === undefined) {\n          return false;\n        }\n\n        return props;\n      },\n    });\n  }\n  //     getContent(node, schema) {\n  //       const block = blockConfig.parse?.(node as HTMLElement);\n  //\n  //       if (block !== undefined && block.content !== undefined) {\n  //         return Fragment.from(\n  //           typeof block.content === \"string\"\n  //             ? schema.text(block.content)\n  //             : inlineContentToNodes(block.content, schema)\n  //         );\n  //       }\n  //\n  //       return Fragment.empty;\n  //     },\n  //   });\n  // }\n\n  return rules;\n}\n\n// A function to create custom block for API consumers\n// we want to hide the tiptap node from API consumers and provide a simpler API surface instead\nexport function createBlockSpec<\n  T extends CustomBlockConfig,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(blockConfig: T, blockImplementation: CustomBlockImplementation<T, I, S>) {\n  const node = createStronglyTypedTiptapNode({\n    name: blockConfig.type as T[\"type\"],\n    content: (blockConfig.content === \"inline\"\n      ? \"inline*\"\n      : \"\") as T[\"content\"] extends \"inline\" ? \"inline*\" : \"\",\n    group: \"blockContent\",\n    selectable: true,\n\n    addAttributes() {\n      return propsToAttributes(blockConfig.propSchema);\n    },\n\n    parseHTML() {\n      return getParseRules(blockConfig, blockImplementation.parse);\n    },\n\n    renderHTML() {\n      // renderHTML is not really used, as we always use a nodeView, and we use toExternalHTML / toInternalHTML for serialization\n      // There's an edge case when this gets called nevertheless; before the nodeviews have been mounted\n      // this is why we implement it with a temporary placeholder\n      const div = document.createElement(\"div\");\n      div.setAttribute(\"data-tmp-placeholder\", \"true\");\n      return {\n        dom: div,\n      };\n    },\n\n    addNodeView() {\n      return ({ getPos }) => {\n        // Gets the BlockNote editor instance\n        const editor = this.options.editor;\n        // Gets the block\n        const block = getBlockFromPos(\n          getPos,\n          editor,\n          this.editor,\n          blockConfig.type\n        );\n        // Gets the custom HTML attributes for `blockContent` nodes\n        const blockContentDOMAttributes =\n          this.options.domAttributes?.blockContent || {};\n\n        const output = blockImplementation.render(block as any, editor);\n\n        return wrapInBlockStructure(\n          output,\n          block.type,\n          block.props,\n          blockConfig.propSchema,\n          blockContentDOMAttributes\n        );\n      };\n    },\n  });\n\n  if (node.name !== blockConfig.type) {\n    throw new Error(\n      \"Node name does not match block type. This is a bug in BlockNote.\"\n    );\n  }\n\n  return createInternalBlockSpec(blockConfig, {\n    node,\n    toInternalHTML: (block, editor) => {\n      const blockContentDOMAttributes =\n        node.options.domAttributes?.blockContent || {};\n\n      const output = blockImplementation.render(block as any, editor as any);\n\n      return wrapInBlockStructure(\n        output,\n        block.type,\n        block.props,\n        blockConfig.propSchema,\n        blockContentDOMAttributes\n      );\n    },\n    toExternalHTML: (block, editor) => {\n      const blockContentDOMAttributes =\n        node.options.domAttributes?.blockContent || {};\n\n      let output = blockImplementation.toExternalHTML?.(\n        block as any,\n        editor as any\n      );\n      if (output === undefined) {\n        output = blockImplementation.render(block as any, editor as any);\n      }\n\n      return wrapInBlockStructure(\n        output,\n        block.type,\n        block.props,\n        blockConfig.propSchema,\n        blockContentDOMAttributes\n      );\n    },\n  });\n}\n","import { KeyboardShortcutCommand, Node } from \"@tiptap/core\";\n\nimport { camelToDataKebab } from \"../../util/string\";\nimport { PropSchema, Props } from \"../propTypes\";\nimport {\n  CustomInlineContentConfig,\n  InlineContentConfig,\n  InlineContentImplementation,\n  InlineContentSchemaFromSpecs,\n  InlineContentSpec,\n  InlineContentSpecs,\n} from \"./types\";\n\n// Function that adds necessary classes and attributes to the `dom` element\n// returned from a custom inline content's 'render' function, to ensure no data\n// is lost on internal copy & paste.\nexport function addInlineContentAttributes<\n  IType extends string,\n  PSchema extends PropSchema\n>(\n  element: {\n    dom: HTMLElement;\n    contentDOM?: HTMLElement;\n  },\n  inlineContentType: IType,\n  inlineContentProps: Props<PSchema>,\n  propSchema: PSchema\n): {\n  dom: HTMLElement;\n  contentDOM?: HTMLElement;\n} {\n  // Sets content type attribute\n  element.dom.setAttribute(\"data-inline-content-type\", inlineContentType);\n  // Adds props as HTML attributes in kebab-case with \"data-\" prefix. Skips props\n  // set to their default values.\n  Object.entries(inlineContentProps)\n    .filter(([prop, value]) => value !== propSchema[prop].default)\n    .map(([prop, value]) => {\n      return [camelToDataKebab(prop), value];\n    })\n    .forEach(([prop, value]) => element.dom.setAttribute(prop, value));\n\n  if (element.contentDOM !== undefined) {\n    element.contentDOM.setAttribute(\"data-editable\", \"\");\n  }\n\n  return element;\n}\n\n// see https://github.com/TypeCellOS/BlockNote/pull/435\nexport function addInlineContentKeyboardShortcuts<\n  T extends CustomInlineContentConfig\n>(\n  config: T\n): {\n  [p: string]: KeyboardShortcutCommand;\n} {\n  return {\n    Backspace: ({ editor }) => {\n      const resolvedPos = editor.state.selection.$from;\n\n      return (\n        editor.state.selection.empty &&\n        resolvedPos.node().type.name === config.type &&\n        resolvedPos.parentOffset === 0\n      );\n    },\n  };\n}\n\n// This helper function helps to instantiate a InlineContentSpec with a\n// config and implementation that conform to the type of Config\nexport function createInternalInlineContentSpec<T extends InlineContentConfig>(\n  config: T,\n  implementation: InlineContentImplementation<T>\n) {\n  return {\n    config,\n    implementation,\n  } satisfies InlineContentSpec<T>;\n}\n\nexport function createInlineContentSpecFromTipTapNode<\n  T extends Node,\n  P extends PropSchema\n>(node: T, propSchema: P) {\n  return createInternalInlineContentSpec(\n    {\n      type: node.name as T[\"name\"],\n      propSchema,\n      content: node.config.content === \"inline*\" ? \"styled\" : \"none\",\n    },\n    {\n      node,\n    }\n  );\n}\n\nexport function getInlineContentSchemaFromSpecs<T extends InlineContentSpecs>(\n  specs: T\n) {\n  return Object.fromEntries(\n    Object.entries(specs).map(([key, value]) => [key, value.config])\n  ) as InlineContentSchemaFromSpecs<T>;\n}\n","import { Node } from \"@tiptap/core\";\nimport { ParseRule } from \"@tiptap/pm/model\";\nimport { nodeToCustomInlineContent } from \"../../api/nodeConversions/nodeConversions\";\nimport { propsToAttributes } from \"../blocks/internal\";\nimport { Props } from \"../propTypes\";\nimport { StyleSchema } from \"../styles/types\";\nimport {\n  addInlineContentAttributes,\n  addInlineContentKeyboardShortcuts,\n  createInlineContentSpecFromTipTapNode,\n} from \"./internal\";\nimport {\n  CustomInlineContentConfig,\n  InlineContentConfig,\n  InlineContentFromConfig,\n  InlineContentSpec,\n} from \"./types\";\n\n// TODO: support serialization\n\nexport type CustomInlineContentImplementation<\n  T extends InlineContentConfig,\n  // B extends BlockSchema,\n  // I extends InlineContentSchema,\n  S extends StyleSchema\n> = {\n  render: (\n    /**\n     * The custom inline content to render\n     */\n    inlineContent: InlineContentFromConfig<T, S>\n    /**\n     * The BlockNote editor instance\n     * This is typed generically. If you want an editor with your custom schema, you need to\n     * cast it manually, e.g.: `const e = editor as BlockNoteEditor<typeof mySchema>;`\n     */\n    // editor: BlockNoteEditor<B, I, S>\n    // (note) if we want to fix the manual cast, we need to prevent circular references and separate block definition and render implementations\n    // or allow manually passing <BSchema>, but that's not possible without passing the other generics because Typescript doesn't support partial inferred generics\n  ) => {\n    dom: HTMLElement;\n    contentDOM?: HTMLElement;\n    // destroy?: () => void;\n  };\n};\n\nexport function getInlineContentParseRules(\n  config: CustomInlineContentConfig\n): ParseRule[] {\n  return [\n    {\n      tag: `[data-inline-content-type=\"${config.type}\"]`,\n      contentElement: (element) => {\n        const htmlElement = element as HTMLElement;\n\n        if (htmlElement.matches(\"[data-editable]\")) {\n          return htmlElement;\n        }\n\n        return htmlElement.querySelector(\"[data-editable]\") || htmlElement;\n      },\n    },\n  ];\n}\n\nexport function createInlineContentSpec<\n  T extends CustomInlineContentConfig,\n  S extends StyleSchema\n>(\n  inlineContentConfig: T,\n  inlineContentImplementation: CustomInlineContentImplementation<T, S>\n): InlineContentSpec<T> {\n  const node = Node.create({\n    name: inlineContentConfig.type,\n    inline: true,\n    group: \"inline\",\n    selectable: inlineContentConfig.content === \"styled\",\n    atom: inlineContentConfig.content === \"none\",\n    content: (inlineContentConfig.content === \"styled\"\n      ? \"inline*\"\n      : \"\") as T[\"content\"] extends \"styled\" ? \"inline*\" : \"\",\n\n    addAttributes() {\n      return propsToAttributes(inlineContentConfig.propSchema);\n    },\n\n    addKeyboardShortcuts() {\n      return addInlineContentKeyboardShortcuts(inlineContentConfig);\n    },\n\n    parseHTML() {\n      return getInlineContentParseRules(inlineContentConfig);\n    },\n\n    renderHTML({ node }) {\n      const editor = this.options.editor;\n\n      const output = inlineContentImplementation.render(\n        nodeToCustomInlineContent(\n          node,\n          editor.inlineContentSchema,\n          editor.styleSchema\n        ) as any as InlineContentFromConfig<T, S> // TODO: fix cast\n      );\n\n      return addInlineContentAttributes(\n        output,\n        inlineContentConfig.type,\n        node.attrs as Props<T[\"propSchema\"]>,\n        inlineContentConfig.propSchema\n      );\n    },\n  });\n\n  return createInlineContentSpecFromTipTapNode(\n    node,\n    inlineContentConfig.propSchema\n  ) as InlineContentSpec<T>; // TODO: fix cast\n}\n","import { Attributes, Mark } from \"@tiptap/core\";\nimport {\n  StyleConfig,\n  StyleImplementation,\n  StylePropSchema,\n  StyleSchemaFromSpecs,\n  StyleSpec,\n  StyleSpecs,\n} from \"./types\";\n\nexport function stylePropsToAttributes(\n  propSchema: StylePropSchema\n): Attributes {\n  if (propSchema === \"boolean\") {\n    return {};\n  }\n  return {\n    stringValue: {\n      default: undefined,\n      keepOnSplit: true,\n      parseHTML: (element) => element.getAttribute(\"data-value\"),\n      renderHTML: (attributes) =>\n        attributes.stringValue !== undefined\n          ? {\n              \"data-value\": attributes.stringValue,\n            }\n          : {},\n    },\n  };\n}\n\n// Function that adds necessary classes and attributes to the `dom` element\n// returned from a custom style's 'render' function, to ensure no data is lost\n// on internal copy & paste.\nexport function addStyleAttributes<\n  SType extends string,\n  PSchema extends StylePropSchema\n>(\n  element: {\n    dom: HTMLElement;\n    contentDOM?: HTMLElement;\n  },\n  styleType: SType,\n  styleValue: PSchema extends \"boolean\" ? undefined : string,\n  propSchema: PSchema\n): {\n  dom: HTMLElement;\n  contentDOM?: HTMLElement;\n} {\n  // Sets content type attribute\n  element.dom.setAttribute(\"data-style-type\", styleType);\n  // Adds style value as an HTML attribute in kebab-case with \"data-\" prefix, if\n  // the style takes a string value.\n  if (propSchema === \"string\") {\n    element.dom.setAttribute(\"data-value\", styleValue as string);\n  }\n\n  if (element.contentDOM !== undefined) {\n    element.contentDOM.setAttribute(\"data-editable\", \"\");\n  }\n\n  return element;\n}\n\n// This helper function helps to instantiate a stylespec with a\n// config and implementation that conform to the type of Config\nexport function createInternalStyleSpec<T extends StyleConfig>(\n  config: T,\n  implementation: StyleImplementation\n) {\n  return {\n    config,\n    implementation,\n  } satisfies StyleSpec<T>;\n}\n\nexport function createStyleSpecFromTipTapMark<\n  T extends Mark,\n  P extends StylePropSchema\n>(mark: T, propSchema: P) {\n  return createInternalStyleSpec(\n    {\n      type: mark.name as T[\"name\"],\n      propSchema,\n    },\n    {\n      mark,\n    }\n  );\n}\n\nexport function getStyleSchemaFromSpecs<T extends StyleSpecs>(specs: T) {\n  return Object.fromEntries(\n    Object.entries(specs).map(([key, value]) => [key, value.config])\n  ) as StyleSchemaFromSpecs<T>;\n}\n","import { Mark } from \"@tiptap/core\";\nimport { ParseRule } from \"@tiptap/pm/model\";\nimport {\n  addStyleAttributes,\n  createInternalStyleSpec,\n  stylePropsToAttributes,\n} from \"./internal\";\nimport { StyleConfig, StyleSpec } from \"./types\";\nimport {UnreachableCaseError} from \"../../util/typescript\";\n\nexport type CustomStyleImplementation<T extends StyleConfig> = {\n  render: T[\"propSchema\"] extends \"boolean\"\n    ? () => {\n        dom: HTMLElement;\n        contentDOM?: HTMLElement;\n      }\n    : (value: string) => {\n        dom: HTMLElement;\n        contentDOM?: HTMLElement;\n      };\n};\n\n// TODO: support serialization\n\nexport function getStyleParseRules(config: StyleConfig): ParseRule[] {\n  return [\n    {\n      tag: `[data-style-type=\"${config.type}\"]`,\n      contentElement: (element) => {\n        const htmlElement = element as HTMLElement;\n\n        if (htmlElement.matches(\"[data-editable]\")) {\n          return htmlElement;\n        }\n\n        return htmlElement.querySelector(\"[data-editable]\") || htmlElement;\n      },\n    },\n  ];\n}\n\nexport function createStyleSpec<T extends StyleConfig>(\n  styleConfig: T,\n  styleImplementation: CustomStyleImplementation<T>\n): StyleSpec<T> {\n  const mark = Mark.create({\n    name: styleConfig.type,\n\n    addAttributes() {\n      return stylePropsToAttributes(styleConfig.propSchema);\n    },\n\n    parseHTML() {\n      return getStyleParseRules(styleConfig);\n    },\n\n    renderHTML({ mark }) {\n      let renderResult: {\n        dom: HTMLElement;\n        contentDOM?: HTMLElement;\n      };\n\n      if (styleConfig.propSchema === \"boolean\") {\n        // @ts-ignore not sure why this is complaining\n        renderResult = styleImplementation.render();\n      } else if (styleConfig.propSchema === \"string\") {\n        renderResult = styleImplementation.render(mark.attrs.stringValue);\n      } else {\n        throw new UnreachableCaseError(styleConfig.propSchema);\n      }\n\n      // const renderResult = styleImplementation.render();\n      return addStyleAttributes(\n        renderResult,\n        styleConfig.type,\n        mark.attrs.stringValue,\n        styleConfig.propSchema\n      );\n    },\n  });\n\n  return createInternalStyleSpec(styleConfig, {\n    mark,\n  });\n}\n","import { Mark } from \"@tiptap/core\";\nimport { createStyleSpecFromTipTapMark } from \"../../schema\";\n\nconst BackgroundColorMark = Mark.create({\n  name: \"backgroundColor\",\n\n  addAttributes() {\n    return {\n      stringValue: {\n        default: undefined,\n        parseHTML: (element) => element.getAttribute(\"data-background-color\"),\n        renderHTML: (attributes) => ({\n          \"data-background-color\": attributes.stringValue,\n        }),\n      },\n    };\n  },\n\n  parseHTML() {\n    return [\n      {\n        tag: \"span\",\n        getAttrs: (element) => {\n          if (typeof element === \"string\") {\n            return false;\n          }\n\n          if (element.hasAttribute(\"data-background-color\")) {\n            return {\n              stringValue: element.getAttribute(\"data-background-color\"),\n            };\n          }\n\n          return false;\n        },\n      },\n    ];\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    return [\"span\", HTMLAttributes, 0];\n  },\n});\n\nexport const BackgroundColor = createStyleSpecFromTipTapMark(\n  BackgroundColorMark,\n  \"string\"\n);\n","import { Mark } from \"@tiptap/core\";\nimport { createStyleSpecFromTipTapMark } from \"../../schema\";\n\nconst TextColorMark = Mark.create({\n  name: \"textColor\",\n\n  addAttributes() {\n    return {\n      stringValue: {\n        default: undefined,\n        parseHTML: (element) => element.getAttribute(\"data-text-color\"),\n        renderHTML: (attributes) => ({\n          \"data-text-color\": attributes.stringValue,\n        }),\n      },\n    };\n  },\n\n  parseHTML() {\n    return [\n      {\n        tag: \"span\",\n        getAttrs: (element) => {\n          if (typeof element === \"string\") {\n            return false;\n          }\n\n          if (element.hasAttribute(\"data-text-color\")) {\n            return { stringValue: element.getAttribute(\"data-text-color\") };\n          }\n\n          return false;\n        },\n      },\n    ];\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    return [\"span\", HTMLAttributes, 0];\n  },\n});\n\nexport const TextColor = createStyleSpecFromTipTapMark(TextColorMark, \"string\");\n","import { InputRule } from \"@tiptap/core\";\nimport {\n  PropSchema,\n  createBlockSpecFromStronglyTypedTiptapNode,\n  createStronglyTypedTiptapNode,\n} from \"../../schema\";\nimport { createDefaultBlockDOMOutputSpec } from \"../defaultBlockHelpers\";\nimport { defaultProps } from \"../defaultProps\";\n\nexport const headingPropSchema = {\n  ...defaultProps,\n  level: { default: 1, values: [1, 2, 3] as const },\n} satisfies PropSchema;\n\nconst HeadingBlockContent = createStronglyTypedTiptapNode({\n  name: \"heading\",\n  content: \"inline*\",\n  group: \"blockContent\",\n  addAttributes() {\n    return {\n      level: {\n        default: 1,\n        // instead of \"level\" attributes, use \"data-level\"\n        parseHTML: (element) => {\n          const attr = element.getAttribute(\"data-level\")!;\n          const parsed = parseInt(attr);\n          if (isFinite(parsed)) {\n            return parsed;\n          }\n          return undefined;\n        },\n        renderHTML: (attributes) => {\n          return {\n            \"data-level\": (attributes.level as number).toString(),\n          };\n        },\n      },\n    };\n  },\n\n  addInputRules() {\n    return [\n      ...[1, 2, 3].map((level) => {\n        // Creates a heading of appropriate level when starting with \"#\", \"##\", or \"###\".\n        return new InputRule({\n          find: new RegExp(`^(#{${level}})\\\\s$`),\n          handler: ({ state, chain, range }) => {\n            chain()\n              .BNUpdateBlock(state.selection.from, {\n                type: \"heading\",\n                props: {\n                  level: level as any,\n                },\n              })\n              // Removes the \"#\" character(s) used to set the heading.\n              .deleteRange({ from: range.from, to: range.to });\n          },\n        });\n      }),\n    ];\n  },\n\n  addKeyboardShortcuts() {\n    return {\n      \"Mod-Alt-1\": () =>\n        this.editor.commands.BNUpdateBlock(this.editor.state.selection.anchor, {\n          type: \"heading\",\n          props: {\n            level: 1 as any,\n          },\n        }),\n      \"Mod-Alt-2\": () =>\n        this.editor.commands.BNUpdateBlock(this.editor.state.selection.anchor, {\n          type: \"heading\",\n          props: {\n            level: 2 as any,\n          },\n        }),\n      \"Mod-Alt-3\": () =>\n        this.editor.commands.BNUpdateBlock(this.editor.state.selection.anchor, {\n          type: \"heading\",\n          props: {\n            level: 3 as any,\n          },\n        }),\n    };\n  },\n  parseHTML() {\n    return [\n      {\n        tag: \"div[data-content-type=\" + this.name + \"]\",\n        getAttrs: (element) => {\n          if (typeof element === \"string\") {\n            return false;\n          }\n\n          return {\n            level: element.getAttribute(\"data-level\"),\n          };\n        },\n      },\n      {\n        tag: \"h1\",\n        attrs: { level: 1 },\n        node: \"heading\",\n      },\n      {\n        tag: \"h2\",\n        attrs: { level: 2 },\n        node: \"heading\",\n      },\n      {\n        tag: \"h3\",\n        attrs: { level: 3 },\n        node: \"heading\",\n      },\n    ];\n  },\n\n  renderHTML({ node, HTMLAttributes }) {\n    return createDefaultBlockDOMOutputSpec(\n      this.name,\n      `h${node.attrs.level}`,\n      {\n        ...(this.options.domAttributes?.blockContent || {}),\n        ...HTMLAttributes,\n      },\n      this.options.domAttributes?.inlineContent || {}\n    );\n  },\n});\n\nexport const Heading = createBlockSpecFromStronglyTypedTiptapNode(\n  HeadingBlockContent,\n  headingPropSchema\n);\n","// from https://raw.githubusercontent.com/ueberdosis/tiptap/develop/packages/core/src/EventEmitter.ts (MIT)\n\ntype 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  // eslint-disable-next-line @typescript-eslint/ban-types\n  private callbacks: { [key: string]: Function[] } = {};\n\n  public on<EventName extends StringKeyOf<T>>(\n    event: EventName,\n    fn: CallbackFunction<T, EventName>\n  ) {\n    if (!this.callbacks[event]) {\n      this.callbacks[event] = [];\n    }\n\n    this.callbacks[event].push(fn);\n\n    return () => this.off(event, fn);\n  }\n\n  protected emit<EventName extends StringKeyOf<T>>(\n    event: EventName,\n    ...args: CallbackType<T, EventName>\n  ) {\n    const callbacks = this.callbacks[event];\n\n    if (callbacks) {\n      callbacks.forEach((callback) => callback.apply(this, args));\n    }\n  }\n\n  public off<EventName extends StringKeyOf<T>>(\n    event: EventName,\n    fn?: CallbackFunction<T, EventName>\n  ) {\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\n  protected removeAllListeners(): void {\n    this.callbacks = {};\n  }\n}\n","import { EditorState, Plugin, PluginKey } from \"prosemirror-state\";\nimport { EditorView } from \"prosemirror-view\";\n\nimport { EventEmitter } from \"../../util/EventEmitter\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport {\n  BlockSchema,\n  InlineContentSchema,\n  SpecificBlock,\n  StyleSchema,\n} from \"../../schema\";\nimport {\n  BaseUiElementCallbacks,\n  BaseUiElementState,\n} from \"../../extensions-shared/BaseUiElementTypes\";\nexport type ImageToolbarCallbacks = BaseUiElementCallbacks;\n\nexport type ImageToolbarState<\n  B extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema = StyleSchema\n> = BaseUiElementState & {\n  block: SpecificBlock<B, \"image\", I, S>;\n};\n\nexport class ImageToolbarView<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> {\n  private imageToolbarState?: ImageToolbarState<BSchema, I, S>;\n  public updateImageToolbar: () => void;\n\n  public prevWasEditable: boolean | null = null;\n\n  constructor(\n    private readonly pluginKey: PluginKey,\n    private readonly pmView: EditorView,\n    updateImageToolbar: (\n      imageToolbarState: ImageToolbarState<BSchema, I, S>\n    ) => void\n  ) {\n    this.updateImageToolbar = () => {\n      if (!this.imageToolbarState) {\n        throw new Error(\"Attempting to update uninitialized image toolbar\");\n      }\n\n      updateImageToolbar(this.imageToolbarState);\n    };\n\n    pmView.dom.addEventListener(\"mousedown\", this.mouseDownHandler);\n\n    pmView.dom.addEventListener(\"dragstart\", this.dragstartHandler);\n\n    pmView.dom.addEventListener(\"blur\", this.blurHandler);\n\n    document.addEventListener(\"scroll\", this.scrollHandler);\n  }\n\n  mouseDownHandler = () => {\n    if (this.imageToolbarState?.show) {\n      this.imageToolbarState.show = false;\n      this.updateImageToolbar();\n    }\n  };\n\n  // For dragging the whole editor.\n  dragstartHandler = () => {\n    if (this.imageToolbarState?.show) {\n      this.imageToolbarState.show = false;\n      this.updateImageToolbar();\n    }\n  };\n\n  blurHandler = (event: FocusEvent) => {\n    const editorWrapper = this.pmView.dom.parentElement!;\n\n    // Checks if the focus is moving to an element outside the editor. If it is,\n    // the toolbar is hidden.\n    if (\n      // An element is clicked.\n      event &&\n      event.relatedTarget &&\n      // Element is inside the editor.\n      (editorWrapper === (event.relatedTarget as Node) ||\n        editorWrapper.contains(event.relatedTarget as Node))\n    ) {\n      return;\n    }\n\n    if (this.imageToolbarState?.show) {\n      this.imageToolbarState.show = false;\n      this.updateImageToolbar();\n    }\n  };\n\n  scrollHandler = () => {\n    if (this.imageToolbarState?.show) {\n      const blockElement = document.querySelector(\n        `[data-node-type=\"blockContainer\"][data-id=\"${this.imageToolbarState.block.id}\"]`\n      )!;\n\n      this.imageToolbarState.referencePos =\n        blockElement.getBoundingClientRect();\n      this.updateImageToolbar();\n    }\n  };\n\n  update(view: EditorView, prevState: EditorState) {\n    const pluginState: {\n      block: SpecificBlock<BSchema, \"image\", I, S>;\n    } = this.pluginKey.getState(view.state);\n\n    if (!this.imageToolbarState?.show && pluginState.block) {\n      const blockElement = document.querySelector(\n        `[data-node-type=\"blockContainer\"][data-id=\"${pluginState.block.id}\"]`\n      )!;\n\n      this.imageToolbarState = {\n        show: true,\n        referencePos: blockElement.getBoundingClientRect(),\n        block: pluginState.block,\n      };\n\n      this.updateImageToolbar();\n\n      return;\n    }\n\n    if (\n      !view.state.selection.eq(prevState.selection) ||\n      !view.state.doc.eq(prevState.doc)\n    ) {\n      if (this.imageToolbarState?.show) {\n        this.imageToolbarState.show = false;\n\n        this.updateImageToolbar();\n      }\n    }\n  }\n\n  destroy() {\n    this.pmView.dom.removeEventListener(\"mousedown\", this.mouseDownHandler);\n\n    this.pmView.dom.removeEventListener(\"dragstart\", this.dragstartHandler);\n\n    this.pmView.dom.removeEventListener(\"blur\", this.blurHandler);\n\n    document.removeEventListener(\"scroll\", this.scrollHandler);\n  }\n}\n\nexport const imageToolbarPluginKey = new PluginKey(\"ImageToolbarPlugin\");\n\nexport class ImageToolbarProsemirrorPlugin<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> extends EventEmitter<any> {\n  private view: ImageToolbarView<BSchema, I, S> | undefined;\n  public readonly plugin: Plugin;\n\n  constructor(_editor: BlockNoteEditor<BSchema, I, S>) {\n    super();\n    this.plugin = new Plugin<{\n      block: SpecificBlock<BSchema, \"image\", I, S> | undefined;\n    }>({\n      key: imageToolbarPluginKey,\n      view: (editorView) => {\n        this.view = new ImageToolbarView(\n          // editor,\n          imageToolbarPluginKey,\n          editorView,\n          (state) => {\n            this.emit(\"update\", state);\n          }\n        );\n        return this.view;\n      },\n      state: {\n        init: () => {\n          return {\n            block: undefined,\n          };\n        },\n        apply: (transaction) => {\n          const block: SpecificBlock<BSchema, \"image\", I, S> | undefined =\n            transaction.getMeta(imageToolbarPluginKey)?.block;\n\n          return {\n            block,\n          };\n        },\n      },\n    });\n  }\n\n  public onUpdate(callback: (state: ImageToolbarState<BSchema, I, S>) => void) {\n    return this.on(\"update\", callback);\n  }\n}\n","import type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport { imageToolbarPluginKey } from \"../../extensions/ImageToolbar/ImageToolbarPlugin\";\n\nimport {\n  BlockFromConfig,\n  BlockSchemaWithBlock,\n  CustomBlockConfig,\n  InlineContentSchema,\n  PropSchema,\n  StyleSchema,\n  createBlockSpec,\n} from \"../../schema\";\nimport { defaultProps } from \"../defaultProps\";\n\nexport const imagePropSchema = {\n  textAlignment: defaultProps.textAlignment,\n  backgroundColor: defaultProps.backgroundColor,\n  // Image url.\n  url: {\n    default: \"\" as const,\n  },\n  // Image caption.\n  caption: {\n    default: \"\" as const,\n  },\n  // Image width in px.\n  width: {\n    default: 512 as const,\n  },\n} satisfies PropSchema;\n\n// Converts text alignment prop values to the flexbox `align-items` values.\nconst textAlignmentToAlignItems = (\n  textAlignment: \"left\" | \"center\" | \"right\" | \"justify\"\n): \"flex-start\" | \"center\" | \"flex-end\" => {\n  switch (textAlignment) {\n    case \"left\":\n      return \"flex-start\";\n    case \"center\":\n      return \"center\";\n    case \"right\":\n      return \"flex-end\";\n    default:\n      return \"flex-start\";\n  }\n};\n\n// Min image width in px.\nconst minWidth = 64;\n\nconst blockConfig = {\n  type: \"image\" as const,\n  propSchema: imagePropSchema,\n  content: \"none\",\n} satisfies CustomBlockConfig;\n\nexport const renderImage = (\n  block: BlockFromConfig<typeof blockConfig, InlineContentSchema, StyleSchema>,\n  editor: BlockNoteEditor<BlockSchemaWithBlock<\"image\", typeof blockConfig>>\n) => {\n  // Wrapper element to set the image alignment, contains both image/image\n  // upload dashboard and caption.\n  const wrapper = document.createElement(\"div\");\n  wrapper.className = \"bn-image-block-content-wrapper\";\n  wrapper.style.alignItems = textAlignmentToAlignItems(\n    block.props.textAlignment\n  );\n\n  // Button element that acts as a placeholder for images with no src.\n  const addImageButton = document.createElement(\"div\");\n  addImageButton.className = \"bn-add-image-button\";\n  addImageButton.style.display = block.props.url === \"\" ? \"\" : \"none\";\n\n  // Icon for the add image button.\n  const addImageButtonIcon = document.createElement(\"div\");\n  addImageButtonIcon.className = \"bn-add-image-button-icon\";\n\n  // Text for the add image button.\n  const addImageButtonText = document.createElement(\"p\");\n  addImageButtonText.className = \"bn-add-image-button-text\";\n  addImageButtonText.innerText = \"Add Image\";\n\n  // Wrapper element for the image, resize handles and caption.\n  const imageAndCaptionWrapper = document.createElement(\"div\");\n  imageAndCaptionWrapper.className = \"bn-image-and-caption-wrapper\";\n  imageAndCaptionWrapper.style.display = block.props.url !== \"\" ? \"\" : \"none\";\n\n  // Wrapper element for the image and resize handles.\n  const imageWrapper = document.createElement(\"div\");\n  imageWrapper.className = \"bn-image-wrapper\";\n  imageWrapper.style.display = block.props.url !== \"\" ? \"\" : \"none\";\n\n  // Image element.\n  const image = document.createElement(\"img\");\n  image.className = \"bn-image\";\n  image.src = block.props.url;\n  image.alt = \"placeholder\";\n  image.contentEditable = \"false\";\n  image.draggable = false;\n  image.style.width = `${Math.min(\n    block.props.width,\n    editor.domElement.firstElementChild!.clientWidth\n  )}px`;\n\n  // Resize handle elements.\n  const leftResizeHandle = document.createElement(\"div\");\n  leftResizeHandle.className = \"bn-image-resize-handle\";\n  leftResizeHandle.style.left = \"4px\";\n  const rightResizeHandle = document.createElement(\"div\");\n  rightResizeHandle.className = \"bn-image-resize-handle\";\n  rightResizeHandle.style.right = \"4px\";\n\n  // Caption element.\n  const caption = document.createElement(\"p\");\n  caption.className = \"bn-image-caption\";\n  caption.innerText = block.props.caption;\n  caption.style.padding = block.props.caption ? \"4px\" : \"\";\n\n  // Adds a light blue outline to selected image blocks.\n  const handleEditorUpdate = () => {\n    const selection = editor.getSelection()?.blocks || [];\n    const currentBlock = editor.getTextCursorPosition().block;\n\n    const isSelected =\n      [currentBlock, ...selection].find(\n        (selectedBlock) => selectedBlock.id === block.id\n      ) !== undefined;\n\n    if (isSelected) {\n      addImageButton.style.outline = \"4px solid rgb(100, 160, 255)\";\n      imageAndCaptionWrapper.style.outline = \"4px solid rgb(100, 160, 255)\";\n    } else {\n      addImageButton.style.outline = \"\";\n      imageAndCaptionWrapper.style.outline = \"\";\n    }\n  };\n  editor.onEditorContentChange(handleEditorUpdate);\n  editor.onEditorSelectionChange(handleEditorUpdate);\n\n  // Temporary parameters set when the user begins resizing the image, used to\n  // calculate the new width of the image.\n  let resizeParams:\n    | {\n        handleUsed: \"left\" | \"right\";\n        initialWidth: number;\n        initialClientX: number;\n      }\n    | undefined;\n\n  // Updates the image width with an updated width depending on the cursor X\n  // offset from when the resize began, and which resize handle is being used.\n  const windowMouseMoveHandler = (event: MouseEvent) => {\n    if (!resizeParams) {\n      return;\n    }\n\n    let newWidth: number;\n\n    if (textAlignmentToAlignItems(block.props.textAlignment) === \"center\") {\n      if (resizeParams.handleUsed === \"left\") {\n        newWidth =\n          resizeParams.initialWidth +\n          (resizeParams.initialClientX - event.clientX) * 2;\n      } else {\n        newWidth =\n          resizeParams.initialWidth +\n          (event.clientX - resizeParams.initialClientX) * 2;\n      }\n    } else {\n      if (resizeParams.handleUsed === \"left\") {\n        newWidth =\n          resizeParams.initialWidth +\n          resizeParams.initialClientX -\n          event.clientX;\n      } else {\n        newWidth =\n          resizeParams.initialWidth +\n          event.clientX -\n          resizeParams.initialClientX;\n      }\n    }\n\n    // Ensures the image is not wider than the editor and not smaller than a\n    // predetermined minimum width.\n    if (newWidth < minWidth) {\n      image.style.width = `${minWidth}px`;\n    } else if (newWidth > editor.domElement.firstElementChild!.clientWidth) {\n      image.style.width = `${\n        editor.domElement.firstElementChild!.clientWidth\n      }px`;\n    } else {\n      image.style.width = `${newWidth}px`;\n    }\n  };\n  // Stops mouse movements from resizing the image and updates the block's\n  // `width` prop to the new value.\n  const windowMouseUpHandler = (event: MouseEvent) => {\n    if (!resizeParams) {\n      return;\n    }\n\n    // Hides the drag handles if the cursor is no longer over the image.\n    if (\n      (!event.target || !imageWrapper.contains(event.target as Node)) &&\n      imageWrapper.contains(leftResizeHandle) &&\n      imageWrapper.contains(rightResizeHandle)\n    ) {\n      leftResizeHandle.style.display = \"none\";\n      rightResizeHandle.style.display = \"none\";\n    }\n\n    resizeParams = undefined;\n\n    editor.updateBlock(block, {\n      type: \"image\",\n      props: {\n        // Removes \"px\" from the end of the width string and converts to float.\n        width: parseFloat(image.style.width.slice(0, -2)) as any,\n      },\n    });\n  };\n\n  // Prevents focus from moving to the button.\n  const addImageButtonMouseDownHandler = (event: MouseEvent) => {\n    event.preventDefault();\n  };\n  // Opens the image toolbar.\n  const addImageButtonClickHandler = () => {\n    editor._tiptapEditor.view.dispatch(\n      editor._tiptapEditor.state.tr.setMeta(imageToolbarPluginKey, {\n        block: block,\n      })\n    );\n  };\n\n  // Shows the resize handles when hovering over the image with the cursor.\n  const imageMouseEnterHandler = () => {\n    if (editor.isEditable) {\n      leftResizeHandle.style.display = \"block\";\n      rightResizeHandle.style.display = \"block\";\n    } else {\n      leftResizeHandle.style.display = \"none\";\n      rightResizeHandle.style.display = \"none\";\n    }\n  };\n  // Hides the resize handles when the cursor leaves the image, unless the\n  // cursor moves to one of the resize handles.\n  const imageMouseLeaveHandler = (event: MouseEvent) => {\n    if (\n      event.relatedTarget === leftResizeHandle ||\n      event.relatedTarget === rightResizeHandle\n    ) {\n      return;\n    }\n\n    if (resizeParams) {\n      return;\n    }\n\n    leftResizeHandle.style.display = \"none\";\n    rightResizeHandle.style.display = \"none\";\n  };\n\n  // Sets the resize params, allowing the user to begin resizing the image by\n  // moving the cursor left or right.\n  const leftResizeHandleMouseDownHandler = (event: MouseEvent) => {\n    event.preventDefault();\n\n    leftResizeHandle.style.display = \"block\";\n    rightResizeHandle.style.display = \"block\";\n\n    resizeParams = {\n      handleUsed: \"left\",\n      initialWidth: block.props.width,\n      initialClientX: event.clientX,\n    };\n  };\n  const rightResizeHandleMouseDownHandler = (event: MouseEvent) => {\n    event.preventDefault();\n\n    leftResizeHandle.style.display = \"block\";\n    rightResizeHandle.style.display = \"block\";\n\n    resizeParams = {\n      handleUsed: \"right\",\n      initialWidth: block.props.width,\n      initialClientX: event.clientX,\n    };\n  };\n\n  wrapper.appendChild(addImageButton);\n  addImageButton.appendChild(addImageButtonIcon);\n  addImageButton.appendChild(addImageButtonText);\n  wrapper.appendChild(imageAndCaptionWrapper);\n  imageAndCaptionWrapper.appendChild(imageWrapper);\n  imageWrapper.appendChild(image);\n  imageWrapper.appendChild(leftResizeHandle);\n  imageWrapper.appendChild(rightResizeHandle);\n  imageAndCaptionWrapper.appendChild(caption);\n\n  window.addEventListener(\"mousemove\", windowMouseMoveHandler);\n  window.addEventListener(\"mouseup\", windowMouseUpHandler);\n  addImageButton.addEventListener(\"mousedown\", addImageButtonMouseDownHandler);\n  addImageButton.addEventListener(\"click\", addImageButtonClickHandler);\n  image.addEventListener(\"mouseenter\", imageMouseEnterHandler);\n  image.addEventListener(\"mouseleave\", imageMouseLeaveHandler);\n  leftResizeHandle.addEventListener(\n    \"mousedown\",\n    leftResizeHandleMouseDownHandler\n  );\n  rightResizeHandle.addEventListener(\n    \"mousedown\",\n    rightResizeHandleMouseDownHandler\n  );\n\n  return {\n    dom: wrapper,\n    destroy: () => {\n      window.removeEventListener(\"mousemove\", windowMouseMoveHandler);\n      window.removeEventListener(\"mouseup\", windowMouseUpHandler);\n      addImageButton.removeEventListener(\n        \"mousedown\",\n        addImageButtonMouseDownHandler\n      );\n      addImageButton.removeEventListener(\"click\", addImageButtonClickHandler);\n      leftResizeHandle.removeEventListener(\n        \"mousedown\",\n        leftResizeHandleMouseDownHandler\n      );\n      rightResizeHandle.removeEventListener(\n        \"mousedown\",\n        rightResizeHandleMouseDownHandler\n      );\n    },\n  };\n};\n\nexport const Image = createBlockSpec(\n  {\n    type: \"image\" as const,\n    propSchema: imagePropSchema,\n    content: \"none\",\n  },\n  {\n    render: renderImage,\n    toExternalHTML: (block) => {\n      if (block.props.url === \"\") {\n        const div = document.createElement(\"p\");\n        div.innerHTML = \"Add Image\";\n\n        return {\n          dom: div,\n        };\n      }\n\n      const figure = document.createElement(\"figure\");\n\n      const img = document.createElement(\"img\");\n      img.src = block.props.url;\n      figure.appendChild(img);\n\n      if (block.props.caption !== \"\") {\n        const figcaption = document.createElement(\"figcaption\");\n        figcaption.innerHTML = block.props.caption;\n        figure.appendChild(figcaption);\n      }\n\n      return {\n        dom: figure,\n      };\n    },\n    parse: (element: HTMLElement) => {\n      if (element.tagName === \"FIGURE\") {\n        const img = element.querySelector(\"img\");\n        const caption = element.querySelector(\"figcaption\");\n        return {\n          url: img?.getAttribute(\"src\") || \"\",\n          caption:\n            caption?.textContent || img?.getAttribute(\"alt\") || undefined,\n        };\n      } else if (element.tagName === \"IMG\") {\n        return {\n          url: element.getAttribute(\"src\") || \"\",\n          caption: element.getAttribute(\"alt\") || undefined,\n        };\n      }\n\n      return undefined;\n    },\n  }\n);\n","import { Editor } from \"@tiptap/core\";\nimport { getBlockInfoFromPos } from \"../../api/getBlockInfoFromPos\";\n\nexport const handleEnter = (editor: Editor) => {\n  const { node, contentType } = getBlockInfoFromPos(\n    editor.state.doc,\n    editor.state.selection.from\n  )!;\n\n  const selectionEmpty =\n    editor.state.selection.anchor === editor.state.selection.head;\n\n  if (!contentType.name.endsWith(\"ListItem\") || !selectionEmpty) {\n    return false;\n  }\n\n  return editor.commands.first(({ state, chain, commands }) => [\n    () =>\n      // Changes list item block to a text block if the content is empty.\n      commands.command(() => {\n        if (node.textContent.length === 0) {\n          return commands.BNUpdateBlock(state.selection.from, {\n            type: \"paragraph\",\n            props: {},\n          });\n        }\n\n        return false;\n      }),\n\n    () =>\n      // Splits the current block, moving content inside that's after the cursor to a new block of the same type\n      // below.\n      commands.command(() => {\n        if (node.textContent.length > 0) {\n          chain()\n            .deleteSelection()\n            .BNSplitBlock(state.selection.from, true)\n            .run();\n\n          return true;\n        }\n\n        return false;\n      }),\n  ]);\n};\n","import { InputRule } from \"@tiptap/core\";\nimport {\n  PropSchema,\n  createBlockSpecFromStronglyTypedTiptapNode,\n  createStronglyTypedTiptapNode,\n} from \"../../../schema\";\nimport { createDefaultBlockDOMOutputSpec } from \"../../defaultBlockHelpers\";\nimport { defaultProps } from \"../../defaultProps\";\nimport { handleEnter } from \"../ListItemKeyboardShortcuts\";\n\nexport const bulletListItemPropSchema = {\n  ...defaultProps,\n} satisfies PropSchema;\n\nconst BulletListItemBlockContent = createStronglyTypedTiptapNode({\n  name: \"bulletListItem\",\n  content: \"inline*\",\n  group: \"blockContent\",\n  addInputRules() {\n    return [\n      // Creates an unordered list when starting with \"-\", \"+\", or \"*\".\n      new InputRule({\n        find: new RegExp(`^[-+*]\\\\s$`),\n        handler: ({ state, chain, range }) => {\n          chain()\n            .BNUpdateBlock(state.selection.from, {\n              type: \"bulletListItem\",\n              props: {},\n            })\n            // Removes the \"-\", \"+\", or \"*\" character used to set the list.\n            .deleteRange({ from: range.from, to: range.to });\n        },\n      }),\n    ];\n  },\n\n  addKeyboardShortcuts() {\n    return {\n      Enter: () => handleEnter(this.editor),\n      \"Mod-Shift-7\": () =>\n        this.editor.commands.BNUpdateBlock(this.editor.state.selection.anchor, {\n          type: \"bulletListItem\",\n          props: {},\n        }),\n    };\n  },\n\n  parseHTML() {\n    return [\n      // Case for regular HTML list structure.\n      {\n        tag: \"div[data-content-type=\" + this.name + \"]\", // TODO: remove if we can't come up with test case that needs this\n      },\n      {\n        tag: \"li\",\n        getAttrs: (element) => {\n          if (typeof element === \"string\") {\n            return false;\n          }\n\n          const parent = element.parentElement;\n\n          if (parent === null) {\n            return false;\n          }\n\n          if (\n            parent.tagName === \"UL\" ||\n            (parent.tagName === \"DIV\" && parent.parentElement!.tagName === \"UL\")\n          ) {\n            return {};\n          }\n\n          return false;\n        },\n        node: \"bulletListItem\",\n      },\n      // Case for BlockNote list structure.\n      {\n        tag: \"p\",\n        getAttrs: (element) => {\n          if (typeof element === \"string\") {\n            return false;\n          }\n\n          const parent = element.parentElement;\n\n          if (parent === null) {\n            return false;\n          }\n\n          if (parent.getAttribute(\"data-content-type\") === \"bulletListItem\") {\n            return {};\n          }\n\n          return false;\n        },\n        priority: 300,\n        node: \"bulletListItem\",\n      },\n    ];\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    return createDefaultBlockDOMOutputSpec(\n      this.name,\n      // We use a <p> tag, because for <li> tags we'd need a <ul> element to put\n      // them in to be semantically correct, which we can't have due to the\n      // schema.\n      \"p\",\n      {\n        ...(this.options.domAttributes?.blockContent || {}),\n        ...HTMLAttributes,\n      },\n      this.options.domAttributes?.inlineContent || {}\n    );\n  },\n});\n\nexport const BulletListItem = createBlockSpecFromStronglyTypedTiptapNode(\n  BulletListItemBlockContent,\n  bulletListItemPropSchema\n);\n","import { Plugin, PluginKey } from \"prosemirror-state\";\nimport { getBlockInfoFromPos } from \"../../../api/getBlockInfoFromPos\";\n\n// ProseMirror Plugin which automatically assigns indices to ordered list items per nesting level.\nconst PLUGIN_KEY = new PluginKey(`numbered-list-indexing`);\nexport const NumberedListIndexingPlugin = () => {\n  return new Plugin({\n    key: PLUGIN_KEY,\n    appendTransaction: (_transactions, _oldState, newState) => {\n      const tr = newState.tr;\n      tr.setMeta(\"numberedListIndexing\", true);\n\n      let modified = false;\n\n      // Traverses each node the doc using DFS, so blocks which are on the same nesting level will be traversed in the\n      // same order they appear. This means the index of each list item block can be calculated by incrementing the\n      // index of the previous list item block.\n      newState.doc.descendants((node, pos) => {\n        if (\n          node.type.name === \"blockContainer\" &&\n          node.firstChild!.type.name === \"numberedListItem\"\n        ) {\n          let newIndex = \"1\";\n          const isFirstBlockInDoc = pos === 1;\n\n          const blockInfo = getBlockInfoFromPos(tr.doc, pos + 1)!;\n          if (blockInfo === undefined) {\n            return;\n          }\n\n          // Checks if this block is the start of a new ordered list, i.e. if it's the first block in the document, the\n          // first block in its nesting level, or the previous block is not an ordered list item.\n          if (!isFirstBlockInDoc) {\n            const prevBlockInfo = getBlockInfoFromPos(tr.doc, pos - 2)!;\n            if (prevBlockInfo === undefined) {\n              return;\n            }\n\n            const isFirstBlockInNestingLevel =\n              blockInfo.depth !== prevBlockInfo.depth;\n\n            if (!isFirstBlockInNestingLevel) {\n              const prevBlockContentNode = prevBlockInfo.contentNode;\n              const prevBlockContentType = prevBlockInfo.contentType;\n\n              const isPrevBlockOrderedListItem =\n                prevBlockContentType.name === \"numberedListItem\";\n\n              if (isPrevBlockOrderedListItem) {\n                const prevBlockIndex = prevBlockContentNode.attrs[\"index\"];\n\n                newIndex = (parseInt(prevBlockIndex) + 1).toString();\n              }\n            }\n          }\n\n          const contentNode = blockInfo.contentNode;\n          const index = contentNode.attrs[\"index\"];\n\n          if (index !== newIndex) {\n            modified = true;\n\n            tr.setNodeMarkup(pos + 1, undefined, {\n              index: newIndex,\n            });\n          }\n        }\n      });\n\n      return modified ? tr : null;\n    },\n  });\n};\n","import { InputRule } from \"@tiptap/core\";\nimport {\n  PropSchema,\n  createBlockSpecFromStronglyTypedTiptapNode,\n  createStronglyTypedTiptapNode,\n} from \"../../../schema\";\nimport { createDefaultBlockDOMOutputSpec } from \"../../defaultBlockHelpers\";\nimport { defaultProps } from \"../../defaultProps\";\nimport { handleEnter } from \"../ListItemKeyboardShortcuts\";\nimport { NumberedListIndexingPlugin } from \"./NumberedListIndexingPlugin\";\n\nexport const numberedListItemPropSchema = {\n  ...defaultProps,\n} satisfies PropSchema;\n\nconst NumberedListItemBlockContent = createStronglyTypedTiptapNode({\n  name: \"numberedListItem\",\n  content: \"inline*\",\n  group: \"blockContent\",\n  addAttributes() {\n    return {\n      index: {\n        default: null,\n        parseHTML: (element) => element.getAttribute(\"data-index\"),\n        renderHTML: (attributes) => {\n          return {\n            \"data-index\": attributes.index,\n          };\n        },\n      },\n    };\n  },\n\n  addInputRules() {\n    return [\n      // Creates an ordered list when starting with \"1.\".\n      new InputRule({\n        find: new RegExp(`^1\\\\.\\\\s$`),\n        handler: ({ state, chain, range }) => {\n          chain()\n            .BNUpdateBlock(state.selection.from, {\n              type: \"numberedListItem\",\n              props: {},\n            })\n            // Removes the \"1.\" characters used to set the list.\n            .deleteRange({ from: range.from, to: range.to });\n        },\n      }),\n    ];\n  },\n\n  addKeyboardShortcuts() {\n    return {\n      Enter: () => handleEnter(this.editor),\n      \"Mod-Shift-8\": () =>\n        this.editor.commands.BNUpdateBlock(this.editor.state.selection.anchor, {\n          type: \"numberedListItem\",\n          props: {},\n        }),\n    };\n  },\n\n  addProseMirrorPlugins() {\n    return [NumberedListIndexingPlugin()];\n  },\n\n  parseHTML() {\n    return [\n      {\n        tag: \"div[data-content-type=\" + this.name + \"]\", // TODO: remove if we can't come up with test case that needs this\n      },\n      // Case for regular HTML list structure.\n      // (e.g.: when pasting from other apps)\n      {\n        tag: \"li\",\n        getAttrs: (element) => {\n          if (typeof element === \"string\") {\n            return false;\n          }\n\n          const parent = element.parentElement;\n\n          if (parent === null) {\n            return false;\n          }\n\n          if (\n            parent.tagName === \"OL\" ||\n            (parent.tagName === \"DIV\" && parent.parentElement!.tagName === \"OL\")\n          ) {\n            return {};\n          }\n\n          return false;\n        },\n        node: \"numberedListItem\",\n      },\n      // Case for BlockNote list structure.\n      // (e.g.: when pasting from blocknote)\n      {\n        tag: \"p\",\n        getAttrs: (element) => {\n          if (typeof element === \"string\") {\n            return false;\n          }\n\n          const parent = element.parentElement;\n\n          if (parent === null) {\n            return false;\n          }\n\n          if (parent.getAttribute(\"data-content-type\") === \"numberedListItem\") {\n            return {};\n          }\n\n          return false;\n        },\n        priority: 300,\n        node: \"numberedListItem\",\n      },\n    ];\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    return createDefaultBlockDOMOutputSpec(\n      this.name,\n      // We use a <p> tag, because for <li> tags we'd need an <ol> element to\n      // put them in to be semantically correct, which we can't have due to the\n      // schema.\n      \"p\",\n      {\n        ...(this.options.domAttributes?.blockContent || {}),\n        ...HTMLAttributes,\n      },\n      this.options.domAttributes?.inlineContent || {}\n    );\n  },\n});\n\nexport const NumberedListItem = createBlockSpecFromStronglyTypedTiptapNode(\n  NumberedListItemBlockContent,\n  numberedListItemPropSchema\n);\n","import {\n  createBlockSpecFromStronglyTypedTiptapNode,\n  createStronglyTypedTiptapNode,\n} from \"../../schema\";\nimport { createDefaultBlockDOMOutputSpec } from \"../defaultBlockHelpers\";\nimport { defaultProps } from \"../defaultProps\";\n\nexport const paragraphPropSchema = {\n  ...defaultProps,\n};\n\nexport const ParagraphBlockContent = createStronglyTypedTiptapNode({\n  name: \"paragraph\",\n  content: \"inline*\",\n  group: \"blockContent\",\n  parseHTML() {\n    return [\n      { tag: \"div[data-content-type=\" + this.name + \"]\" },\n      {\n        tag: \"p\",\n        priority: 200,\n        node: \"paragraph\",\n      },\n    ];\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    return createDefaultBlockDOMOutputSpec(\n      this.name,\n      \"p\",\n      {\n        ...(this.options.domAttributes?.blockContent || {}),\n        ...HTMLAttributes,\n      },\n      this.options.domAttributes?.inlineContent || {}\n    );\n  },\n});\n\nexport const Paragraph = createBlockSpecFromStronglyTypedTiptapNode(\n  ParagraphBlockContent,\n  paragraphPropSchema\n);\n","import { callOrReturn, Extension, getExtensionField } from \"@tiptap/core\";\nimport { columnResizing, tableEditing } from \"prosemirror-tables\";\n\nexport const TableExtension = Extension.create({\n  name: \"BlockNoteTableExtension\",\n\n  addProseMirrorPlugins: () => {\n    return [\n      columnResizing({\n        cellMinWidth: 100,\n      }),\n      tableEditing(),\n    ];\n  },\n\n  addKeyboardShortcuts() {\n    return {\n      // Makes enter create a new line within the cell.\n      Enter: () => {\n        if (\n          this.editor.state.selection.empty &&\n          this.editor.state.selection.$head.parent.type.name ===\n            \"tableParagraph\"\n        ) {\n          this.editor.commands.setHardBreak();\n\n          return true;\n        }\n\n        return false;\n      },\n      // Ensures that backspace won't delete the table if the text cursor is at\n      // the start of a cell and the selection is empty.\n      Backspace: () => {\n        const selection = this.editor.state.selection;\n        const selectionIsEmpty = selection.empty;\n        const selectionIsAtStartOfNode = selection.$head.parentOffset === 0;\n        const selectionIsInTableParagraphNode =\n          selection.$head.node().type.name === \"tableParagraph\";\n\n        return (\n          selectionIsEmpty &&\n          selectionIsAtStartOfNode &&\n          selectionIsInTableParagraphNode\n        );\n      },\n    };\n  },\n\n  extendNodeSchema(extension) {\n    const context = {\n      name: extension.name,\n      options: extension.options,\n      storage: extension.storage,\n    };\n\n    return {\n      tableRole: callOrReturn(\n        getExtensionField(extension, \"tableRole\", context)\n      ),\n    };\n  },\n});\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { TableCell } from \"@tiptap/extension-table-cell\";\nimport { TableHeader } from \"@tiptap/extension-table-header\";\nimport { TableRow } from \"@tiptap/extension-table-row\";\nimport {\n  createBlockSpecFromStronglyTypedTiptapNode,\n  createStronglyTypedTiptapNode,\n} from \"../../schema\";\nimport { createDefaultBlockDOMOutputSpec } from \"../defaultBlockHelpers\";\nimport { defaultProps } from \"../defaultProps\";\nimport { TableExtension } from \"./TableExtension\";\n\nexport const tablePropSchema = {\n  ...defaultProps,\n};\n\nexport const TableBlockContent = createStronglyTypedTiptapNode({\n  name: \"table\",\n  content: \"tableRow+\",\n  group: \"blockContent\",\n  tableRole: \"table\",\n\n  isolating: true,\n\n  parseHTML() {\n    return [{ tag: \"table\" }];\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    return createDefaultBlockDOMOutputSpec(\n      this.name,\n      \"table\",\n      {\n        ...(this.options.domAttributes?.blockContent || {}),\n        ...HTMLAttributes,\n      },\n      this.options.domAttributes?.inlineContent || {}\n    );\n  },\n});\n\nconst TableParagraph = Node.create({\n  name: \"tableParagraph\",\n  group: \"tableContent\",\n  content: \"inline*\",\n\n  parseHTML() {\n    return [{ tag: \"p\" }];\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    return [\n      \"p\",\n      mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n      0,\n    ];\n  },\n});\n\nexport const Table = createBlockSpecFromStronglyTypedTiptapNode(\n  TableBlockContent,\n  tablePropSchema,\n  [\n    TableExtension,\n    TableParagraph,\n    TableHeader.extend({\n      content: \"tableContent\",\n    }),\n    TableCell.extend({\n      content: \"tableContent\",\n    }),\n    TableRow,\n  ]\n);\n","import Bold from \"@tiptap/extension-bold\";\nimport Code from \"@tiptap/extension-code\";\nimport Italic from \"@tiptap/extension-italic\";\nimport Strike from \"@tiptap/extension-strike\";\nimport Underline from \"@tiptap/extension-underline\";\nimport { BackgroundColor } from \"../extensions/BackgroundColor/BackgroundColorMark\";\nimport { TextColor } from \"../extensions/TextColor/TextColorMark\";\nimport {\n  BlockSpecs,\n  InlineContentSpecs,\n  StyleSpecs,\n  createStyleSpecFromTipTapMark,\n  getBlockSchemaFromSpecs,\n  getInlineContentSchemaFromSpecs,\n  getStyleSchemaFromSpecs,\n} from \"../schema\";\nimport { Heading } from \"./HeadingBlockContent/HeadingBlockContent\";\nimport { Image } from \"./ImageBlockContent/ImageBlockContent\";\nimport { BulletListItem } from \"./ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent\";\nimport { NumberedListItem } from \"./ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent\";\nimport { Paragraph } from \"./ParagraphBlockContent/ParagraphBlockContent\";\nimport { Table } from \"./TableBlockContent/TableBlockContent\";\n\nexport const defaultBlockSpecs = {\n  paragraph: Paragraph,\n  heading: Heading,\n  bulletListItem: BulletListItem,\n  numberedListItem: NumberedListItem,\n  image: Image,\n  table: Table,\n} satisfies BlockSpecs;\n\nexport const defaultBlockSchema = getBlockSchemaFromSpecs(defaultBlockSpecs);\n\nexport type DefaultBlockSchema = typeof defaultBlockSchema;\n\nexport const defaultStyleSpecs = {\n  bold: createStyleSpecFromTipTapMark(Bold, \"boolean\"),\n  italic: createStyleSpecFromTipTapMark(Italic, \"boolean\"),\n  underline: createStyleSpecFromTipTapMark(Underline, \"boolean\"),\n  strike: createStyleSpecFromTipTapMark(Strike, \"boolean\"),\n  code: createStyleSpecFromTipTapMark(Code, \"boolean\"),\n  textColor: TextColor,\n  backgroundColor: BackgroundColor,\n} satisfies StyleSpecs;\n\nexport const defaultStyleSchema = getStyleSchemaFromSpecs(defaultStyleSpecs);\n\nexport type DefaultStyleSchema = typeof defaultStyleSchema;\n\nexport const defaultInlineContentSpecs = {\n  text: { config: \"text\", implementation: {} as any },\n  link: { config: \"link\", implementation: {} as any },\n} satisfies InlineContentSpecs;\n\nexport const defaultInlineContentSchema = getInlineContentSchemaFromSpecs(\n  defaultInlineContentSpecs\n);\n\nexport type DefaultInlineContentSchema = typeof defaultInlineContentSchema;\n","import { Node } from \"prosemirror-model\";\n\n/**\n * Get a TipTap node by id\n */\nexport function getNodeById(\n  id: string,\n  doc: Node\n): { node: Node; posBeforeNode: number } {\n  let targetNode: Node | undefined = undefined;\n  let posBeforeNode: number | undefined = undefined;\n\n  doc.firstChild!.descendants((node, pos) => {\n    // Skips traversing nodes after node with target ID has been found.\n    if (targetNode) {\n      return false;\n    }\n\n    // Keeps traversing nodes if block with target ID has not been found.\n    if (node.type.name !== \"blockContainer\" || node.attrs.id !== id) {\n      return true;\n    }\n\n    targetNode = node;\n    posBeforeNode = pos + 1;\n\n    return false;\n  });\n\n  if (targetNode === undefined || posBeforeNode === undefined) {\n    throw Error(\"Could not find block in the editor with matching ID.\");\n  }\n\n  return {\n    node: targetNode,\n    posBeforeNode: posBeforeNode,\n  };\n}\n","import { Editor } from \"@tiptap/core\";\nimport { Node } from \"prosemirror-model\";\n\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport {\n  BlockIdentifier,\n  BlockSchema,\n  InlineContentSchema,\n  PartialBlock,\n  StyleSchema,\n} from \"../../schema\";\nimport { blockToNode } from \"../nodeConversions/nodeConversions\";\nimport { getNodeById } from \"../nodeUtil\";\nimport { EditorState } from \"prosemirror-state\";\n\nexport function insertBlocks<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  blocksToInsert: PartialBlock<BSchema, I, S>[],\n  referenceBlock: BlockIdentifier,\n  placement: \"before\" | \"after\" | \"nested\" = \"before\",\n  editor: BlockNoteEditor<BSchema, I, S>,\n  eraseHistory?: boolean\n): void {\n  const ttEditor = editor._tiptapEditor;\n\n  const id =\n    typeof referenceBlock === \"string\" ? referenceBlock : referenceBlock.id;\n\n  const nodesToInsert: Node[] = [];\n  for (const blockSpec of blocksToInsert) {\n    nodesToInsert.push(\n      blockToNode(blockSpec, ttEditor.schema, editor.styleSchema)\n    );\n  }\n\n  let insertionPos = -1;\n\n  const { node, posBeforeNode } = getNodeById(id, ttEditor.state.doc);\n\n  if (placement === \"before\") {\n    insertionPos = posBeforeNode;\n  }\n\n  if (placement === \"after\") {\n    insertionPos = posBeforeNode + node.nodeSize;\n  }\n\n  if (placement === \"nested\") {\n    // Case if block doesn't already have children.\n    if (node.childCount < 2) {\n      insertionPos = posBeforeNode + node.firstChild!.nodeSize + 1;\n\n      const blockGroupNode = ttEditor.state.schema.nodes[\"blockGroup\"].create(\n        {},\n        nodesToInsert\n      );\n\n      ttEditor.view.dispatch(\n        ttEditor.state.tr.insert(insertionPos, blockGroupNode)\n      );\n\n      return;\n    }\n\n    insertionPos = posBeforeNode + node.firstChild!.nodeSize + 2;\n  }\n\n  ttEditor.view.dispatch(ttEditor.state.tr.insert(insertionPos, nodesToInsert));\n\n  if (eraseHistory) {\n    const newEditorState = EditorState.create({\n      doc: ttEditor.state.doc,\n      plugins: ttEditor.state.plugins,\n      schema: ttEditor.state.schema,\n    });\n    ttEditor.view.updateState(newEditorState);\n  }\n}\n\nexport function updateBlock<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  blockToUpdate: BlockIdentifier,\n  update: PartialBlock<BSchema, I, S>,\n  editor: Editor\n) {\n  const id =\n    typeof blockToUpdate === \"string\" ? blockToUpdate : blockToUpdate.id;\n  const { posBeforeNode } = getNodeById(id, editor.state.doc);\n\n  editor.commands.BNUpdateBlock(posBeforeNode + 1, update);\n}\n\nexport function removeBlocks(\n  blocksToRemove: BlockIdentifier[],\n  editor: Editor,\n  eraseHistory?: boolean\n) {\n  const idsOfBlocksToRemove = new Set<string>(\n    blocksToRemove.map((block) =>\n      typeof block === \"string\" ? block : block.id\n    )\n  );\n\n  let removedSize = 0;\n\n  editor.state.doc.descendants((node, pos) => {\n    // Skips traversing nodes after all target blocks have been removed.\n    if (idsOfBlocksToRemove.size === 0) {\n      return false;\n    }\n\n    // Keeps traversing nodes if block with target ID has not been found.\n    if (\n      node.type.name !== \"blockContainer\" ||\n      !idsOfBlocksToRemove.has(node.attrs.id)\n    ) {\n      return true;\n    }\n\n    idsOfBlocksToRemove.delete(node.attrs.id);\n    const oldDocSize = editor.state.doc.nodeSize;\n\n    editor.commands.BNDeleteBlock(pos - removedSize + 1);\n\n    const newDocSize = editor.state.doc.nodeSize;\n    removedSize += oldDocSize - newDocSize;\n\n    return false;\n  });\n\n  if (eraseHistory) {\n    const newEditorState = EditorState.create({\n      doc: editor.state.doc,\n      plugins: editor.state.plugins,\n      schema: editor.state.schema,\n    });\n    editor.view.updateState(newEditorState);\n  }\n\n  if (idsOfBlocksToRemove.size > 0) {\n    const notFoundIds = [...idsOfBlocksToRemove].join(\"\\n\");\n\n    throw Error(\n      \"Blocks with the following IDs could not be found in the editor: \" +\n        notFoundIds\n    );\n  }\n}\n\nexport function replaceBlocks<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  blocksToRemove: BlockIdentifier[],\n  blocksToInsert: PartialBlock<BSchema, I, S>[],\n  editor: BlockNoteEditor<BSchema, I, S>,\n  eraseHistory = false\n) {\n  insertBlocks(\n    blocksToInsert,\n    blocksToRemove[0],\n    \"before\",\n    editor,\n    eraseHistory\n  );\n  removeBlocks(blocksToRemove, editor._tiptapEditor, eraseHistory);\n}\n","import { Element as HASTElement, Parent as HASTParent } from \"hast\";\n\n/**\n * Rehype plugin which removes <u> tags. Used to remove underlines before converting HTML to markdown, as Markdown\n * doesn't support underlines.\n */\nexport function removeUnderlines() {\n  const removeUnderlinesHelper = (tree: HASTParent) => {\n    let numChildElements = tree.children.length;\n\n    for (let i = 0; i < numChildElements; i++) {\n      const node = tree.children[i];\n\n      if (node.type === \"element\") {\n        // Recursively removes underlines from child elements.\n        removeUnderlinesHelper(node);\n\n        if ((node as HASTElement).tagName === \"u\") {\n          // Lifts child nodes outside underline element, deletes the underline element, and updates current index &\n          // the number of child elements.\n          if (node.children.length > 0) {\n            tree.children.splice(i, 1, ...node.children);\n\n            const numElementsAdded = node.children.length - 1;\n            numChildElements += numElementsAdded;\n            i += numElementsAdded;\n          } else {\n            tree.children.splice(i, 1);\n\n            numChildElements--;\n            i--;\n          }\n        }\n      }\n    }\n  };\n\n  return removeUnderlinesHelper;\n}\n","import { Schema } from \"prosemirror-model\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeRemark from \"rehype-remark\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkStringify from \"remark-stringify\";\nimport { unified } from \"unified\";\nimport type { BlockNoteEditor } from \"../../../editor/BlockNoteEditor\";\nimport {\n  Block,\n  BlockSchema,\n  InlineContentSchema,\n  StyleSchema,\n} from \"../../../schema\";\nimport { createExternalHTMLExporter } from \"../html/externalHTMLExporter\";\nimport { removeUnderlines } from \"./removeUnderlinesRehypePlugin\";\n\nexport function cleanHTMLToMarkdown(cleanHTMLString: string) {\n  const markdownString = unified()\n    .use(rehypeParse, { fragment: true })\n    .use(removeUnderlines)\n    .use(rehypeRemark)\n    .use(remarkGfm)\n    .use(remarkStringify)\n    .processSync(cleanHTMLString);\n\n  return markdownString.value as string;\n}\n\nexport function blocksToMarkdown<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  blocks: Block<BSchema, I, S>[],\n  schema: Schema,\n  editor: BlockNoteEditor<BSchema, I, S>\n): string {\n  const exporter = createExternalHTMLExporter(schema, editor);\n  const externalHTML = exporter.exportBlocks(blocks);\n\n  return cleanHTMLToMarkdown(externalHTML);\n}\n","function getChildIndex(node: Element) {\n  return Array.prototype.indexOf.call(node.parentElement!.childNodes, node);\n}\n\nfunction isWhitespaceNode(node: Node) {\n  return node.nodeType === 3 && !/\\S/.test(node.nodeValue || \"\");\n}\n\n/**\n * Step 1, Turns:\n *\n * <ul>\n *  <li>item</li>\n *  <li>\n *   <ul>\n *      <li>...</li>\n *      <li>...</li>\n *   </ul>\n * </li>\n *\n * Into:\n * <ul>\n *  <li>item</li>\n *  <ul>\n *      <li>...</li>\n *      <li>...</li>\n *  </ul>\n * </ul>\n *\n */\nfunction liftNestedListsToParent(element: HTMLElement) {\n  element.querySelectorAll(\"li > ul, li > ol\").forEach((list) => {\n    const index = getChildIndex(list);\n    const parentListItem = list.parentElement!;\n    const siblingsAfter = Array.from(parentListItem.childNodes).slice(\n      index + 1\n    );\n    list.remove();\n    siblingsAfter.forEach((sibling) => {\n      sibling.remove();\n    });\n\n    parentListItem.insertAdjacentElement(\"afterend\", list);\n\n    siblingsAfter.reverse().forEach((sibling) => {\n      if (isWhitespaceNode(sibling)) {\n        return;\n      }\n      const siblingContainer = document.createElement(\"li\");\n      siblingContainer.append(sibling);\n      list.insertAdjacentElement(\"afterend\", siblingContainer);\n    });\n    if (parentListItem.childNodes.length === 0) {\n      parentListItem.remove();\n    }\n  });\n}\n\n/**\n * Step 2, Turns (output of liftNestedListsToParent):\n *\n * <li>item</li>\n * <ul>\n *   <li>...</li>\n *   <li>...</li>\n * </ul>\n *\n * Into:\n * <div>\n *  <li>item</li>\n *  <div data-node-type=\"blockGroup\">\n *      <ul>\n *          <li>...</li>\n *          <li>...</li>\n *      </ul>\n *  </div>\n * </div>\n *\n * This resulting format is parsed\n */\nfunction createGroups(element: HTMLElement) {\n  element.querySelectorAll(\"li + ul, li + ol\").forEach((list) => {\n    const listItem = list.previousElementSibling as HTMLElement;\n    const blockContainer = document.createElement(\"div\");\n\n    listItem.insertAdjacentElement(\"afterend\", blockContainer);\n    blockContainer.append(listItem);\n\n    const blockGroup = document.createElement(\"div\");\n    blockGroup.setAttribute(\"data-node-type\", \"blockGroup\");\n    blockContainer.append(blockGroup);\n\n    while (\n      blockContainer.nextElementSibling?.nodeName === \"UL\" ||\n      blockContainer.nextElementSibling?.nodeName === \"OL\"\n    ) {\n      blockGroup.append(blockContainer.nextElementSibling);\n    }\n  });\n}\n\nexport function nestedListsToBlockNoteStructure(\n  elementOrHTML: HTMLElement | string\n) {\n  if (typeof elementOrHTML === \"string\") {\n    const element = document.createElement(\"div\");\n    element.innerHTML = elementOrHTML;\n    elementOrHTML = element;\n  }\n  liftNestedListsToParent(elementOrHTML);\n  createGroups(elementOrHTML);\n  return elementOrHTML;\n}\n","import { DOMParser, Schema } from \"prosemirror-model\";\nimport {\n  Block,\n  BlockSchema,\n  InlineContentSchema,\n  StyleSchema,\n} from \"../../../schema\";\n\nimport { nodeToBlock } from \"../../nodeConversions/nodeConversions\";\nimport { nestedListsToBlockNoteStructure } from \"./util/nestedLists\";\nexport async function HTMLToBlocks<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  html: string,\n  blockSchema: BSchema,\n  icSchema: I,\n  styleSchema: S,\n  pmSchema: Schema\n): Promise<Block<BSchema, I, S>[]> {\n  const htmlNode = nestedListsToBlockNoteStructure(html);\n  const parser = DOMParser.fromSchema(pmSchema);\n\n  // Other approach might be to use\n  // const doc = pmSchema.nodes[\"doc\"].createAndFill()!;\n  // and context: doc.resolve(3),\n\n  const parentNode = parser.parse(htmlNode, {\n    topNode: pmSchema.nodes[\"blockGroup\"].create(),\n  });\n\n  const blocks: Block<BSchema, I, S>[] = [];\n\n  for (let i = 0; i < parentNode.childCount; i++) {\n    blocks.push(\n      nodeToBlock(parentNode.child(i), blockSchema, icSchema, styleSchema)\n    );\n  }\n\n  return blocks;\n}\n","import { Schema } from \"prosemirror-model\";\nimport rehypeStringify from \"rehype-stringify\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkParse from \"remark-parse\";\nimport remarkRehype, { defaultHandlers } from \"remark-rehype\";\nimport { unified } from \"unified\";\nimport {\n  Block,\n  BlockSchema,\n  InlineContentSchema,\n  StyleSchema,\n} from \"../../../schema\";\nimport { HTMLToBlocks } from \"../html/parseHTML\";\n\n// modified version of https://github.com/syntax-tree/mdast-util-to-hast/blob/main/lib/handlers/code.js\n// that outputs a data-language attribute instead of a CSS class (e.g.: language-typescript)\nfunction code(state: any, node: any) {\n  const value = node.value ? node.value + \"\\n\" : \"\";\n  /** @type {Properties} */\n  const properties: any = {};\n\n  if (node.lang) {\n    // changed line\n    properties[\"data-language\"] = node.lang;\n  }\n\n  // Create `<code>`.\n  /** @type {Element} */\n  let result: any = {\n    type: \"element\",\n    tagName: \"code\",\n    properties,\n    children: [{ type: \"text\", value }],\n  };\n\n  if (node.meta) {\n    result.data = { meta: node.meta };\n  }\n\n  state.patch(node, result);\n  result = state.applyData(node, result);\n\n  // Create `<pre>`.\n  result = {\n    type: \"element\",\n    tagName: \"pre\",\n    properties: {},\n    children: [result],\n  };\n  state.patch(node, result);\n  return result;\n}\n\nexport function markdownToBlocks<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  markdown: string,\n  blockSchema: BSchema,\n  icSchema: I,\n  styleSchema: S,\n  pmSchema: Schema\n): Promise<Block<BSchema, I, S>[]> {\n  const htmlString = unified()\n    .use(remarkParse)\n    .use(remarkGfm)\n    .use(remarkRehype, {\n      handlers: {\n        ...(defaultHandlers as any),\n        code,\n      },\n    })\n    .use(rehypeStringify)\n    .processSync(markdown);\n\n  return HTMLToBlocks(\n    htmlString.value as string,\n    blockSchema,\n    icSchema,\n    styleSchema,\n    pmSchema\n  );\n}\n","import { isNodeSelection, posToDOMRect } from \"@tiptap/core\";\nimport { EditorState, Plugin, PluginKey } from \"prosemirror-state\";\nimport { EditorView } from \"prosemirror-view\";\n\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport {\n  BaseUiElementCallbacks,\n  BaseUiElementState,\n} from \"../../extensions-shared/BaseUiElementTypes\";\nimport { BlockSchema, InlineContentSchema, StyleSchema } from \"../../schema\";\nimport { EventEmitter } from \"../../util/EventEmitter\";\n\nexport type FormattingToolbarCallbacks = BaseUiElementCallbacks;\n\nexport type FormattingToolbarState = BaseUiElementState;\n\nexport class FormattingToolbarView {\n  private formattingToolbarState?: FormattingToolbarState;\n  public updateFormattingToolbar: () => void;\n\n  public preventHide = false;\n  public preventShow = false;\n  public prevWasEditable: boolean | null = null;\n\n  public shouldShow: (props: {\n    view: EditorView;\n    state: EditorState;\n    from: number;\n    to: number;\n  }) => boolean = ({ state }) => !state.selection.empty;\n\n  constructor(\n    private readonly editor: BlockNoteEditor<\n      BlockSchema,\n      InlineContentSchema,\n      StyleSchema\n    >,\n    private readonly pmView: EditorView,\n    updateFormattingToolbar: (\n      formattingToolbarState: FormattingToolbarState\n    ) => void\n  ) {\n    this.updateFormattingToolbar = () => {\n      if (!this.formattingToolbarState) {\n        throw new Error(\n          \"Attempting to update uninitialized formatting toolbar\"\n        );\n      }\n\n      updateFormattingToolbar(this.formattingToolbarState);\n    };\n\n    pmView.dom.addEventListener(\"mousedown\", this.viewMousedownHandler);\n    pmView.dom.addEventListener(\"mouseup\", this.viewMouseupHandler);\n    pmView.dom.addEventListener(\"dragstart\", this.dragstartHandler);\n\n    pmView.dom.addEventListener(\"focus\", this.focusHandler);\n    pmView.dom.addEventListener(\"blur\", this.blurHandler);\n\n    document.addEventListener(\"scroll\", this.scrollHandler);\n  }\n\n  viewMousedownHandler = () => {\n    this.preventShow = true;\n  };\n\n  viewMouseupHandler = () => {\n    this.preventShow = false;\n    setTimeout(() => this.update(this.pmView));\n  };\n\n  // For dragging the whole editor.\n  dragstartHandler = () => {\n    if (this.formattingToolbarState?.show) {\n      this.formattingToolbarState.show = false;\n      this.updateFormattingToolbar();\n    }\n  };\n\n  focusHandler = () => {\n    // we use `setTimeout` to make sure `selection` is already updated\n    setTimeout(() => this.update(this.pmView));\n  };\n\n  blurHandler = (event: FocusEvent) => {\n    if (this.preventHide) {\n      this.preventHide = false;\n\n      return;\n    }\n\n    const editorWrapper = this.pmView.dom.parentElement!;\n\n    // Checks if the focus is moving to an element outside the editor. If it is,\n    // the toolbar is hidden.\n    if (\n      // An element is clicked.\n      event &&\n      event.relatedTarget &&\n      // Element is inside the editor.\n      (editorWrapper === (event.relatedTarget as Node) ||\n        editorWrapper.contains(event.relatedTarget as Node))\n    ) {\n      return;\n    }\n\n    if (this.formattingToolbarState?.show) {\n      this.formattingToolbarState.show = false;\n      this.updateFormattingToolbar();\n    }\n  };\n\n  scrollHandler = () => {\n    if (this.formattingToolbarState?.show) {\n      this.formattingToolbarState.referencePos = this.getSelectionBoundingBox();\n      this.updateFormattingToolbar();\n    }\n  };\n\n  update(view: EditorView, oldState?: EditorState) {\n    const { state, composing } = view;\n    const { doc, selection } = state;\n    const isSame =\n      oldState && oldState.doc.eq(doc) && oldState.selection.eq(selection);\n\n    if (\n      (this.prevWasEditable === null ||\n        this.prevWasEditable === this.editor.isEditable) &&\n      (composing || isSame)\n    ) {\n      return;\n    }\n\n    this.prevWasEditable = this.editor.isEditable;\n\n    // support for CellSelections\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\n    const shouldShow = this.shouldShow?.({\n      view,\n      state,\n      from,\n      to,\n    });\n\n    // Checks if menu should be shown/updated.\n    if (\n      this.editor.isEditable &&\n      !this.preventShow &&\n      (shouldShow || this.preventHide)\n    ) {\n      this.formattingToolbarState = {\n        show: true,\n        referencePos: this.getSelectionBoundingBox(),\n      };\n\n      this.updateFormattingToolbar();\n\n      return;\n    }\n\n    // Checks if menu should be hidden.\n    if (\n      this.formattingToolbarState?.show &&\n      !this.preventHide &&\n      (!shouldShow || this.preventShow || !this.editor.isEditable)\n    ) {\n      this.formattingToolbarState.show = false;\n      this.updateFormattingToolbar();\n\n      return;\n    }\n  }\n\n  destroy() {\n    this.pmView.dom.removeEventListener(\"mousedown\", this.viewMousedownHandler);\n    this.pmView.dom.removeEventListener(\"mouseup\", this.viewMouseupHandler);\n    this.pmView.dom.removeEventListener(\"dragstart\", this.dragstartHandler);\n\n    this.pmView.dom.removeEventListener(\"focus\", this.focusHandler);\n    this.pmView.dom.removeEventListener(\"blur\", this.blurHandler);\n\n    document.removeEventListener(\"scroll\", this.scrollHandler);\n  }\n\n  getSelectionBoundingBox() {\n    const { state } = this.pmView;\n    const { selection } = state;\n\n    // support for CellSelections\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\n    if (isNodeSelection(selection)) {\n      const node = this.pmView.nodeDOM(from) as HTMLElement;\n\n      if (node) {\n        return node.getBoundingClientRect();\n      }\n    }\n\n    return posToDOMRect(this.pmView, from, to);\n  }\n}\n\nexport const formattingToolbarPluginKey = new PluginKey(\n  \"FormattingToolbarPlugin\"\n);\n\nexport class FormattingToolbarProsemirrorPlugin extends EventEmitter<any> {\n  private view: FormattingToolbarView | undefined;\n  public readonly plugin: Plugin;\n\n  constructor(editor: BlockNoteEditor<any, any, any>) {\n    super();\n    this.plugin = new Plugin({\n      key: formattingToolbarPluginKey,\n      view: (editorView) => {\n        this.view = new FormattingToolbarView(editor, editorView, (state) => {\n          this.emit(\"update\", state);\n        });\n        return this.view;\n      },\n    });\n  }\n\n  public onUpdate(callback: (state: FormattingToolbarState) => void) {\n    return this.on(\"update\", callback);\n  }\n}\n","import { getMarkRange, posToDOMRect, Range } from \"@tiptap/core\";\nimport { EditorView } from \"@tiptap/pm/view\";\nimport { Mark } from \"prosemirror-model\";\nimport { Plugin, PluginKey } from \"prosemirror-state\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport { BaseUiElementState } from \"../../extensions-shared/BaseUiElementTypes\";\nimport { BlockSchema, InlineContentSchema, StyleSchema } from \"../../schema\";\nimport { EventEmitter } from \"../../util/EventEmitter\";\n\nexport type HyperlinkToolbarState = BaseUiElementState & {\n  // The hovered hyperlink's URL, and the text it's displayed with in the\n  // editor.\n  url: string;\n  text: string;\n};\n\nclass HyperlinkToolbarView {\n  private hyperlinkToolbarState?: HyperlinkToolbarState;\n  public updateHyperlinkToolbar: () => void;\n\n  menuUpdateTimer: ReturnType<typeof setTimeout> | undefined;\n  startMenuUpdateTimer: () => void;\n  stopMenuUpdateTimer: () => void;\n\n  mouseHoveredHyperlinkMark: Mark | undefined;\n  mouseHoveredHyperlinkMarkRange: Range | undefined;\n\n  keyboardHoveredHyperlinkMark: Mark | undefined;\n  keyboardHoveredHyperlinkMarkRange: Range | undefined;\n\n  hyperlinkMark: Mark | undefined;\n  hyperlinkMarkRange: Range | undefined;\n\n  constructor(\n    private readonly editor: BlockNoteEditor<any, any, any>,\n    private readonly pmView: EditorView,\n    updateHyperlinkToolbar: (\n      hyperlinkToolbarState: HyperlinkToolbarState\n    ) => void\n  ) {\n    this.updateHyperlinkToolbar = () => {\n      if (!this.hyperlinkToolbarState) {\n        throw new Error(\"Attempting to update uninitialized hyperlink toolbar\");\n      }\n\n      updateHyperlinkToolbar(this.hyperlinkToolbarState);\n    };\n\n    this.startMenuUpdateTimer = () => {\n      this.menuUpdateTimer = setTimeout(() => {\n        this.update();\n      }, 250);\n    };\n\n    this.stopMenuUpdateTimer = () => {\n      if (this.menuUpdateTimer) {\n        clearTimeout(this.menuUpdateTimer);\n        this.menuUpdateTimer = undefined;\n      }\n\n      return false;\n    };\n\n    this.pmView.dom.addEventListener(\"mouseover\", this.mouseOverHandler);\n    document.addEventListener(\"click\", this.clickHandler, true);\n    document.addEventListener(\"scroll\", this.scrollHandler);\n  }\n\n  mouseOverHandler = (event: MouseEvent) => {\n    // Resets the hyperlink mark currently hovered by the mouse cursor.\n    this.mouseHoveredHyperlinkMark = undefined;\n    this.mouseHoveredHyperlinkMarkRange = undefined;\n\n    this.stopMenuUpdateTimer();\n\n    if (\n      event.target instanceof HTMLAnchorElement &&\n      event.target.nodeName === \"A\"\n    ) {\n      // Finds link mark at the hovered element's position to update mouseHoveredHyperlinkMark and\n      // mouseHoveredHyperlinkMarkRange.\n      const hoveredHyperlinkElement = event.target;\n      const posInHoveredHyperlinkMark =\n        this.pmView.posAtDOM(hoveredHyperlinkElement, 0) + 1;\n      const resolvedPosInHoveredHyperlinkMark = this.pmView.state.doc.resolve(\n        posInHoveredHyperlinkMark\n      );\n      const marksAtPos = resolvedPosInHoveredHyperlinkMark.marks();\n\n      for (const mark of marksAtPos) {\n        if (\n          mark.type.name === this.pmView.state.schema.mark(\"link\").type.name\n        ) {\n          this.mouseHoveredHyperlinkMark = mark;\n          this.mouseHoveredHyperlinkMarkRange =\n            getMarkRange(\n              resolvedPosInHoveredHyperlinkMark,\n              mark.type,\n              mark.attrs\n            ) || undefined;\n\n          break;\n        }\n      }\n    }\n\n    this.startMenuUpdateTimer();\n\n    return false;\n  };\n\n  clickHandler = (event: MouseEvent) => {\n    const editorWrapper = this.pmView.dom.parentElement!;\n\n    if (\n      // Toolbar is open.\n      this.hyperlinkMark &&\n      // An element is clicked.\n      event &&\n      event.target &&\n      // The clicked element is not the editor.\n      !(\n        editorWrapper === (event.target as Node) ||\n        editorWrapper.contains(event.target as Node)\n      )\n    ) {\n      if (this.hyperlinkToolbarState?.show) {\n        this.hyperlinkToolbarState.show = false;\n        this.updateHyperlinkToolbar();\n      }\n    }\n  };\n\n  scrollHandler = () => {\n    if (this.hyperlinkMark !== undefined) {\n      if (this.hyperlinkToolbarState?.show) {\n        this.hyperlinkToolbarState.referencePos = posToDOMRect(\n          this.pmView,\n          this.hyperlinkMarkRange!.from,\n          this.hyperlinkMarkRange!.to\n        );\n        this.updateHyperlinkToolbar();\n      }\n    }\n  };\n\n  editHyperlink(url: string, text: string) {\n    const tr = this.pmView.state.tr.insertText(\n      text,\n      this.hyperlinkMarkRange!.from,\n      this.hyperlinkMarkRange!.to\n    );\n    tr.addMark(\n      this.hyperlinkMarkRange!.from,\n      this.hyperlinkMarkRange!.from + text.length,\n      this.pmView.state.schema.mark(\"link\", { href: url })\n    );\n    this.pmView.dispatch(tr);\n    this.pmView.focus();\n\n    if (this.hyperlinkToolbarState?.show) {\n      this.hyperlinkToolbarState.show = false;\n      this.updateHyperlinkToolbar();\n    }\n  }\n\n  deleteHyperlink() {\n    this.pmView.dispatch(\n      this.pmView.state.tr\n        .removeMark(\n          this.hyperlinkMarkRange!.from,\n          this.hyperlinkMarkRange!.to,\n          this.hyperlinkMark!.type\n        )\n        .setMeta(\"preventAutolink\", true)\n    );\n    this.pmView.focus();\n\n    if (this.hyperlinkToolbarState?.show) {\n      this.hyperlinkToolbarState.show = false;\n      this.updateHyperlinkToolbar();\n    }\n  }\n\n  update() {\n    if (!this.pmView.hasFocus()) {\n      return;\n    }\n\n    // Saves the currently hovered hyperlink mark before it's updated.\n    const prevHyperlinkMark = this.hyperlinkMark;\n\n    // Resets the currently hovered hyperlink mark.\n    this.hyperlinkMark = undefined;\n    this.hyperlinkMarkRange = undefined;\n\n    // Resets the hyperlink mark currently hovered by the keyboard cursor.\n    this.keyboardHoveredHyperlinkMark = undefined;\n    this.keyboardHoveredHyperlinkMarkRange = undefined;\n\n    // Finds link mark at the editor selection's position to update keyboardHoveredHyperlinkMark and\n    // keyboardHoveredHyperlinkMarkRange.\n    if (this.pmView.state.selection.empty) {\n      const marksAtPos = this.pmView.state.selection.$from.marks();\n\n      for (const mark of marksAtPos) {\n        if (\n          mark.type.name === this.pmView.state.schema.mark(\"link\").type.name\n        ) {\n          this.keyboardHoveredHyperlinkMark = mark;\n          this.keyboardHoveredHyperlinkMarkRange =\n            getMarkRange(\n              this.pmView.state.selection.$from,\n              mark.type,\n              mark.attrs\n            ) || undefined;\n\n          break;\n        }\n      }\n    }\n\n    if (this.mouseHoveredHyperlinkMark) {\n      this.hyperlinkMark = this.mouseHoveredHyperlinkMark;\n      this.hyperlinkMarkRange = this.mouseHoveredHyperlinkMarkRange;\n    }\n\n    // Keyboard cursor position takes precedence over mouse hovered hyperlink.\n    if (this.keyboardHoveredHyperlinkMark) {\n      this.hyperlinkMark = this.keyboardHoveredHyperlinkMark;\n      this.hyperlinkMarkRange = this.keyboardHoveredHyperlinkMarkRange;\n    }\n\n    if (this.hyperlinkMark && this.editor.isEditable) {\n      this.hyperlinkToolbarState = {\n        show: true,\n        referencePos: posToDOMRect(\n          this.pmView,\n          this.hyperlinkMarkRange!.from,\n          this.hyperlinkMarkRange!.to\n        ),\n        url: this.hyperlinkMark!.attrs.href,\n        text: this.pmView.state.doc.textBetween(\n          this.hyperlinkMarkRange!.from,\n          this.hyperlinkMarkRange!.to\n        ),\n      };\n      this.updateHyperlinkToolbar();\n\n      return;\n    }\n\n    // Hides menu.\n    if (\n      this.hyperlinkToolbarState?.show &&\n      prevHyperlinkMark &&\n      (!this.hyperlinkMark || !this.editor.isEditable)\n    ) {\n      this.hyperlinkToolbarState.show = false;\n      this.updateHyperlinkToolbar();\n\n      return;\n    }\n  }\n\n  destroy() {\n    this.pmView.dom.removeEventListener(\"mouseover\", this.mouseOverHandler);\n    document.removeEventListener(\"scroll\", this.scrollHandler);\n    document.removeEventListener(\"click\", this.clickHandler, true);\n  }\n}\n\nexport const hyperlinkToolbarPluginKey = new PluginKey(\n  \"HyperlinkToolbarPlugin\"\n);\n\nexport class HyperlinkToolbarProsemirrorPlugin<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> extends EventEmitter<any> {\n  private view: HyperlinkToolbarView | undefined;\n  public readonly plugin: Plugin;\n\n  constructor(editor: BlockNoteEditor<BSchema, I, S>) {\n    super();\n    this.plugin = new Plugin({\n      key: hyperlinkToolbarPluginKey,\n      view: (editorView) => {\n        this.view = new HyperlinkToolbarView(editor, editorView, (state) => {\n          this.emit(\"update\", state);\n        });\n        return this.view;\n      },\n    });\n  }\n\n  public onUpdate(callback: (state: HyperlinkToolbarState) => void) {\n    return this.on(\"update\", callback);\n  }\n\n  /**\n   * Edit the currently hovered hyperlink.\n   */\n  public editHyperlink = (url: string, text: string) => {\n    this.view!.editHyperlink(url, text);\n  };\n\n  /**\n   * Delete the currently hovered hyperlink.\n   */\n  public deleteHyperlink = () => {\n    this.view!.deleteHyperlink();\n  };\n\n  /**\n   * When hovering on/off hyperlinks using the mouse cursor, the hyperlink\n   * toolbar will open & close with a delay.\n   *\n   * This function starts the delay timer, and should be used for when the mouse cursor enters the hyperlink toolbar.\n   */\n  public startHideTimer = () => {\n    this.view!.startMenuUpdateTimer();\n  };\n\n  /**\n   * When hovering on/off hyperlinks using the mouse cursor, the hyperlink\n   * toolbar will open & close with a delay.\n   *\n   * This function stops the delay timer, and should be used for when the mouse cursor exits the hyperlink toolbar.\n   */\n  public stopHideTimer = () => {\n    this.view!.stopMenuUpdateTimer();\n  };\n}\n","import { findParentNode } from \"@tiptap/core\";\nimport { EditorState, Plugin, PluginKey } from \"prosemirror-state\";\nimport { Decoration, DecorationSet, EditorView } from \"prosemirror-view\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport { BlockSchema, InlineContentSchema, StyleSchema } from \"../../schema\";\nimport { BaseUiElementState } from \"../BaseUiElementTypes\";\nimport { SuggestionItem } from \"./SuggestionItem\";\n\nconst findBlock = findParentNode((node) => node.type.name === \"blockContainer\");\n\nexport type SuggestionsMenuState<T extends SuggestionItem> =\n  BaseUiElementState & {\n    // The suggested items to display.\n    filteredItems: T[];\n    // The index of the suggested item that's currently hovered by the keyboard.\n    keyboardHoveredItemIndex: number;\n  };\n\nclass SuggestionsMenuView<\n  T extends SuggestionItem,\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> {\n  private suggestionsMenuState?: SuggestionsMenuState<T>;\n  public updateSuggestionsMenu: () => void;\n\n  pluginState: SuggestionPluginState<T>;\n\n  constructor(\n    private readonly editor: BlockNoteEditor<BSchema, I, S>,\n    private readonly pluginKey: PluginKey,\n    updateSuggestionsMenu: (\n      suggestionsMenuState: SuggestionsMenuState<T>\n    ) => void = () => {\n      // noop\n    }\n  ) {\n    this.pluginState = getDefaultPluginState<T>();\n\n    this.updateSuggestionsMenu = () => {\n      if (!this.suggestionsMenuState) {\n        throw new Error(\"Attempting to update uninitialized suggestions menu\");\n      }\n\n      updateSuggestionsMenu(this.suggestionsMenuState);\n    };\n\n    document.addEventListener(\"scroll\", this.handleScroll);\n  }\n\n  handleScroll = () => {\n    if (this.suggestionsMenuState?.show) {\n      const decorationNode = document.querySelector(\n        `[data-decoration-id=\"${this.pluginState.decorationId}\"]`\n      );\n      this.suggestionsMenuState.referencePos =\n        decorationNode!.getBoundingClientRect();\n      this.updateSuggestionsMenu();\n    }\n  };\n\n  update(view: EditorView, prevState: EditorState) {\n    const prev = this.pluginKey.getState(prevState);\n    const next = this.pluginKey.getState(view.state);\n\n    // See how the state changed\n    const started = !prev.active && next.active;\n    const stopped = prev.active && !next.active;\n    // TODO: Currently also true for cases in which an update isn't needed so selected list item index updates still\n    //  cause the view to update. May need to be more strict.\n    const changed = prev.active && next.active;\n\n    // Cancel when suggestion isn't active\n    if (!started && !changed && !stopped) {\n      return;\n    }\n\n    this.pluginState = stopped ? prev : next;\n\n    if (stopped || !this.editor.isEditable) {\n      this.suggestionsMenuState!.show = false;\n      this.updateSuggestionsMenu();\n\n      return;\n    }\n\n    const decorationNode = document.querySelector(\n      `[data-decoration-id=\"${this.pluginState.decorationId}\"]`\n    );\n\n    if (this.editor.isEditable) {\n      this.suggestionsMenuState = {\n        show: true,\n        referencePos: decorationNode!.getBoundingClientRect(),\n        filteredItems: this.pluginState.items,\n        keyboardHoveredItemIndex: this.pluginState.keyboardHoveredItemIndex!,\n      };\n\n      this.updateSuggestionsMenu();\n    }\n  }\n\n  destroy() {\n    document.removeEventListener(\"scroll\", this.handleScroll);\n  }\n}\n\ntype SuggestionPluginState<T extends SuggestionItem> = {\n  // True when the menu is shown, false when hidden.\n  active: boolean;\n  // The character that triggered the menu being shown. Allowing the trigger to be different to the default\n  // trigger allows other extensions to open it programmatically.\n  triggerCharacter: string | undefined;\n  // The editor position just after the trigger character, i.e. where the user query begins. Used to figure out\n  // which menu items to show and can also be used to delete the trigger character.\n  queryStartPos: number | undefined;\n  // The items that should be shown in the menu.\n  items: T[];\n  // The index of the item in the menu that's currently hovered using the keyboard.\n  keyboardHoveredItemIndex: number | undefined;\n  // The number of characters typed after the last query that matched with at least 1 item. Used to close the\n  // menu if the user keeps entering queries that don't return any results.\n  notFoundCount: number | undefined;\n  decorationId: string | undefined;\n};\n\nfunction getDefaultPluginState<\n  T extends SuggestionItem\n>(): SuggestionPluginState<T> {\n  return {\n    active: false,\n    triggerCharacter: undefined,\n    queryStartPos: undefined,\n    items: [] as T[],\n    keyboardHoveredItemIndex: undefined,\n    notFoundCount: 0,\n    decorationId: undefined,\n  };\n}\n\n/**\n * A ProseMirror plugin for suggestions, designed to make '/'-commands possible as well as mentions.\n *\n * This is basically a simplified version of TipTap's [Suggestions](https://github.com/ueberdosis/tiptap/tree/db92a9b313c5993b723c85cd30256f1d4a0b65e1/packages/suggestion) plugin.\n *\n * This version is adapted from the aforementioned version in the following ways:\n * - This version supports generic items instead of only strings (to allow for more advanced filtering for example)\n * - This version hides some unnecessary complexity from the user of the plugin.\n * - This version handles key events differently\n */\nexport const setupSuggestionsMenu = <\n  T extends SuggestionItem,\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  editor: BlockNoteEditor<BSchema, I, S>,\n  updateSuggestionsMenu: (\n    suggestionsMenuState: SuggestionsMenuState<T>\n  ) => void,\n\n  pluginKey: PluginKey,\n  defaultTriggerCharacter: string,\n  items: (query: string) => T[] = () => [],\n  onSelectItem: (props: {\n    item: T;\n    editor: BlockNoteEditor<BSchema, I, S>;\n  }) => void = () => {\n    // noop\n  }\n) => {\n  // Assertions\n  if (defaultTriggerCharacter.length !== 1) {\n    throw new Error(\"'char' should be a single character\");\n  }\n\n  let suggestionsPluginView: SuggestionsMenuView<T, BSchema, I, S>;\n\n  const deactivate = (view: EditorView) => {\n    view.dispatch(view.state.tr.setMeta(pluginKey, { deactivate: true }));\n  };\n\n  return {\n    plugin: new Plugin({\n      key: pluginKey,\n\n      view: () => {\n        suggestionsPluginView = new SuggestionsMenuView<T, BSchema, I, S>(\n          editor,\n          pluginKey,\n\n          updateSuggestionsMenu\n        );\n        return suggestionsPluginView;\n      },\n\n      state: {\n        // Initialize the plugin's internal state.\n        init(): SuggestionPluginState<T> {\n          return getDefaultPluginState<T>();\n        },\n\n        // Apply changes to the plugin state from an editor transaction.\n        apply(transaction, prev, oldState, newState): SuggestionPluginState<T> {\n          // TODO: More clearly define which transactions should be ignored.\n          if (transaction.getMeta(\"orderedListIndexing\") !== undefined) {\n            return prev;\n          }\n\n          // Checks if the menu should be shown.\n          if (transaction.getMeta(pluginKey)?.activate) {\n            return {\n              active: true,\n              triggerCharacter:\n                transaction.getMeta(pluginKey)?.triggerCharacter || \"\",\n              queryStartPos: newState.selection.from,\n              items: items(\"\"),\n              keyboardHoveredItemIndex: 0,\n              // TODO: Maybe should be 1 if the menu has no possible items? Probably redundant since a menu with no items\n              //  is useless in practice.\n              notFoundCount: 0,\n              decorationId: `id_${Math.floor(Math.random() * 0xffffffff)}`,\n            };\n          }\n\n          // Checks if the menu is hidden, in which case it doesn't need to be hidden or updated.\n          if (!prev.active) {\n            return prev;\n          }\n\n          const next = { ...prev };\n\n          // Updates which menu items to show by checking which items the current query (the text between the trigger\n          // character and caret) matches with.\n          next.items = items(\n            newState.doc.textBetween(\n              prev.queryStartPos!,\n              newState.selection.from\n            )\n          );\n\n          // Updates notFoundCount if the query doesn't match any items.\n          next.notFoundCount = 0;\n          if (next.items.length === 0) {\n            // Checks how many characters were typed or deleted since the last transaction, and updates the notFoundCount\n            // accordingly. Also ensures the notFoundCount does not become negative.\n            next.notFoundCount = Math.max(\n              0,\n              prev.notFoundCount! +\n                (newState.selection.from - oldState.selection.from)\n            );\n          }\n\n          // Hides the menu. This is done after items and notFoundCount are already updated as notFoundCount is needed to\n          // check if the menu should be hidden.\n          if (\n            // Highlighting text should hide the menu.\n            newState.selection.from !== newState.selection.to ||\n            // Transactions with plugin metadata {deactivate: true} should hide the menu.\n            transaction.getMeta(pluginKey)?.deactivate ||\n            // Certain mouse events should hide the menu.\n            // TODO: Change to global mousedown listener.\n            transaction.getMeta(\"focus\") ||\n            transaction.getMeta(\"blur\") ||\n            transaction.getMeta(\"pointer\") ||\n            // Moving the caret before the character which triggered the menu should hide it.\n            (prev.active && newState.selection.from < prev.queryStartPos!) ||\n            // Entering more than 3 characters, after the last query that matched with at least 1 menu item, should hide\n            // the menu.\n            next.notFoundCount > 3\n          ) {\n            return getDefaultPluginState<T>();\n          }\n\n          // Updates keyboardHoveredItemIndex if the up or down arrow key was\n          // pressed, or resets it if the keyboard cursor moved.\n          if (\n            transaction.getMeta(pluginKey)?.selectedItemIndexChanged !==\n            undefined\n          ) {\n            let newIndex =\n              transaction.getMeta(pluginKey).selectedItemIndexChanged;\n\n            // Allows selection to jump between first and last items.\n            if (newIndex < 0) {\n              newIndex = prev.items.length - 1;\n            } else if (newIndex >= prev.items.length) {\n              newIndex = 0;\n            }\n\n            next.keyboardHoveredItemIndex = newIndex;\n          } else if (oldState.selection.from !== newState.selection.from) {\n            next.keyboardHoveredItemIndex = 0;\n          }\n\n          return next;\n        },\n      },\n\n      props: {\n        handleKeyDown(view, event) {\n          const menuIsActive = (this as Plugin).getState(view.state).active;\n\n          // Shows the menu if the default trigger character was pressed and the menu isn't active.\n          if (event.key === defaultTriggerCharacter && !menuIsActive) {\n            view.dispatch(\n              view.state.tr\n                .insertText(defaultTriggerCharacter)\n                .scrollIntoView()\n                .setMeta(pluginKey, {\n                  activate: true,\n                  triggerCharacter: defaultTriggerCharacter,\n                })\n            );\n\n            return true;\n          }\n\n          // Doesn't handle other keystrokes if the menu isn't active.\n          if (!menuIsActive) {\n            return false;\n          }\n\n          // Handles keystrokes for navigating the menu.\n          const {\n            triggerCharacter,\n            queryStartPos,\n            items,\n            keyboardHoveredItemIndex,\n          } = pluginKey.getState(view.state);\n\n          // Moves the keyboard selection to the previous item.\n          if (event.key === \"ArrowUp\") {\n            view.dispatch(\n              view.state.tr.setMeta(pluginKey, {\n                selectedItemIndexChanged: keyboardHoveredItemIndex - 1,\n              })\n            );\n            return true;\n          }\n\n          // Moves the keyboard selection to the next item.\n          if (event.key === \"ArrowDown\") {\n            view.dispatch(\n              view.state.tr.setMeta(pluginKey, {\n                selectedItemIndexChanged: keyboardHoveredItemIndex + 1,\n              })\n            );\n            return true;\n          }\n\n          // Selects an item and closes the menu.\n          if (event.key === \"Enter\") {\n            if (items.length === 0) {\n              return true;\n            }\n\n            deactivate(view);\n            editor._tiptapEditor\n              .chain()\n              .focus()\n              .deleteRange({\n                from: queryStartPos! - triggerCharacter!.length,\n                to: editor._tiptapEditor.state.selection.from,\n              })\n              .run();\n\n            onSelectItem({\n              item: items[keyboardHoveredItemIndex],\n              editor: editor,\n            });\n\n            return true;\n          }\n\n          // Closes the menu.\n          if (event.key === \"Escape\") {\n            deactivate(view);\n            return true;\n          }\n\n          return false;\n        },\n\n        // Setup decorator on the currently active suggestion.\n        decorations(state) {\n          const { active, decorationId, queryStartPos, triggerCharacter } = (\n            this as Plugin\n          ).getState(state);\n\n          if (!active) {\n            return null;\n          }\n\n          // If the menu was opened programmatically by another extension, it may not use a trigger character. In this\n          // case, the decoration is set on the whole block instead, as the decoration range would otherwise be empty.\n          if (triggerCharacter === \"\") {\n            const blockNode = findBlock(state.selection);\n            if (blockNode) {\n              return DecorationSet.create(state.doc, [\n                Decoration.node(\n                  blockNode.pos,\n                  blockNode.pos + blockNode.node.nodeSize,\n                  {\n                    nodeName: \"span\",\n                    class: \"bn-suggestion-decorator\",\n                    \"data-decoration-id\": decorationId,\n                  }\n                ),\n              ]);\n            }\n          }\n          // Creates an inline decoration around the trigger character.\n          return DecorationSet.create(state.doc, [\n            Decoration.inline(\n              queryStartPos - triggerCharacter.length,\n              queryStartPos,\n              {\n                nodeName: \"span\",\n                class: \"bn-suggestion-decorator\",\n                \"data-decoration-id\": decorationId,\n              }\n            ),\n          ]);\n        },\n      },\n    }),\n    itemCallback: (item: T) => {\n      deactivate(editor._tiptapEditor.view);\n      editor._tiptapEditor\n        .chain()\n        .focus()\n        .deleteRange({\n          from:\n            suggestionsPluginView.pluginState.queryStartPos! -\n            suggestionsPluginView.pluginState.triggerCharacter!.length,\n          to: editor._tiptapEditor.state.selection.from,\n        })\n        .run();\n\n      onSelectItem({\n        item: item,\n        editor: editor,\n      });\n    },\n  };\n};\n","import { Plugin, PluginKey } from \"prosemirror-state\";\n\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport {\n  SuggestionsMenuState,\n  setupSuggestionsMenu,\n} from \"../../extensions-shared/suggestion/SuggestionPlugin\";\nimport { BlockSchema, InlineContentSchema, StyleSchema } from \"../../schema\";\nimport { EventEmitter } from \"../../util/EventEmitter\";\nimport { BaseSlashMenuItem } from \"./BaseSlashMenuItem\";\n\nexport const slashMenuPluginKey = new PluginKey(\"SlashMenuPlugin\");\n\nexport class SlashMenuProsemirrorPlugin<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema,\n  SlashMenuItem extends BaseSlashMenuItem<BSchema, I, S>\n> extends EventEmitter<any> {\n  public readonly plugin: Plugin;\n  public readonly itemCallback: (item: SlashMenuItem) => void;\n\n  constructor(editor: BlockNoteEditor<BSchema, I, S>, items: SlashMenuItem[]) {\n    super();\n    const suggestions = setupSuggestionsMenu<SlashMenuItem, BSchema, I, S>(\n      editor,\n      (state) => {\n        this.emit(\"update\", state);\n      },\n      slashMenuPluginKey,\n      \"/\",\n      (query) =>\n        items.filter(\n          ({ name, aliases }: SlashMenuItem) =>\n            name.toLowerCase().startsWith(query.toLowerCase()) ||\n            (aliases &&\n              aliases.filter((alias) =>\n                alias.toLowerCase().startsWith(query.toLowerCase())\n              ).length !== 0)\n        ),\n      ({ item, editor }) => item.execute(editor)\n    );\n\n    this.plugin = suggestions.plugin;\n    this.itemCallback = suggestions.itemCallback;\n  }\n\n  public onUpdate(\n    callback: (state: SuggestionsMenuState<SlashMenuItem>) => void\n  ) {\n    return this.on(\"update\", callback);\n  }\n}\n","import { Fragment, Node, ResolvedPos, Slice } from \"prosemirror-model\";\nimport { Selection } from \"prosemirror-state\";\nimport { Mappable } from \"prosemirror-transform\";\n\n/**\n * This class represents an editor selection which spans multiple nodes/blocks. It's currently only used to allow users\n * to drag multiple blocks at the same time. Expects the selection anchor and head to be between nodes, i.e. just before\n * the first target node and just after the last, and that anchor and head are at the same nesting level.\n *\n * Partially based on ProseMirror's NodeSelection implementation:\n * (https://github.com/ProseMirror/prosemirror-state/blob/master/src/selection.ts)\n * MultipleNodeSelection differs from NodeSelection in the following ways:\n * 1. Stores which nodes are included in the selection instead of just a single node.\n * 2. Already expects the selection to start just before the first target node and ends just after the last, while a\n * NodeSelection automatically sets both anchor and head to just before the single target node.\n */\nexport class MultipleNodeSelection extends Selection {\n  nodes: Array<Node>;\n\n  constructor($anchor: ResolvedPos, $head: ResolvedPos) {\n    super($anchor, $head);\n\n    // Parent is at the same nesting level as anchor/head since they are just before/ just after target nodes.\n    const parentNode = $anchor.node();\n\n    this.nodes = [];\n    $anchor.doc.nodesBetween($anchor.pos, $head.pos, (node, _pos, parent) => {\n      if (parent !== null && parent.eq(parentNode)) {\n        this.nodes.push(node);\n        return false;\n      }\n      return;\n    });\n  }\n\n  static create(doc: Node, from: number, to = from): MultipleNodeSelection {\n    return new MultipleNodeSelection(doc.resolve(from), doc.resolve(to));\n  }\n\n  content(): Slice {\n    return new Slice(Fragment.from(this.nodes), 0, 0);\n  }\n\n  eq(selection: Selection): boolean {\n    if (!(selection instanceof MultipleNodeSelection)) {\n      return false;\n    }\n\n    if (this.nodes.length !== selection.nodes.length) {\n      return false;\n    }\n\n    if (this.from !== selection.from || this.to !== selection.to) {\n      return false;\n    }\n\n    for (let i = 0; i < this.nodes.length; i++) {\n      if (!this.nodes[i].eq(selection.nodes[i])) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  map(doc: Node, mapping: Mappable): Selection {\n    const fromResult = mapping.mapResult(this.from);\n    const toResult = mapping.mapResult(this.to);\n\n    if (toResult.deleted) {\n      return Selection.near(doc.resolve(fromResult.pos));\n    }\n\n    if (fromResult.deleted) {\n      return Selection.near(doc.resolve(toResult.pos));\n    }\n\n    return new MultipleNodeSelection(\n      doc.resolve(fromResult.pos),\n      doc.resolve(toResult.pos)\n    );\n  }\n\n  toJSON(): any {\n    return { type: \"node\", anchor: this.anchor, head: this.head };\n  }\n}\n","export const MAX_NUM_BLOCKS = 800;\n","import { PluginView } from \"@tiptap/pm/state\";\nimport { Node } from \"prosemirror-model\";\nimport { NodeSelection, Plugin, PluginKey, Selection } from \"prosemirror-state\";\nimport { EditorView } from \"prosemirror-view\";\nimport { createExternalHTMLExporter } from \"../../api/exporters/html/externalHTMLExporter\";\nimport { createInternalHTMLSerializer } from \"../../api/exporters/html/internalHTMLSerializer\";\nimport { cleanHTMLToMarkdown } from \"../../api/exporters/markdown/markdownExporter\";\nimport { getBlockInfoFromPos } from \"../../api/getBlockInfoFromPos\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport { BaseUiElementState } from \"../../extensions-shared/BaseUiElementTypes\";\nimport {\n  Block,\n  BlockSchema,\n  InlineContentSchema,\n  StyleSchema,\n} from \"../../schema\";\nimport { EventEmitter } from \"../../util/EventEmitter\";\nimport { slashMenuPluginKey } from \"../SlashMenu/SlashMenuPlugin\";\nimport { MultipleNodeSelection } from \"./MultipleNodeSelection\";\nimport { MAX_NUM_BLOCKS } from \"../../util/constants\";\n\nlet dragImageElement: Element | undefined;\n\nexport type SideMenuState<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> = BaseUiElementState & {\n  // The block that the side menu is attached to.\n  block: Block<BSchema, I, S>;\n};\n\nexport function getDraggableBlockFromCoords(\n  coords: { left: number; top: number },\n  view: EditorView\n) {\n  if (!view.dom.isConnected) {\n    // view is not connected to the DOM, this can cause posAtCoords to fail\n    // (Cannot read properties of null (reading 'nearestDesc'), https://github.com/TypeCellOS/BlockNote/issues/123)\n    return undefined;\n  }\n\n  const pos = view.posAtCoords(coords);\n  if (!pos) {\n    return undefined;\n  }\n  let node = view.domAtPos(pos.pos).node as HTMLElement;\n\n  if (node === view.dom) {\n    // mouse over root\n    return undefined;\n  }\n\n  while (\n    node &&\n    node.parentNode &&\n    node.parentNode !== view.dom &&\n    !node.hasAttribute?.(\"data-id\")\n  ) {\n    node = node.parentNode as HTMLElement;\n  }\n  if (!node) {\n    return undefined;\n  }\n  return { node, id: node.getAttribute(\"data-id\")! };\n}\n\nfunction blockPositionFromCoords(\n  coords: { left: number; top: number },\n  view: EditorView\n) {\n  const block = getDraggableBlockFromCoords(coords, view);\n\n  if (block && block.node.nodeType === 1) {\n    // TODO: this uses undocumented PM APIs? do we need this / let's add docs?\n    const docView = (view as any).docView;\n    const desc = docView.nearestDesc(block.node, true);\n    if (!desc || desc === docView) {\n      return null;\n    }\n    return desc.posBefore;\n  }\n  return null;\n}\n\nfunction blockPositionsFromSelection(selection: Selection, doc: Node) {\n  // Absolute positions just before the first block spanned by the selection, and just after the last block. Having the\n  // selection start and end just before and just after the target blocks ensures no whitespace/line breaks are left\n  // behind after dragging & dropping them.\n  let beforeFirstBlockPos: number;\n  let afterLastBlockPos: number;\n\n  // Even the user starts dragging blocks but drops them in the same place, the selection will still be moved just\n  // before & just after the blocks spanned by the selection, and therefore doesn't need to change if they try to drag\n  // the same blocks again. If this happens, the anchor & head move out of the block content node they were originally\n  // in. If the anchor should update but the head shouldn't and vice versa, it means the user selection is outside a\n  // block content node, which should never happen.\n  const selectionStartInBlockContent =\n    doc.resolve(selection.from).node().type.spec.group === \"blockContent\";\n  const selectionEndInBlockContent =\n    doc.resolve(selection.to).node().type.spec.group === \"blockContent\";\n\n  // Ensures that entire outermost nodes are selected if the selection spans multiple nesting levels.\n  const minDepth = Math.min(selection.$anchor.depth, selection.$head.depth);\n\n  if (selectionStartInBlockContent && selectionEndInBlockContent) {\n    // Absolute positions at the start of the first block in the selection and at the end of the last block. User\n    // selections will always start and end in block content nodes, but we want the start and end positions of their\n    // parent block nodes, which is why minDepth - 1 is used.\n    const startFirstBlockPos = selection.$from.start(minDepth - 1);\n    const endLastBlockPos = selection.$to.end(minDepth - 1);\n\n    // Shifting start and end positions by one moves them just outside the first and last selected blocks.\n    beforeFirstBlockPos = doc.resolve(startFirstBlockPos - 1).pos;\n    afterLastBlockPos = doc.resolve(endLastBlockPos + 1).pos;\n  } else {\n    beforeFirstBlockPos = selection.from;\n    afterLastBlockPos = selection.to;\n  }\n\n  return { from: beforeFirstBlockPos, to: afterLastBlockPos };\n}\n\nfunction setDragImage(view: EditorView, from: number, to = from) {\n  if (from === to) {\n    // Moves to position to be just after the first (and only) selected block.\n    to += view.state.doc.resolve(from + 1).node().nodeSize;\n  }\n\n  // Parent element is cloned to remove all unselected children without affecting the editor content.\n  const parentClone = view.domAtPos(from).node.cloneNode(true) as Element;\n  const parent = view.domAtPos(from).node as Element;\n\n  const getElementIndex = (parentElement: Element, targetElement: Element) =>\n    Array.prototype.indexOf.call(parentElement.children, targetElement);\n\n  const firstSelectedBlockIndex = getElementIndex(\n    parent,\n    // Expects from position to be just before the first selected block.\n    view.domAtPos(from + 1).node.parentElement!\n  );\n  const lastSelectedBlockIndex = getElementIndex(\n    parent,\n    // Expects to position to be just after the last selected block.\n    view.domAtPos(to - 1).node.parentElement!\n  );\n\n  for (let i = parent.childElementCount - 1; i >= 0; i--) {\n    if (i > lastSelectedBlockIndex || i < firstSelectedBlockIndex) {\n      parentClone.removeChild(parentClone.children[i]);\n    }\n  }\n\n  // dataTransfer.setDragImage(element) only works if element is attached to the DOM.\n  unsetDragImage();\n  dragImageElement = parentClone;\n\n  // TODO: This is hacky, need a better way of assigning classes to the editor so that they can also be applied to the\n  //  drag preview.\n  const classes = view.dom.className.split(\" \");\n  const inheritedClasses = classes\n    .filter(\n      (className) =>\n        className !== \"ProseMirror\" &&\n        className !== \"bn-root\" &&\n        className !== \"bn-editor\"\n    )\n    .join(\" \");\n\n  dragImageElement.className =\n    dragImageElement.className + \" bn-drag-preview \" + inheritedClasses;\n\n  document.body.appendChild(dragImageElement);\n}\n\nfunction unsetDragImage() {\n  if (dragImageElement !== undefined) {\n    document.body.removeChild(dragImageElement);\n    dragImageElement = undefined;\n  }\n}\n\nfunction dragStart<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  e: { dataTransfer: DataTransfer | null; clientY: number },\n  editor: BlockNoteEditor<BSchema, I, S>\n) {\n  if (!e.dataTransfer) {\n    return;\n  }\n\n  const view = editor.prosemirrorView;\n\n  const editorBoundingBox = view.dom.getBoundingClientRect();\n\n  const coords = {\n    left: editorBoundingBox.left + editorBoundingBox.width / 2, // take middle of editor\n    top: e.clientY,\n  };\n\n  const pos = blockPositionFromCoords(coords, view);\n  if (pos != null) {\n    const selection = view.state.selection;\n    const doc = view.state.doc;\n\n    const { from, to } = blockPositionsFromSelection(selection, doc);\n\n    const draggedBlockInSelection = from <= pos && pos < to;\n    const multipleBlocksSelected =\n      selection.$anchor.node() !== selection.$head.node() ||\n      selection instanceof MultipleNodeSelection;\n\n    if (draggedBlockInSelection && multipleBlocksSelected) {\n      view.dispatch(\n        view.state.tr.setSelection(MultipleNodeSelection.create(doc, from, to))\n      );\n      setDragImage(view, from, to);\n    } else {\n      view.dispatch(\n        view.state.tr.setSelection(NodeSelection.create(view.state.doc, pos))\n      );\n      setDragImage(view, pos);\n    }\n\n    const selectedSlice = view.state.selection.content();\n    const schema = editor._tiptapEditor.schema;\n\n    const internalHTMLSerializer = createInternalHTMLSerializer(schema, editor);\n    const internalHTML = internalHTMLSerializer.serializeProseMirrorFragment(\n      selectedSlice.content\n    );\n\n    const externalHTMLExporter = createExternalHTMLExporter(schema, editor);\n    const externalHTML = externalHTMLExporter.exportProseMirrorFragment(\n      selectedSlice.content\n    );\n\n    const plainText = cleanHTMLToMarkdown(externalHTML);\n\n    e.dataTransfer.clearData();\n    e.dataTransfer.setData(\"blocknote/html\", internalHTML);\n    e.dataTransfer.setData(\"text/html\", externalHTML);\n    e.dataTransfer.setData(\"text/plain\", plainText);\n    e.dataTransfer.effectAllowed = \"move\";\n    e.dataTransfer.setDragImage(dragImageElement!, 0, 0);\n    view.dragging = { slice: selectedSlice, move: true };\n  }\n}\n\nexport class SideMenuView<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> implements PluginView\n{\n  private sideMenuState?: SideMenuState<BSchema, I, S>;\n\n  // When true, the drag handle with be anchored at the same level as root elements\n  // When false, the drag handle with be just to the left of the element\n  // TODO: Is there any case where we want this to be false?\n  private horizontalPosAnchoredAtRoot: boolean;\n  private horizontalPosAnchor: number;\n\n  private hoveredBlock: HTMLElement | undefined;\n\n  // Used to check if currently dragged content comes from this editor instance.\n  public isDragging = false;\n\n  public menuFrozen = false;\n\n  constructor(\n    private readonly editor: BlockNoteEditor<BSchema, I, S>,\n    private readonly pmView: EditorView,\n    private readonly updateSideMenu: (\n      sideMenuState: SideMenuState<BSchema, I, S>\n    ) => void\n  ) {\n    this.horizontalPosAnchoredAtRoot = true;\n    this.horizontalPosAnchor = (\n      this.pmView.dom.firstChild! as HTMLElement\n    ).getBoundingClientRect().x;\n\n    document.body.addEventListener(\"drop\", this.onDrop, true);\n    document.body.addEventListener(\"dragover\", this.onDragOver);\n    this.pmView.dom.addEventListener(\"dragstart\", this.onDragStart);\n\n    // Shows or updates menu position whenever the cursor moves, if the menu isn't frozen.\n    document.body.addEventListener(\"mousemove\", this.onMouseMove, true);\n\n    this.onMouseDown = this.onMouseDown.bind(this);\n\n    document.body.addEventListener(\"mousedown\", this.onMouseDown);\n\n    // Makes menu scroll with the page.\n    document.addEventListener(\"scroll\", this.onScroll);\n\n    // Unfreezes the menu whenever the user clicks anywhere.\n    document.body.addEventListener(\"mousedown\", this.onMouseDown, true);\n    // Hides and unfreezes the menu whenever the user presses a key.\n    document.body.addEventListener(\"keydown\", this.onKeyDown, true);\n  }\n\n  /**\n   * Sets isDragging when dragging text.\n   */\n  onDragStart = () => {\n    this.isDragging = true;\n  };\n\n  /**\n   * If the event is outside the editor contents,\n   * we dispatch a fake event, so that we can still drop the content\n   * when dragging / dropping to the side of the editor\n   */\n  onDrop = (event: DragEvent) => {\n    this.editor._tiptapEditor.commands.blur();\n\n    if ((event as any).synthetic || !this.isDragging) {\n      return;\n    }\n\n    const pos = this.pmView.posAtCoords({\n      left: event.clientX,\n      top: event.clientY,\n    });\n\n    this.isDragging = false;\n\n    if (!pos || pos.inside === -1) {\n      const evt = new Event(\"drop\", event) as any;\n      const editorBoundingBox = (\n        this.pmView.dom.firstChild! as HTMLElement\n      ).getBoundingClientRect();\n      evt.clientX = editorBoundingBox.left + editorBoundingBox.width / 2;\n      evt.clientY = event.clientY;\n      evt.dataTransfer = event.dataTransfer;\n      evt.preventDefault = () => event.preventDefault();\n      evt.synthetic = true; // prevent recursion\n      // console.log(\"dispatch fake drop\");\n      this.pmView.dom.dispatchEvent(evt);\n    }\n  };\n\n  /**\n   * If the event is outside the editor contents,\n   * we dispatch a fake event, so that we can still drop the content\n   * when dragging / dropping to the side of the editor\n   */\n  onDragOver = (event: DragEvent) => {\n    if ((event as any).synthetic || !this.isDragging) {\n      return;\n    }\n    const pos = this.pmView.posAtCoords({\n      left: event.clientX,\n      top: event.clientY,\n    });\n\n    if (!pos || pos.inside === -1) {\n      const evt = new Event(\"dragover\", event) as any;\n      const editorBoundingBox = (\n        this.pmView.dom.firstChild! as HTMLElement\n      ).getBoundingClientRect();\n      evt.clientX = editorBoundingBox.left + editorBoundingBox.width / 2;\n      evt.clientY = event.clientY;\n      evt.dataTransfer = event.dataTransfer;\n      evt.preventDefault = () => event.preventDefault();\n      evt.synthetic = true; // prevent recursion\n      // console.log(\"dispatch fake dragover\");\n      this.pmView.dom.dispatchEvent(evt);\n    }\n  };\n\n  onKeyDown = (_event: KeyboardEvent) => {\n    if (this.sideMenuState?.show) {\n      this.sideMenuState.show = false;\n      this.updateSideMenu(this.sideMenuState);\n    }\n    this.menuFrozen = false;\n  };\n\n  onMouseDown = (_event: MouseEvent) => {\n    if (this.sideMenuState && !this.sideMenuState.show) {\n      this.sideMenuState.show = true;\n      this.updateSideMenu(this.sideMenuState);\n    }\n    this.menuFrozen = false;\n  };\n\n  // onMouseDown() {\n  //   if (this.sideMenuState) {\n  //     this.sideMenuState.show = true;\n  //     this.updateSideMenu(this.sideMenuState);\n  //     this.menuFrozen = false;\n  //   }\n  // }\n\n  onMouseMove = (event: MouseEvent) => {\n    if (this.menuFrozen) {\n      return;\n    }\n\n    // Editor itself may have padding or other styling which affects\n    // size/position, so we get the boundingRect of the first child (i.e. the\n    // blockGroup that wraps all blocks in the editor) for more accurate side\n    // menu placement.\n    const editorBoundingBox = (\n      this.pmView.dom.firstChild! as HTMLElement\n    ).getBoundingClientRect();\n    // We want the full area of the editor to check if the cursor is hovering\n    // above it though.\n    const editorOuterBoundingBox = this.pmView.dom.getBoundingClientRect();\n    const cursorWithinEditor =\n      event.clientX >= editorOuterBoundingBox.left &&\n      event.clientX <= editorOuterBoundingBox.right &&\n      event.clientY >= editorOuterBoundingBox.top &&\n      event.clientY <= editorOuterBoundingBox.bottom;\n\n    const editorWrapper = this.pmView.dom.parentElement!;\n\n    // Doesn't update if the mouse hovers an element that's over the editor but\n    // isn't a part of it or the side menu.\n    if (\n      // Cursor is within the editor area\n      cursorWithinEditor &&\n      // An element is hovered\n      event &&\n      event.target &&\n      // Element is outside the editor\n      !(\n        editorWrapper === event.target ||\n        editorWrapper.contains(event.target as HTMLElement)\n      )\n    ) {\n      if (this.sideMenuState?.show) {\n        this.sideMenuState.show = false;\n        this.updateSideMenu(this.sideMenuState);\n      }\n\n      return;\n    }\n\n    // hide sidemenu when hover from editor to outside\n    if (!cursorWithinEditor && this.sideMenuState) {\n      this.sideMenuState.show = false;\n      this.updateSideMenu(this.sideMenuState);\n    }\n\n    this.horizontalPosAnchor = editorBoundingBox.x;\n\n    // Gets block at mouse cursor's vertical position.\n    const coords = {\n      left: editorBoundingBox.left + editorBoundingBox.width / 2, // take middle of editor\n      top: event.clientY,\n    };\n    const block = getDraggableBlockFromCoords(coords, this.pmView);\n\n    // Closes the menu if the mouse cursor is beyond the editor vertically.\n    if (!block || !this.editor.isEditable) {\n      if (this.sideMenuState?.show) {\n        this.sideMenuState.show = false;\n        this.updateSideMenu(this.sideMenuState);\n      }\n\n      return;\n    }\n\n    // Doesn't update if the menu is already open and the mouse cursor is still hovering the same block.\n    if (\n      this.sideMenuState?.show &&\n      this.hoveredBlock?.hasAttribute(\"data-id\") &&\n      this.hoveredBlock?.getAttribute(\"data-id\") === block.id\n    ) {\n      return;\n    }\n\n    this.hoveredBlock = block.node;\n\n    // Gets the block's content node, which lets to ignore child blocks when determining the block menu's position.\n    const blockContent = block.node.firstChild as HTMLElement;\n\n    if (!blockContent) {\n      return;\n    }\n\n    // Shows or updates elements.\n    if (this.editor.isEditable) {\n      const blockContentBoundingBox = blockContent.getBoundingClientRect();\n\n      this.sideMenuState = {\n        show: cursorWithinEditor,\n        referencePos: new DOMRect(\n          this.horizontalPosAnchoredAtRoot\n            ? this.horizontalPosAnchor\n            : blockContentBoundingBox.x,\n          blockContentBoundingBox.y,\n          blockContentBoundingBox.width,\n          blockContentBoundingBox.height\n        ),\n        block: this.editor.getBlock(\n          this.hoveredBlock!.getAttribute(\"data-id\")!\n        )!,\n      };\n\n      this.updateSideMenu(this.sideMenuState);\n    }\n  };\n\n  onScroll = () => {\n    if (this.sideMenuState?.show) {\n      const blockContent = this.hoveredBlock!.firstChild as HTMLElement;\n      const blockContentBoundingBox = blockContent.getBoundingClientRect();\n\n      this.sideMenuState.referencePos = new DOMRect(\n        this.horizontalPosAnchoredAtRoot\n          ? this.horizontalPosAnchor\n          : blockContentBoundingBox.x,\n        blockContentBoundingBox.y,\n        blockContentBoundingBox.width,\n        blockContentBoundingBox.height\n      );\n      this.updateSideMenu(this.sideMenuState);\n    }\n  };\n\n  destroy() {\n    if (this.sideMenuState?.show) {\n      this.sideMenuState.show = false;\n      this.updateSideMenu(this.sideMenuState);\n    }\n    document.body.removeEventListener(\"mousemove\", this.onMouseMove);\n    document.body.removeEventListener(\"dragover\", this.onDragOver);\n    this.pmView.dom.removeEventListener(\"dragstart\", this.onDragStart);\n    document.body.removeEventListener(\"drop\", this.onDrop, true);\n    document.removeEventListener(\"scroll\", this.onScroll);\n    document.body.removeEventListener(\"mousedown\", this.onMouseDown, true);\n    document.body.removeEventListener(\"keydown\", this.onKeyDown, true);\n  }\n\n  addBlock() {\n    if (this.sideMenuState?.show) {\n      this.sideMenuState.show = false;\n      this.updateSideMenu(this.sideMenuState);\n    }\n\n    this.menuFrozen = true;\n\n    const blockContent = this.hoveredBlock!.firstChild! as HTMLElement;\n    const blockContentBoundingBox = blockContent.getBoundingClientRect();\n\n    const pos = this.pmView.posAtCoords({\n      left: blockContentBoundingBox.left + blockContentBoundingBox.width / 2,\n      top: blockContentBoundingBox.top + blockContentBoundingBox.height / 2,\n    });\n    if (!pos) {\n      return;\n    }\n\n    const blockInfo = getBlockInfoFromPos(\n      this.editor._tiptapEditor.state.doc,\n      pos.pos\n    );\n    if (blockInfo === undefined) {\n      return;\n    }\n\n    const { contentNode, endPos } = blockInfo;\n\n    // Creates a new block if current one is not empty for the suggestion menu to open in.\n    if (contentNode.textContent.length !== 0) {\n      const newBlockInsertionPos = endPos + 1;\n      const newBlockContentPos = newBlockInsertionPos + 2;\n\n      this.editor._tiptapEditor\n        .chain()\n        .BNCreateBlock(newBlockInsertionPos)\n        .BNUpdateBlock(newBlockContentPos, { type: \"paragraph\", props: {} })\n        .setTextSelection(newBlockContentPos)\n        .run();\n    } else {\n      this.editor._tiptapEditor.commands.setTextSelection(endPos);\n    }\n\n    // Focuses and activates the suggestion menu.\n    this.pmView.focus();\n    this.pmView.dispatch(\n      this.pmView.state.tr.scrollIntoView().setMeta(slashMenuPluginKey, {\n        // TODO import suggestion plugin key\n        activate: true,\n        type: \"drag\",\n      })\n    );\n  }\n\n  // onMouseDown() {\n  //   if (this.sideMenuState) {\n  //     this.sideMenuState.show = true;\n  //     this.updateSideMenu(this.sideMenuState);\n  //     this.menuFrozen = false;\n  //   }\n  // }\n}\n\nexport const sideMenuPluginKey = new PluginKey(\"SideMenuPlugin\");\n\nexport class SideMenuProsemirrorPlugin<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> extends EventEmitter<any> {\n  private sideMenuView: SideMenuView<BSchema, I, S> | undefined;\n  public readonly plugin: Plugin;\n\n  constructor(\n    private readonly editor: BlockNoteEditor<BSchema, I, S>,\n    private getTotalBlocks: () => number,\n    private maxBlocksLimit: number,\n    private errorCallback?: () => void\n  ) {\n    super();\n    this.plugin = new Plugin({\n      key: sideMenuPluginKey,\n      view: (editorView) => {\n        this.sideMenuView = new SideMenuView(\n          editor,\n          editorView,\n          (sideMenuState) => {\n            this.emit(\"update\", sideMenuState);\n          }\n        ) as any;\n        return this.sideMenuView!;\n      },\n    });\n  }\n\n  public onUpdate(callback: (state: SideMenuState<BSchema, I, S>) => void) {\n    return this.on(\"update\", callback);\n  }\n\n  /**\n   * If the block is empty, opens the slash menu. If the block has content,\n   * creates a new block below and opens the slash menu in it.\n   */\n  addBlock = () => {\n    if (this.getTotalBlocks() >= (this.maxBlocksLimit || MAX_NUM_BLOCKS)) {\n      this.errorCallback?.();\n      return;\n    }\n    this.sideMenuView!.addBlock();\n  };\n\n  /**\n   * Handles drag & drop events for blocks.\n   */\n  blockDragStart = (event: {\n    dataTransfer: DataTransfer | null;\n    clientY: number;\n  }) => {\n    this.sideMenuView!.isDragging = true;\n    dragStart(event, this.editor);\n  };\n\n  /**\n   * Handles drag & drop events for blocks.\n   */\n  blockDragEnd = () => unsetDragImage();\n  /**\n   * Freezes the side menu. When frozen, the side menu will stay\n   * attached to the same block regardless of which block is hovered by the\n   * mouse cursor.\n   */\n  freezeMenu = () => (this.sideMenuView!.menuFrozen = true);\n  /**\n   * Unfreezes the side menu. When frozen, the side menu will stay\n   * attached to the same block regardless of which block is hovered by the\n   * mouse cursor.\n   */\n  unfreezeMenu = () => (this.sideMenuView!.menuFrozen = false);\n}\n","import { defaultBlockSchema } from \"../../blocks/defaultBlocks\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport {\n  Block,\n  BlockSchema,\n  InlineContentSchema,\n  PartialBlock,\n  StyleSchema,\n  isStyledTextInlineContent,\n} from \"../../schema\";\nimport { imageToolbarPluginKey } from \"../ImageToolbar/ImageToolbarPlugin\";\nimport { BaseSlashMenuItem } from \"./BaseSlashMenuItem\";\n\n// Sets the editor's text cursor position to the next content editable block,\n// so either a block with inline content or a table. The last block is always a\n// paragraph, so this function won't try to set the cursor position past the\n// last block.\nfunction setSelectionToNextContentEditableBlock<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(editor: BlockNoteEditor<BSchema, I, S>) {\n  let block = editor.getTextCursorPosition().block;\n  let contentType = editor.blockSchema[block.type].content;\n\n  while (contentType === \"none\") {\n    block = editor.getTextCursorPosition().nextBlock!;\n    contentType = editor.blockSchema[block.type].content as\n      | \"inline\"\n      | \"table\"\n      | \"none\";\n    editor.setTextCursorPosition(block, \"end\");\n  }\n}\n\n// Checks if the current block is empty or only contains a slash, and if so,\n// updates the current block instead of inserting a new one below. If the new\n// block doesn't contain editable content, the cursor is moved to the next block\n// that does.\nfunction insertOrUpdateBlock<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  editor: BlockNoteEditor<BSchema, I, S>,\n  block: PartialBlock<BSchema, I, S>\n): Block<BSchema, I, S> {\n  const currentBlock = editor.getTextCursorPosition().block;\n\n  if (currentBlock.content === undefined) {\n    throw new Error(\"Slash Menu open in a block that doesn't contain content.\");\n  }\n\n  if (\n    Array.isArray(currentBlock.content) &&\n    ((currentBlock.content.length === 1 &&\n      isStyledTextInlineContent(currentBlock.content[0]) &&\n      currentBlock.content[0].type === \"text\" &&\n      currentBlock.content[0].text === \"/\") ||\n      currentBlock.content.length === 0)\n  ) {\n    editor.updateBlock(currentBlock, block);\n  } else {\n    editor.insertBlocks([block], currentBlock, \"after\");\n    editor.setTextCursorPosition(\n      editor.getTextCursorPosition().nextBlock!,\n      \"end\"\n    );\n  }\n\n  const insertedBlock = editor.getTextCursorPosition().block;\n  setSelectionToNextContentEditableBlock(editor);\n\n  return insertedBlock;\n}\n\nexport const getDefaultSlashMenuItems = <\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  schema: BSchema = defaultBlockSchema as unknown as BSchema\n) => {\n  const slashMenuItems: BaseSlashMenuItem<BSchema, I, S>[] = [];\n\n  if (\"heading\" in schema && \"level\" in schema.heading.propSchema) {\n    // Command for creating a level 1 heading\n    if (schema.heading.propSchema.level.values?.includes(1)) {\n      slashMenuItems.push({\n        name: \"Heading 1\",\n        aliases: [\"h\", \"heading1\", \"h1\"],\n        execute: (editor) =>\n          insertOrUpdateBlock(editor, {\n            type: \"heading\",\n            props: { level: 1 },\n          } as PartialBlock<BSchema, I, S>),\n      });\n    }\n\n    // Command for creating a level 2 heading\n    if (schema.heading.propSchema.level.values?.includes(2)) {\n      slashMenuItems.push({\n        name: \"Heading 2\",\n        aliases: [\"h2\", \"heading2\", \"subheading\"],\n        execute: (editor) =>\n          insertOrUpdateBlock(editor, {\n            type: \"heading\",\n            props: { level: 2 },\n          } as PartialBlock<BSchema, I, S>),\n      });\n    }\n\n    // Command for creating a level 3 heading\n    if (schema.heading.propSchema.level.values?.includes(3)) {\n      slashMenuItems.push({\n        name: \"Heading 3\",\n        aliases: [\"h3\", \"heading3\", \"subheading\"],\n        execute: (editor) =>\n          insertOrUpdateBlock(editor, {\n            type: \"heading\",\n            props: { level: 3 },\n          } as PartialBlock<BSchema, I, S>),\n      });\n    }\n  }\n\n  if (\"bulletListItem\" in schema) {\n    slashMenuItems.push({\n      name: \"Bullet List\",\n      aliases: [\"ul\", \"list\", \"bulletlist\", \"bullet list\"],\n      execute: (editor) =>\n        insertOrUpdateBlock(editor, {\n          type: \"bulletListItem\",\n        }),\n    });\n  }\n\n  if (\"numberedListItem\" in schema) {\n    slashMenuItems.push({\n      name: \"Numbered List\",\n      aliases: [\"li\", \"list\", \"numberedlist\", \"numbered list\"],\n      execute: (editor) =>\n        insertOrUpdateBlock(editor, {\n          type: \"numberedListItem\",\n        }),\n    });\n  }\n\n  if (\"paragraph\" in schema) {\n    slashMenuItems.push({\n      name: \"Paragraph\",\n      aliases: [\"p\"],\n      execute: (editor) =>\n        insertOrUpdateBlock(editor, {\n          type: \"paragraph\",\n        }),\n    });\n  }\n\n  if (\"table\" in schema) {\n    slashMenuItems.push({\n      name: \"Table\",\n      aliases: [\"table\"],\n      execute: (editor) => {\n        insertOrUpdateBlock(editor, {\n          type: \"table\",\n          content: {\n            type: \"tableContent\",\n            rows: [\n              {\n                cells: [\"\", \"\", \"\"],\n              },\n              {\n                cells: [\"\", \"\", \"\"],\n              },\n            ],\n          },\n        } as PartialBlock<BSchema, I, S>);\n      },\n    });\n  }\n\n  if (\"image\" in schema) {\n    slashMenuItems.push({\n      name: \"Image\",\n      aliases: [\n        \"image\",\n        \"imageUpload\",\n        \"upload\",\n        \"img\",\n        \"picture\",\n        \"media\",\n        \"url\",\n        \"drive\",\n        \"dropbox\",\n      ],\n      execute: (editor) => {\n        const insertedBlock = insertOrUpdateBlock(editor, {\n          type: \"image\",\n        });\n\n        // Immediately open the image toolbar\n        editor._tiptapEditor.view.dispatch(\n          editor._tiptapEditor.state.tr.setMeta(imageToolbarPluginKey, {\n            block: insertedBlock,\n          })\n        );\n      },\n    });\n  }\n\n  return slashMenuItems;\n};\n","import { Plugin, PluginKey, PluginView } from \"prosemirror-state\";\nimport { Decoration, DecorationSet, EditorView } from \"prosemirror-view\";\nimport { EventEmitter } from \"../../util/EventEmitter\";\nimport { nodeToBlock } from \"../../api/nodeConversions/nodeConversions\";\nimport { DefaultBlockSchema } from \"../../blocks/defaultBlocks\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport {\n  Block,\n  BlockFromConfigNoChildren,\n  BlockSchemaWithBlock,\n  InlineContentSchema,\n  PartialBlock,\n  SpecificBlock,\n  StyleSchema,\n} from \"../../schema\";\nimport { getDraggableBlockFromCoords } from \"../SideMenu/SideMenuPlugin\";\n\nlet dragImageElement: HTMLElement | undefined;\n\nfunction setHiddenDragImage() {\n  if (dragImageElement) {\n    return;\n  }\n\n  dragImageElement = document.createElement(\"div\");\n  dragImageElement.innerHTML = \"_\";\n  dragImageElement.style.visibility = \"hidden\";\n  document.body.appendChild(dragImageElement);\n}\n\nfunction unsetHiddenDragImage() {\n  if (dragImageElement) {\n    document.body.removeChild(dragImageElement);\n    dragImageElement = undefined;\n  }\n}\n\nexport type TableHandlesState<\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> = {\n  show: boolean;\n  referencePosCell: DOMRect;\n  referencePosTable: DOMRect;\n\n  block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], I, S>;\n  colIndex: number;\n  rowIndex: number;\n\n  draggingState:\n    | {\n        draggedCellOrientation: \"row\" | \"col\";\n        originalIndex: number;\n        mousePos: number;\n      }\n    | undefined;\n};\n\nfunction getChildIndex(node: Element) {\n  return Array.prototype.indexOf.call(node.parentElement!.childNodes, node);\n}\n\n// Finds the DOM element corresponding to the table cell that the target element\n// is currently in. If the target element is not in a table cell, returns null.\nfunction domCellAround(target: Element | null): Element | null {\n  while (target && target.nodeName !== \"TD\" && target.nodeName !== \"TH\") {\n    target =\n      target.classList && target.classList.contains(\"ProseMirror\")\n        ? null\n        : (target.parentNode as Element);\n  }\n  return target;\n}\n\n// Hides elements in the DOMwith the provided class names.\nfunction hideElementsWithClassNames(classNames: string[]) {\n  classNames.forEach((className) => {\n    const elementsToHide = document.getElementsByClassName(className);\n    for (let i = 0; i < elementsToHide.length; i++) {\n      (elementsToHide[i] as HTMLElement).style.visibility = \"hidden\";\n    }\n  });\n}\n\nexport class TableHandlesView<\n  BSchema extends BlockSchemaWithBlock<\"table\", DefaultBlockSchema[\"table\"]>,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> implements PluginView\n{\n  public state?: TableHandlesState<I, S>;\n  public updateState: () => void;\n\n  public tableId: string | undefined;\n  public tablePos: number | undefined;\n\n  public menuFrozen = false;\n\n  public prevWasEditable: boolean | null = null;\n\n  constructor(\n    private readonly editor: BlockNoteEditor<BSchema, I, S>,\n    private readonly pmView: EditorView,\n    updateState: (state: TableHandlesState<I, S>) => void\n  ) {\n    this.updateState = () => {\n      if (!this.state) {\n        throw new Error(\"Attempting to update uninitialized image toolbar\");\n      }\n\n      updateState(this.state);\n    };\n\n    pmView.dom.addEventListener(\"mousemove\", this.mouseMoveHandler);\n\n    document.addEventListener(\"dragover\", this.dragOverHandler);\n    document.addEventListener(\"drop\", this.dropHandler);\n\n    document.addEventListener(\"scroll\", this.scrollHandler);\n  }\n\n  mouseMoveHandler = (event: MouseEvent) => {\n    if (this.menuFrozen) {\n      return;\n    }\n\n    const target = domCellAround(event.target as HTMLElement);\n\n    if (!target || !this.editor.isEditable) {\n      if (this.state?.show) {\n        this.state.show = false;\n        this.updateState();\n      }\n      return;\n    }\n\n    const colIndex = getChildIndex(target);\n    const rowIndex = getChildIndex(target.parentElement!);\n    const cellRect = target.getBoundingClientRect();\n    const tableRect =\n      target.parentElement!.parentElement!.getBoundingClientRect();\n\n    const blockEl = getDraggableBlockFromCoords(cellRect, this.pmView);\n    if (!blockEl) {\n      throw new Error(\n        \"Found table cell element, but could not find surrounding blockContent element.\"\n      );\n    }\n    this.tableId = blockEl.id;\n\n    if (\n      this.state !== undefined &&\n      this.state.show &&\n      this.tableId === blockEl.id &&\n      this.state.rowIndex === rowIndex &&\n      this.state.colIndex === colIndex\n    ) {\n      return;\n    }\n\n    let block: Block<any, any, any> | undefined = undefined;\n\n    // Copied from `getBlock`. We don't use `getBlock` since we also need the PM\n    // node for the table, so we would effectively be doing the same work twice.\n    this.editor._tiptapEditor.state.doc.descendants((node, pos) => {\n      if (typeof block !== \"undefined\") {\n        return false;\n      }\n\n      if (node.type.name !== \"blockContainer\" || node.attrs.id !== blockEl.id) {\n        return true;\n      }\n\n      block = nodeToBlock(\n        node,\n        this.editor.blockSchema,\n        this.editor.inlineContentSchema,\n        this.editor.styleSchema,\n        this.editor.blockCache\n      );\n      this.tablePos = pos + 1;\n\n      return false;\n    });\n\n    this.state = {\n      show: true,\n      referencePosCell: cellRect,\n      referencePosTable: tableRect,\n\n      block: block! as SpecificBlock<BSchema, \"table\", I, S>,\n      colIndex: colIndex,\n      rowIndex: rowIndex,\n\n      draggingState: undefined,\n    };\n    this.updateState();\n\n    return false;\n  };\n\n  dragOverHandler = (event: DragEvent) => {\n    if (this.state?.draggingState === undefined) {\n      return;\n    }\n\n    event.preventDefault();\n    event.dataTransfer!.dropEffect = \"move\";\n\n    hideElementsWithClassNames([\n      \"column-resize-handle\",\n      \"prosemirror-dropcursor-block\",\n      \"prosemirror-dropcursor-inline\",\n    ]);\n\n    // The mouse cursor coordinates, bounded to the table's bounding box. The\n    // bounding box is shrunk by 1px on each side to ensure that the bounded\n    // coordinates are always inside a table cell.\n    const boundedMouseCoords = {\n      left: Math.min(\n        Math.max(event.clientX, this.state.referencePosTable.left + 1),\n        this.state.referencePosTable.right - 1\n      ),\n      top: Math.min(\n        Math.max(event.clientY, this.state.referencePosTable.top + 1),\n        this.state.referencePosTable.bottom - 1\n      ),\n    };\n\n    // Gets the table cell element that the bounded mouse cursor coordinates lie\n    // in.\n    const tableCellElements = document\n      .elementsFromPoint(boundedMouseCoords.left, boundedMouseCoords.top)\n      .filter(\n        (element) => element.tagName === \"TD\" || element.tagName === \"TH\"\n      );\n    if (tableCellElements.length === 0) {\n      throw new Error(\n        \"Could not find table cell element that the mouse cursor is hovering over.\"\n      );\n    }\n    const tableCellElement = tableCellElements[0];\n\n    let emitStateUpdate = false;\n\n    // Gets current row and column index.\n    const rowIndex = getChildIndex(tableCellElement.parentElement!);\n    const colIndex = getChildIndex(tableCellElement);\n\n    // Checks if the drop cursor needs to be updated. This affects decorations\n    // only so it doesn't trigger a state update.\n    const oldIndex =\n      this.state.draggingState.draggedCellOrientation === \"row\"\n        ? this.state.rowIndex\n        : this.state.colIndex;\n    const newIndex =\n      this.state.draggingState.draggedCellOrientation === \"row\"\n        ? rowIndex\n        : colIndex;\n    const dispatchDecorationsTransaction = newIndex !== oldIndex;\n\n    // Checks if either the hovered cell has changed and updates the row and\n    // column index. Also updates the reference DOMRect.\n    if (this.state.rowIndex !== rowIndex || this.state.colIndex !== colIndex) {\n      this.state.rowIndex = rowIndex;\n      this.state.colIndex = colIndex;\n\n      this.state.referencePosCell = tableCellElement.getBoundingClientRect();\n\n      emitStateUpdate = true;\n    }\n\n    // Checks if the mouse cursor position along the axis that the user is\n    // dragging on has changed and updates it.\n    const mousePos =\n      this.state.draggingState.draggedCellOrientation === \"row\"\n        ? boundedMouseCoords.top\n        : boundedMouseCoords.left;\n    if (this.state.draggingState.mousePos !== mousePos) {\n      this.state.draggingState.mousePos = mousePos;\n\n      emitStateUpdate = true;\n    }\n\n    // Emits a state update if any of the fields have changed.\n    if (emitStateUpdate) {\n      this.updateState();\n    }\n\n    // Dispatches a dummy transaction to force a decorations update if\n    // necessary.\n    if (dispatchDecorationsTransaction) {\n      this.pmView.dispatch(\n        this.pmView.state.tr.setMeta(tableHandlesPluginKey, true)\n      );\n    }\n  };\n\n  dropHandler = (event: DragEvent) => {\n    if (this.state === undefined || this.state.draggingState === undefined) {\n      return;\n    }\n\n    event.preventDefault();\n\n    const rows = this.state.block.content.rows;\n\n    if (this.state.draggingState.draggedCellOrientation === \"row\") {\n      const rowToMove = rows[this.state.draggingState.originalIndex];\n      rows.splice(this.state.draggingState.originalIndex, 1);\n      rows.splice(this.state.rowIndex, 0, rowToMove);\n    } else {\n      const cellsToMove = rows.map(\n        (row) => row.cells[this.state!.draggingState!.originalIndex]\n      );\n      rows.forEach((row, rowIndex) => {\n        row.cells.splice(this.state!.draggingState!.originalIndex, 1);\n        row.cells.splice(this.state!.colIndex, 0, cellsToMove[rowIndex]);\n      });\n    }\n\n    this.editor.updateBlock(this.state.block, {\n      type: \"table\",\n      content: {\n        type: \"tableContent\",\n        rows: rows,\n      },\n    } as PartialBlock<BSchema, I, S>);\n  };\n\n  scrollHandler = () => {\n    if (this.state?.show) {\n      const tableElement = document.querySelector(\n        `[data-node-type=\"blockContainer\"][data-id=\"${this.tableId}\"] table`\n      )!;\n      const cellElement = tableElement.querySelector(\n        `tr:nth-child(${this.state.rowIndex + 1}) > td:nth-child(${\n          this.state.colIndex + 1\n        })`\n      )!;\n\n      this.state.referencePosTable = tableElement.getBoundingClientRect();\n      this.state.referencePosCell = cellElement.getBoundingClientRect();\n      this.updateState();\n    }\n  };\n\n  destroy() {\n    this.pmView.dom.removeEventListener(\"mousedown\", this.mouseMoveHandler);\n\n    document.removeEventListener(\"dragover\", this.dragOverHandler);\n    document.removeEventListener(\"drop\", this.dropHandler);\n\n    document.removeEventListener(\"scroll\", this.scrollHandler);\n  }\n}\n\nexport const tableHandlesPluginKey = new PluginKey(\"TableHandlesPlugin\");\n\nexport class TableHandlesProsemirrorPlugin<\n  BSchema extends BlockSchemaWithBlock<\"table\", DefaultBlockSchema[\"table\"]>,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n> extends EventEmitter<any> {\n  private view: TableHandlesView<BSchema, I, S> | undefined;\n  public readonly plugin: Plugin;\n\n  constructor(private readonly editor: BlockNoteEditor<BSchema, I, S>) {\n    super();\n    this.plugin = new Plugin({\n      key: tableHandlesPluginKey,\n      view: (editorView) => {\n        this.view = new TableHandlesView(editor, editorView, (state) => {\n          this.emit(\"update\", state);\n        });\n        return this.view;\n      },\n      // We use decorations to render the drop cursor when dragging a table row\n      // or column. The decorations are updated in the `dragOverHandler` method.\n      props: {\n        decorations: (state) => {\n          if (\n            this.view === undefined ||\n            this.view.state === undefined ||\n            this.view.state.draggingState === undefined ||\n            this.view.tablePos === undefined\n          ) {\n            return;\n          }\n\n          const newIndex =\n            this.view.state.draggingState.draggedCellOrientation === \"row\"\n              ? this.view.state.rowIndex\n              : this.view.state.colIndex;\n\n          const decorations: Decoration[] = [];\n\n          if (newIndex === this.view.state.draggingState.originalIndex) {\n            return DecorationSet.create(state.doc, decorations);\n          }\n\n          // Gets the table to show the drop cursor in.\n          const tableResolvedPos = state.doc.resolve(this.view.tablePos + 1);\n          const tableNode = tableResolvedPos.node();\n\n          if (this.view.state.draggingState.draggedCellOrientation === \"row\") {\n            // Gets the row at the new index.\n            const rowResolvedPos = state.doc.resolve(\n              tableResolvedPos.posAtIndex(newIndex) + 1\n            );\n            const rowNode = rowResolvedPos.node();\n\n            // Iterates over all cells in the row.\n            for (let i = 0; i < rowNode.childCount; i++) {\n              // Gets each cell in the row.\n              const cellResolvedPos = state.doc.resolve(\n                rowResolvedPos.posAtIndex(i) + 1\n              );\n              const cellNode = cellResolvedPos.node();\n\n              // Creates a decoration at the start or end of each cell,\n              // depending on whether the new index is before or after the\n              // original index.\n              const decorationPos =\n                cellResolvedPos.pos +\n                (newIndex > this.view.state.draggingState.originalIndex\n                  ? cellNode.nodeSize - 2\n                  : 0);\n              decorations.push(\n                // The widget is a small bar which spans the width of the cell.\n                Decoration.widget(decorationPos, () => {\n                  const widget = document.createElement(\"div\");\n                  widget.className = \"bn-table-drop-cursor\";\n                  widget.style.left = \"0\";\n                  widget.style.right = \"0\";\n                  // This is only necessary because the drop indicator's height\n                  // is an even number of pixels, whereas the border between\n                  // table cells is an odd number of pixels. So this makes the\n                  // positioning slightly more consistent regardless of where\n                  // the row is being dropped.\n                  if (\n                    newIndex > this.view!.state!.draggingState!.originalIndex\n                  ) {\n                    widget.style.bottom = \"-2px\";\n                  } else {\n                    widget.style.top = \"-3px\";\n                  }\n                  widget.style.height = \"4px\";\n\n                  return widget;\n                })\n              );\n            }\n          } else {\n            // Iterates over all rows in the table.\n            for (let i = 0; i < tableNode.childCount; i++) {\n              // Gets each row in the table.\n              const rowResolvedPos = state.doc.resolve(\n                tableResolvedPos.posAtIndex(i) + 1\n              );\n\n              // Gets the cell at the new index in the row.\n              const cellResolvedPos = state.doc.resolve(\n                rowResolvedPos.posAtIndex(newIndex) + 1\n              );\n              const cellNode = cellResolvedPos.node();\n\n              // Creates a decoration at the start or end of each cell,\n              // depending on whether the new index is before or after the\n              // original index.\n              const decorationPos =\n                cellResolvedPos.pos +\n                (newIndex > this.view.state.draggingState.originalIndex\n                  ? cellNode.nodeSize - 2\n                  : 0);\n              decorations.push(\n                // The widget is a small bar which spans the height of the cell.\n                Decoration.widget(decorationPos, () => {\n                  const widget = document.createElement(\"div\");\n                  widget.className = \"bn-table-drop-cursor\";\n                  widget.style.top = \"0\";\n                  widget.style.bottom = \"0\";\n                  // This is only necessary because the drop indicator's width\n                  // is an even number of pixels, whereas the border between\n                  // table cells is an odd number of pixels. So this makes the\n                  // positioning slightly more consistent regardless of where\n                  // the column is being dropped.\n                  if (\n                    newIndex > this.view!.state!.draggingState!.originalIndex\n                  ) {\n                    widget.style.right = \"-2px\";\n                  } else {\n                    widget.style.left = \"-3px\";\n                  }\n                  widget.style.width = \"4px\";\n\n                  return widget;\n                })\n              );\n            }\n          }\n\n          return DecorationSet.create(state.doc, decorations);\n        },\n      },\n    });\n  }\n\n  public onUpdate(callback: (state: TableHandlesState<I, S>) => void) {\n    return this.on(\"update\", callback);\n  }\n\n  /**\n   * Callback that should be set on the `dragStart` event for whichever element\n   * is used as the column drag handle.\n   */\n  colDragStart = (event: {\n    dataTransfer: DataTransfer | null;\n    clientX: number;\n  }) => {\n    if (this.view!.state === undefined) {\n      throw new Error(\n        \"Attempted to drag table column, but no table block was hovered prior.\"\n      );\n    }\n\n    this.view!.state.draggingState = {\n      draggedCellOrientation: \"col\",\n      originalIndex: this.view!.state.colIndex,\n      mousePos: event.clientX,\n    };\n    this.view!.updateState();\n\n    this.editor._tiptapEditor.view.dispatch(\n      this.editor._tiptapEditor.state.tr.setMeta(tableHandlesPluginKey, {\n        draggedCellOrientation:\n          this.view!.state.draggingState.draggedCellOrientation,\n        originalIndex: this.view!.state.colIndex,\n        newIndex: this.view!.state.colIndex,\n        tablePos: this.view!.tablePos,\n      })\n    );\n\n    setHiddenDragImage();\n    event.dataTransfer!.setDragImage(dragImageElement!, 0, 0);\n    event.dataTransfer!.effectAllowed = \"move\";\n  };\n\n  /**\n   * Callback that should be set on the `dragStart` event for whichever element\n   * is used as the row drag handle.\n   */\n  rowDragStart = (event: {\n    dataTransfer: DataTransfer | null;\n    clientY: number;\n  }) => {\n    if (this.view!.state === undefined) {\n      throw new Error(\n        \"Attempted to drag table row, but no table block was hovered prior.\"\n      );\n    }\n\n    this.view!.state.draggingState = {\n      draggedCellOrientation: \"row\",\n      originalIndex: this.view!.state.rowIndex,\n      mousePos: event.clientY,\n    };\n    this.view!.updateState();\n\n    this.editor._tiptapEditor.view.dispatch(\n      this.editor._tiptapEditor.state.tr.setMeta(tableHandlesPluginKey, {\n        draggedCellOrientation:\n          this.view!.state.draggingState.draggedCellOrientation,\n        originalIndex: this.view!.state.rowIndex,\n        newIndex: this.view!.state.rowIndex,\n        tablePos: this.view!.tablePos,\n      })\n    );\n\n    setHiddenDragImage();\n    event.dataTransfer!.setDragImage(dragImageElement!, 0, 0);\n    event.dataTransfer!.effectAllowed = \"copyMove\";\n  };\n\n  /**\n   * Callback that should be set on the `dragEnd` event for both the element\n   * used as the row drag handle, and the one used as the column drag handle.\n   */\n  dragEnd = () => {\n    if (this.view!.state === undefined) {\n      throw new Error(\n        \"Attempted to drag table row, but no table block was hovered prior.\"\n      );\n    }\n\n    this.view!.state.draggingState = undefined;\n    this.view!.updateState();\n\n    this.editor._tiptapEditor.view.dispatch(\n      this.editor._tiptapEditor.state.tr.setMeta(tableHandlesPluginKey, null)\n    );\n\n    unsetHiddenDragImage();\n  };\n\n  /**\n   * Freezes the drag handles. When frozen, they will stay attached to the same\n   * cell regardless of which cell is hovered by the mouse cursor.\n   */\n  freezeHandles = () => (this.view!.menuFrozen = true);\n\n  /**\n   * Unfreezes the drag handles. When frozen, they will stay attached to the\n   * same cell regardless of which cell is hovered by the mouse cursor.\n   */\n  unfreezeHandles = () => (this.view!.menuFrozen = false);\n}\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"prosemirror-state\";\n\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport { BlockSchema, InlineContentSchema, StyleSchema } from \"../../schema\";\nimport { createExternalHTMLExporter } from \"./html/externalHTMLExporter\";\nimport { createInternalHTMLSerializer } from \"./html/internalHTMLSerializer\";\nimport { cleanHTMLToMarkdown } from \"./markdown/markdownExporter\";\n\nexport const createCopyToClipboardExtension = <\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  editor: BlockNoteEditor<BSchema, I, S>\n) =>\n  Extension.create<{ editor: BlockNoteEditor<BSchema, I, S> }, undefined>({\n    name: \"copyToClipboard\",\n    addProseMirrorPlugins() {\n      const tiptap = this.editor;\n      const schema = this.editor.schema;\n      return [\n        new Plugin({\n          props: {\n            handleDOMEvents: {\n              copy(_view, event) {\n                // Stops the default browser copy behaviour.\n                event.preventDefault();\n                event.clipboardData!.clearData();\n\n                const selectedFragment =\n                  tiptap.state.selection.content().content;\n\n                const internalHTMLSerializer = createInternalHTMLSerializer(\n                  schema,\n                  editor\n                );\n                const internalHTML =\n                  internalHTMLSerializer.serializeProseMirrorFragment(\n                    selectedFragment\n                  );\n\n                const externalHTMLExporter = createExternalHTMLExporter(\n                  schema,\n                  editor\n                );\n                const externalHTML =\n                  externalHTMLExporter.exportProseMirrorFragment(\n                    selectedFragment\n                  );\n\n                const plainText = cleanHTMLToMarkdown(externalHTML);\n\n                // TODO: Writing to other MIME types not working in Safari for\n                //  some reason.\n                event.clipboardData!.setData(\"blocknote/html\", internalHTML);\n                event.clipboardData!.setData(\"text/html\", externalHTML);\n                event.clipboardData!.setData(\"text/plain\", plainText);\n\n                // Prevent default PM handler to be called\n                return true;\n              },\n            },\n          },\n        }),\n      ];\n    },\n  });\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"prosemirror-state\";\n\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor\";\nimport { BlockSchema, InlineContentSchema, StyleSchema } from \"../../schema\";\nimport { nestedListsToBlockNoteStructure } from \"./html/util/nestedLists\";\n\nconst acceptedMIMETypes = [\n  \"blocknote/html\",\n  \"text/html\",\n  \"text/plain\",\n] as const;\n\nexport const createPasteFromClipboardExtension = <\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  editor: BlockNoteEditor<BSchema, I, S>\n) =>\n  Extension.create<{ editor: BlockNoteEditor<BSchema, I, S> }, undefined>({\n    name: \"pasteFromClipboard\",\n    addProseMirrorPlugins() {\n      return [\n        new Plugin({\n          props: {\n            handleDOMEvents: {\n              paste(_view, event) {\n                event.preventDefault();\n                let format: (typeof acceptedMIMETypes)[number] | null = null;\n\n                for (const mimeType of acceptedMIMETypes) {\n                  if (event.clipboardData!.types.includes(mimeType)) {\n                    format = mimeType;\n                    break;\n                  }\n                }\n\n                if (format !== null) {\n                  let data = event.clipboardData!.getData(format);\n                  if (format === \"text/html\") {\n                    const htmlNode = nestedListsToBlockNoteStructure(\n                      data.trim()\n                    );\n\n                    data = htmlNode.innerHTML;\n                  }\n                  editor._tiptapEditor.view.pasteHTML(data);\n                }\n\n                return true;\n              },\n            },\n          },\n        }),\n      ];\n    },\n  });\n","import { Extension } from \"@tiptap/core\";\nimport { defaultProps } from \"../../blocks/defaultProps\";\n\nexport const BackgroundColorExtension = Extension.create({\n  name: \"blockBackgroundColor\",\n\n  addGlobalAttributes() {\n    return [\n      {\n        types: [\"blockContainer\"],\n        attributes: {\n          backgroundColor: {\n            default: defaultProps.backgroundColor.default,\n            parseHTML: (element) =>\n              element.hasAttribute(\"data-background-color\")\n                ? element.getAttribute(\"data-background-color\")\n                : defaultProps.backgroundColor.default,\n            renderHTML: (attributes) =>\n              attributes.backgroundColor !==\n                defaultProps.backgroundColor.default && {\n                \"data-background-color\": attributes.backgroundColor,\n              },\n          },\n        },\n      },\n    ];\n  },\n});\n","import { Editor, Extension } from \"@tiptap/core\";\nimport { Node as ProsemirrorNode } from \"prosemirror-model\";\nimport { Plugin, PluginKey } from \"prosemirror-state\";\nimport { Decoration, DecorationSet } from \"prosemirror-view\";\nimport { slashMenuPluginKey } from \"../SlashMenu/SlashMenuPlugin\";\n\nconst PLUGIN_KEY = new PluginKey(`blocknote-placeholder`);\n\n/**\n * This is a modified version of the tiptap\n * placeholder plugin, that also sets hasAnchorClass\n *\n * It does not set a data-placeholder (text is currently done in css)\n *\n */\nexport interface PlaceholderOptions {\n  emptyEditorClass: string;\n  emptyNodeClass: string;\n  isFilterClass: string;\n  hasAnchorClass: string;\n  placeholder:\n    | ((PlaceholderProps: {\n        editor: Editor;\n        node: ProsemirrorNode;\n        pos: number;\n        hasAnchor: boolean;\n      }) => string)\n    | string;\n  showOnlyWhenEditable: boolean;\n  showOnlyCurrent: boolean;\n  includeChildren: boolean;\n}\n\nexport const Placeholder = Extension.create<PlaceholderOptions>({\n  name: \"placeholder\",\n\n  addOptions() {\n    return {\n      emptyEditorClass: \"bn-is-editor-empty\",\n      emptyNodeClass: \"bn-is-empty\",\n      isFilterClass: \"bn-is-filter\",\n      hasAnchorClass: \"bn-has-anchor\",\n      placeholder: \"Write something …\",\n      showOnlyWhenEditable: true,\n      showOnlyCurrent: true,\n      includeChildren: false,\n    };\n  },\n\n  addProseMirrorPlugins() {\n    return [\n      new Plugin({\n        key: PLUGIN_KEY,\n        props: {\n          decorations: (state) => {\n            const { doc, selection } = state;\n            // Get state of slash menu\n            const menuState = slashMenuPluginKey.getState(state);\n            const active =\n              this.editor.isEditable || !this.options.showOnlyWhenEditable;\n            const { anchor } = selection;\n            const decorations: Decoration[] = [];\n\n            if (!active) {\n              return;\n            }\n\n            doc.descendants((node, pos) => {\n              const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;\n              const isEmpty = !node.isLeaf && !node.childCount;\n\n              if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {\n                const classes = [this.options.emptyNodeClass];\n\n                // TODO: Doesn't work?\n                if (this.editor.isEmpty) {\n                  classes.push(this.options.emptyEditorClass);\n                }\n\n                if (hasAnchor) {\n                  classes.push(this.options.hasAnchorClass);\n                }\n\n                // If slash menu is of drag type and active, show the filter placeholder\n                if (menuState?.triggerCharacter === \"\" && menuState?.active) {\n                  classes.push(this.options.isFilterClass);\n                }\n                // using widget, didn't work (caret position bug)\n                // const decoration = Decoration.widget(\n                //   pos + 1,\n                //   () => {\n                //     const el = document.createElement(\"span\");\n                //     el.innerText = \"hello\";\n                //     return el;\n                //   },\n                //   { side: 0 }\n\n                // Code that sets variables / classes\n                // const ph =\n                //   typeof this.options.placeholder === \"function\"\n                //     ? this.options.placeholder({\n                //         editor: this.editor,\n                //         node,\n                //         pos,\n                //         hasAnchor,\n                //       })\n                //     : this.options.placeholder;\n                // const decoration = Decoration.node(pos, pos + node.nodeSize, {\n                //   class: classes.join(\" \"),\n                //   style: `--placeholder:'${ph.replaceAll(\"'\", \"\\\\'\")}';`,\n                //   \"data-placeholder\": ph,\n                // });\n\n                // Latest version, only set isEmpty and hasAnchor, rest is done via CSS\n\n                const decoration = Decoration.node(pos, pos + node.nodeSize, {\n                  class: classes.join(\" \"),\n                });\n                decorations.push(decoration);\n              }\n\n              return this.options.includeChildren;\n            });\n\n            return DecorationSet.create(doc, decorations);\n          },\n        },\n      }),\n    ];\n  },\n});\n","import { Extension } from \"@tiptap/core\";\n\nexport const TextAlignmentExtension = Extension.create({\n  name: \"textAlignment\",\n\n  addGlobalAttributes() {\n    return [\n      {\n        // Attribute is applied to block content instead of container so that child blocks don't inherit the text\n        // alignment styling.\n        types: [\"paragraph\", \"heading\", \"bulletListItem\", \"numberedListItem\"],\n        attributes: {\n          textAlignment: {\n            default: \"left\",\n            parseHTML: (element) => {\n              return element.getAttribute(\"data-text-alignment\");\n            },\n            renderHTML: (attributes) =>\n              attributes.textAlignment !== \"left\" && {\n                \"data-text-alignment\": attributes.textAlignment,\n              },\n          },\n        },\n      },\n    ];\n  },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { defaultProps } from \"../../blocks/defaultProps\";\n\nexport const TextColorExtension = Extension.create({\n  name: \"blockTextColor\",\n\n  addGlobalAttributes() {\n    return [\n      {\n        types: [\"blockContainer\"],\n        attributes: {\n          textColor: {\n            default: defaultProps.textColor.default,\n            parseHTML: (element) =>\n              element.hasAttribute(\"data-text-color\")\n                ? element.getAttribute(\"data-text-color\")\n                : defaultProps.textColor.default,\n            renderHTML: (attributes) =>\n              attributes.textColor !== defaultProps.textColor.default && {\n                \"data-text-color\": attributes.textColor,\n              },\n          },\n        },\n      },\n    ];\n  },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"prosemirror-state\";\nimport { Node } from \"prosemirror-model\";\n\n// based on https://github.com/ueberdosis/tiptap/blob/40a9404c94c7fef7900610c195536384781ae101/demos/src/Experiments/TrailingNode/Vue/trailing-node.ts\n\n/**\n * Extension based on:\n * - https://github.com/ueberdosis/tiptap/blob/v1/packages/tiptap-extensions/src/extensions/TrailingNode.js\n * - https://github.com/remirror/remirror/blob/e0f1bec4a1e8073ce8f5500d62193e52321155b9/packages/prosemirror-trailing-node/src/trailing-node-plugin.ts\n */\n\nexport interface TrailingNodeOptions {\n  node: string;\n  getTotalBlocks: () => number;\n  maxBlocksLimit: number;\n  isWholeDocEmpty: () => boolean;\n  countBlocks: (node: Node | null) => number;\n}\n\n/**\n * Add a trailing node to the document so the user can always click at the bottom of the document and start typing\n */\nexport const TrailingNode = Extension.create<TrailingNodeOptions>({\n  name: \"trailingNode\",\n\n  addProseMirrorPlugins() {\n    const plugin = new PluginKey(this.name);\n    // const disabledNodes = Object.entries(this.editor.schema.nodes)\n    //   .map(([, value]) => value)\n    //   .filter((node) => this.options.notAfter.includes(node.name));\n\n    return [\n      new Plugin({\n        key: plugin,\n        appendTransaction: (_, __, state) => {\n          const { doc, tr, schema } = state;\n          const shouldInsertNodeAtEnd = plugin.getState(state);\n          const endPosition = doc.content.size - 2;\n          const type = schema.nodes[\"blockContainer\"];\n          const contentType = schema.nodes[\"paragraph\"];\n          if (\n            !shouldInsertNodeAtEnd ||\n            this.options.getTotalBlocks() >= this.options.maxBlocksLimit ||\n            this.options.countBlocks(doc.firstChild) >=\n              this.options.maxBlocksLimit\n          ) {\n            return;\n          }\n\n          return tr.insert(\n            endPosition,\n            type.create(undefined, contentType.create())\n          );\n        },\n        state: {\n          init: (_, _state) => {\n            // (maybe fix): use same logic as apply() here\n            // so it works when initializing\n          },\n          apply: (tr, value) => {\n            if (!tr.docChanged) {\n              return value;\n            }\n\n            let lastNode = tr.doc.lastChild;\n\n            if (!lastNode || lastNode.type.name !== \"blockGroup\") {\n              throw new Error(\"Expected blockGroup\");\n            }\n\n            lastNode = lastNode.lastChild;\n\n            if (!lastNode || lastNode.type.name !== \"blockContainer\") {\n              throw new Error(\"Expected blockContainer\");\n            }\n\n            const lastContentNode = lastNode.firstChild;\n\n            if (!lastContentNode) {\n              throw new Error(\"Expected blockContent\");\n            }\n\n            // If last node is not empty (size > 4) or it doesn't contain\n            // inline content, we need to add a trailing node.\n            return (\n              lastNode.nodeSize > 4 ||\n              lastContentNode.type.spec.content !== \"inline*\"\n            );\n          },\n        },\n      }),\n    ];\n  },\n});\n","import { Plugin, PluginKey } from \"prosemirror-state\";\n\nconst PLUGIN_KEY = new PluginKey(\"non-editable-block\");\n// Prevent typing for blocks without inline content, as this would otherwise\n// convert them into paragraph blocks.\nexport const NonEditableBlockPlugin = () => {\n  return new Plugin({\n    key: PLUGIN_KEY,\n    props: {\n      handleKeyDown: (view, event) => {\n        if (\"node\" in view.state.selection) {\n          event.preventDefault();\n        }\n      },\n    },\n  });\n};\n","import { findChildren } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"prosemirror-state\";\nimport { Decoration, DecorationSet } from \"prosemirror-view\";\n\nconst PLUGIN_KEY = new PluginKey(`previous-blocks`);\n\nconst nodeAttributes: Record<string, string> = {\n  // Numbered List Items\n  index: \"index\",\n  // Headings\n  level: \"level\",\n  // All Blocks\n  type: \"type\",\n  depth: \"depth\",\n  \"depth-change\": \"depth-change\",\n};\n\n/**\n * This plugin tracks transformation of Block node attributes, so we can support CSS transitions.\n *\n * Problem it solves: ProseMirror recreates the DOM when transactions happen. So when a transaction changes a Node attribute,\n * it results in a completely new DOM element. This means CSS transitions don't work.\n *\n * Solution: When attributes change on a node, this plugin sets a data-* attribute with the \"previous\" value. This way we can still use CSS transitions. (See block.module.css)\n */\nexport const PreviousBlockTypePlugin = () => {\n  let timeout: any;\n  return new Plugin({\n    key: PLUGIN_KEY,\n    view(_editorView) {\n      return {\n        update: async (view, _prevState) => {\n          if (this.key?.getState(view.state).updatedBlocks.size > 0) {\n            // use setTimeout 0 to clear the decorations so that at least\n            // for one DOM-render the decorations have been applied\n            timeout = setTimeout(() => {\n              view.dispatch(\n                view.state.tr.setMeta(PLUGIN_KEY, { clearUpdate: true })\n              );\n            }, 0);\n          }\n        },\n        destroy: () => {\n          if (timeout) {\n            clearTimeout(timeout);\n          }\n        },\n      };\n    },\n    state: {\n      init() {\n        return {\n          // Block attributes, by block ID, from just before the previous transaction.\n          prevTransactionOldBlockAttrs: {} as any,\n          // Block attributes, by block ID, from just before the current transaction.\n          currentTransactionOldBlockAttrs: {} as any,\n          // Set of IDs of blocks whose attributes changed from the current transaction.\n          updatedBlocks: new Set<string>(),\n        };\n      },\n\n      apply(transaction, prev, oldState, newState) {\n        prev.currentTransactionOldBlockAttrs = {};\n        prev.updatedBlocks.clear();\n\n        if (!transaction.docChanged || oldState.doc.eq(newState.doc)) {\n          return prev;\n        }\n\n        // TODO: Instead of iterating through the entire document, only check nodes affected by the transactions. Will\n        //  also probably require checking nodes affected by the previous transaction too.\n        // We didn't get this to work yet:\n        // const transform = combineTransactionSteps(oldState.doc, [transaction]);\n        // // const { mapping } = transform;\n        // const changes = getChangedRanges(transform);\n        //\n        // changes.forEach(({ oldRange, newRange }) => {\n        // const oldNodes = findChildrenInRange(\n        //   oldState.doc,\n        //   oldRange,\n        //   (node) => node.attrs.id\n        // );\n        //\n        // const newNodes = findChildrenInRange(\n        //   newState.doc,\n        //   newRange,\n        //   (node) => node.attrs.id\n        // );\n\n        const currentTransactionOriginalOldBlockAttrs = {} as any;\n\n        const oldNodes = findChildren(oldState.doc, (node) => node.attrs.id);\n        const oldNodesById = new Map(\n          oldNodes.map((node) => [node.node.attrs.id, node])\n        );\n        const newNodes = findChildren(newState.doc, (node) => node.attrs.id);\n\n        // Traverses all block containers in the new editor state.\n        for (const node of newNodes) {\n          const oldNode = oldNodesById.get(node.node.attrs.id);\n\n          const oldContentNode = oldNode?.node.firstChild;\n          const newContentNode = node.node.firstChild;\n\n          if (oldNode && oldContentNode && newContentNode) {\n            const newAttrs = {\n              index: newContentNode.attrs.index,\n              level: newContentNode.attrs.level,\n              type: newContentNode.type.name,\n              depth: newState.doc.resolve(node.pos).depth,\n            };\n\n            let oldAttrs = {\n              index: oldContentNode.attrs.index,\n              level: oldContentNode.attrs.level,\n              type: oldContentNode.type.name,\n              depth: oldState.doc.resolve(oldNode.pos).depth,\n            };\n\n            currentTransactionOriginalOldBlockAttrs[node.node.attrs.id] =\n              oldAttrs;\n\n            // Whenever a transaction is appended by the OrderedListItemIndexPlugin, it's given the metadata:\n            // { \"orderedListIndexing\": true }\n            // These appended transactions happen immediately after any transaction which causes ordered list item\n            // indices to require updating, including those which trigger animations. Therefore, these animations are\n            // immediately overridden when the PreviousBlockTypePlugin processes the appended transaction, despite only\n            // the listItemIndex attribute changing. To solve this, oldAttrs must be edited for transactions with the\n            // \"orderedListIndexing\" metadata, so the correct animation can be re-triggered.\n            if (transaction.getMeta(\"numberedListIndexing\")) {\n              // If the block existed before the transaction, gets the attributes from before the previous transaction\n              // (i.e. the transaction that caused list item indices to need updating).\n              if (node.node.attrs.id in prev.prevTransactionOldBlockAttrs) {\n                oldAttrs =\n                  prev.prevTransactionOldBlockAttrs[node.node.attrs.id];\n              }\n\n              // Stops list item indices themselves being animated (looks smoother), unless the block's content type is\n              // changing from a numbered list item to something else.\n              if (newAttrs.type === \"numberedListItem\") {\n                oldAttrs.index = newAttrs.index;\n              }\n            }\n\n            prev.currentTransactionOldBlockAttrs[node.node.attrs.id] = oldAttrs;\n\n            // TODO: faster deep equal?\n            if (JSON.stringify(oldAttrs) !== JSON.stringify(newAttrs)) {\n              (oldAttrs as any)[\"depth-change\"] =\n                oldAttrs.depth - newAttrs.depth;\n\n              // for debugging:\n              // console.log(\n              //   \"id:\",\n              //   node.node.attrs.id,\n              //   \"previousBlockTypePlugin changes detected, oldAttrs\",\n              //   oldAttrs,\n              //   \"new\",\n              //   newAttrs\n              // );\n\n              prev.updatedBlocks.add(node.node.attrs.id);\n            }\n          }\n        }\n\n        prev.prevTransactionOldBlockAttrs =\n          currentTransactionOriginalOldBlockAttrs;\n\n        return prev;\n      },\n    },\n    props: {\n      decorations(state) {\n        const pluginState = (this as Plugin).getState(state);\n        if (pluginState.updatedBlocks.size === 0) {\n          return undefined;\n        }\n\n        const decorations: Decoration[] = [];\n\n        state.doc.descendants((node, pos) => {\n          if (!node.attrs.id) {\n            return;\n          }\n\n          if (!pluginState.updatedBlocks.has(node.attrs.id)) {\n            return;\n          }\n\n          const prevAttrs =\n            pluginState.currentTransactionOldBlockAttrs[node.attrs.id];\n          const decorationAttrs: any = {};\n\n          for (const [nodeAttr, val] of Object.entries(prevAttrs)) {\n            decorationAttrs[\"data-prev-\" + nodeAttributes[nodeAttr]] =\n              val || \"none\";\n          }\n\n          // for debugging:\n          // console.log(\n          //   \"previousBlockTypePlugin committing decorations\",\n          //   decorationAttrs\n          // );\n\n          const decoration = Decoration.node(pos, pos + node.nodeSize, {\n            ...decorationAttrs,\n          });\n\n          decorations.push(decoration);\n        });\n\n        return DecorationSet.create(state.doc, decorations);\n      },\n    },\n  });\n};\n","import { Node } from \"@tiptap/core\";\nimport { Fragment, Node as PMNode, Slice } from \"prosemirror-model\";\nimport { NodeSelection, TextSelection } from \"prosemirror-state\";\n\nimport { getBlockInfoFromPos } from \"../api/getBlockInfoFromPos\";\nimport {\n  blockToNode,\n  inlineContentToNodes,\n  tableContentToNodes,\n} from \"../api/nodeConversions/nodeConversions\";\nimport type { BlockNoteEditor } from \"../editor/BlockNoteEditor\";\nimport { NonEditableBlockPlugin } from \"../extensions/NonEditableBlocks/NonEditableBlockPlugin\";\nimport { PreviousBlockTypePlugin } from \"../extensions/PreviousBlockType/PreviousBlockTypePlugin\";\nimport {\n  BlockNoteDOMAttributes,\n  BlockSchema,\n  InlineContentSchema,\n  PartialBlock,\n  StyleSchema,\n} from \"../schema\";\nimport { mergeCSSClasses } from \"../util/browser\";\nimport { UnreachableCaseError } from \"../util/typescript\";\n\n// Object containing all possible block attributes.\nconst BlockAttributes: Record<string, string> = {\n  blockColor: \"data-block-color\",\n  blockStyle: \"data-block-style\",\n  id: \"data-id\",\n  depth: \"data-depth\",\n  depthChange: \"data-depth-change\",\n};\n\ndeclare module \"@tiptap/core\" {\n  interface Commands<ReturnType> {\n    block: {\n      BNCreateBlock: (pos: number) => ReturnType;\n      BNDeleteBlock: (posInBlock: number) => ReturnType;\n      BNMergeBlocks: (posBetweenBlocks: number) => ReturnType;\n      BNSplitBlock: (posInBlock: number, keepType: boolean) => ReturnType;\n      BNUpdateBlock: <\n        BSchema extends BlockSchema,\n        I extends InlineContentSchema,\n        S extends StyleSchema\n      >(\n        posInBlock: number,\n        block: PartialBlock<BSchema, I, S>\n      ) => ReturnType;\n      BNCreateOrUpdateBlock: <\n        BSchema extends BlockSchema,\n        I extends InlineContentSchema,\n        S extends StyleSchema\n      >(\n        posInBlock: number,\n        block: PartialBlock<BSchema, I, S>\n      ) => ReturnType;\n    };\n  }\n}\n\n/**\n * The main \"Block node\" documents consist of\n */\nexport const BlockContainer = Node.create<{\n  domAttributes?: BlockNoteDOMAttributes;\n  editor: BlockNoteEditor<BlockSchema, InlineContentSchema, StyleSchema>;\n}>({\n  name: \"blockContainer\",\n  group: \"blockContainer\",\n  // A block always contains content, and optionally a blockGroup which contains nested blocks\n  content: \"blockContent blockGroup?\",\n  // Ensures content-specific keyboard handlers trigger first.\n  priority: 50,\n  defining: true,\n\n  parseHTML() {\n    return [\n      {\n        tag: \"div\",\n        getAttrs: (element) => {\n          if (typeof element === \"string\") {\n            return false;\n          }\n\n          const attrs: Record<string, string> = {};\n          for (const [nodeAttr, HTMLAttr] of Object.entries(BlockAttributes)) {\n            if (element.getAttribute(HTMLAttr)) {\n              attrs[nodeAttr] = element.getAttribute(HTMLAttr)!;\n            }\n          }\n\n          if (element.getAttribute(\"data-node-type\") === \"blockContainer\") {\n            return attrs;\n          }\n\n          return false;\n        },\n      },\n    ];\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    const blockOuter = document.createElement(\"div\");\n    blockOuter.className = \"bn-block-outer\";\n    blockOuter.setAttribute(\"data-node-type\", \"blockOuter\");\n    for (const [attribute, value] of Object.entries(HTMLAttributes)) {\n      if (attribute !== \"class\") {\n        blockOuter.setAttribute(attribute, value);\n      }\n    }\n\n    const blockHTMLAttributes = {\n      ...(this.options.domAttributes?.blockContainer || {}),\n      ...HTMLAttributes,\n    };\n    const block = document.createElement(\"div\");\n    block.className = mergeCSSClasses(\"bn-block\", blockHTMLAttributes.class);\n    block.setAttribute(\"data-node-type\", this.name);\n    for (const [attribute, value] of Object.entries(blockHTMLAttributes)) {\n      if (attribute !== \"class\") {\n        block.setAttribute(attribute, value);\n      }\n    }\n\n    blockOuter.appendChild(block);\n\n    return {\n      dom: blockOuter,\n      contentDOM: block,\n    };\n  },\n\n  addCommands() {\n    return {\n      // Creates a new text block at a given position.\n      BNCreateBlock:\n        (pos) =>\n        ({ state, dispatch }) => {\n          const newBlock =\n            state.schema.nodes[\"blockContainer\"].createAndFill()!;\n\n          if (dispatch) {\n            state.tr.insert(pos, newBlock);\n          }\n\n          return true;\n        },\n      // Deletes a block at a given position.\n      BNDeleteBlock:\n        (posInBlock) =>\n        ({ state, dispatch }) => {\n          const blockInfo = getBlockInfoFromPos(state.doc, posInBlock);\n          if (blockInfo === undefined) {\n            return false;\n          }\n\n          const { startPos, endPos } = blockInfo;\n\n          if (dispatch) {\n            state.tr.deleteRange(startPos, endPos);\n          }\n\n          return true;\n        },\n      // Updates a block at a given position.\n      BNUpdateBlock:\n        (posInBlock, block) =>\n        ({ state, dispatch }) => {\n          const blockInfo = getBlockInfoFromPos(state.doc, posInBlock);\n          if (blockInfo === undefined) {\n            return false;\n          }\n\n          const { startPos, endPos, node, contentNode } = blockInfo;\n\n          if (dispatch) {\n            // Adds blockGroup node with child blocks if necessary.\n            if (block.children !== undefined) {\n              const childNodes = [];\n\n              // Creates ProseMirror nodes for each child block, including their descendants.\n              for (const child of block.children) {\n                childNodes.push(\n                  blockToNode(\n                    child,\n                    state.schema,\n                    this.options.editor.styleSchema\n                  )\n                );\n              }\n\n              // Checks if a blockGroup node already exists.\n              if (node.childCount === 2) {\n                // Replaces all child nodes in the existing blockGroup with the ones created earlier.\n                state.tr.replace(\n                  startPos + contentNode.nodeSize + 1,\n                  endPos - 1,\n                  new Slice(Fragment.from(childNodes), 0, 0)\n                );\n              } else {\n                // Inserts a new blockGroup containing the child nodes created earlier.\n                state.tr.insert(\n                  startPos + contentNode.nodeSize,\n                  state.schema.nodes[\"blockGroup\"].create({}, childNodes)\n                );\n              }\n            }\n\n            const oldType = contentNode.type.name;\n            const newType = block.type || oldType;\n\n            // The code below determines the new content of the block.\n            // or \"keep\" to keep as-is\n            let content: PMNode[] | \"keep\" = \"keep\";\n\n            // Has there been any custom content provided?\n            if (block.content) {\n              if (typeof block.content === \"string\") {\n                // Adds a single text node with no marks to the content.\n                content = [state.schema.text(block.content)];\n              } else if (Array.isArray(block.content)) {\n                // Adds a text node with the provided styles converted into marks to the content,\n                // for each InlineContent object.\n                content = inlineContentToNodes(\n                  block.content,\n                  state.schema,\n                  this.options.editor.styleSchema\n                );\n              } else if (block.content.type === \"tableContent\") {\n                content = tableContentToNodes(\n                  block.content,\n                  state.schema,\n                  this.options.editor.styleSchema\n                );\n              } else {\n                throw new UnreachableCaseError(block.content.type);\n              }\n            } else {\n              // no custom content has been provided, use existing content IF possible\n\n              // Since some block types contain inline content and others don't,\n              // we either need to call setNodeMarkup to just update type &\n              // attributes, or replaceWith to replace the whole blockContent.\n              const oldContentType = state.schema.nodes[oldType].spec.content;\n              const newContentType = state.schema.nodes[newType].spec.content;\n\n              if (oldContentType === \"\") {\n                // keep old content, because it's empty anyway and should be compatible with\n                // any newContentType\n              } else if (newContentType !== oldContentType) {\n                // the content type changed, replace the previous content\n                content = [];\n              } else {\n                // keep old content, because the content type is the same and should be compatible\n              }\n            }\n\n            // Now, changes the blockContent node type and adds the provided props\n            // as attributes. Also preserves all existing attributes that are\n            // compatible with the new type.\n            //\n            // Use either setNodeMarkup or replaceWith depending on whether the\n            // content is being replaced or not.\n            if (content === \"keep\") {\n              // use setNodeMarkup to only update the type and attributes\n              state.tr.setNodeMarkup(\n                startPos,\n                block.type === undefined\n                  ? undefined\n                  : state.schema.nodes[block.type],\n                {\n                  ...contentNode.attrs,\n                  ...block.props,\n                }\n              );\n            } else {\n              // use replaceWith to replace the content and the block itself\n              // also  reset the selection since replacing the block content\n              // sets it to the next block.\n              state.tr\n                .replaceWith(\n                  startPos,\n                  endPos,\n                  state.schema.nodes[newType].create(\n                    {\n                      ...contentNode.attrs,\n                      ...block.props,\n                    },\n                    content\n                  )\n                )\n                // If the node doesn't contain editable content, we want to\n                // select the whole node. But if it does have editable content,\n                // we want to set the selection to the start of it.\n                .setSelection(\n                  state.schema.nodes[newType].spec.content === \"\"\n                    ? new NodeSelection(state.tr.doc.resolve(startPos))\n                    : state.schema.nodes[newType].spec.content === \"inline*\"\n                    ? new TextSelection(state.tr.doc.resolve(startPos))\n                    : // Need to offset the position as we have to get through the\n                      // `tableRow` and `tableCell` nodes to get to the\n                      // `tableParagraph` node we want to set the selection in.\n                      new TextSelection(state.tr.doc.resolve(startPos + 4))\n                );\n            }\n\n            // Adds all provided props as attributes to the parent blockContainer node too, and also preserves existing\n            // attributes.\n            state.tr.setNodeMarkup(startPos - 1, undefined, {\n              ...node.attrs,\n              ...block.props,\n            });\n          }\n\n          return true;\n        },\n      // Appends the text contents of a block to the nearest previous block, given a position between them. Children of\n      // the merged block are moved out of it first, rather than also being merged.\n      //\n      // In the example below, the position passed into the function is between Block1 and Block2.\n      //\n      // Block1\n      //    Block2\n      // Block3\n      //    Block4\n      //        Block5\n      //\n      // Becomes:\n      //\n      // Block1\n      //    Block2Block3\n      // Block4\n      //     Block5\n      BNMergeBlocks:\n        (posBetweenBlocks) =>\n        ({ state, dispatch }) => {\n          const nextNodeIsBlock =\n            state.doc.resolve(posBetweenBlocks + 1).node().type.name ===\n            \"blockContainer\";\n          const prevNodeIsBlock =\n            state.doc.resolve(posBetweenBlocks - 1).node().type.name ===\n            \"blockContainer\";\n\n          if (!nextNodeIsBlock || !prevNodeIsBlock) {\n            return false;\n          }\n\n          const nextBlockInfo = getBlockInfoFromPos(\n            state.doc,\n            posBetweenBlocks + 1\n          );\n\n          const { node, contentNode, startPos, endPos, depth } = nextBlockInfo!;\n\n          // Removes a level of nesting all children of the next block by 1 level, if it contains both content and block\n          // group nodes.\n          if (node.childCount === 2) {\n            const childBlocksStart = state.doc.resolve(\n              startPos + contentNode.nodeSize + 1\n            );\n            const childBlocksEnd = state.doc.resolve(endPos - 1);\n            const childBlocksRange =\n              childBlocksStart.blockRange(childBlocksEnd);\n\n            // Moves the block group node inside the block into the block group node that the current block is in.\n            if (dispatch) {\n              state.tr.lift(childBlocksRange!, depth - 1);\n            }\n          }\n\n          let prevBlockEndPos = posBetweenBlocks - 1;\n          let prevBlockInfo = getBlockInfoFromPos(state.doc, prevBlockEndPos);\n\n          // Finds the nearest previous block, regardless of nesting level.\n          while (prevBlockInfo!.numChildBlocks > 0) {\n            prevBlockEndPos--;\n            prevBlockInfo = getBlockInfoFromPos(state.doc, prevBlockEndPos);\n            if (prevBlockInfo === undefined) {\n              return false;\n            }\n          }\n\n          // Deletes next block and adds its text content to the nearest previous block.\n\n          if (dispatch) {\n            dispatch(\n              state.tr\n                .deleteRange(startPos, startPos + contentNode.nodeSize)\n                .replace(\n                  prevBlockEndPos - 1,\n                  startPos,\n                  new Slice(contentNode.content, 0, 0)\n                )\n                .scrollIntoView()\n            );\n\n            state.tr.setSelection(\n              new TextSelection(state.doc.resolve(prevBlockEndPos - 1))\n            );\n          }\n\n          return true;\n        },\n      // Splits a block at a given position. Content after the position is moved to a new block below, at the same\n      // nesting level.\n      BNSplitBlock:\n        (posInBlock, keepType) =>\n        ({ state, dispatch }) => {\n          const blockInfo = getBlockInfoFromPos(state.doc, posInBlock);\n          if (blockInfo === undefined) {\n            return false;\n          }\n\n          const { contentNode, contentType, startPos, endPos, depth } =\n            blockInfo;\n\n          const originalBlockContent = state.doc.cut(startPos + 1, posInBlock);\n          const newBlockContent = state.doc.cut(posInBlock, endPos - 1);\n\n          const newBlock =\n            state.schema.nodes[\"blockContainer\"].createAndFill()!;\n\n          const newBlockInsertionPos = endPos + 1;\n          const newBlockContentPos = newBlockInsertionPos + 2;\n\n          if (dispatch) {\n            // Creates a new block. Since the schema requires it to have a content node, a paragraph node is created\n            // automatically, spanning newBlockContentPos to newBlockContentPos + 1.\n            state.tr.insert(newBlockInsertionPos, newBlock);\n\n            // Replaces the content of the newly created block's content node. Doesn't replace the whole content node so\n            // its type doesn't change.\n            state.tr.replace(\n              newBlockContentPos,\n              newBlockContentPos + 1,\n              newBlockContent.content.size > 0\n                ? new Slice(\n                    Fragment.from(newBlockContent),\n                    depth + 2,\n                    depth + 2\n                  )\n                : undefined\n            );\n\n            // Changes the type of the content node. The range doesn't matter as long as both from and to positions are\n            // within the content node.\n            if (keepType) {\n              state.tr.setBlockType(\n                newBlockContentPos,\n                newBlockContentPos,\n                state.schema.node(contentType).type,\n                contentNode.attrs\n              );\n            }\n\n            // Sets the selection to the start of the new block's content node.\n            state.tr.setSelection(\n              new TextSelection(state.doc.resolve(newBlockContentPos))\n            );\n\n            // Replaces the content of the original block's content node. Doesn't replace the whole content node so its\n            // type doesn't change.\n            state.tr.replace(\n              startPos + 1,\n              endPos - 1,\n              originalBlockContent.content.size > 0\n                ? new Slice(\n                    Fragment.from(originalBlockContent),\n                    depth + 2,\n                    depth + 2\n                  )\n                : undefined\n            );\n          }\n\n          return true;\n        },\n    };\n  },\n\n  addProseMirrorPlugins() {\n    return [PreviousBlockTypePlugin(), NonEditableBlockPlugin()];\n  },\n\n  addKeyboardShortcuts() {\n    // handleBackspace is partially adapted from https://github.com/ueberdosis/tiptap/blob/ed56337470efb4fd277128ab7ef792b37cfae992/packages/core/src/extensions/keymap.ts\n    const handleBackspace = () =>\n      this.editor.commands.first(({ commands }) => [\n        // Deletes the selection if it's not empty.\n        () => commands.deleteSelection(),\n        // Undoes an input rule if one was triggered in the last editor state change.\n        () => commands.undoInputRule(),\n        // Reverts block content type to a paragraph if the selection is at the start of the block.\n        () =>\n          commands.command(({ state }) => {\n            const { contentType, startPos } = getBlockInfoFromPos(\n              state.doc,\n              state.selection.from\n            )!;\n\n            const selectionAtBlockStart = state.selection.from === startPos + 1;\n            const isParagraph = contentType.name === \"paragraph\";\n\n            if (selectionAtBlockStart && !isParagraph) {\n              return commands.BNUpdateBlock(state.selection.from, {\n                type: \"paragraph\",\n                props: {},\n              });\n            }\n\n            return false;\n          }),\n        // Removes a level of nesting if the block is indented if the selection is at the start of the block.\n        () =>\n          commands.command(({ state }) => {\n            const { startPos } = getBlockInfoFromPos(\n              state.doc,\n              state.selection.from\n            )!;\n\n            const selectionAtBlockStart = state.selection.from === startPos + 1;\n\n            if (selectionAtBlockStart) {\n              return commands.liftListItem(\"blockContainer\");\n            }\n\n            return false;\n          }),\n        // Merges block with the previous one if it isn't indented, isn't the first block in the doc, and the selection\n        // is at the start of the block.\n        () =>\n          commands.command(({ state }) => {\n            const { depth, startPos } = getBlockInfoFromPos(\n              state.doc,\n              state.selection.from\n            )!;\n\n            const selectionAtBlockStart = state.selection.from === startPos + 1;\n            const selectionEmpty = state.selection.empty;\n            const blockAtDocStart = startPos === 2;\n\n            const posBetweenBlocks = startPos - 1;\n\n            if (\n              !blockAtDocStart &&\n              selectionAtBlockStart &&\n              selectionEmpty &&\n              depth === 2\n            ) {\n              return commands.BNMergeBlocks(posBetweenBlocks);\n            }\n\n            return false;\n          }),\n      ]);\n\n    const handleDelete = () =>\n      this.editor.commands.first(({ commands }) => [\n        // Deletes the selection if it's not empty.\n        () => commands.deleteSelection(),\n        // Merges block with the next one (at the same nesting level or lower),\n        // if one exists, the block has no children, and the selection is at the\n        // end of the block.\n        () =>\n          commands.command(({ state }) => {\n            const { node, depth, endPos } = getBlockInfoFromPos(\n              state.doc,\n              state.selection.from\n            )!;\n\n            const blockAtDocEnd = false;\n            const selectionAtBlockEnd = state.selection.from === endPos - 1;\n            const selectionEmpty = state.selection.empty;\n            const hasChildBlocks = node.childCount === 2;\n\n            if (\n              !blockAtDocEnd &&\n              selectionAtBlockEnd &&\n              selectionEmpty &&\n              !hasChildBlocks\n            ) {\n              let oldDepth = depth;\n              let newPos = endPos + 2;\n              let newDepth = state.doc.resolve(newPos).depth;\n\n              while (newDepth < oldDepth) {\n                oldDepth = newDepth;\n                newPos += 2;\n                newDepth = state.doc.resolve(newPos).depth;\n              }\n\n              return commands.BNMergeBlocks(newPos - 1);\n            }\n\n            return false;\n          }),\n      ]);\n\n    const handleEnter = () =>\n      this.editor.commands.first(({ commands }) => [\n        // Removes a level of nesting if the block is empty & indented, while the selection is also empty & at the start\n        // of the block.\n        () =>\n          commands.command(({ state }) => {\n            const { node, depth } = getBlockInfoFromPos(\n              state.doc,\n              state.selection.from\n            )!;\n\n            const selectionAtBlockStart =\n              state.selection.$anchor.parentOffset === 0;\n            const selectionEmpty =\n              state.selection.anchor === state.selection.head;\n            const blockEmpty = node.textContent.length === 0;\n            const blockIndented = depth > 2;\n\n            if (\n              selectionAtBlockStart &&\n              selectionEmpty &&\n              blockEmpty &&\n              blockIndented\n            ) {\n              return commands.liftListItem(\"blockContainer\");\n            }\n\n            return false;\n          }),\n        // Creates a new block and moves the selection to it if the current one is empty, while the selection is also\n        // empty & at the start of the block.\n        () =>\n          commands.command(({ state, chain }) => {\n            const { node, endPos } = getBlockInfoFromPos(\n              state.doc,\n              state.selection.from\n            )!;\n\n            const selectionAtBlockStart =\n              state.selection.$anchor.parentOffset === 0;\n            const selectionEmpty =\n              state.selection.anchor === state.selection.head;\n            const blockEmpty = node.textContent.length === 0;\n\n            if (selectionAtBlockStart && selectionEmpty && blockEmpty) {\n              const newBlockInsertionPos = endPos + 1;\n              const newBlockContentPos = newBlockInsertionPos + 2;\n\n              chain()\n                .BNCreateBlock(newBlockInsertionPos)\n                .setTextSelection(newBlockContentPos)\n                .run();\n\n              return true;\n            }\n\n            return false;\n          }),\n        // Splits the current block, moving content inside that's after the cursor to a new text block below. Also\n        // deletes the selection beforehand, if it's not empty.\n        () =>\n          commands.command(({ state, chain }) => {\n            const { node } = getBlockInfoFromPos(\n              state.doc,\n              state.selection.from\n            )!;\n\n            const selectionAtBlockStart =\n              state.selection.$anchor.parentOffset === 0;\n            const blockEmpty = node.textContent.length === 0;\n\n            if (!blockEmpty) {\n              chain()\n                .deleteSelection()\n                .BNSplitBlock(state.selection.from, selectionAtBlockStart)\n                .run();\n\n              return true;\n            }\n\n            return false;\n          }),\n      ]);\n\n    return {\n      Backspace: handleBackspace,\n      Delete: handleDelete,\n      Enter: handleEnter,\n      // Always returning true for tab key presses ensures they're not captured by the browser. Otherwise, they blur the\n      // editor since the browser will try to use tab for keyboard navigation.\n      Tab: () => {\n        this.editor.commands.sinkListItem(\"blockContainer\");\n        return true;\n      },\n      \"Shift-Tab\": () => {\n        this.editor.commands.liftListItem(\"blockContainer\");\n        return true;\n      },\n      \"Mod-Alt-0\": () =>\n        this.editor.commands.BNCreateBlock(\n          this.editor.state.selection.anchor + 2\n        ),\n    };\n  },\n});\n","import { Node } from \"@tiptap/core\";\nimport { BlockNoteDOMAttributes } from \"../schema\";\nimport { mergeCSSClasses } from \"../util/browser\";\n\nexport const BlockGroup = Node.create<{\n  domAttributes?: BlockNoteDOMAttributes;\n}>({\n  name: \"blockGroup\",\n  group: \"blockGroup\",\n  content: \"blockContainer+\",\n\n  parseHTML() {\n    return [\n      {\n        tag: \"div\",\n        getAttrs: (element) => {\n          if (typeof element === \"string\") {\n            return false;\n          }\n\n          if (element.getAttribute(\"data-node-type\") === \"blockGroup\") {\n            // Null means the element matches, but we don't want to add any attributes to the node.\n            return null;\n          }\n\n          return false;\n        },\n      },\n    ];\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    const blockGroupHTMLAttributes = {\n      ...(this.options.domAttributes?.blockGroup || {}),\n      ...HTMLAttributes,\n    };\n    const blockGroup = document.createElement(\"div\");\n    blockGroup.className = mergeCSSClasses(\n      \"bn-block-group\",\n      blockGroupHTMLAttributes.class\n    );\n    blockGroup.setAttribute(\"data-node-type\", \"blockGroup\");\n    for (const [attribute, value] of Object.entries(blockGroupHTMLAttributes)) {\n      if (attribute !== \"class\") {\n        blockGroup.setAttribute(attribute, value);\n      }\n    }\n\n    return {\n      dom: blockGroup,\n      contentDOM: blockGroup,\n    };\n  },\n});\n","import {Node} from \"@tiptap/core\";\n\nexport const Doc = Node.create({\n    name: \"doc\",\n    topNode: true,\n    content: \"blockGroup\",\n});\n","import { Mark } from \"@tiptap/core\";\n\nexport const CustomContentPropsMark = Mark.create({\n  name: \"customContentProps\",\n\n  addAttributes() {\n    return {\n      customContentProps: {\n        default: undefined,\n      },\n    };\n  },\n\n  renderHTML({ HTMLAttributes }) {\n    return [\"span\", HTMLAttributes, 0]; // have to keep this, we might have to find another way to add custom props to content instead of setting it in Mark\n  },\n});\n","import { Extensions, extensions } from \"@tiptap/core\";\n\nimport type { BlockNoteEditor } from \"./BlockNoteEditor\";\n\nimport Collaboration from \"@tiptap/extension-collaboration\";\nimport CollaborationCursor from \"@tiptap/extension-collaboration-cursor\";\nimport { Dropcursor } from \"@tiptap/extension-dropcursor\";\nimport { Gapcursor } from \"@tiptap/extension-gapcursor\";\nimport { HardBreak } from \"@tiptap/extension-hard-break\";\nimport { History } from \"@tiptap/extension-history\";\nimport { Link } from \"@tiptap/extension-link\";\nimport { Text } from \"@tiptap/extension-text\";\nimport * as Y from \"yjs\";\nimport { createCopyToClipboardExtension } from \"../api/exporters/copyExtension\";\nimport { createPasteFromClipboardExtension } from \"../api/parsers/pasteExtension\";\nimport { BackgroundColorExtension } from \"../extensions/BackgroundColor/BackgroundColorExtension\";\nimport { Placeholder } from \"../extensions/Placeholder/PlaceholderExtension\";\nimport { TextAlignmentExtension } from \"../extensions/TextAlignment/TextAlignmentExtension\";\nimport { TextColorExtension } from \"../extensions/TextColor/TextColorExtension\";\nimport { TrailingNode } from \"../extensions/TrailingNode/TrailingNodeExtension\";\nimport UniqueID from \"../extensions/UniqueID/UniqueID\";\nimport { BlockContainer, BlockGroup, Doc } from \"../pm-nodes\";\nimport {\n  BlockNoteDOMAttributes,\n  BlockSchema,\n  BlockSpecs,\n  InlineContentSchema,\n  InlineContentSpecs,\n  StyleSchema,\n  StyleSpecs,\n} from \"../schema\";\nimport { CustomContentPropsMark } from \"../extensions/CustomMark/CustomMark\";\nimport { Node } from \"prosemirror-model\";\n\n/**\n * Get all the Tiptap extensions BlockNote is configured with by default\n */\nexport const getBlockNoteExtensions = <\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(opts: {\n  editor: BlockNoteEditor<BSchema, I, S>;\n  domAttributes: Partial<BlockNoteDOMAttributes>;\n  blockSchema: BSchema;\n  blockSpecs: BlockSpecs;\n  inlineContentSpecs: InlineContentSpecs;\n  styleSpecs: StyleSpecs;\n  collaboration?: {\n    fragment: Y.XmlFragment;\n    user: {\n      name: string;\n      color: string;\n    };\n    provider: any;\n    renderCursor?: (user: any) => HTMLElement;\n  };\n  getTotalBlocks: () => number;\n  maxBlocksLimit: number;\n  isWholeDocEmpty: () => boolean;\n  countBlocks: (node: Node | null) => number;\n}) => {\n  const ret: Extensions = [\n    extensions.ClipboardTextSerializer,\n    extensions.Commands,\n    extensions.Editable,\n    extensions.FocusEvents,\n    extensions.Tabindex,\n\n    // DevTools,\n    Gapcursor,\n\n    // DropCursor,\n    Placeholder.configure({\n      includeChildren: true,\n      showOnlyCurrent: false,\n    }),\n    UniqueID.configure({\n      types: [\"blockContainer\"],\n    }),\n    HardBreak,\n    // Comments,\n\n    // basics:\n    Text,\n\n    // marks:\n    Link,\n    ...Object.values(opts.styleSpecs).map((styleSpec) => {\n      return styleSpec.implementation.mark;\n    }),\n\n    TextColorExtension,\n\n    BackgroundColorExtension,\n    TextAlignmentExtension,\n    CustomContentPropsMark,\n    // nodes\n    Doc,\n    BlockContainer.configure({\n      editor: opts.editor as any,\n      domAttributes: opts.domAttributes,\n    }),\n    BlockGroup.configure({\n      domAttributes: opts.domAttributes,\n    }),\n    ...Object.values(opts.inlineContentSpecs)\n      .filter((a) => a.config !== \"link\" && a.config !== \"text\")\n      .map((inlineContentSpec) => {\n        return inlineContentSpec.implementation!.node.configure({\n          editor: opts.editor as any,\n        });\n      }),\n\n    ...Object.values(opts.blockSpecs).flatMap((blockSpec) => {\n      return [\n        // dependent nodes (e.g.: tablecell / row)\n        ...(blockSpec.implementation.requiredExtensions || []).map((ext) =>\n          ext.configure({\n            editor: opts.editor,\n            domAttributes: opts.domAttributes,\n          })\n        ),\n        // the actual node itself\n        blockSpec.implementation.node.configure({\n          editor: opts.editor,\n          domAttributes: opts.domAttributes,\n        }),\n      ];\n    }),\n    createCopyToClipboardExtension(opts.editor),\n    createPasteFromClipboardExtension(opts.editor),\n\n    Dropcursor.configure({ width: 5, color: \"#ddeeff\" }),\n    // This needs to be at the bottom of this list, because Key events (such as enter, when selecting a /command),\n    // should be handled before Enter handlers in other components like splitListItem\n    TrailingNode.configure({\n      getTotalBlocks: opts.getTotalBlocks,\n      maxBlocksLimit: opts.maxBlocksLimit,\n      isWholeDocEmpty: opts.isWholeDocEmpty,\n      countBlocks: opts.countBlocks,\n    }),\n  ];\n\n  if (opts.collaboration) {\n    ret.push(\n      Collaboration.configure({\n        fragment: opts.collaboration.fragment,\n      })\n    );\n    if (opts.collaboration.provider?.awareness) {\n      const defaultRender = (user: { color: string; name: string }) => {\n        const cursor = document.createElement(\"span\");\n\n        cursor.classList.add(\"collaboration-cursor__caret\");\n        cursor.setAttribute(\"style\", `border-color: ${user.color}`);\n\n        const label = document.createElement(\"span\");\n\n        label.classList.add(\"collaboration-cursor__label\");\n        label.setAttribute(\"style\", `background-color: ${user.color}`);\n        label.insertBefore(document.createTextNode(user.name), null);\n\n        const nonbreakingSpace1 = document.createTextNode(\"\\u2060\");\n        const nonbreakingSpace2 = document.createTextNode(\"\\u2060\");\n        cursor.insertBefore(nonbreakingSpace1, null);\n        cursor.insertBefore(label, null);\n        cursor.insertBefore(nonbreakingSpace2, null);\n        return cursor;\n      };\n      ret.push(\n        CollaborationCursor.configure({\n          user: opts.collaboration.user,\n          render: opts.collaboration.renderCursor || defaultRender,\n          provider: opts.collaboration.provider,\n        })\n      );\n    }\n  } else {\n    // disable history extension when collaboration is enabled as Yjs takes care of undo / redo\n    ret.push(History);\n  }\n\n  return ret;\n};\n","import { Fragment, Slice } from \"@tiptap/pm/model\";\nimport { EditorView } from \"@tiptap/pm/view\";\n\n// helper function to remove a child from a fragment\nfunction removeChild(node: Fragment, n: number) {\n  const children: any[] = [];\n  node.forEach((child, _, i) => {\n    if (i !== n) {\n      children.push(child);\n    }\n  });\n  return Fragment.from(children);\n}\n\n/**\n * fix for https://github.com/ProseMirror/prosemirror/issues/1430#issuecomment-1822570821\n *\n * Without this fix, pasting two paragraphs would cause the second one to be indented in the other\n * this fix wraps every element in the slice in it's own blockContainer, to prevent Prosemirror from nesting the\n * elements on paste.\n *\n * The exception is when we encounter blockGroups with listitems, because those actually should be nested\n */\nexport function transformPasted(slice: Slice, view: EditorView) {\n  let f = Fragment.from(slice.content);\n  for (let i = 0; i < f.childCount; i++) {\n    if (f.child(i).type.spec.group === \"blockContent\") {\n      const content = [f.child(i)];\n\n      // when there is a blockGroup with lists, it should be nested in the new blockcontainer\n      // (if we remove this if-block, the nesting bug will be fixed, but lists won't be nested correctly)\n      if (\n        i + 1 < f.childCount &&\n        f.child(i + 1).type.spec.group === \"blockGroup\"\n      ) {\n        const nestedChild = f\n          .child(i + 1)\n          .child(0)\n          .child(0);\n\n        if (\n          nestedChild.type.name === \"bulletListItem\" ||\n          nestedChild.type.name === \"numberedListItem\"\n        ) {\n          content.push(f.child(i + 1));\n          f = removeChild(f, i + 1);\n        }\n      }\n      const container = view.state.schema.nodes.blockContainer.create(\n        undefined,\n        content\n      );\n      f = f.replaceChild(i, container);\n    }\n  }\n\n  return new Slice(f, slice.openStart, slice.openEnd);\n}\n","import { Editor, EditorOptions, Extension } from \"@tiptap/core\";\nimport { Fragment, Node, Slice } from \"prosemirror-model\";\n// import \"./blocknote.css\";\nimport { Editor as TiptapEditor } from \"@tiptap/core/dist/packages/core/src/Editor\";\nimport * as Y from \"yjs\";\nimport {\n  insertBlocks,\n  removeBlocks,\n  replaceBlocks,\n  updateBlock,\n} from \"../api/blockManipulation/blockManipulation\";\nimport { createExternalHTMLExporter } from \"../api/exporters/html/externalHTMLExporter\";\nimport { blocksToMarkdown } from \"../api/exporters/markdown/markdownExporter\";\nimport { getBlockInfo, getBlockInfoFromPos } from \"../api/getBlockInfoFromPos\";\nimport {\n  blockToNode,\n  nodeToBlock,\n} from \"../api/nodeConversions/nodeConversions\";\nimport { getNodeById } from \"../api/nodeUtil\";\nimport { HTMLToBlocks } from \"../api/parsers/html/parseHTML\";\nimport { markdownToBlocks } from \"../api/parsers/markdown/parseMarkdown\";\nimport {\n  DefaultBlockSchema,\n  DefaultInlineContentSchema,\n  DefaultStyleSchema,\n  defaultBlockSchema,\n  defaultBlockSpecs,\n  defaultInlineContentSpecs,\n  defaultStyleSpecs,\n} from \"../blocks/defaultBlocks\";\nimport { FormattingToolbarProsemirrorPlugin } from \"../extensions/FormattingToolbar/FormattingToolbarPlugin\";\nimport { HyperlinkToolbarProsemirrorPlugin } from \"../extensions/HyperlinkToolbar/HyperlinkToolbarPlugin\";\nimport { ImageToolbarProsemirrorPlugin } from \"../extensions/ImageToolbar/ImageToolbarPlugin\";\nimport { SideMenuProsemirrorPlugin } from \"../extensions/SideMenu/SideMenuPlugin\";\nimport { BaseSlashMenuItem } from \"../extensions/SlashMenu/BaseSlashMenuItem\";\nimport { SlashMenuProsemirrorPlugin } from \"../extensions/SlashMenu/SlashMenuPlugin\";\nimport { getDefaultSlashMenuItems } from \"../extensions/SlashMenu/defaultSlashMenuItems\";\nimport { TableHandlesProsemirrorPlugin } from \"../extensions/TableHandles/TableHandlesPlugin\";\nimport { UniqueID } from \"../extensions/UniqueID/UniqueID\";\nimport {\n  Block,\n  BlockIdentifier,\n  BlockNoteDOMAttributes,\n  BlockSchema,\n  BlockSchemaFromSpecs,\n  BlockSchemaWithBlock,\n  BlockSpecs,\n  InlineContentSchema,\n  InlineContentSchemaFromSpecs,\n  InlineContentSpecs,\n  PartialBlock,\n  StyleSchema,\n  StyleSchemaFromSpecs,\n  StyleSpecs,\n  Styles,\n  getBlockSchemaFromSpecs,\n  getInlineContentSchemaFromSpecs,\n  getStyleSchemaFromSpecs,\n} from \"../schema\";\nimport { mergeCSSClasses } from \"../util/browser\";\nimport { UnreachableCaseError } from \"../util/typescript\";\n\nimport { getBlockNoteExtensions } from \"./BlockNoteExtensions\";\nimport { TextCursorPosition } from \"./cursorPositionTypes\";\n\nimport { Selection } from \"./selectionTypes\";\nimport { transformPasted } from \"./transformPasted\";\n\n// CSS\nimport \"prosemirror-tables/style/tables.css\";\nimport \"./Block.css\";\nimport \"./editor.css\";\nimport { MAX_NUM_BLOCKS } from \"../util/constants\";\nimport normalizeUrl from \"normalize-url\";\n\nexport type BlockNoteEditorOptions<\n  BSpecs extends BlockSpecs,\n  ISpecs extends InlineContentSpecs,\n  SSpecs extends StyleSpecs\n> = {\n  // TODO: Figure out if enableBlockNoteExtensions/disableHistoryExtension are needed and document them.\n  enableBlockNoteExtensions: boolean;\n  /**\n   *\n   * (couldn't fix any type, see https://github.com/TypeCellOS/BlockNote/pull/191#discussion_r1210708771)\n   *\n   * @default defaultSlashMenuItems from `./extensions/SlashMenu`\n   */\n  slashMenuItems: BaseSlashMenuItem<any, any, any>[];\n\n  /**\n   * The HTML element that should be used as the parent element for the editor.\n   *\n   * @default: undefined, the editor is not attached to the DOM\n   */\n  parentElement: HTMLElement;\n  /**\n   * An object containing attributes that should be added to HTML elements of the editor.\n   *\n   * @example { editor: { class: \"my-editor-class\" } }\n   */\n  domAttributes: Partial<BlockNoteDOMAttributes>;\n  /**\n   *  A callback function that runs when the editor is ready to be used.\n   */\n  onEditorReady: (\n    editor: BlockNoteEditor<\n      BlockSchemaFromSpecs<BSpecs>,\n      InlineContentSchemaFromSpecs<ISpecs>,\n      StyleSchemaFromSpecs<SSpecs>\n    >\n  ) => void;\n  /**\n   * A callback function that runs whenever the editor's contents change.\n   */\n  onEditorContentChange: (\n    editor: BlockNoteEditor<\n      BlockSchemaFromSpecs<BSpecs>,\n      InlineContentSchemaFromSpecs<ISpecs>,\n      StyleSchemaFromSpecs<SSpecs>\n    >\n  ) => void;\n  /**\n   * A callback function that runs whenever the text cursor position changes.\n   */\n  onTextCursorPositionChange: (\n    editor: BlockNoteEditor<\n      BlockSchemaFromSpecs<BSpecs>,\n      InlineContentSchemaFromSpecs<ISpecs>,\n      StyleSchemaFromSpecs<SSpecs>\n    >\n  ) => void;\n  /**\n   * Locks the editor from being editable by the user if set to `false`.\n   */\n  editable: boolean;\n  /**\n   * The content that should be in the editor when it's created, represented as an array of partial block objects.\n   */\n  initialContent: PartialBlock<\n    BlockSchemaFromSpecs<BSpecs>,\n    InlineContentSchemaFromSpecs<ISpecs>,\n    StyleSchemaFromSpecs<SSpecs>\n  >[];\n  /**\n   * Use default BlockNote font and reset the styles of <p> <li> <h1> elements etc., that are used in BlockNote.\n   *\n   * @default true\n   */\n  defaultStyles: boolean;\n\n  /**\n   * A list of block types that should be available in the editor.\n   */\n  blockSpecs: BSpecs;\n\n  styleSpecs: SSpecs;\n\n  inlineContentSpecs: ISpecs;\n\n  /**\n   * A custom function to handle file uploads.\n   * @param file The file that should be uploaded.\n   * @returns The URL of the uploaded file.\n   */\n  uploadFile: (file: File) => Promise<string>;\n\n  /**\n   * When enabled, allows for collaboration between multiple users.\n   */\n  collaboration: {\n    /**\n     * The Yjs XML fragment that's used for collaboration.\n     */\n    fragment: Y.XmlFragment;\n    /**\n     * The user info for the current user that's shown to other collaborators.\n     */\n    user: {\n      name: string;\n      color: string;\n    };\n    /**\n     * A Yjs provider (used for awareness / cursor information)\n     */\n    provider: any;\n    /**\n     * Optional function to customize how cursors of users are rendered\n     */\n    renderCursor?: (user: any) => HTMLElement;\n  };\n\n  // tiptap options, undocumented\n  // _tiptapOptions: any;\n\n  maxBlocksLimit: number;\n\n  errorCallback?: () => void;\n  _tiptapOptions: Partial<EditorOptions>;\n};\n\nconst blockNoteTipTapOptions = {\n  enableInputRules: true,\n  enablePasteRules: true,\n  enableCoreExtensions: false,\n};\n\nexport class BlockNoteEditor<\n  BSchema extends BlockSchema = DefaultBlockSchema,\n  ISchema extends InlineContentSchema = DefaultInlineContentSchema,\n  SSchema extends StyleSchema = DefaultStyleSchema\n> {\n  public readonly _tiptapEditor: TiptapEditor & { contentComponent: any };\n  public blockCache = new WeakMap<Node, Block<any, any, any>>();\n  public readonly blockSchema: BSchema;\n  public readonly inlineContentSchema: ISchema;\n  public readonly styleSchema: SSchema;\n\n  public readonly blockImplementations: BlockSpecs;\n  public readonly inlineContentImplementations: InlineContentSpecs;\n  public readonly styleImplementations: StyleSpecs;\n\n  public ready = false;\n\n  public readonly sideMenu: SideMenuProsemirrorPlugin<\n    BSchema,\n    ISchema,\n    SSchema\n  >;\n  public readonly formattingToolbar: FormattingToolbarProsemirrorPlugin;\n  public readonly slashMenu: SlashMenuProsemirrorPlugin<\n    BSchema,\n    ISchema,\n    SSchema,\n    any\n  >;\n  public readonly hyperlinkToolbar: HyperlinkToolbarProsemirrorPlugin<\n    BSchema,\n    ISchema,\n    SSchema\n  >;\n  public readonly imageToolbar: ImageToolbarProsemirrorPlugin<\n    BSchema,\n    ISchema,\n    SSchema\n  >;\n  public readonly tableHandles:\n    | TableHandlesProsemirrorPlugin<\n        BSchema extends BlockSchemaWithBlock<\n          \"table\",\n          DefaultBlockSchema[\"table\"]\n        >\n          ? BSchema\n          : any,\n        ISchema,\n        SSchema\n      >\n    | undefined;\n\n  isWholeDocEmpty() {\n    let isWholeDocEmpty = true;\n    if (\n      this._tiptapEditor.state.doc.firstChild?.childCount &&\n      this._tiptapEditor.state.doc.firstChild?.childCount > 1\n    ) {\n      isWholeDocEmpty = false;\n    } else {\n      this._tiptapEditor.state.doc.firstChild?.descendants((node) => {\n        if (node.type.name !== \"blockContainer\") {\n          return;\n        }\n        const bnNode = nodeToBlock(\n          node,\n          this.blockSchema,\n          this.inlineContentSchema,\n          this.styleSchema,\n          this.blockCache\n        );\n        if (\n          bnNode.content &&\n          Array.isArray(bnNode.content) &&\n          bnNode.content.length > 0\n        ) {\n          isWholeDocEmpty = false;\n        }\n      });\n    }\n\n    return isWholeDocEmpty;\n  }\n\n  countBlocks(node: Node | null): number {\n    if (!node) {\n      return 0;\n    }\n    const sliceTopLevelBlocks: Block<BSchema, ISchema, SSchema>[] = [];\n\n    node.descendants((_node) => {\n      if (_node.type.name !== \"blockContainer\") {\n        return;\n      }\n\n      const info = getBlockInfo(_node);\n      if (info.contentType.name && info.contentType.name !== \"blockGroup\") {\n        sliceTopLevelBlocks.push(\n          nodeToBlock(\n            _node,\n            this.blockSchema,\n            this.inlineContentSchema,\n            this.styleSchema,\n            this.blockCache\n          )\n        );\n      }\n      return false;\n    });\n\n    const blocks = sliceTopLevelBlocks.slice();\n\n    let count = 0;\n\n    const callback = (_block: Block<BSchema, ISchema, SSchema>) => {\n      count++;\n      return true;\n    };\n\n    function traverseBlockArray(\n      blockArray: Block<BSchema, ISchema, SSchema>[]\n    ): boolean {\n      for (const block of blockArray) {\n        if (!callback(block)) {\n          return false;\n        }\n\n        const children = block.children;\n\n        if (!traverseBlockArray(children)) {\n          return false;\n        }\n      }\n\n      return true;\n    }\n\n    traverseBlockArray(blocks);\n\n    return count;\n  }\n\n  handleBlocksLimit(slice: Slice): boolean {\n    const sliceBlocksCount = this.countBlocks(slice.content.firstChild);\n    const isWholeDocEmpty = this.isWholeDocEmpty();\n\n    if (\n      !(\n        isWholeDocEmpty &&\n        sliceBlocksCount <= (this.options.maxBlocksLimit || MAX_NUM_BLOCKS)\n      ) &&\n      sliceBlocksCount + this.totalBlocks() >\n        (this.options.maxBlocksLimit || MAX_NUM_BLOCKS)\n    ) {\n      this.options.errorCallback?.();\n\n      let count = 0;\n      let fragment = Fragment.empty;\n\n      const limit =\n        (this.options.maxBlocksLimit || MAX_NUM_BLOCKS) - this.totalBlocks();\n\n      slice.content.descendants((node) => {\n        if (node.type.name !== \"blockContainer\") {\n          return;\n        }\n\n        if (count < limit) {\n          fragment = fragment.append(Fragment.from(node));\n        }\n\n        count++;\n      });\n\n      if (count > 0) {\n        this._tiptapEditor.view.dispatch(\n          this._tiptapEditor.state.tr.replaceSelection(\n            new Slice(fragment, 0, 0)\n          )\n        );\n      }\n      return true; // meaning new lines won't be added\n    }\n    return false;\n  }\n\n  // <<<<<<< HEAD:packages/core/src/BlockNoteEditor.ts\n\n  //   constructor(\n  //     private readonly options: Partial<BlockNoteEditorOptions<BSchema>> = {}\n  // =======\n  public readonly uploadFile: ((file: File) => Promise<string>) | undefined;\n\n  public static create<\n    BSpecs extends BlockSpecs = typeof defaultBlockSpecs,\n    ISpecs extends InlineContentSpecs = typeof defaultInlineContentSpecs,\n    SSpecs extends StyleSpecs = typeof defaultStyleSpecs\n  >(options: Partial<BlockNoteEditorOptions<BSpecs, ISpecs, SSpecs>> = {}) {\n    return new BlockNoteEditor(options) as BlockNoteEditor<\n      BlockSchemaFromSpecs<BSpecs>,\n      InlineContentSchemaFromSpecs<ISpecs>,\n      StyleSchemaFromSpecs<SSpecs>\n    >;\n  }\n\n  private constructor(\n    private readonly options: Partial<BlockNoteEditorOptions<any, any, any>> // >>>>>>> upstream/main:packages/core/src/editor/BlockNoteEditor.ts\n  ) {\n    // apply defaults\n    const newOptions = {\n      defaultStyles: true,\n      blockSpecs: options.blockSpecs || defaultBlockSpecs,\n      styleSpecs: options.styleSpecs || defaultStyleSpecs,\n      inlineContentSpecs:\n        options.inlineContentSpecs || defaultInlineContentSpecs,\n      ...options,\n    };\n\n    // <<<<<<< HEAD:packages/core/src/BlockNoteEditor.ts\n    this.sideMenu = new SideMenuProsemirrorPlugin(\n      this,\n      this.totalBlocks.bind(this),\n      this.options.maxBlocksLimit || MAX_NUM_BLOCKS,\n      this.options.errorCallback\n    );\n    // =======\n    this.blockSchema = getBlockSchemaFromSpecs(newOptions.blockSpecs);\n    this.inlineContentSchema = getInlineContentSchemaFromSpecs(\n      newOptions.inlineContentSpecs\n    );\n    this.styleSchema = getStyleSchemaFromSpecs(newOptions.styleSpecs);\n    this.blockImplementations = newOptions.blockSpecs;\n    this.inlineContentImplementations = newOptions.inlineContentSpecs;\n    this.styleImplementations = newOptions.styleSpecs;\n\n    //     this.sideMenu = new SideMenuProsemirrorPlugin(this);\n    // >>>>>>> upstream/main:packages/core/src/editor/BlockNoteEditor.ts\n    this.formattingToolbar = new FormattingToolbarProsemirrorPlugin(this);\n    this.slashMenu = new SlashMenuProsemirrorPlugin(\n      this,\n      newOptions.slashMenuItems ||\n        (getDefaultSlashMenuItems(this.blockSchema) as any)\n    );\n    this.hyperlinkToolbar = new HyperlinkToolbarProsemirrorPlugin(this);\n    this.imageToolbar = new ImageToolbarProsemirrorPlugin(this);\n\n    if (this.blockSchema.table === defaultBlockSchema.table) {\n      this.tableHandles = new TableHandlesProsemirrorPlugin(this as any);\n    }\n\n    const extensions = getBlockNoteExtensions({\n      editor: this,\n      domAttributes: newOptions.domAttributes || {},\n      blockSchema: this.blockSchema,\n      blockSpecs: newOptions.blockSpecs,\n      styleSpecs: newOptions.styleSpecs,\n      inlineContentSpecs: newOptions.inlineContentSpecs,\n      collaboration: newOptions.collaboration,\n      getTotalBlocks: () => this.totalBlocks(),\n      maxBlocksLimit: newOptions.maxBlocksLimit || MAX_NUM_BLOCKS,\n      isWholeDocEmpty: () => this.isWholeDocEmpty(),\n      countBlocks: (node: Node | null) => this.countBlocks.bind(this)(node),\n    });\n\n    const blockNoteUIExtension = Extension.create({\n      name: \"BlockNoteUIExtension\",\n\n      addProseMirrorPlugins: () => {\n        return [\n          this.sideMenu.plugin,\n          this.formattingToolbar.plugin,\n          this.slashMenu.plugin,\n          this.hyperlinkToolbar.plugin,\n          this.imageToolbar.plugin,\n          ...(this.tableHandles ? [this.tableHandles.plugin] : []),\n        ];\n      },\n    });\n    extensions.push(blockNoteUIExtension);\n\n    this.uploadFile = newOptions.uploadFile;\n\n    if (newOptions.collaboration && newOptions.initialContent) {\n      console.warn(\n        \"When using Collaboration, initialContent might cause conflicts, because changes should come from the collaboration provider\"\n      );\n    }\n\n    const initialContent =\n      newOptions.initialContent ||\n      (options.collaboration\n        ? undefined\n        : [\n            {\n              type: \"paragraph\",\n              id: UniqueID.options.generateID(),\n            },\n          ]);\n    const styleSchema = this.styleSchema;\n\n    const tiptapOptions: Partial<EditorOptions> = {\n      ...blockNoteTipTapOptions,\n      ...newOptions._tiptapOptions,\n      onBeforeCreate(editor) {\n        newOptions._tiptapOptions?.onBeforeCreate?.(editor);\n        // We always set the initial content to a single paragraph block. This\n        // allows us to easily replace it with the actual initial content once\n        // the TipTap editor is initialized.\n        const schema = editor.editor.schema;\n\n        // This is a hack to make \"initial content detection\" by y-prosemirror (and also tiptap isEmpty)\n        // properly detect whether or not the document has changed.\n        // We change the doc.createAndFill function to make sure the initial block id is set, instead of null\n        let cache: any;\n        const oldCreateAndFill = schema.nodes.doc.createAndFill;\n        (schema.nodes.doc as any).createAndFill = (...args: any) => {\n          if (cache) {\n            return cache;\n          }\n          const ret = oldCreateAndFill.apply(schema.nodes.doc, args);\n\n          // create a copy that we can mutate (otherwise, assigning attrs is not safe and corrupts the pm state)\n          const jsonNode = JSON.parse(JSON.stringify(ret!.toJSON()));\n          jsonNode.content[0].content[0].attrs.id = \"initialBlockId\";\n\n          cache = Node.fromJSON(schema, jsonNode);\n          return ret;\n        };\n\n        const root = schema.node(\n          \"doc\",\n          undefined,\n          schema.node(\"blockGroup\", undefined, [\n            blockToNode(\n              { id: \"initialBlockId\", type: \"paragraph\" },\n              schema,\n              styleSchema\n            ),\n          ])\n        );\n        editor.editor.options.content = root.toJSON();\n      },\n      onCreate: (editor) => {\n        newOptions._tiptapOptions?.onCreate?.(editor);\n        // We need to wait for the TipTap editor to init before we can set the\n        // initial content, as the schema may contain custom blocks which need\n        // it to render.\n        if (initialContent !== undefined) {\n          this.replaceBlocks(this.topLevelBlocks, initialContent as any, true);\n        }\n\n        newOptions.onEditorReady?.(this);\n        this.ready = true;\n      },\n      onUpdate: (editor) => {\n        newOptions._tiptapOptions?.onUpdate?.(editor);\n        // This seems to be necessary due to a bug in TipTap:\n        // https://github.com/ueberdosis/tiptap/issues/2583\n        if (!this.ready) {\n          return;\n        }\n\n        newOptions.onEditorContentChange?.(this);\n      },\n      onSelectionUpdate: (editor) => {\n        newOptions._tiptapOptions?.onSelectionUpdate?.(editor);\n        // This seems to be necessary due to a bug in TipTap:\n        // https://github.com/ueberdosis/tiptap/issues/2583\n        if (!this.ready) {\n          return;\n        }\n\n        newOptions.onTextCursorPositionChange?.(this);\n      },\n      editable:\n        options.editable !== undefined\n          ? options.editable\n          : newOptions._tiptapOptions?.editable !== undefined\n          ? newOptions._tiptapOptions?.editable\n          : true,\n      extensions:\n        newOptions.enableBlockNoteExtensions === false\n          ? newOptions._tiptapOptions?.extensions || []\n          : [...(newOptions._tiptapOptions?.extensions || []), ...extensions],\n      editorProps: {\n        handleKeyDown: (_view, event) => {\n          if (event.key === \"Enter\") {\n            if (\n              this.totalBlocks() >=\n              (this.options.maxBlocksLimit || MAX_NUM_BLOCKS)\n            ) {\n              this.options.errorCallback?.();\n              return true; // meaning new lines won't be added\n            }\n          }\n          return false;\n        },\n\n        handlePaste: (_view, _event, slice) => {\n          return this.handleBlocksLimit(slice);\n        },\n        ...newOptions._tiptapOptions?.editorProps,\n        attributes: {\n          ...newOptions._tiptapOptions?.editorProps?.attributes,\n          ...newOptions.domAttributes?.editor,\n          class: mergeCSSClasses(\n            \"bn-root\",\n            \"bn-editor\",\n            newOptions.defaultStyles ? \"bn-default-styles\" : \"\",\n            newOptions.domAttributes?.editor?.class || \"\"\n          ),\n        },\n        transformPasted,\n      },\n    };\n\n    if (newOptions.parentElement) {\n      tiptapOptions.element = newOptions.parentElement;\n    }\n\n    this._tiptapEditor = new Editor(tiptapOptions) as Editor & {\n      contentComponent: any;\n    };\n  }\n\n  public get prosemirrorView() {\n    return this._tiptapEditor.view;\n  }\n\n  public get domElement() {\n    return this._tiptapEditor.view.dom as HTMLDivElement;\n  }\n\n  public isFocused() {\n    return this._tiptapEditor.view.hasFocus();\n  }\n\n  public focus() {\n    this._tiptapEditor.view.focus();\n  }\n\n  /**\n   * Gets a snapshot of all top-level (non-nested) blocks in the editor.\n   * @returns A snapshot of all top-level (non-nested) blocks in the editor.\n   */\n  public get topLevelBlocks(): Block<BSchema, ISchema, SSchema>[] {\n    const blocks: Block<BSchema, ISchema, SSchema>[] = [];\n\n    this._tiptapEditor.state.doc.firstChild!.descendants((node) => {\n      blocks.push(\n        nodeToBlock(\n          node,\n          this.blockSchema,\n          this.inlineContentSchema,\n          this.styleSchema,\n          this.blockCache\n        )\n      );\n\n      return false;\n    });\n\n    return blocks;\n  }\n\n  /**\n   * Gets a snapshot of an existing block from the editor.\n   * @param blockIdentifier The identifier of an existing block that should be retrieved.\n   * @returns The block that matches the identifier, or `undefined` if no matching block was found.\n   */\n  public getBlock(\n    blockIdentifier: BlockIdentifier\n  ): Block<BSchema, ISchema, SSchema> | undefined {\n    const id =\n      typeof blockIdentifier === \"string\"\n        ? blockIdentifier\n        : blockIdentifier.id;\n    let newBlock: Block<BSchema, ISchema, SSchema> | undefined = undefined;\n\n    this._tiptapEditor.state.doc.firstChild!.descendants((node) => {\n      if (typeof newBlock !== \"undefined\") {\n        return false;\n      }\n\n      if (node.type.name !== \"blockContainer\" || node.attrs.id !== id) {\n        return true;\n      }\n\n      newBlock = nodeToBlock(\n        node,\n        this.blockSchema,\n        this.inlineContentSchema,\n        this.styleSchema,\n        this.blockCache\n      );\n\n      return false;\n    });\n\n    return newBlock;\n  }\n\n  /**\n   * Traverses all blocks in the editor depth-first, and executes a callback for each.\n   * @param callback The callback to execute for each block. Returning `false` stops the traversal.\n   * @param reverse Whether the blocks should be traversed in reverse order.\n   */\n  public forEachBlock(\n    callback: (block: Block<BSchema, ISchema, SSchema>) => boolean,\n    reverse = false\n  ): void {\n    const blocks = this.topLevelBlocks.slice();\n\n    if (reverse) {\n      blocks.reverse();\n    }\n\n    function traverseBlockArray(\n      blockArray: Block<BSchema, ISchema, SSchema>[]\n    ): boolean {\n      for (const block of blockArray) {\n        if (!callback(block)) {\n          return false;\n        }\n\n        const children = reverse\n          ? block.children.slice().reverse()\n          : block.children;\n\n        if (!traverseBlockArray(children)) {\n          return false;\n        }\n      }\n\n      return true;\n    }\n\n    traverseBlockArray(blocks);\n  }\n\n  public totalBlocks(): number {\n    let count = 0;\n    this.forEachBlock(() => {\n      count++;\n      return true;\n    });\n    return count;\n  }\n\n  /**\n   * Executes a callback whenever the editor's contents change.\n   * @param callback The callback to execute.\n   */\n  public onEditorContentChange(callback: () => void) {\n    this._tiptapEditor.on(\"update\", callback);\n  }\n\n  /**\n   * Executes a callback whenever the editor's selection changes.\n   * @param callback The callback to execute.\n   */\n  public onEditorSelectionChange(callback: () => void) {\n    this._tiptapEditor.on(\"selectionUpdate\", callback);\n  }\n\n  /**\n   * Gets a snapshot of the current text cursor position.\n   * @returns A snapshot of the current text cursor position.\n   */\n  public getTextCursorPosition(): TextCursorPosition<\n    BSchema,\n    ISchema,\n    SSchema\n  > {\n    const { node, depth, startPos, endPos } = getBlockInfoFromPos(\n      this._tiptapEditor.state.doc,\n      this._tiptapEditor.state.selection.from\n    )!;\n\n    // Index of the current blockContainer node relative to its parent blockGroup.\n    const nodeIndex = this._tiptapEditor.state.doc\n      .resolve(endPos)\n      .index(depth - 1);\n    // Number of the parent blockGroup's child blockContainer nodes.\n    const numNodes = this._tiptapEditor.state.doc\n      .resolve(endPos + 1)\n      .node().childCount;\n\n    // Gets previous blockContainer node at the same nesting level, if the current node isn't the first child.\n    let prevNode: Node | undefined = undefined;\n    if (nodeIndex > 0) {\n      prevNode = this._tiptapEditor.state.doc.resolve(startPos - 2).node();\n    }\n\n    // Gets next blockContainer node at the same nesting level, if the current node isn't the last child.\n    let nextNode: Node | undefined = undefined;\n    if (nodeIndex < numNodes - 1) {\n      nextNode = this._tiptapEditor.state.doc.resolve(endPos + 2).node();\n    }\n\n    return {\n      block: nodeToBlock(\n        node,\n        this.blockSchema,\n        this.inlineContentSchema,\n        this.styleSchema,\n        this.blockCache\n      ),\n      prevBlock:\n        prevNode === undefined\n          ? undefined\n          : nodeToBlock(\n              prevNode,\n              this.blockSchema,\n              this.inlineContentSchema,\n              this.styleSchema,\n              this.blockCache\n            ),\n      nextBlock:\n        nextNode === undefined\n          ? undefined\n          : nodeToBlock(\n              nextNode,\n              this.blockSchema,\n              this.inlineContentSchema,\n              this.styleSchema,\n              this.blockCache\n            ),\n    };\n  }\n\n  /**\n   * Sets the text cursor position to the start or end of an existing block. Throws an error if the target block could\n   * not be found.\n   * @param targetBlock The identifier of an existing block that the text cursor should be moved to.\n   * @param placement Whether the text cursor should be placed at the start or end of the block.\n   */\n  public setTextCursorPosition(\n    targetBlock: BlockIdentifier,\n    placement: \"start\" | \"end\" = \"start\"\n  ) {\n    const id = typeof targetBlock === \"string\" ? targetBlock : targetBlock.id;\n\n    const { posBeforeNode } = getNodeById(id, this._tiptapEditor.state.doc);\n    const { startPos, contentNode } = getBlockInfoFromPos(\n      this._tiptapEditor.state.doc,\n      posBeforeNode + 2\n    )!;\n\n    const contentType: \"none\" | \"inline\" | \"table\" =\n      this.blockSchema[contentNode.type.name]!.content;\n\n    if (contentType === \"none\") {\n      this._tiptapEditor.commands.setNodeSelection(startPos);\n      return;\n    }\n\n    if (contentType === \"inline\") {\n      if (placement === \"start\") {\n        this._tiptapEditor.commands.setTextSelection(startPos + 1);\n      } else {\n        this._tiptapEditor.commands.setTextSelection(\n          startPos + contentNode.nodeSize - 1\n        );\n      }\n    } else if (contentType === \"table\") {\n      if (placement === \"start\") {\n        // Need to offset the position as we have to get through the `tableRow`\n        // and `tableCell` nodes to get to the `tableParagraph` node we want to\n        // set the selection in.\n        this._tiptapEditor.commands.setTextSelection(startPos + 4);\n      } else {\n        this._tiptapEditor.commands.setTextSelection(\n          startPos + contentNode.nodeSize - 4\n        );\n      }\n    } else {\n      throw new UnreachableCaseError(contentType);\n    }\n  }\n\n  /**\n   * Gets a snapshot of the current selection.\n   */\n  public getSelection(): Selection<BSchema, ISchema, SSchema> | undefined {\n    // Either the TipTap selection is empty, or it's a node selection. In either\n    // case, it only spans one block, so we return undefined.\n    if (\n      this._tiptapEditor.state.selection.from ===\n        this._tiptapEditor.state.selection.to ||\n      \"node\" in this._tiptapEditor.state.selection\n    ) {\n      return undefined;\n    }\n\n    const blocks: Block<BSchema, ISchema, SSchema>[] = [];\n\n    // TODO: This adds all child blocks to the same array. Needs to find min\n    //  depth and only add blocks at that depth.\n    this._tiptapEditor.state.doc.descendants((node, pos) => {\n      if (node.type.spec.group !== \"blockContent\") {\n        return true;\n      }\n\n      if (\n        pos + node.nodeSize < this._tiptapEditor.state.selection.from ||\n        pos > this._tiptapEditor.state.selection.to\n      ) {\n        return true;\n      }\n\n      blocks.push(\n        nodeToBlock(\n          this._tiptapEditor.state.doc.resolve(pos).node(),\n          this.blockSchema,\n          this.inlineContentSchema,\n          this.styleSchema,\n          this.blockCache\n        )\n      );\n\n      return false;\n    });\n\n    return { blocks: blocks };\n  }\n\n  /**\n   * Checks if the editor is currently editable, or if it's locked.\n   * @returns True if the editor is editable, false otherwise.\n   */\n  public get isEditable(): boolean {\n    return this._tiptapEditor.isEditable;\n  }\n\n  /**\n   * Makes the editor editable or locks it, depending on the argument passed.\n   * @param editable True to make the editor editable, or false to lock it.\n   */\n  public set isEditable(editable: boolean) {\n    this._tiptapEditor.setEditable(editable);\n  }\n\n  /**\n   * Inserts new blocks into the editor. If a block's `id` is undefined, BlockNote generates one automatically. Throws an\n   * error if the reference block could not be found.\n   * @param blocksToInsert An array of partial blocks that should be inserted.\n   * @param referenceBlock An identifier for an existing block, at which the new blocks should be inserted.\n   * @param placement Whether the blocks should be inserted just before, just after, or nested inside the\n   * `referenceBlock`. Inserts the blocks at the start of the existing block's children if \"nested\" is used.\n   */\n  public insertBlocks(\n    blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[],\n    referenceBlock: BlockIdentifier,\n    placement: \"before\" | \"after\" | \"nested\" = \"before\",\n    checkBlocksLimit = false,\n    eraseHistory = false\n  ): void {\n    if (checkBlocksLimit) {\n      if (\n        this.totalBlocks() >= (this.options.maxBlocksLimit || MAX_NUM_BLOCKS)\n      ) {\n        this.options.errorCallback?.();\n        return;\n      }\n    }\n    // insertBlocks(blocksToInsert, referenceBlock, placement, this._tiptapEditor);\n    insertBlocks(blocksToInsert, referenceBlock, placement, this, eraseHistory);\n  }\n\n  /**\n   * Updates an existing block in the editor. Since updatedBlock is a PartialBlock object, some fields might not be\n   * defined. These undefined fields are kept as-is from the existing block. Throws an error if the block to update could\n   * not be found.\n   * @param blockToUpdate The block that should be updated.\n   * @param update A partial block which defines how the existing block should be changed.\n   */\n  public updateBlock(\n    blockToUpdate: BlockIdentifier,\n    update: PartialBlock<BSchema, ISchema, SSchema>\n  ) {\n    updateBlock(blockToUpdate, update, this._tiptapEditor);\n  }\n\n  /**\n   * Removes existing blocks from the editor. Throws an error if any of the blocks could not be found.\n   * @param blocksToRemove An array of identifiers for existing blocks that should be removed.\n   */\n  public removeBlocks(blocksToRemove: BlockIdentifier[]) {\n    removeBlocks(blocksToRemove, this._tiptapEditor);\n  }\n\n  /**\n   * Replaces existing blocks in the editor with new blocks. If the blocks that should be removed are not adjacent or\n   * are at different nesting levels, `blocksToInsert` will be inserted at the position of the first block in\n   * `blocksToRemove`. Throws an error if any of the blocks to remove could not be found.\n   * @param blocksToRemove An array of blocks that should be replaced.\n   * @param blocksToInsert An array of partial blocks to replace the old ones with.\n   */\n  public replaceBlocks(\n    blocksToRemove: BlockIdentifier[],\n    blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[],\n    eraseHistory = false\n  ) {\n    replaceBlocks(blocksToRemove, blocksToInsert, this, eraseHistory);\n  }\n\n  /**\n   * Gets the active text styles at the text cursor position or at the end of the current selection if it's active.\n   */\n  public getActiveStyles() {\n    const styles: Styles<SSchema> = {};\n    const marks = this._tiptapEditor.state.selection.$to.marks();\n\n    for (const mark of marks) {\n      const config = this.styleSchema[mark.type.name];\n      console.log(\n        \"[this.styleSchema]\",\n        JSON.stringify(this.styleSchema, null, 2)\n      );\n      if (!config) {\n        // console.warn(\"mark not found in styleschema\", mark.type.name);\n        continue;\n      }\n      if (config.propSchema === \"boolean\") {\n        (styles as any)[config.type] = true;\n      } else {\n        (styles as any)[config.type] = mark.attrs.stringValue;\n      }\n    }\n\n    return styles;\n  }\n\n  /**\n   * Adds styles to the currently selected content.\n   * @param styles The styles to add.\n   */\n  public addStyles(styles: Styles<SSchema>) {\n    this._tiptapEditor.view.focus();\n\n    for (const [style, value] of Object.entries(styles)) {\n      const config = this.styleSchema[style];\n      if (!config) {\n        throw new Error(`style ${style} not found in styleSchema`);\n      }\n      if (config.propSchema === \"boolean\") {\n        this._tiptapEditor.commands.setMark(style);\n      } else if (config.propSchema === \"string\") {\n        this._tiptapEditor.commands.setMark(style, { stringValue: value });\n      } else {\n        throw new UnreachableCaseError(config.propSchema);\n      }\n    }\n  }\n\n  /**\n   * Removes styles from the currently selected content.\n   * @param styles The styles to remove.\n   */\n  public removeStyles(styles: Styles<SSchema>) {\n    this._tiptapEditor.view.focus();\n\n    for (const style of Object.keys(styles)) {\n      this._tiptapEditor.commands.unsetMark(style);\n    }\n  }\n\n  /**\n   * Toggles styles on the currently selected content.\n   * @param styles The styles to toggle.\n   */\n  public toggleStyles(styles: Styles<SSchema>) {\n    this._tiptapEditor.view.focus();\n\n    for (const [style, value] of Object.entries(styles)) {\n      const config = this.styleSchema[style];\n      if (!config) {\n        throw new Error(`style ${style} not found in styleSchema`);\n      }\n      if (config.propSchema === \"boolean\") {\n        this._tiptapEditor.commands.toggleMark(style);\n      } else if (config.propSchema === \"string\") {\n        this._tiptapEditor.commands.toggleMark(style, { stringValue: value });\n      } else {\n        throw new UnreachableCaseError(config.propSchema);\n      }\n    }\n  }\n\n  /**\n   * Gets the currently selected text.\n   */\n  public getSelectedText() {\n    return this._tiptapEditor.state.doc.textBetween(\n      this._tiptapEditor.state.selection.from,\n      this._tiptapEditor.state.selection.to\n    );\n  }\n\n  /**\n   * Gets the URL of the last link in the current selection, or `undefined` if there are no links in the selection.\n   */\n  public getSelectedLinkUrl() {\n    return this._tiptapEditor.getAttributes(\"link\").href as string | undefined;\n  }\n\n  /**\n   * Creates a new link to replace the selected content.\n   * @param url The link URL.\n   * @param text The text to display the link with.\n   */\n  public createLink(url: string, text?: string) {\n    if (url === \"\") {\n      return;\n    }\n\n    const normalizedUrl = url.startsWith(\"/\")\n      ? url\n      : normalizeUrl(url, { defaultProtocol: \"https\" });\n\n    const { from, to } = this._tiptapEditor.state.selection;\n\n    if (!text) {\n      text = this._tiptapEditor.state.doc.textBetween(from, to);\n    }\n\n    const mark = this._tiptapEditor.schema.mark(\"link\", {\n      href: normalizedUrl,\n    });\n\n    this._tiptapEditor.view.dispatch(\n      this._tiptapEditor.view.state.tr\n        .insertText(text, from, to)\n        .addMark(from, from + text.length, mark)\n    );\n  }\n\n  /**\n   * Checks if the block containing the text cursor can be nested.\n   */\n  public canNestBlock() {\n    const { startPos, depth } = getBlockInfoFromPos(\n      this._tiptapEditor.state.doc,\n      this._tiptapEditor.state.selection.from\n    )!;\n\n    return this._tiptapEditor.state.doc.resolve(startPos).index(depth - 1) > 0;\n  }\n\n  /**\n   * Nests the block containing the text cursor into the block above it.\n   */\n  public nestBlock() {\n    this._tiptapEditor.commands.sinkListItem(\"blockContainer\");\n  }\n\n  /**\n   * Checks if the block containing the text cursor is nested.\n   */\n  public canUnnestBlock() {\n    const { depth } = getBlockInfoFromPos(\n      this._tiptapEditor.state.doc,\n      this._tiptapEditor.state.selection.from\n    )!;\n\n    return depth > 2;\n  }\n\n  /**\n   * Lifts the block containing the text cursor out of its parent.\n   */\n  public unnestBlock() {\n    this._tiptapEditor.commands.liftListItem(\"blockContainer\");\n  }\n\n  // TODO: Fix when implementing HTML/Markdown import & export\n  /**\n   * Serializes blocks into an HTML string. To better conform to HTML standards, children of blocks which aren't list\n   * items are un-nested in the output HTML.\n   * @param blocks An array of blocks that should be serialized into HTML.\n   * @returns The blocks, serialized as an HTML string.\n   */\n  public async blocksToHTMLLossy(\n    blocks = this.topLevelBlocks\n  ): Promise<string> {\n    const exporter = createExternalHTMLExporter(\n      this._tiptapEditor.schema,\n      this\n    );\n    return exporter.exportBlocks(blocks);\n  }\n\n  /**\n   * Parses blocks from an HTML string. Tries to create `Block` objects out of any HTML block-level elements, and\n   * `InlineNode` objects from any HTML inline elements, though not all element types are recognized. If BlockNote\n   * doesn't recognize an HTML element's tag, it will parse it as a paragraph or plain text.\n   * @param html The HTML string to parse blocks from.\n   * @returns The blocks parsed from the HTML string.\n   */\n  public async tryParseHTMLToBlocks(\n    html: string\n  ): Promise<Block<BSchema, ISchema, SSchema>[]> {\n    return HTMLToBlocks(\n      html,\n      this.blockSchema,\n      this.inlineContentSchema,\n      this.styleSchema,\n      this._tiptapEditor.schema\n    );\n  }\n\n  /**\n   * Serializes blocks into a Markdown string. The output is simplified as Markdown does not support all features of\n   * BlockNote - children of blocks which aren't list items are un-nested and certain styles are removed.\n   * @param blocks An array of blocks that should be serialized into Markdown.\n   * @returns The blocks, serialized as a Markdown string.\n   */\n  public async blocksToMarkdownLossy(\n    blocks: Block<BSchema, ISchema, SSchema>[] = this.topLevelBlocks\n  ): Promise<string> {\n    return blocksToMarkdown(blocks, this._tiptapEditor.schema, this);\n  }\n\n  /**\n   * Creates a list of blocks from a Markdown string. Tries to create `Block` and `InlineNode` objects based on\n   * Markdown syntax, though not all symbols are recognized. If BlockNote doesn't recognize a symbol, it will parse it\n   * as text.\n   * @param markdown The Markdown string to parse blocks from.\n   * @returns The blocks parsed from the Markdown string.\n   */\n  public async tryParseMarkdownToBlocks(\n    markdown: string\n  ): Promise<Block<BSchema, ISchema, SSchema>[]> {\n    return markdownToBlocks(\n      markdown,\n      this.blockSchema,\n      this.inlineContentSchema,\n      this.styleSchema,\n      this._tiptapEditor.schema\n    );\n  }\n\n  /**\n   * Updates the user info for the current user that's shown to other collaborators.\n   */\n  public updateCollaborationUserInfo(user: { name: string; color: string }) {\n    if (!this.options.collaboration) {\n      throw new Error(\n        \"Cannot update collaboration user info when collaboration is disabled.\"\n      );\n    }\n    this._tiptapEditor.commands.updateUser(user);\n  }\n}\n","import UniqueID from \"../../extensions/UniqueID/UniqueID\";\nimport {\n  Block,\n  BlockSchema,\n  PartialBlock,\n  TableContent,\n} from \"../../schema/blocks/types\";\nimport {\n  InlineContent,\n  InlineContentSchema,\n  PartialInlineContent,\n  StyledText,\n  isPartialLinkInlineContent,\n  isStyledTextInlineContent,\n} from \"../../schema/inlineContent/types\";\nimport { StyleSchema } from \"../../schema/styles/types\";\n\nfunction textShorthandToStyledText(\n  content: string | StyledText<any>[] = \"\"\n): StyledText<any>[] {\n  if (typeof content === \"string\") {\n    return [\n      {\n        type: \"text\",\n        text: content,\n        styles: {},\n      },\n    ];\n  }\n  return content;\n}\n\nfunction partialContentToInlineContent(\n  content: PartialInlineContent<any, any> | TableContent<any> | undefined\n): InlineContent<any, any>[] | TableContent<any> | undefined {\n  if (typeof content === \"string\") {\n    return textShorthandToStyledText(content);\n  }\n\n  if (Array.isArray(content)) {\n    return content.flatMap((partialContent) => {\n      if (typeof partialContent === \"string\") {\n        return textShorthandToStyledText(partialContent);\n      } else if (isPartialLinkInlineContent(partialContent)) {\n        return {\n          ...partialContent,\n          content: textShorthandToStyledText(partialContent.content),\n        };\n      } else if (isStyledTextInlineContent(partialContent)) {\n        return partialContent;\n      } else {\n        // custom inline content\n\n        return {\n          props: {},\n          ...partialContent,\n          content: partialContentToInlineContent(partialContent.content),\n        } as any;\n      }\n    });\n  }\n\n  return content;\n}\n\nexport function partialBlocksToBlocksForTesting<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  schema: BSchema,\n  partialBlocks: Array<PartialBlock<BSchema, I, S>>\n): Array<Block<BSchema, I, S>> {\n  return partialBlocks.map((partialBlock) =>\n    partialBlockToBlockForTesting(schema, partialBlock)\n  );\n}\n\nexport function partialBlockToBlockForTesting<\n  BSchema extends BlockSchema,\n  I extends InlineContentSchema,\n  S extends StyleSchema\n>(\n  schema: BSchema,\n  partialBlock: PartialBlock<BSchema, I, S>\n): Block<BSchema, I, S> {\n  const withDefaults: Block<BSchema, I, S> = {\n    id: \"\",\n    type: partialBlock.type!,\n    props: {} as any,\n    content:\n      schema[partialBlock.type!].content === \"inline\" ? [] : (undefined as any),\n    children: [] as any,\n    ...partialBlock,\n  };\n\n  Object.entries(schema[partialBlock.type!].propSchema).forEach(\n    ([propKey, propValue]) => {\n      if (withDefaults.props[propKey] === undefined) {\n        (withDefaults.props as any)[propKey] = propValue.default;\n      }\n    }\n  );\n\n  return {\n    ...withDefaults,\n    content: partialContentToInlineContent(withDefaults.content),\n    children: withDefaults.children.map((c) => {\n      return partialBlockToBlockForTesting(schema, c);\n    }),\n  } as any;\n}\n\nexport function addIdsToBlock(block: PartialBlock<any, any, any>) {\n  if (!block.id) {\n    block.id = UniqueID.options.generateID();\n  }\n  if (block.children) {\n    addIdsToBlocks(block.children);\n  }\n}\n\nexport function addIdsToBlocks(blocks: PartialBlock<any, any, any>[]) {\n  for (const block of blocks) {\n    addIdsToBlock(block);\n  }\n}\n"],"names":["removeDuplicates","array","by","seen","item","key","findDuplicates","items","filtered","el","index","UniqueID","Extension","testOptions","v4","element","attributes","dragSourceElement","transformPasted","Plugin","PluginKey","transactions","oldState","newState","docChanges","transaction","filterTransactions","tr","_a","_b","types","attributeName","generateID","transform","combineTransactionSteps","mapping","getChangedRanges","newRange","newNodes","findChildrenInRange","node","newIds","id","duplicatedNewIds","pos","initialDoc","jsonNode","deleted","view","handleDragstart","event","slice","removeId","fragment","list","nodeWithoutId","Fragment","Slice","getBlockInfo","blockContainer","contentNode","contentType","numChildBlocks","getBlockInfoFromPos","doc","outerBlockGroupEndPos","$pos","maxDepth","depth","startPos","endPos","isLinkInlineContent","content","isPartialLinkInlineContent","isStyledTextInlineContent","UnreachableCaseError","val","toggleStyles","colorStyles","styledTextToNodes","styledText","schema","styleSchema","marks","style","value","config","text","linkToNodes","link","linkMark","styledTextArrayToNodes","nodes","inlineContentToNodes","blockContent","blockOrInlineContentToContentNode","tableContentToNodes","tableContent","rowNodes","row","columnNodes","cell","pNode","textNodes","cellNode","rowNode","block","type","blockToNode","children","child","groupNode","contentNodeToTableContent","inlineContentSchema","ret","contentNodeToInlineContent","currentContent","customContentProps","nodeToCustomInlineContent","styles","mark","props","icConfig","attr","propSchema","nodeToBlock","blockSchema","blockCache","cachedBlock","blockInfo","blockSpec","blockConfig","i","options","serializeNodeInner","serializer","editor","toExternalHTML","dom","contentDOM","DOMSerializer","blockContentNode","blockGroupNode","impl","serializeProseMirrorFragment","internalHTML","parent","simplifyBlocks","listItemBlockTypes","simplifyBlocksHelper","tree","blockGroup","numChildElements","activeList","isListItemBlock","listItemBlockType","numElementsRemoved","fromDom","listItemElement","numElementsAdded","createExternalHTMLExporter","unified","rehypeParse","rehypeStringify","blocks","createInternalHTMLSerializer","uploadToTmpFilesDotOrg_DEV_ONLY","file","body","isAppleOS","formatKeyboardShortcut","shortcut","mergeCSSClasses","classes","c","createDefaultBlockDOMOutputSpec","blockName","htmlTag","blockContentHTMLAttributes","inlineContentHTMLAttributes","attribute","inlineContent","defaultBlockToHTML","toDOM","renderSpec","defaultProps","inheritedProps","camelToDataKebab","str","propsToAttributes","tiptapAttributes","name","_spec","spec","asNumber","getBlockFromPos","getPos","tipTapEditor","blockIdentifier","wrapInBlockStructure","blockType","blockProps","domAttributes","prop","createStronglyTypedTiptapNode","Node","createInternalBlockSpec","implementation","createBlockSpecFromStronglyTypedTiptapNode","requiredExtensions","getBlockSchemaFromSpecs","specs","getParseRules","customParseFunction","rules","createBlockSpec","blockImplementation","div","blockContentDOMAttributes","output","addInlineContentAttributes","inlineContentType","inlineContentProps","addInlineContentKeyboardShortcuts","resolvedPos","createInternalInlineContentSpec","createInlineContentSpecFromTipTapNode","getInlineContentSchemaFromSpecs","getInlineContentParseRules","htmlElement","createInlineContentSpec","inlineContentConfig","inlineContentImplementation","stylePropsToAttributes","addStyleAttributes","styleType","styleValue","createInternalStyleSpec","createStyleSpecFromTipTapMark","getStyleSchemaFromSpecs","getStyleParseRules","createStyleSpec","styleConfig","styleImplementation","Mark","renderResult","BackgroundColorMark","HTMLAttributes","BackgroundColor","TextColorMark","TextColor","headingPropSchema","HeadingBlockContent","parsed","level","InputRule","state","chain","range","Heading","EventEmitter","__publicField","fn","args","callbacks","callback","ImageToolbarView","pluginKey","pmView","updateImageToolbar","editorWrapper","blockElement","prevState","pluginState","imageToolbarPluginKey","ImageToolbarProsemirrorPlugin","_editor","editorView","imagePropSchema","textAlignmentToAlignItems","textAlignment","minWidth","Image","wrapper","addImageButton","addImageButtonIcon","addImageButtonText","imageAndCaptionWrapper","imageWrapper","image","leftResizeHandle","rightResizeHandle","caption","handleEditorUpdate","selection","selectedBlock","resizeParams","windowMouseMoveHandler","newWidth","windowMouseUpHandler","addImageButtonMouseDownHandler","addImageButtonClickHandler","imageMouseEnterHandler","imageMouseLeaveHandler","leftResizeHandleMouseDownHandler","rightResizeHandleMouseDownHandler","figure","img","figcaption","handleEnter","selectionEmpty","commands","bulletListItemPropSchema","BulletListItemBlockContent","BulletListItem","PLUGIN_KEY","NumberedListIndexingPlugin","_transactions","_oldState","modified","newIndex","isFirstBlockInDoc","prevBlockInfo","prevBlockContentNode","prevBlockIndex","numberedListItemPropSchema","NumberedListItemBlockContent","NumberedListItem","paragraphPropSchema","ParagraphBlockContent","Paragraph","TableExtension","columnResizing","tableEditing","selectionIsEmpty","selectionIsAtStartOfNode","selectionIsInTableParagraphNode","extension","context","callOrReturn","getExtensionField","tablePropSchema","TableBlockContent","TableParagraph","mergeAttributes","Table","TableHeader","TableCell","TableRow","defaultBlockSpecs","defaultBlockSchema","defaultStyleSpecs","Bold","Italic","Underline","Strike","Code","defaultStyleSchema","defaultInlineContentSpecs","defaultInlineContentSchema","getNodeById","targetNode","posBeforeNode","insertBlocks","blocksToInsert","referenceBlock","placement","eraseHistory","ttEditor","nodesToInsert","insertionPos","newEditorState","EditorState","updateBlock","blockToUpdate","update","removeBlocks","blocksToRemove","idsOfBlocksToRemove","removedSize","oldDocSize","newDocSize","notFoundIds","replaceBlocks","removeUnderlines","removeUnderlinesHelper","cleanHTMLToMarkdown","cleanHTMLString","rehypeRemark","remarkGfm","remarkStringify","blocksToMarkdown","externalHTML","getChildIndex","isWhitespaceNode","liftNestedListsToParent","parentListItem","siblingsAfter","sibling","siblingContainer","createGroups","listItem","nestedListsToBlockNoteStructure","elementOrHTML","HTMLToBlocks","html","icSchema","pmSchema","htmlNode","parentNode","DOMParser","code","properties","result","markdownToBlocks","markdown","htmlString","remarkParse","remarkRehype","defaultHandlers","FormattingToolbarView","updateFormattingToolbar","composing","isSame","ranges","from","to","shouldShow","isNodeSelection","posToDOMRect","formattingToolbarPluginKey","FormattingToolbarProsemirrorPlugin","HyperlinkToolbarView","updateHyperlinkToolbar","hoveredHyperlinkElement","posInHoveredHyperlinkMark","resolvedPosInHoveredHyperlinkMark","marksAtPos","getMarkRange","url","prevHyperlinkMark","hyperlinkToolbarPluginKey","HyperlinkToolbarProsemirrorPlugin","findBlock","findParentNode","SuggestionsMenuView","updateSuggestionsMenu","decorationNode","getDefaultPluginState","prev","next","started","stopped","changed","setupSuggestionsMenu","defaultTriggerCharacter","onSelectItem","suggestionsPluginView","deactivate","_c","_d","menuIsActive","triggerCharacter","queryStartPos","keyboardHoveredItemIndex","active","decorationId","blockNode","DecorationSet","Decoration","slashMenuPluginKey","SlashMenuProsemirrorPlugin","suggestions","query","aliases","alias","MultipleNodeSelection","Selection","$anchor","$head","_pos","fromResult","toResult","MAX_NUM_BLOCKS","dragImageElement","getDraggableBlockFromCoords","coords","blockPositionFromCoords","docView","desc","blockPositionsFromSelection","beforeFirstBlockPos","afterLastBlockPos","selectionStartInBlockContent","selectionEndInBlockContent","minDepth","startFirstBlockPos","endLastBlockPos","setDragImage","parentClone","getElementIndex","parentElement","targetElement","firstSelectedBlockIndex","lastSelectedBlockIndex","unsetDragImage","inheritedClasses","className","dragStart","e","editorBoundingBox","draggedBlockInSelection","multipleBlocksSelected","NodeSelection","selectedSlice","plainText","SideMenuView","updateSideMenu","evt","_event","editorOuterBoundingBox","cursorWithinEditor","_e","blockContentBoundingBox","newBlockInsertionPos","newBlockContentPos","sideMenuPluginKey","SideMenuProsemirrorPlugin","getTotalBlocks","maxBlocksLimit","errorCallback","sideMenuState","setSelectionToNextContentEditableBlock","insertOrUpdateBlock","currentBlock","insertedBlock","getDefaultSlashMenuItems","slashMenuItems","setHiddenDragImage","unsetHiddenDragImage","domCellAround","target","hideElementsWithClassNames","classNames","elementsToHide","TableHandlesView","updateState","colIndex","rowIndex","cellRect","tableRect","blockEl","boundedMouseCoords","tableCellElements","tableCellElement","emitStateUpdate","oldIndex","dispatchDecorationsTransaction","mousePos","tableHandlesPluginKey","rows","rowToMove","cellsToMove","tableElement","cellElement","TableHandlesProsemirrorPlugin","decorations","tableResolvedPos","tableNode","rowResolvedPos","cellResolvedPos","decorationPos","widget","createCopyToClipboardExtension","tiptap","_view","selectedFragment","acceptedMIMETypes","createPasteFromClipboardExtension","format","mimeType","data","BackgroundColorExtension","Placeholder","menuState","anchor","hasAnchor","isEmpty","decoration","TextAlignmentExtension","TextColorExtension","TrailingNode","plugin","_","__","shouldInsertNodeAtEnd","endPosition","_state","lastNode","lastContentNode","NonEditableBlockPlugin","nodeAttributes","PreviousBlockTypePlugin","timeout","_editorView","_prevState","currentTransactionOriginalOldBlockAttrs","oldNodes","findChildren","oldNodesById","oldNode","oldContentNode","newContentNode","newAttrs","oldAttrs","prevAttrs","decorationAttrs","nodeAttr","BlockAttributes","BlockContainer","attrs","HTMLAttr","blockOuter","blockHTMLAttributes","dispatch","newBlock","posInBlock","childNodes","oldType","newType","oldContentType","newContentType","TextSelection","posBetweenBlocks","nextNodeIsBlock","prevNodeIsBlock","nextBlockInfo","childBlocksStart","childBlocksEnd","childBlocksRange","prevBlockEndPos","keepType","originalBlockContent","newBlockContent","selectionAtBlockStart","isParagraph","blockAtDocStart","selectionAtBlockEnd","hasChildBlocks","oldDepth","newPos","newDepth","blockEmpty","blockIndented","BlockGroup","blockGroupHTMLAttributes","Doc","CustomContentPropsMark","getBlockNoteExtensions","opts","extensions","Gapcursor","HardBreak","Text","Link","styleSpec","a","inlineContentSpec","ext","Dropcursor","Collaboration","defaultRender","user","cursor","label","nonbreakingSpace1","nonbreakingSpace2","CollaborationCursor","History","removeChild","n","f","nestedChild","container","blockNoteTipTapOptions","BlockNoteEditor","newOptions","blockNoteUIExtension","initialContent","tiptapOptions","cache","oldCreateAndFill","root","_g","_f","_h","_j","_i","Editor","isWholeDocEmpty","bnNode","sliceTopLevelBlocks","_node","info","count","_block","traverseBlockArray","blockArray","sliceBlocksCount","limit","reverse","nodeIndex","numNodes","prevNode","nextNode","targetBlock","editable","checkBlocksLimit","normalizedUrl","normalizeUrl","textShorthandToStyledText","partialContentToInlineContent","partialContent","partialBlocksToBlocksForTesting","partialBlocks","partialBlock","partialBlockToBlockForTesting","withDefaults","propKey","propValue","addIdsToBlock","addIdsToBlocks"],"mappings":"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"}