diff --git a/apps/client/package.json b/apps/client/package.json index 7b208216..8540a010 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -42,10 +42,12 @@ "react-router-dom": "^6.24.0", "socket.io-client": "^4.7.5", "tippy.js": "^6.3.7", + "tiptap-extension-global-drag-handle": "^0.1.10", "zod": "^3.23.8" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.47.0", + "@types/file-saver": "^2.0.7", "@types/js-cookie": "^3.0.6", "@types/katex": "^0.16.7", "@types/node": "20.14.9", diff --git a/apps/client/src/features/editor/components/callout/callout-view.tsx b/apps/client/src/features/editor/components/callout/callout-view.tsx index ee110673..0df410a3 100644 --- a/apps/client/src/features/editor/components/callout/callout-view.tsx +++ b/apps/client/src/features/editor/components/callout/callout-view.tsx @@ -1,9 +1,4 @@ -import { - Editor, - NodeViewContent, - NodeViewProps, - NodeViewWrapper, -} from "@tiptap/react"; +import { NodeViewContent, NodeViewProps, NodeViewWrapper } from "@tiptap/react"; import { IconAlertTriangleFilled, IconCircleCheckFilled, diff --git a/apps/client/src/features/editor/extensions/drag-handle.ts b/apps/client/src/features/editor/extensions/drag-handle.ts deleted file mode 100644 index bf43fd18..00000000 --- a/apps/client/src/features/editor/extensions/drag-handle.ts +++ /dev/null @@ -1,371 +0,0 @@ -// MIT - source: https://github.com/NiclasDev63/tiptap-extension-global-drag-handle -import { Extension } from "@tiptap/core"; -import { - NodeSelection, - Plugin, - PluginKey, - TextSelection, -} from "@tiptap/pm/state"; -import { Fragment, Slice, Node } from "@tiptap/pm/model"; - -// @ts-ignore -import { __serializeForClipboard, EditorView } from "@tiptap/pm/view"; - -export interface GlobalDragHandleOptions { - /** - * The width of the drag handle - */ - dragHandleWidth: number; - - /** - * The treshold for scrolling - */ - scrollTreshold: number; - - /* - * The css selector to query for the drag handle. (eg: '.custom-handle'). - * If handle element is found, that element will be used as drag handle. If not, a default handle will be created - */ - dragHandleSelector?: string; -} -function absoluteRect(node: Element) { - const data = node.getBoundingClientRect(); - const modal = node.closest('[role="dialog"]'); - - if (modal && window.getComputedStyle(modal).transform !== "none") { - const modalRect = modal.getBoundingClientRect(); - - return { - top: data.top - modalRect.top, - left: data.left - modalRect.left, - width: data.width, - }; - } - return { - top: data.top, - left: data.left, - width: data.width, - }; -} - -function nodeDOMAtCoords(coords: { x: number; y: number }) { - return document - .elementsFromPoint(coords.x, coords.y) - .find( - (elem: Element) => - elem.parentElement?.matches?.(".ProseMirror") || - elem.matches( - [ - "li", - "p:not(:first-child)", - "pre", - "blockquote", - "h1, h2, h3, h4, h5, h6", - ".tableWrapper", - ].join(", "), - ), - ); -} - -function nodePosAtDOM( - node: Element, - view: EditorView, - options: GlobalDragHandleOptions, -) { - const boundingRect = node.getBoundingClientRect(); - - return view.posAtCoords({ - left: boundingRect.left + 50 + options.dragHandleWidth, - top: boundingRect.top + 1, - })?.inside; -} - -function calcNodePos(pos: number, view: EditorView) { - const $pos = view.state.doc.resolve(pos); - if ($pos.depth > 1) return $pos.before($pos.depth); - return pos; -} - -export function DragHandlePlugin( - options: GlobalDragHandleOptions & { pluginKey: string }, -) { - let listType = ""; - function handleDragStart(event: DragEvent, view: EditorView) { - view.focus(); - - if (!event.dataTransfer) return; - - const node = nodeDOMAtCoords({ - x: event.clientX + 50 + options.dragHandleWidth, - y: event.clientY, - }); - - if (!(node instanceof Element)) return; - - let draggedNodePos = nodePosAtDOM(node, view, options); - if (draggedNodePos == null || draggedNodePos < 0) return; - draggedNodePos = calcNodePos(draggedNodePos, view); - - const { from, to } = view.state.selection; - const diff = from - to; - - const fromSelectionPos = calcNodePos(from, view); - let differentNodeSelected = false; - - const nodePos = view.state.doc.resolve(fromSelectionPos); - - // Check if nodePos points to the top level node - if (nodePos.node().type.name === "doc") differentNodeSelected = true; - else { - const nodeSelection = NodeSelection.create( - view.state.doc, - nodePos.before(), - ); - // Check if the node where the drag event started is part of the current selection - differentNodeSelected = !( - draggedNodePos + 1 >= nodeSelection.$from.pos && - draggedNodePos <= nodeSelection.$to.pos - ); - } - - if ( - !differentNodeSelected && - diff !== 0 && - !(view.state.selection instanceof NodeSelection) - ) { - const endSelection = NodeSelection.create(view.state.doc, to - 1); - const multiNodeSelection = TextSelection.create( - view.state.doc, - draggedNodePos, - endSelection.$to.pos, - ); - view.dispatch(view.state.tr.setSelection(multiNodeSelection)); - } else { - const nodeSelection = NodeSelection.create( - view.state.doc, - draggedNodePos, - ); - view.dispatch(view.state.tr.setSelection(nodeSelection)); - } - - // If the selected node is a list item, we need to save the type of the wrapping list e.g. OL or UL - if ( - view.state.selection instanceof NodeSelection && - view.state.selection.node.type.name === "listItem" - ) { - listType = node.parentElement!.tagName; - } - - const slice = view.state.selection.content(); - const { dom, text } = __serializeForClipboard(view, slice); - - event.dataTransfer.clearData(); - event.dataTransfer.setData("text/html", dom.innerHTML); - event.dataTransfer.setData("text/plain", text); - event.dataTransfer.effectAllowed = "copyMove"; - - event.dataTransfer.setDragImage(node, 0, 0); - - view.dragging = { slice, move: event.ctrlKey }; - } - - let dragHandleElement: HTMLElement | null = null; - - function hideDragHandle() { - if (dragHandleElement) { - dragHandleElement.classList.add("hide"); - } - } - - function showDragHandle() { - if (dragHandleElement) { - dragHandleElement.classList.remove("hide"); - } - } - - return new Plugin({ - key: new PluginKey(options.pluginKey), - view: (view) => { - const handleBySelector = options.dragHandleSelector - ? document.querySelector(options.dragHandleSelector) - : null; - dragHandleElement = handleBySelector ?? document.createElement("div"); - dragHandleElement.draggable = true; - dragHandleElement.dataset.dragHandle = ""; - dragHandleElement.classList.add("drag-handle"); - - function onDragHandleDragStart(e: DragEvent) { - handleDragStart(e, view); - } - - dragHandleElement.addEventListener("dragstart", onDragHandleDragStart); - - function onDragHandleDrag(e: DragEvent) { - hideDragHandle(); - let scrollY = window.scrollY; - if (e.clientY < options.scrollTreshold) { - window.scrollTo({ top: scrollY - 30, behavior: "smooth" }); - } else if (window.innerHeight - e.clientY < options.scrollTreshold) { - window.scrollTo({ top: scrollY + 30, behavior: "smooth" }); - } - } - - dragHandleElement.addEventListener("drag", onDragHandleDrag); - - hideDragHandle(); - - if (!handleBySelector) { - view?.dom?.parentElement?.appendChild(dragHandleElement); - } - - return { - destroy: () => { - if (!handleBySelector) { - dragHandleElement?.remove?.(); - } - dragHandleElement?.removeEventListener("drag", onDragHandleDrag); - dragHandleElement?.removeEventListener( - "dragstart", - onDragHandleDragStart, - ); - dragHandleElement = null; - }, - }; - }, - props: { - handleDOMEvents: { - mousemove: (view, event) => { - if (!view.editable) { - return; - } - - const node = nodeDOMAtCoords({ - x: event.clientX + 50 + options.dragHandleWidth, - y: event.clientY, - }); - - const notDragging = node?.closest(".not-draggable"); - - //const isNodeInTable = node?.closest("td") || node?.closest("th"); - - if ( - !(node instanceof Element) || - node.matches("ul, ol") || - notDragging || - node.matches(".tableWrapper") - ) { - hideDragHandle(); - return; - } - - const compStyle = window.getComputedStyle(node); - const parsedLineHeight = parseInt(compStyle.lineHeight, 10); - const lineHeight = isNaN(parsedLineHeight) - ? parseInt(compStyle.fontSize) * 1.2 - : parsedLineHeight; - const paddingTop = parseInt(compStyle.paddingTop, 10); - - const rect = absoluteRect(node); - - rect.top += (lineHeight - 24) / 2; - rect.top += paddingTop; - // Li markers - if (node.matches("ul:not([data-type=taskList]) li, ol li")) { - rect.left -= options.dragHandleWidth; - } - rect.width = options.dragHandleWidth; - - if (!dragHandleElement) return; - - dragHandleElement.style.left = `${rect.left - rect.width}px`; - dragHandleElement.style.top = `${rect.top}px`; - showDragHandle(); - }, - keydown: () => { - hideDragHandle(); - }, - mousewheel: () => { - hideDragHandle(); - }, - // dragging class is used for CSS - dragstart: (view) => { - view.dom.classList.add("dragging"); - }, - drop: (view, event) => { - view.dom.classList.remove("dragging"); - hideDragHandle(); - let droppedNode: Node | null = null; - const dropPos = view.posAtCoords({ - left: event.clientX, - top: event.clientY, - }); - - if (!dropPos) return; - - if (view.state.selection instanceof NodeSelection) { - droppedNode = view.state.selection.node; - } - if (!droppedNode) return; - - const resolvedPos = view.state.doc.resolve(dropPos.pos); - - const isDroppedInsideList = - resolvedPos.parent.type.name === "listItem"; - - // If the selected node is a list item and is not dropped inside a list, we need to wrap it inside
    tag otherwise ol list items will be transformed into ul list item when dropped - if ( - view.state.selection instanceof NodeSelection && - view.state.selection.node.type.name === "listItem" && - !isDroppedInsideList && - listType == "OL" - ) { - const text = droppedNode.textContent; - if (!text) return; - const paragraph = view.state.schema.nodes.paragraph?.createAndFill( - {}, - view.state.schema.text(text), - ); - const listItem = view.state.schema.nodes.listItem?.createAndFill( - {}, - paragraph, - ); - - const newList = view.state.schema.nodes.orderedList?.createAndFill( - null, - listItem, - ); - const slice = new Slice(Fragment.from(newList), 0, 0); - view.dragging = { slice, move: event.ctrlKey }; - } - }, - dragend: (view) => { - view.dom.classList.remove("dragging"); - }, - }, - }, - }); -} - -const GlobalDragHandle = Extension.create({ - name: "globalDragHandle", - - addOptions() { - return { - dragHandleWidth: 20, - scrollTreshold: 100, - }; - }, - - addProseMirrorPlugins() { - return [ - DragHandlePlugin({ - pluginKey: "globalDragHandle", - dragHandleWidth: this.options.dragHandleWidth, - scrollTreshold: this.options.scrollTreshold, - dragHandleSelector: this.options.dragHandleSelector, - }), - ]; - }, -}); - -export default GlobalDragHandle; diff --git a/apps/client/src/features/editor/extensions/extensions.ts b/apps/client/src/features/editor/extensions/extensions.ts index 00757ba2..1453b2c2 100644 --- a/apps/client/src/features/editor/extensions/extensions.ts +++ b/apps/client/src/features/editor/extensions/extensions.ts @@ -41,7 +41,7 @@ import { import { IUser } from "@/features/user/types/user.types.ts"; import MathInlineView from "@/features/editor/components/math/math-inline.tsx"; import MathBlockView from "@/features/editor/components/math/math-block.tsx"; -import GlobalDragHandle from "@/features/editor/extensions/drag-handle.ts"; +import GlobalDragHandle from "tiptap-extension-global-drag-handle"; import { Youtube } from "@tiptap/extension-youtube"; import ImageView from "@/features/editor/components/image/image-view.tsx"; import CalloutView from "@/features/editor/components/callout/callout-view.tsx"; diff --git a/apps/client/src/features/editor/styles/table.css b/apps/client/src/features/editor/styles/table.css index 7564def5..19a1029b 100644 --- a/apps/client/src/features/editor/styles/table.css +++ b/apps/client/src/features/editor/styles/table.css @@ -1,6 +1,6 @@ .tableWrapper { - margin-top: 3rem; - margin-bottom: 3rem; + margin-top: 1rem; + margin-bottom: 1rem; overflow-x: auto; & table { overflow-x: hidden; diff --git a/apps/client/src/features/group/components/add-group-member-modal.tsx b/apps/client/src/features/group/components/add-group-member-modal.tsx index 5b8ac1db..8b05c595 100644 --- a/apps/client/src/features/group/components/add-group-member-modal.tsx +++ b/apps/client/src/features/group/components/add-group-member-modal.tsx @@ -1,4 +1,4 @@ -import { Button, Divider, Group, Modal, ScrollArea } from "@mantine/core"; +import { Button, Divider, Group, Modal } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import React, { useState } from "react"; import { MultiUserSelect } from "@/features/group/components/multi-user-select.tsx"; diff --git a/apps/client/src/features/page-history/components/history-list.tsx b/apps/client/src/features/page-history/components/history-list.tsx index 9d797914..70e79de3 100644 --- a/apps/client/src/features/page-history/components/history-list.tsx +++ b/apps/client/src/features/page-history/components/history-list.tsx @@ -2,7 +2,6 @@ import { usePageHistoryListQuery, usePageHistoryQuery, } from "@/features/page-history/queries/page-history-query"; -import { useParams } from "react-router-dom"; import HistoryItem from "@/features/page-history/components/history-item"; import { activeHistoryIdAtom, diff --git a/apps/client/src/features/page/components/header/page-header-menu.tsx b/apps/client/src/features/page/components/header/page-header-menu.tsx index fccb1c1f..514805b2 100644 --- a/apps/client/src/features/page/components/header/page-header-menu.tsx +++ b/apps/client/src/features/page/components/header/page-header-menu.tsx @@ -60,7 +60,7 @@ function PageActionMenu({ readOnly }: PageActionMenuProps) { }); const { openDeleteModal } = useDeletePageModal(); const [tree] = useAtom(treeApiAtom); - const [opened, { open: openExportModal, close: closeExportModal }] = + const [exportOpened, { open: openExportModal, close: closeExportModal }] = useDisclosure(false); const handleCopyLink = () => { @@ -156,7 +156,7 @@ function PageActionMenu({ readOnly }: PageActionMenuProps) { diff --git a/apps/client/src/features/page/components/page-export-modal.tsx b/apps/client/src/features/page/components/page-export-modal.tsx index 21fe19e8..d4c99144 100644 --- a/apps/client/src/features/page/components/page-export-modal.tsx +++ b/apps/client/src/features/page/components/page-export-modal.tsx @@ -36,29 +36,38 @@ export default function PageExportModal({ }; return ( - <> - - -
    - Export format -
    - -
    + + + + + Export page + + + + +
    + Format +
    + +
    - - - - -
    - + + + + + + + ); } diff --git a/apps/client/src/features/page/components/page-import-modal.tsx b/apps/client/src/features/page/components/page-import-modal.tsx new file mode 100644 index 00000000..8ac6eda7 --- /dev/null +++ b/apps/client/src/features/page/components/page-import-modal.tsx @@ -0,0 +1,148 @@ +import { Modal, Button, SimpleGrid, FileButton } from "@mantine/core"; +import { + IconCheck, + IconFileCode, + IconMarkdown, + IconX, +} from "@tabler/icons-react"; +import { importPage } from "@/features/page/services/page-service.ts"; +import { notifications } from "@mantine/notifications"; +import { treeDataAtom } from "@/features/page/tree/atoms/tree-data-atom.ts"; +import { useAtom } from "jotai"; +import { buildTree } from "@/features/page/tree/utils"; +import { IPage } from "@/features/page/types/page.types.ts"; +import React from "react"; + +interface PageImportModalProps { + spaceId: string; + open: boolean; + onClose: () => void; +} + +export default function PageImportModal({ + spaceId, + open, + onClose, +}: PageImportModalProps) { + return ( + <> + + + + + Import pages + + + + + + + + + ); +} + +interface ImportFormatSelection { + spaceId: string; + onClose: () => void; +} +function ImportFormatSelection({ spaceId, onClose }: ImportFormatSelection) { + const [treeData, setTreeData] = useAtom(treeDataAtom); + + const handleFileUpload = async (selectedFiles: File[]) => { + if (!selectedFiles) { + return; + } + + onClose(); + + const alert = notifications.show({ + title: "Importing pages", + message: "Page import is in progress. Please do not close this tab.", + loading: true, + autoClose: false, + }); + + const pages: IPage[] = []; + let pageCount = 0; + + for (const file of selectedFiles) { + try { + const page = await importPage(file, spaceId); + pages.push(page); + pageCount += 1; + } catch (err) { + console.log("Failed to import page", err); + } + } + + const newTreeNodes = buildTree(pages); + const fullTree = treeData.concat(newTreeNodes); + + if (newTreeNodes?.length && fullTree?.length > 0) { + setTreeData(fullTree); + } + + if (pageCount > 0) { + notifications.update({ + id: alert, + color: "teal", + title: `Successfully imported ${pageCount} pages`, + message: "Your import is complete.", + icon: , + loading: false, + autoClose: 5000, + }); + } else { + notifications.update({ + id: alert, + color: "red", + title: `Failed to import pages`, + message: "Unable to import pages. Please try again.", + icon: , + loading: false, + autoClose: 5000, + }); + } + }; + + return ( + <> + + + {(props) => ( + + )} + + + + {(props) => ( + + )} + + + + ); +} diff --git a/apps/client/src/features/page/services/page-service.ts b/apps/client/src/features/page/services/page-service.ts index f7228ec5..dfebdb25 100644 --- a/apps/client/src/features/page/services/page-service.ts +++ b/apps/client/src/features/page/services/page-service.ts @@ -67,6 +67,20 @@ export async function exportPage(data: IExportPageParams): Promise { saveAs(req.data, fileName); } +export async function importPage(file: File, spaceId: string) { + const formData = new FormData(); + formData.append("spaceId", spaceId); + formData.append("file", file); + + const req = await api.post("/pages/import", formData, { + headers: { + "Content-Type": "multipart/form-data", + }, + }); + + return req.data; +} + export async function uploadFile(file: File, pageId: string) { const formData = new FormData(); formData.append("pageId", pageId); diff --git a/apps/client/src/features/page/tree/components/space-tree.tsx b/apps/client/src/features/page/tree/components/space-tree.tsx index e30a9db8..f78485a1 100644 --- a/apps/client/src/features/page/tree/components/space-tree.tsx +++ b/apps/client/src/features/page/tree/components/space-tree.tsx @@ -447,9 +447,11 @@ function NodeMenu({ node, treeApi }: NodeMenuProps) { leftSection={ } - onClick={() => - openDeleteModal({ onConfirm: () => treeApi?.delete(node) }) - } + onClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + openDeleteModal({ onConfirm: () => treeApi?.delete(node) }); + }} > Delete diff --git a/apps/client/src/features/search/search-spotlight.tsx b/apps/client/src/features/search/search-spotlight.tsx index fb842bd8..1fc26aef 100644 --- a/apps/client/src/features/search/search-spotlight.tsx +++ b/apps/client/src/features/search/search-spotlight.tsx @@ -2,7 +2,7 @@ import { Group, Center, Text } from "@mantine/core"; import { Spotlight } from "@mantine/spotlight"; import { IconFileDescription, IconSearch } from "@tabler/icons-react"; import React, { useState } from "react"; -import { useNavigate, useParams } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { useDebouncedValue } from "@mantine/hooks"; import { usePageSearchQuery } from "@/features/search/queries/search-query"; import { buildPageUrl } from "@/features/page/page.utils.ts"; diff --git a/apps/client/src/features/space/components/settings-modal.tsx b/apps/client/src/features/space/components/settings-modal.tsx index 90cc5196..e2f4ed73 100644 --- a/apps/client/src/features/space/components/settings-modal.tsx +++ b/apps/client/src/features/space/components/settings-modal.tsx @@ -1,4 +1,4 @@ -import { Modal, Tabs, rem, Group, Divider, ScrollArea } from "@mantine/core"; +import { Modal, Tabs, rem, Group, ScrollArea } from "@mantine/core"; import SpaceMembersList from "@/features/space/components/space-members.tsx"; import AddSpaceMembersModal from "@/features/space/components/add-space-members-modal.tsx"; import React, { useMemo } from "react"; diff --git a/apps/client/src/features/space/components/sidebar/space-name.tsx b/apps/client/src/features/space/components/sidebar/space-name.tsx index 121bedaf..88888629 100644 --- a/apps/client/src/features/space/components/sidebar/space-name.tsx +++ b/apps/client/src/features/space/components/sidebar/space-name.tsx @@ -1,4 +1,4 @@ -import { UnstyledButton, Group, Avatar, Text, rem } from "@mantine/core"; +import { UnstyledButton, Group, Text } from "@mantine/core"; import classes from "./space-name.module.css"; interface SpaceNameProps { diff --git a/apps/client/src/features/space/components/sidebar/space-sidebar.tsx b/apps/client/src/features/space/components/sidebar/space-sidebar.tsx index fdac628b..c56c93a7 100644 --- a/apps/client/src/features/space/components/sidebar/space-sidebar.tsx +++ b/apps/client/src/features/space/components/sidebar/space-sidebar.tsx @@ -1,13 +1,15 @@ import { ActionIcon, Group, - rem, + Menu, Text, Tooltip, UnstyledButton, } from "@mantine/core"; import { spotlight } from "@mantine/spotlight"; import { + IconArrowDown, + IconDots, IconHome, IconPlus, IconSearch, @@ -32,6 +34,7 @@ import { SpaceCaslAction, SpaceCaslSubject, } from "@/features/space/permissions/permissions.type.ts"; +import PageImportModal from "@/features/page/components/page-import-modal.tsx"; export function SpaceSidebar() { const [tree] = useAtom(treeApiAtom); @@ -140,18 +143,20 @@ export function SpaceSidebar() { SpaceCaslAction.Manage, SpaceCaslSubject.Page, ) && ( - - - - - + + + + + + + + + )} @@ -177,3 +182,54 @@ export function SpaceSidebar() { ); } + +interface SpaceMenuProps { + spaceId: string; + onSpaceSettings: () => void; +} +function SpaceMenu({ spaceId, onSpaceSettings }: SpaceMenuProps) { + const [importOpened, { open: openImportModal, close: closeImportModal }] = + useDisclosure(false); + + return ( + <> + + + + + + + + + + + } + > + Import pages + + + + + } + > + Space settings + + + + + + + ); +} diff --git a/apps/client/src/features/space/components/space-members.tsx b/apps/client/src/features/space/components/space-members.tsx index e33d757c..763cedcc 100644 --- a/apps/client/src/features/space/components/space-members.tsx +++ b/apps/client/src/features/space/components/space-members.tsx @@ -1,5 +1,4 @@ import { Group, Table, Text, Menu, ActionIcon } from "@mantine/core"; -import { useParams } from "react-router-dom"; import React from "react"; import { IconDots } from "@tabler/icons-react"; import { modals } from "@mantine/modals"; diff --git a/apps/client/src/features/workspace/components/members/components/workspace-invites-table.tsx b/apps/client/src/features/workspace/components/members/components/workspace-invites-table.tsx index 9db679b6..a7fbb9c2 100644 --- a/apps/client/src/features/workspace/components/members/components/workspace-invites-table.tsx +++ b/apps/client/src/features/workspace/components/members/components/workspace-invites-table.tsx @@ -1,4 +1,4 @@ -import { Group, Table, Avatar, Text, Badge, Alert } from "@mantine/core"; +import { Group, Table, Avatar, Text, Alert } from "@mantine/core"; import { useWorkspaceInvitationsQuery } from "@/features/workspace/queries/workspace-query.ts"; import React from "react"; import { getUserRoleLabel } from "@/features/workspace/types/user-role-data.ts"; diff --git a/apps/client/src/features/workspace/components/members/components/workspace-members-table.tsx b/apps/client/src/features/workspace/components/members/components/workspace-members-table.tsx index a2b6e79e..ea07b776 100644 --- a/apps/client/src/features/workspace/components/members/components/workspace-members-table.tsx +++ b/apps/client/src/features/workspace/components/members/components/workspace-members-table.tsx @@ -1,4 +1,4 @@ -import { Group, Table, Avatar, Text, Badge } from "@mantine/core"; +import { Group, Table, Text, Badge } from "@mantine/core"; import { useChangeMemberRoleMutation, useWorkspaceMembersQuery, diff --git a/apps/server/package.json b/apps/server/package.json index a17201ba..70203d5d 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -58,8 +58,10 @@ "fastify": "^4.28.0", "fix-esm": "^1.0.1", "fs-extra": "^11.2.0", + "happy-dom": "^14.12.3", "kysely": "^0.27.3", "kysely-migration-cli": "^0.4.2", + "marked": "^13.0.2", "mime-types": "^2.1.35", "nanoid": "^5.0.7", "nestjs-kysely": "^1.0.0", diff --git a/apps/server/src/app.module.ts b/apps/server/src/app.module.ts index 8d718168..f8fd1071 100644 --- a/apps/server/src/app.module.ts +++ b/apps/server/src/app.module.ts @@ -13,6 +13,7 @@ import { StaticModule } from './integrations/static/static.module'; import { EventEmitterModule } from '@nestjs/event-emitter'; import { HealthModule } from './integrations/health/health.module'; import { ExportModule } from './integrations/export/export.module'; +import { ImportModule } from './integrations/import/import.module'; @Module({ imports: [ @@ -24,6 +25,7 @@ import { ExportModule } from './integrations/export/export.module'; QueueModule, StaticModule, HealthModule, + ImportModule, ExportModule, StorageModule.forRootAsync({ imports: [EnvironmentModule], diff --git a/apps/server/src/collaboration/collaboration.util.ts b/apps/server/src/collaboration/collaboration.util.ts index e17f9ae3..d1e55f9d 100644 --- a/apps/server/src/collaboration/collaboration.util.ts +++ b/apps/server/src/collaboration/collaboration.util.ts @@ -27,8 +27,8 @@ import { TiptapVideo, TrailingNode, } from '@docmost/editor-ext'; -import { generateHTML, generateJSON } from '@tiptap/html'; import { generateText, JSONContent } from '@tiptap/core'; +import { generateHTML, generateJSON } from '../common/helpers/prosemirror/html'; export const tiptapExtensions = [ StarterKit, diff --git a/apps/server/src/common/helpers/prosemirror/html/generateHTML.ts b/apps/server/src/common/helpers/prosemirror/html/generateHTML.ts new file mode 100644 index 00000000..3622ed4c --- /dev/null +++ b/apps/server/src/common/helpers/prosemirror/html/generateHTML.ts @@ -0,0 +1,21 @@ +import { Extensions, getSchema, JSONContent } from '@tiptap/core'; +import { DOMSerializer, Node } from '@tiptap/pm/model'; +import { Window } from 'happy-dom'; + +export function generateHTML(doc: JSONContent, extensions: Extensions): string { + const schema = getSchema(extensions); + const contentNode = Node.fromJSON(schema, doc); + + const window = new Window(); + + const fragment = DOMSerializer.fromSchema(schema).serializeFragment( + contentNode.content, + { + document: window.document as unknown as Document, + }, + ); + + const serializer = new window.XMLSerializer(); + // @ts-ignore + return serializer.serializeToString(fragment as unknown as Node); +} diff --git a/apps/server/src/common/helpers/prosemirror/html/generateJSON.ts b/apps/server/src/common/helpers/prosemirror/html/generateJSON.ts new file mode 100644 index 00000000..b78b34da --- /dev/null +++ b/apps/server/src/common/helpers/prosemirror/html/generateJSON.ts @@ -0,0 +1,20 @@ +import { Extensions, getSchema } from '@tiptap/core'; +import { DOMParser, ParseOptions } from '@tiptap/pm/model'; +import { Window, DOMParser as HappyDomParser } from 'happy-dom'; + +export function generateJSON( + html: string, + extensions: Extensions, + options?: ParseOptions, +): Record { + const schema = getSchema(extensions); + + const window = new Window(); + const dom = new HappyDomParser(window).parseFromString( + html, + 'text/html', + ).body; + + // @ts-ignore + return DOMParser.fromSchema(schema).parse(dom, options).toJSON(); +} diff --git a/apps/server/src/common/helpers/prosemirror/html/index.ts b/apps/server/src/common/helpers/prosemirror/html/index.ts new file mode 100644 index 00000000..1778fe76 --- /dev/null +++ b/apps/server/src/common/helpers/prosemirror/html/index.ts @@ -0,0 +1,2 @@ +export * from './generateHTML.js'; +export * from './generateJSON.js'; diff --git a/apps/server/src/core/attachment/interceptors/attachment.interceptor.ts b/apps/server/src/common/interceptors/file.interceptor.ts similarity index 89% rename from apps/server/src/core/attachment/interceptors/attachment.interceptor.ts rename to apps/server/src/common/interceptors/file.interceptor.ts index 548c083b..8f29d314 100644 --- a/apps/server/src/core/attachment/interceptors/attachment.interceptor.ts +++ b/apps/server/src/common/interceptors/file.interceptor.ts @@ -9,7 +9,7 @@ import { Observable } from 'rxjs'; import { FastifyRequest } from 'fastify'; @Injectable() -export class AttachmentInterceptor implements NestInterceptor { +export class FileInterceptor implements NestInterceptor { public intercept( context: ExecutionContext, next: CallHandler, diff --git a/apps/server/src/core/attachment/attachment.controller.ts b/apps/server/src/core/attachment/attachment.controller.ts index 3f0ab177..b69e4bed 100644 --- a/apps/server/src/core/attachment/attachment.controller.ts +++ b/apps/server/src/core/attachment/attachment.controller.ts @@ -16,7 +16,7 @@ import { } from '@nestjs/common'; import { AttachmentService } from './services/attachment.service'; import { FastifyReply } from 'fastify'; -import { AttachmentInterceptor } from './interceptors/attachment.interceptor'; +import { FileInterceptor } from '../../common/interceptors/file.interceptor'; import * as bytes from 'bytes'; import { AuthUser } from '../../common/decorators/auth-user.decorator'; import { AuthWorkspace } from '../../common/decorators/auth-workspace.decorator'; @@ -63,7 +63,7 @@ export class AttachmentController { @UseGuards(JwtAuthGuard) @HttpCode(HttpStatus.OK) @Post('files/upload') - @UseInterceptors(AttachmentInterceptor) + @UseInterceptors(FileInterceptor) async uploadFile( @Req() req: any, @Res() res: FastifyReply, @@ -176,7 +176,7 @@ export class AttachmentController { @UseGuards(JwtAuthGuard) @HttpCode(HttpStatus.OK) @Post('attachments/upload-image') - @UseInterceptors(AttachmentInterceptor) + @UseInterceptors(FileInterceptor) async uploadAvatarOrLogo( @Req() req: any, @Res() res: FastifyReply, diff --git a/apps/server/src/integrations/export/export.controller.ts b/apps/server/src/integrations/export/export.controller.ts index dbdfe035..09b2c5d6 100644 --- a/apps/server/src/integrations/export/export.controller.ts +++ b/apps/server/src/integrations/export/export.controller.ts @@ -28,7 +28,7 @@ import { getMimeType } from '../../common/helpers'; @Controller() export class ImportController { constructor( - private readonly importService: ExportService, + private readonly exportService: ExportService, private readonly pageRepo: PageRepo, private readonly spaceAbility: SpaceAbilityFactory, ) {} @@ -54,7 +54,7 @@ export class ImportController { throw new ForbiddenException(); } - const rawContent = await this.importService.exportPage(dto.format, page); + const rawContent = await this.exportService.exportPage(dto.format, page); const fileExt = getExportExtension(dto.format); const fileName = sanitize(page.title || 'Untitled') + fileExt; diff --git a/apps/server/src/integrations/import/dto/import-dto.ts b/apps/server/src/integrations/import/dto/import-dto.ts new file mode 100644 index 00000000..8f7c8cda --- /dev/null +++ b/apps/server/src/integrations/import/dto/import-dto.ts @@ -0,0 +1,4 @@ +export enum ImportFormat { + HTML = 'html', + Markdown = 'markdown', +} diff --git a/apps/server/src/integrations/import/import.controller.ts b/apps/server/src/integrations/import/import.controller.ts new file mode 100644 index 00000000..461b9daa --- /dev/null +++ b/apps/server/src/integrations/import/import.controller.ts @@ -0,0 +1,78 @@ +import { + BadRequestException, + Controller, + ForbiddenException, + HttpCode, + HttpStatus, + Logger, + Post, + Req, + UseGuards, + UseInterceptors, +} from '@nestjs/common'; +import SpaceAbilityFactory from '../../core/casl/abilities/space-ability.factory'; +import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard'; +import { AuthUser } from '../../common/decorators/auth-user.decorator'; +import { User, Workspace } from '@docmost/db/types/entity.types'; +import { + SpaceCaslAction, + SpaceCaslSubject, +} from '../../core/casl/interfaces/space-ability.type'; +import { FileInterceptor } from '../../common/interceptors/file.interceptor'; +import * as bytes from 'bytes'; +import { MAX_FILE_SIZE } from '../../core/attachment/attachment.constants'; +import { ImportService } from './import.service'; +import { AuthWorkspace } from '../../common/decorators/auth-workspace.decorator'; + +@Controller() +export class ImportController { + private readonly logger = new Logger(ImportController.name); + + constructor( + private readonly importService: ImportService, + private readonly spaceAbility: SpaceAbilityFactory, + ) {} + + @UseInterceptors(FileInterceptor) + @UseGuards(JwtAuthGuard) + @HttpCode(HttpStatus.OK) + @Post('pages/import') + async importPage( + @Req() req: any, + @AuthUser() user: User, + @AuthWorkspace() workspace: Workspace, + ) { + const maxFileSize = bytes(MAX_FILE_SIZE); + + let file = null; + try { + file = await req.file({ + limits: { fileSize: maxFileSize, fields: 3, files: 1 }, + }); + } catch (err: any) { + this.logger.error(err.message); + if (err?.statusCode === 413) { + throw new BadRequestException( + `File too large. Exceeds the ${MAX_FILE_SIZE} limit`, + ); + } + } + + if (!file) { + throw new BadRequestException('Failed to upload file'); + } + + const spaceId = file.fields?.spaceId?.value; + + if (!spaceId) { + throw new BadRequestException('spaceId or format not found'); + } + + const ability = await this.spaceAbility.createForUser(user, spaceId); + if (ability.cannot(SpaceCaslAction.Edit, SpaceCaslSubject.Page)) { + throw new ForbiddenException(); + } + + return this.importService.importPage(file, user.id, spaceId, workspace.id); + } +} diff --git a/apps/server/src/integrations/import/import.module.ts b/apps/server/src/integrations/import/import.module.ts new file mode 100644 index 00000000..097fb15a --- /dev/null +++ b/apps/server/src/integrations/import/import.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { ImportService } from './import.service'; +import { ImportController } from './import.controller'; + +@Module({ + providers: [ImportService], + controllers: [ImportController] +}) +export class ImportModule {} diff --git a/apps/server/src/integrations/import/import.service.ts b/apps/server/src/integrations/import/import.service.ts new file mode 100644 index 00000000..be84dda6 --- /dev/null +++ b/apps/server/src/integrations/import/import.service.ts @@ -0,0 +1,126 @@ +import { BadRequestException, Injectable, Logger } from '@nestjs/common'; +import { PageRepo } from '@docmost/db/repos/page/page.repo'; +import { MultipartFile } from '@fastify/multipart'; +import { sanitize } from 'sanitize-filename-ts'; +import * as path from 'path'; +import { htmlToJson } from '../../collaboration/collaboration.util'; +import { marked } from 'marked'; +import { InjectKysely } from 'nestjs-kysely'; +import { KyselyDB } from '@docmost/db/types/kysely.types'; +import { generateSlugId } from '../../common/helpers'; +import { generateJitteredKeyBetween } from 'fractional-indexing-jittered'; +import { transformHTML } from './utils/html.utils'; + +@Injectable() +export class ImportService { + private readonly logger = new Logger(ImportService.name); + + constructor( + private readonly pageRepo: PageRepo, + @InjectKysely() private readonly db: KyselyDB, + ) {} + + async importPage( + filePromise: Promise, + userId: string, + spaceId: string, + workspaceId: string, + ): Promise { + const file = await filePromise; + const fileBuffer = await file.toBuffer(); + const fileName = sanitize(file.filename).slice(0, 255).split('.')[0]; + const fileExtension = path.extname(file.filename).toLowerCase(); + const fileMimeType = file.mimetype; + const fileContent = fileBuffer.toString(); + + let prosemirrorState = null; + let createdPage = null; + + if (fileExtension.endsWith('.md') && fileMimeType === 'text/markdown') { + prosemirrorState = await this.processMarkdown(fileContent); + } + + if (fileExtension.endsWith('.html') && fileMimeType === 'text/html') { + prosemirrorState = await this.processHTML(fileContent); + } + + if (!prosemirrorState) { + const message = 'Unsupported file format or mime type'; + this.logger.error(message); + throw new BadRequestException(message); + } + + const { title, prosemirrorJson } = + this.extractTitleAndRemoveHeading(prosemirrorState); + + const pageTitle = title || fileName; + + if (prosemirrorJson) { + try { + const pagePosition = await this.getNewPagePosition(spaceId); + + createdPage = await this.pageRepo.insertPage({ + slugId: generateSlugId(), + title: pageTitle, + content: prosemirrorJson, + position: pagePosition, + spaceId: spaceId, + creatorId: userId, + workspaceId: workspaceId, + lastUpdatedById: userId, + }); + } catch (err) { + const message = 'Failed to create page'; + this.logger.error(message, err); + throw new BadRequestException(message); + } + } + + return createdPage; + } + + async processMarkdown(markdownInput: string): Promise { + // turn markdown to html + const html = await marked.parse(markdownInput); + return await this.processHTML(html); + } + + async processHTML(htmlInput: string): Promise { + // turn html to prosemirror state + return htmlToJson(transformHTML(htmlInput)); + } + + extractTitleAndRemoveHeading(prosemirrorState: any) { + let title = null; + + if ( + prosemirrorState?.content?.length > 0 && + prosemirrorState.content[0].type === 'heading' && + prosemirrorState.content[0].attrs?.level === 1 + ) { + title = prosemirrorState.content[0].content[0].text; + + // remove h1 header node from state + prosemirrorState.content.shift(); + } + + return { title, prosemirrorJson: prosemirrorState }; + } + + async getNewPagePosition(spaceId: string): Promise { + const lastPage = await this.db + .selectFrom('pages') + .select(['id', 'position']) + .where('spaceId', '=', spaceId) + .orderBy('position', 'desc') + .limit(1) + .where('parentPageId', 'is', null) + .executeTakeFirst(); + + if (lastPage) { + return generateJitteredKeyBetween(lastPage.position, null); + } else { + return generateJitteredKeyBetween(null, null); + } + } +} diff --git a/apps/server/src/integrations/import/utils/html.utils.ts b/apps/server/src/integrations/import/utils/html.utils.ts new file mode 100644 index 00000000..02c3d778 --- /dev/null +++ b/apps/server/src/integrations/import/utils/html.utils.ts @@ -0,0 +1,80 @@ +import { Window, DOMParser } from 'happy-dom'; + +function transformTaskList(html: string): string { + const window = new Window(); + const doc = new DOMParser(window).parseFromString(html, 'text/html'); + + const ulElements = doc.querySelectorAll('ul'); + ulElements.forEach((ul) => { + let isTaskList = false; + + const liElements = ul.querySelectorAll('li'); + liElements.forEach((li) => { + const checkbox = li.querySelector('input[type="checkbox"]'); + + if (checkbox) { + isTaskList = true; + // Add taskItem data type + li.setAttribute('data-type', 'taskItem'); + // Set data-checked attribute based on the checkbox state + // @ts-ignore + li.setAttribute('data-checked', checkbox.checked ? 'true' : 'false'); + // Remove the checkbox from the li + checkbox.remove(); + + // Move the content of

    out of the

    and remove

    + const pElements = li.querySelectorAll('p'); + pElements.forEach((p) => { + // Append the content of the

    element to its parent (the

  1. element) + while (p.firstChild) { + li.appendChild(p.firstChild); + } + // Remove the now empty

    element + p.remove(); + }); + } + }); + + // If any

  2. contains a checkbox, mark the
      as a task list + if (isTaskList) { + ul.setAttribute('data-type', 'taskList'); + } + }); + + return doc.body.innerHTML; +} + +function transformCallouts(html: string): string { + const window = new Window(); + const doc = new DOMParser(window).parseFromString(html, 'text/html'); + + const calloutRegex = /:::(\w+)\s*([\s\S]*?)\s*:::/g; + + const createCalloutDiv = (type: string, content: string): HTMLElement => { + const div = doc.createElement('div'); + div.setAttribute('data-type', 'callout'); + div.setAttribute('data-callout-type', type); + const p = doc.createElement('p'); + p.textContent = content.trim(); + div.appendChild(p); + return div as unknown as HTMLElement; + }; + + const pElements = doc.querySelectorAll('p'); + + pElements.forEach((p) => { + if (calloutRegex.test(p.innerHTML) && !p.closest('ul, ol')) { + calloutRegex.lastIndex = 0; + const [, type, content] = calloutRegex.exec(p.innerHTML) || []; + const calloutDiv = createCalloutDiv(type, content); + // @ts-ignore + p.replaceWith(calloutDiv); + } + }); + + return doc.body.innerHTML; +} + +export function transformHTML(html: string): string { + return transformTaskList(transformCallouts(html)); +} diff --git a/package.json b/package.json index c8431c6d..18ca0fdf 100644 --- a/package.json +++ b/package.json @@ -24,40 +24,39 @@ "@joplin/turndown": "^4.0.74", "@joplin/turndown-plugin-gfm": "^1.0.56", "@sindresorhus/slugify": "^2.2.1", - "@tiptap/core": "^2.4.0", - "@tiptap/extension-code-block": "^2.4.0", - "@tiptap/extension-collaboration": "^2.4.0", - "@tiptap/extension-collaboration-cursor": "^2.4.0", - "@tiptap/extension-color": "^2.4.0", - "@tiptap/extension-document": "^2.4.0", - "@tiptap/extension-heading": "^2.4.0", - "@tiptap/extension-highlight": "^2.4.0", - "@tiptap/extension-history": "^2.4.0", - "@tiptap/extension-image": "^2.4.0", - "@tiptap/extension-link": "^2.4.0", - "@tiptap/extension-list-item": "^2.4.0", - "@tiptap/extension-list-keymap": "^2.4.0", - "@tiptap/extension-mention": "^2.4.0", - "@tiptap/extension-placeholder": "^2.4.0", - "@tiptap/extension-subscript": "^2.4.0", - "@tiptap/extension-superscript": "^2.4.0", - "@tiptap/extension-table": "^2.4.0", - "@tiptap/extension-table-cell": "^2.4.0", - "@tiptap/extension-table-header": "^2.4.0", - "@tiptap/extension-table-row": "^2.4.0", - "@tiptap/extension-task-item": "^2.4.0", - "@tiptap/extension-task-list": "^2.4.0", - "@tiptap/extension-text": "^2.4.0", - "@tiptap/extension-text-align": "^2.4.0", - "@tiptap/extension-text-style": "^2.4.0", - "@tiptap/extension-typography": "^2.4.0", - "@tiptap/extension-underline": "^2.4.0", - "@tiptap/extension-youtube": "^2.4.0", - "@tiptap/html": "^2.4.0", - "@tiptap/pm": "^2.4.0", - "@tiptap/react": "^2.4.0", - "@tiptap/starter-kit": "^2.4.0", - "@tiptap/suggestion": "^2.4.0", + "@tiptap/core": "^2.5.4", + "@tiptap/extension-code-block": "^2.5.4", + "@tiptap/extension-collaboration": "^2.5.4", + "@tiptap/extension-collaboration-cursor": "^2.5.4", + "@tiptap/extension-color": "^2.5.4", + "@tiptap/extension-document": "^2.5.4", + "@tiptap/extension-heading": "^2.5.4", + "@tiptap/extension-highlight": "^2.5.4", + "@tiptap/extension-history": "^2.5.4", + "@tiptap/extension-image": "^2.5.4", + "@tiptap/extension-link": "^2.5.4", + "@tiptap/extension-list-item": "^2.5.4", + "@tiptap/extension-list-keymap": "^2.5.4", + "@tiptap/extension-mention": "^2.5.4", + "@tiptap/extension-placeholder": "^2.5.4", + "@tiptap/extension-subscript": "^2.5.4", + "@tiptap/extension-superscript": "^2.5.4", + "@tiptap/extension-table": "^2.5.4", + "@tiptap/extension-table-cell": "^2.5.4", + "@tiptap/extension-table-header": "^2.5.4", + "@tiptap/extension-table-row": "^2.5.4", + "@tiptap/extension-task-item": "^2.5.4", + "@tiptap/extension-task-list": "^2.5.4", + "@tiptap/extension-text": "^2.5.4", + "@tiptap/extension-text-align": "^2.5.4", + "@tiptap/extension-text-style": "^2.5.4", + "@tiptap/extension-typography": "^2.5.4", + "@tiptap/extension-underline": "^2.5.4", + "@tiptap/extension-youtube": "^2.5.4", + "@tiptap/pm": "^2.5.4", + "@tiptap/react": "^2.5.4", + "@tiptap/starter-kit": "^2.5.4", + "@tiptap/suggestion": "^2.5.4", "cross-env": "^7.0.3", "fractional-indexing-jittered": "^0.9.1", "ioredis": "^5.4.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 43b78ee3..25ee7b0a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,7 +22,7 @@ importers: version: 2.13.5(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18) '@hocuspocus/transformer': specifier: ^2.13.5 - version: 2.13.5(@tiptap/pm@2.4.0)(y-prosemirror@1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18))(yjs@13.6.18) + version: 2.13.5(@tiptap/pm@2.5.4)(y-prosemirror@1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18))(yjs@13.6.18) '@joplin/turndown': specifier: ^4.0.74 version: 4.0.74 @@ -33,107 +33,104 @@ importers: specifier: ^2.2.1 version: 2.2.1 '@tiptap/core': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/pm@2.5.4) '@tiptap/extension-code-block': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) '@tiptap/extension-collaboration': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)(y-prosemirror@1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)(y-prosemirror@1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18)) '@tiptap/extension-collaboration-cursor': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(y-prosemirror@1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(y-prosemirror@1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18)) '@tiptap/extension-color': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/extension-text-style@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/extension-text-style@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))) '@tiptap/extension-document': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-heading': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-highlight': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-history': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) '@tiptap/extension-image': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-link': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) '@tiptap/extension-list-item': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-list-keymap': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-mention': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)(@tiptap/suggestion@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)(@tiptap/suggestion@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)) '@tiptap/extension-placeholder': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) '@tiptap/extension-subscript': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-superscript': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-table': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) '@tiptap/extension-table-cell': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-table-header': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-table-row': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-task-item': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) '@tiptap/extension-task-list': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-text': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-text-align': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-text-style': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-typography': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-underline': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/extension-youtube': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/html': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) '@tiptap/pm': - specifier: ^2.4.0 - version: 2.4.0 + specifier: ^2.5.4 + version: 2.5.4 '@tiptap/react': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tiptap/starter-kit': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/pm@2.5.4) '@tiptap/suggestion': - specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + specifier: ^2.5.4 + version: 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -209,7 +206,7 @@ importers: version: 5.48.0(react@18.3.1) '@tiptap/extension-code-block-lowlight': specifier: ^2.4.0 - version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/extension-code-block@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + version: 2.4.0(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/extension-code-block@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) axios: specifier: ^1.7.2 version: 1.7.2 @@ -270,6 +267,9 @@ importers: tippy.js: specifier: ^6.3.7 version: 6.3.7 + tiptap-extension-global-drag-handle: + specifier: ^0.1.10 + version: 0.1.10 zod: specifier: ^3.23.8 version: 3.23.8 @@ -277,6 +277,9 @@ importers: '@tanstack/eslint-plugin-query': specifier: ^5.47.0 version: 5.47.0(eslint@9.5.0)(typescript@5.5.2) + '@types/file-saver': + specifier: ^2.0.7 + version: 2.0.7 '@types/js-cookie': specifier: ^3.0.6 version: 3.0.6 @@ -424,12 +427,18 @@ importers: fs-extra: specifier: ^11.2.0 version: 11.2.0 + happy-dom: + specifier: ^14.12.3 + version: 14.12.3 kysely: specifier: ^0.27.3 version: 0.27.3 kysely-migration-cli: specifier: ^0.4.2 version: 0.4.2 + marked: + specifier: ^13.0.2 + version: 13.0.2 mime-types: specifier: ^2.1.35 version: 2.1.35 @@ -3038,12 +3047,6 @@ packages: '@remirror/core-constants@2.0.2': resolution: {integrity: sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==} - '@remirror/core-helpers@3.0.0': - resolution: {integrity: sha512-tusEgQJIqg4qKj6HSBUFcyRnWnziw3neh4T9wOmsPGHFC3w9kl5KSrDb9UAgE8uX6y32FnS7vJ955mWOl3n50A==} - - '@remirror/types@1.0.1': - resolution: {integrity: sha512-VlZQxwGnt1jtQ18D6JqdIF+uFZo525WEqrfp9BOc3COPpK4+AWCgdnAWL+ho6imWcoINlGjR/+3b6y5C1vBVEA==} - '@remix-run/router@1.17.0': resolution: {integrity: sha512-2D6XaHEVvkCn682XBnipbJjgZUU7xjLtA4dGJRBVUKpEaDYOZMENZoZjAOSb7qirxt5RupjzZxz4fK2FO+EFPw==} engines: {node: '>=14.0.0'} @@ -3538,31 +3541,31 @@ packages: peerDependencies: react: ^18.0.0 - '@tiptap/core@2.4.0': - resolution: {integrity: sha512-YJSahk8pkxpCs8SflCZfTnJpE7IPyUWIylfgXM2DefjRQa5DZ+c6sNY0s/zbxKYFQ6AuHVX40r9pCfcqHChGxQ==} + '@tiptap/core@2.5.4': + resolution: {integrity: sha512-Zs/hShr4+W02+0nOlpmr5cS2YjDRLqd+XMt+jsiQH0QNr3s1Lc82pfF6C3CjgLEZtdUzImZrW2ABtLlpvbogaA==} peerDependencies: - '@tiptap/pm': ^2.0.0 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-blockquote@2.4.0': - resolution: {integrity: sha512-nJJy4KsPgQqWTTDOWzFRdjCfG5+QExfZj44dulgDFNh+E66xhamnbM70PklllXJgEcge7xmT5oKM0gKls5XgFw==} + '@tiptap/extension-blockquote@2.5.4': + resolution: {integrity: sha512-UqeJunZM3IiCQGZE0X5YNUOWYkuIieqrwPgOEghAIjnhDcQizQcouRQ5R7cwwv/scNr2JvZHncOTLrALV3Janw==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-bold@2.4.0': - resolution: {integrity: sha512-csnW6hMDEHoRfxcPRLSqeJn+j35Lgtt1YRiOwn7DlS66sAECGRuoGfCvQSPij0TCDp4VCR9if5Sf8EymhnQumQ==} + '@tiptap/extension-bold@2.5.4': + resolution: {integrity: sha512-H5sjqloFMjq7VOSfE+U4T7dqGoflOiF6RW6/gZm/U6KYeHG2/bG0ktq7mWAnnhbiKiy7gUcxyJCV+ILdGX9C5g==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-bubble-menu@2.4.0': - resolution: {integrity: sha512-s99HmttUtpW3rScWq8rqk4+CGCwergNZbHLTkF6Rp6TSboMwfp+rwL5Q/JkcAG9KGLso1vGyXKbt1xHOvm8zMw==} + '@tiptap/extension-bubble-menu@2.5.4': + resolution: {integrity: sha512-GHwef912K1yd75pp9JGDnKSp1DvdOHH8BcHQv0no+a3q2ePFPYcgaSwVRR59jHRX9WzdVfoLcqDSAeoNGOrISw==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-bullet-list@2.4.0': - resolution: {integrity: sha512-9S5DLIvFRBoExvmZ+/ErpTvs4Wf1yOEs8WXlKYUCcZssK7brTFj99XDwpHFA29HKDwma5q9UHhr2OB2o0JYAdw==} + '@tiptap/extension-bullet-list@2.5.4': + resolution: {integrity: sha512-aAfpALeD6OxymkbtrzDqbgkAkzVVHudxOb8GsK1N6m42nFL7Q9JzHJ5/8KzB+xi25CcIbS+HmXJkRIQJXgNbSA==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 '@tiptap/extension-code-block-lowlight@2.4.0': resolution: {integrity: sha512-j0SdFq66A97Cn7bQOMqFYBaYsmOltZZ6o4uDZH6fdTvEFbfXTdtTYs2awsNSbW+w/DtivKZCvAX1FRLR3/g/5A==} @@ -3571,237 +3574,231 @@ packages: '@tiptap/extension-code-block': ^2.0.0 '@tiptap/pm': ^2.0.0 - '@tiptap/extension-code-block@2.4.0': - resolution: {integrity: sha512-QWGdv1D56TBGbbJSj2cIiXGJEKguPiAl9ONzJ/Ql1ZksiQsYwx0YHriXX6TOC//T4VIf6NSClHEtwtxWBQ/Csg==} + '@tiptap/extension-code-block@2.5.4': + resolution: {integrity: sha512-lZRz44ACSL0IC4syWkNsNSe90sZuLig0yidfV9rs2muSCLoS3PRcCIJv4GjdBHouangxxBZqzIqWgPBqe6pqwA==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-code@2.4.0': - resolution: {integrity: sha512-wjhBukuiyJMq4cTcK3RBTzUPV24k5n1eEPlpmzku6ThwwkMdwynnMGMAmSF3fErh3AOyOUPoTTjgMYN2d10SJA==} + '@tiptap/extension-code@2.5.4': + resolution: {integrity: sha512-PCP0VcWR0Jsj3rum3czp1jateR+kv1iuB9E+TieGLN4vFqhoiUwSv2UAuhvD8x66MGCYLA3btgnmPov1w/iNmA==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-collaboration-cursor@2.4.0': - resolution: {integrity: sha512-BTVy9FCTGdHxYieJ4lteVLrRY5qAPQyfunhMwakVf1NT3iU9quE6CaeaIwt6wEDJPMPPKzOHg1/ltSz9nIDe4A==} + '@tiptap/extension-collaboration-cursor@2.5.4': + resolution: {integrity: sha512-M32JChnP5RVdr1n+Tf0gF9bxx0gHvc0uV4SDxCMN3uaNH5YpcofmvKElS60rDGVfCdRTId/aj7P3AtwrvRlYdQ==} peerDependencies: - '@tiptap/core': ^2.0.0 - y-prosemirror: ^1.2.5 + '@tiptap/core': ^2.5.4 + y-prosemirror: ^1.2.6 - '@tiptap/extension-collaboration@2.4.0': - resolution: {integrity: sha512-achU+GU9tqxn3zsU61CbwWrCausf0U23MJIpo8vnywOIx6E955by6okHEHoUazLIGVFXVc5DBzBP7bf+Snzk0Q==} + '@tiptap/extension-collaboration@2.5.4': + resolution: {integrity: sha512-CpQdbr7XpQaVqRFo/A1DchrQZMDb8vrkP+FcUIgvHN0b8hwKDmXRAHDtuk8yTTEatW1EqpX8lx8UxaUTcDNbIg==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 - y-prosemirror: ^1.2.5 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 + y-prosemirror: ^1.2.6 - '@tiptap/extension-color@2.4.0': - resolution: {integrity: sha512-aVuqGtzTIZO93niADdu+Hx8g03X0pS7wjrJcCcYkkDEbC/siC03zlxKZIYBW1Jiabe99Z7/s2KdtLoK6DW2A2g==} + '@tiptap/extension-color@2.5.4': + resolution: {integrity: sha512-f4ltxa4Y9NzD6+xFkjVo925+OltZbtYEuwUSXQKU4NJyjiMBMUOzW+mCgQM2TB5V36VP2ttIvdQ+W99yazJqUg==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/extension-text-style': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/extension-text-style': ^2.5.4 - '@tiptap/extension-document@2.4.0': - resolution: {integrity: sha512-3jRodQJZDGbXlRPERaloS+IERg/VwzpC1IO6YSJR9jVIsBO6xC29P3cKTQlg1XO7p6ZH/0ksK73VC5BzzTwoHg==} + '@tiptap/extension-document@2.5.4': + resolution: {integrity: sha512-4RDrhASxCTOZETYhIhEW1TfZqx3Tm+LQxouvBMFyODmT1PSgsg5Xz1FYpDPr+J49bGAK0Pr9ae0XcGW011L3sA==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-dropcursor@2.4.0': - resolution: {integrity: sha512-c46HoG2PEEpSZv5rmS5UX/lJ6/kP1iVO0Ax+6JrNfLEIiDULUoi20NqdjolEa38La2VhWvs+o20OviiTOKEE9g==} + '@tiptap/extension-dropcursor@2.5.4': + resolution: {integrity: sha512-jzSnuuYhlc0SsHvAteWkE9TJy3eRwkxQs4MO2JxALOzJECN4G82nlX8vciihBD6xf7lVgVSBACejK9+rsTHqCg==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-floating-menu@2.4.0': - resolution: {integrity: sha512-vLb9v+htbHhXyty0oaXjT3VC8St4xuGSHWUB9GuAJAQ+NajIO6rBPbLUmm9qM0Eh2zico5mpSD1Qtn5FM6xYzg==} + '@tiptap/extension-floating-menu@2.5.4': + resolution: {integrity: sha512-EqD4rgi3UhnDcV3H1+ndAS4Ue2zpsU7hFKoevOIV6GS7xVnWN70AGt6swH24QzuHKKISFtWoLpKjrwRORNIxuA==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-gapcursor@2.4.0': - resolution: {integrity: sha512-F4y/0J2lseohkFUw9P2OpKhrJ6dHz69ZScABUvcHxjznJLd6+0Zt7014Lw5PA8/m2d/w0fX8LZQ88pZr4quZPQ==} + '@tiptap/extension-gapcursor@2.5.4': + resolution: {integrity: sha512-wzTh1piODZBS0wmuDgPjjg8PQwclYa5LssnxDIo9pDSnt4l3AfHSAJIJSGIfgt96KnzF1wqRTRpe08qNa1n7/g==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-hard-break@2.4.0': - resolution: {integrity: sha512-3+Z6zxevtHza5IsDBZ4lZqvNR3Kvdqwxq/QKCKu9UhJN1DUjsg/l1Jn2NilSQ3NYkBYh2yJjT8CMo9pQIu776g==} + '@tiptap/extension-hard-break@2.5.4': + resolution: {integrity: sha512-nLn6HP9tqgdGGwbMORXVtcY30DTGctYFaWADRthvBjVgacYSeKlhUcsSu3YgaxtbxZp6BhfRvD2kKrxyQsSjnQ==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-heading@2.4.0': - resolution: {integrity: sha512-fYkyP/VMo7YHO76YVrUjd95Qeo0cubWn/Spavmwm1gLTHH/q7xMtbod2Z/F0wd6QHnc7+HGhO7XAjjKWDjldaw==} + '@tiptap/extension-heading@2.5.4': + resolution: {integrity: sha512-DuAB58/e7eho1rkyad0Z/SjW+EB+H2hRqHlswEeZZYhBTjzey5UmBwkMWTGC/SQiRisx1xYQYTd8T0fiABi5hw==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-highlight@2.4.0': - resolution: {integrity: sha512-p2I/CaMrs6hzpj/dSw6UNobOWTV38yTjPK+B4ShJQ7IN2u/C82KOTOeFfJoFd9KykmpVOVW3w3nKG3ad0HXPuQ==} + '@tiptap/extension-highlight@2.5.4': + resolution: {integrity: sha512-TSYnFBluZu1YQdTCyXl2wuxFuhFUYFzbaV0f1wq2P2Nc8U2OiiuaNz+QggHw5Hf3ILzkRxQCUQnq97Q/5smMwQ==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-history@2.4.0': - resolution: {integrity: sha512-gr5qsKAXEVGr1Lyk1598F7drTaEtAxqZiuuSwTCzZzkiwgEQsWMWTWc9F8FlneCEaqe1aIYg6WKWlmYPaFwr0w==} + '@tiptap/extension-history@2.5.4': + resolution: {integrity: sha512-WB1fZYGIlpahAD6Ba+mj9vIb1tk8S3TsADXDFKxLVpZWZPQ+B7duGJP7g/vRH2XAXEs836JzC2oxjKeaop3k7A==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-horizontal-rule@2.4.0': - resolution: {integrity: sha512-yDgxy+YxagcEsBbdWvbQiXYxsv3noS1VTuGwc9G7ZK9xPmBHJ5y0agOkB7HskwsZvJHoaSqNRsh7oZTkf0VR3g==} + '@tiptap/extension-horizontal-rule@2.5.4': + resolution: {integrity: sha512-uXLDe/iyzQbyfDkJ8kE5XaAkY3EOcbTFLjbueqGlkbWtjJgy+3LysGvh8fQj8PAOaIBMaFRFhTq7GMbW2ebRog==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-image@2.4.0': - resolution: {integrity: sha512-NIVhRPMO/ONo8OywEd+8zh0Q6Q7EbFHtBxVsvfOKj9KtZkaXQfUO4MzONTyptkvAchTpj9pIzeaEY5fyU87gFA==} + '@tiptap/extension-image@2.5.4': + resolution: {integrity: sha512-4ySSP7iPsbbo1SlPJYj546TKettuO6FGY5MQKxH8AGnZWyQGZYl89GpU1iGFAaeHq4dKUemM5D3ikgSynEQLow==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-italic@2.4.0': - resolution: {integrity: sha512-aaW/L9q+KNHHK+X73MPloHeIsT191n3VLd3xm6uUcFDnUNvzYJ/q65/1ZicdtCaOLvTutxdrEvhbkrVREX6a8g==} + '@tiptap/extension-italic@2.5.4': + resolution: {integrity: sha512-TAhtl/fNBgv1elzF3HWES8uwVdpKBSYrq1e6yeYfj74mQn//3ksvdhWQrLzc1e+zcoHbk1PeOp/5ODdPuZ6tkg==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-link@2.4.0': - resolution: {integrity: sha512-r3PjT0bjSKAorHAEBPA0icSMOlqALbxVlWU9vAc+Q3ndzt7ht0CTPNewzFF9kjzARABVt1cblXP/2+c0qGzcsg==} + '@tiptap/extension-link@2.5.4': + resolution: {integrity: sha512-xTB/+T6SHHCXInJni8WdqOfF40a/MiFUf5OoWW9cPrApx3I7TzJ9j8/WDshM0BOnDDw80w1bl9F2zkUQjC0Y2A==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-list-item@2.4.0': - resolution: {integrity: sha512-reUVUx+2cI2NIAqMZhlJ9uK/+zvRzm1GTmlU2Wvzwc7AwLN4yemj6mBDsmBLEXAKPvitfLh6EkeHaruOGymQtg==} + '@tiptap/extension-list-item@2.5.4': + resolution: {integrity: sha512-bPxUCFt9HnAfoaZQgwqCfRAZ6L3QlYhIRDDbOvZag7IxCdQuZmeY4k5OZfQIGijNDTag7CN9cdL4fl9rnm6/sQ==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-list-keymap@2.4.0': - resolution: {integrity: sha512-xWhBvJJW4gpDU0EJ6LjQQrI6ZXE1+0M2i5yJhPCZ0z88z+Ul3+GFy86r7Joh6Ugt3ATsGyZ4RiMXgFCL95Nhjw==} + '@tiptap/extension-list-keymap@2.5.4': + resolution: {integrity: sha512-nuoPF5giGlFQaho1188WcpO8AdYGgTxckILIe39MeVgGWxWDF081nhCOtFgt/KLghr3ndndVaY6wAqKFUrTXtg==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-mention@2.4.0': - resolution: {integrity: sha512-7BqCNfqF1Mv9IrtdlHADwXMFo968UNmthf/TepVXC7EX2Ke6/Y4vvxmpYVNZc55FdswFwpVyZ2VeXBj3AC2JcA==} + '@tiptap/extension-mention@2.5.4': + resolution: {integrity: sha512-U5Kqjhs7FraJzopZydy14/v0+X6unmfYYt42QHhVeSEdZ8y7QtyFigJktJUBzE12CpwGkyh8e3xI9Ozi7lFb0w==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 - '@tiptap/suggestion': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 + '@tiptap/suggestion': ^2.5.4 - '@tiptap/extension-ordered-list@2.4.0': - resolution: {integrity: sha512-Zo0c9M0aowv+2+jExZiAvhCB83GZMjZsxywmuOrdUbq5EGYKb7q8hDyN3hkrktVHr9UPXdPAYTmLAHztTOHYRA==} + '@tiptap/extension-ordered-list@2.5.4': + resolution: {integrity: sha512-cl3cTJitY6yDUmxqgjDUtDWCyX1VVsZNJ6i9yiPeARcxvzFc81KmUJxTGl8WPT5TjqmM+TleRkZjsxgvXX57+Q==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-paragraph@2.4.0': - resolution: {integrity: sha512-+yse0Ow67IRwcACd9K/CzBcxlpr9OFnmf0x9uqpaWt1eHck1sJnti6jrw5DVVkyEBHDh/cnkkV49gvctT/NyCw==} + '@tiptap/extension-paragraph@2.5.4': + resolution: {integrity: sha512-pC1YIkkRPXoU0eDrhfAf8ZrFJQzvw2ftP6KRhLnnSw/Ot1DOjT1r95l7zsFefS9oCDMT/L4HghTAiPZ4rcpPbg==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-placeholder@2.4.0': - resolution: {integrity: sha512-SmWOjgWpmhFt0BPOnL65abCUH0wS5yksUJgtANn5bQoHF4HFSsyl7ETRmgf0ykxdjc7tzOg31FfpWVH4wzKSYg==} + '@tiptap/extension-placeholder@2.5.4': + resolution: {integrity: sha512-mcj4j2Z/L1H5dzWHbbWChuAdJK9F2p06fcjqL4iyJtVx38QQFzCdVmGaTAim8CLp/EynbAOYJ5gk9w2PTdv7+w==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-strike@2.4.0': - resolution: {integrity: sha512-pE1uN/fQPOMS3i+zxPYMmPmI3keubnR6ivwM+KdXWOMnBiHl9N4cNpJgq1n2eUUGKLurC2qrQHpnVyGAwBS6Vg==} + '@tiptap/extension-strike@2.5.4': + resolution: {integrity: sha512-OSN6ePbCwEhi3hYZZOPow/P9Ym2Kv3NhVbUvasjZCiqQuk8TGc33xirPWl9DTjb/BLfL66TtJ2tKUEVOKl5dKg==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-subscript@2.4.0': - resolution: {integrity: sha512-exLSmSFmYN6AVww5oyroFL3KCwstT0U+ojvVhRD6DQ+Hc81d++lBKANfsWAcllXjZVGPWeMNdE66bV7oFCtQcQ==} + '@tiptap/extension-subscript@2.5.4': + resolution: {integrity: sha512-w4jXU6mSktk8x+c2Jfcmb+CD5gGqA7YRtgdEDdlDiwn8HVVhzSTJIEvfyxWkvVBMIybs+36lgdLz0Sr9EhIxUw==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-superscript@2.4.0': - resolution: {integrity: sha512-s+GsbbERNQCn/hyaw5/82y3wHQ7o5byc/eFAKYo1p3p5eESlDaHY/xVYPt3CGOX2TJWZalgSFEFqBVdTSI8mUQ==} + '@tiptap/extension-superscript@2.5.4': + resolution: {integrity: sha512-e2xwXV4rBdR4kkc08t2oxEEUDloHoN8ujti2hvwZo+/reaVMnLNOhNUnhXXsHfjqmDki15edJrFesc47tALiHw==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-table-cell@2.4.0': - resolution: {integrity: sha512-zylResMWLvV17Z6+GEDjvvl+YpJqJhNMyJsZPZNx/72OcNCDN3p2d6RGFwhpnCpdzZDD6LGaIgWaTj9oeg53SA==} + '@tiptap/extension-table-cell@2.5.4': + resolution: {integrity: sha512-ntiexoIOchSQEtyxJ7RfRcX8SIMKoNl/RZT7e7q8luh6O8BAg8ijbjOnPcwaSJhcQIR+fGHqZCqu7Qud2Usp/g==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-table-header@2.4.0': - resolution: {integrity: sha512-FZCOyJHSFsMTCfBh49J1DlwgpUIM5Ivpr57Za8FVvUkk8RKUIOKpNsZqxE+Wrw+2Bvy5H4X7Azb588x0NDqfOQ==} + '@tiptap/extension-table-header@2.5.4': + resolution: {integrity: sha512-0JV7yxf7UQXcnNBeh0ruJzpgxbPWtJjQ5CB7R/2nGGJtK5Zd4qbBSvPwZb90rrzbfGG6gPyH/840nBOV9Hihqw==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-table-row@2.4.0': - resolution: {integrity: sha512-K4FDI4YzyLWZbhIZYYL15uqs6M3QsPZGTpTdkSaxcKMLholcskDSHhJmySxnrjI0+JNAtyIiqlWBfA1/9Zyhng==} + '@tiptap/extension-table-row@2.5.4': + resolution: {integrity: sha512-syE0HO+1nZ6cZP+A1BnOfyBLY5/fSzlqXId1SzDxp3w2RfUldXfrV9ltyyEE6wxruxCgI+V5J3wV3ObSXy9PMA==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-table@2.4.0': - resolution: {integrity: sha512-ceIUnPSqVCb+qC0XZSgApoG3dL3MRvWrGl1nIMxEqPgMsD/MP6MsYV1Lx/GmtdUlEEsV1624cGTBiRzeCuWkZA==} + '@tiptap/extension-table@2.5.4': + resolution: {integrity: sha512-EvK3XQmbuje0re8xCXuGcPO1NgnRh1MYUe2zi4++rPNDN2nTzCvJI1QdYfA9DYMdklnpvygnXCJhgvx1rB/26Q==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-task-item@2.4.0': - resolution: {integrity: sha512-x40vdHnmDiBbA2pjWR/92wVGb6jT13Nk2AhRUI/oP/r4ZGKpTypoB7heDnvLBgH0Y5a51dFqU+G1SFFL30u5uA==} + '@tiptap/extension-task-item@2.5.4': + resolution: {integrity: sha512-zl+L9M3kkIgXYhq3n++WJPfSOBlNA4zxPCo3ZfG/IjmLXOfxYQfgt2mbX9akr6L1XiiyGq8VAMDMvXgW0/21NQ==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 - '@tiptap/extension-task-list@2.4.0': - resolution: {integrity: sha512-vmUB3wEJU81QbiHUygBlselQW8YIW8/85UTwANvWx8+KEWyM7EUF4utcm5R2UobIprIcWb4hyVkvW/5iou25gg==} + '@tiptap/extension-task-list@2.5.4': + resolution: {integrity: sha512-066MGRNRtIfSHEoxeqYQs9rl7pbaxhS09cCfR1FaJVfS7ZMV/B1C3GFdJEJbrgdv6rj2TS/zsnaaUgKFPlhvEQ==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-text-align@2.4.0': - resolution: {integrity: sha512-wpRe2OiLXTK4kTy4RZEPnPjFbK16kYHPAx1552hLXrOdyxbS7Sdbo+w4x7aGLLZZqZdudCFfkdtnqrc7PDVZdA==} + '@tiptap/extension-text-align@2.5.4': + resolution: {integrity: sha512-hQT7wPVISw7fgMTT0XfK6uk3T2qLKpeYWOUBO1ENEdim6HQmFTOIgNyAdVcCipaedQSlD72ysfRXq2S1mzWzEw==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-text-style@2.4.0': - resolution: {integrity: sha512-H0uPWeZ4sXz3o836TDWnpd38qClqzEM2d6QJ9TK+cQ1vE5Gp8wQ5W4fwUV1KAHzpJKE/15+BXBjLyVYQdmXDaQ==} + '@tiptap/extension-text-style@2.5.4': + resolution: {integrity: sha512-OwQ6rQrwVSCTicxJJ67C5Z+LQjZp9HyZDeEcrQgPsv/gtk6H69qo1jShHAdmYn4ck40CkuNyN6VKczd9VZf0+g==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-text@2.4.0': - resolution: {integrity: sha512-LV0bvE+VowE8IgLca7pM8ll7quNH+AgEHRbSrsI3SHKDCYB9gTHMjWaAkgkUVaO1u0IfCrjnCLym/PqFKa+vvg==} + '@tiptap/extension-text@2.5.4': + resolution: {integrity: sha512-+3x/hYqhmCYbvedCcQzQHFtZ5MAcMOlKuczomZtygf8AfDfuQVrG1m4GoJyNzJdqxjN80/xq4e2vDVvqQxYTCw==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-typography@2.4.0': - resolution: {integrity: sha512-RuGenfdPA6ggu5IVLdcIdhGCdRlwSvWp0lETySM3PILE6fxCrxTD54m3pxpY0Q1cg+F71YDUHdSmSipQTwQnsQ==} + '@tiptap/extension-typography@2.5.4': + resolution: {integrity: sha512-LXctwoKdmWw9geXngQWGHcwEHIYLJ5v7GX3GuudN+oHhSV2MTGUTYZ2qv/RLIR9kvB0vcV9vTF98YJxEnjU5Fw==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-underline@2.4.0': - resolution: {integrity: sha512-guWojb7JxUwLz4OKzwNExJwOkhZjgw/ttkXCMBT0PVe55k998MMYe1nvN0m2SeTW9IxurEPtScH4kYJ0XuSm8Q==} + '@tiptap/extension-underline@2.5.4': + resolution: {integrity: sha512-o8T3oWbniA3rLo6LkslPRF8pwdjsaHXJCeK4KmKeCyYhTpMfjypT3uptd+VSSJ4iQkaiFInKeIUOBqqEQ9cADw==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/extension-youtube@2.4.0': - resolution: {integrity: sha512-Ew6Oik9DaqP0xgQSUIWwozqeToJVOY4nqjRoKExGRuLdzgZeS+SmEA22ITBMcnZSJj8XBMgGBLcCWi+A7x1KAg==} + '@tiptap/extension-youtube@2.5.4': + resolution: {integrity: sha512-iHcvXOA32MZsVJTT7mvZ1CWKUo2quQMQXfBniizLm0lUG1ftSioqnDuXy4kEjeCBR2cnZr3yph6tbG/pF0RcHg==} peerDependencies: - '@tiptap/core': ^2.0.0 + '@tiptap/core': ^2.5.4 - '@tiptap/html@2.4.0': - resolution: {integrity: sha512-iM0sa6t0Hb5GTXnjdKvMDtD3KZgA4Mwx3QADeqfR10EjfPNlkh/BHU83oIhss/2JVRBXiUUDnNxW9cfpHX37/g==} + '@tiptap/pm@2.5.4': + resolution: {integrity: sha512-oFIsuniptdUXn93x4aM2sVN3hYKo9Fj55zAkYrWhwxFYUYcPxd5ibra2we+wRK5TaiPu098wpC+yMSTZ/KKMpA==} + + '@tiptap/react@2.5.4': + resolution: {integrity: sha512-2HPHt2lEK6Z4jOV3HHVTee8hD4NS6eEj0zRZWSFjt1zDzXtFqX8VIv7qC1iDYsQgyiFnFnOucOQtAlDewBb23A==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 - - '@tiptap/pm@2.4.0': - resolution: {integrity: sha512-B1HMEqGS4MzIVXnpgRZDLm30mxDWj51LkBT/if1XD+hj5gm8B9Q0c84bhvODX6KIs+c6z+zsY9VkVu8w9Yfgxg==} - - '@tiptap/react@2.4.0': - resolution: {integrity: sha512-baxnIr6Dy+5iGagOEIKFeHzdl1ZRa6Cg+SJ3GDL/BVLpO6KiCM3Mm5ymB726UKP1w7icrBiQD2fGY3Bx8KaiSA==} - peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - '@tiptap/starter-kit@2.4.0': - resolution: {integrity: sha512-DYYzMZdTEnRn9oZhKOeRCcB+TjhNz5icLlvJKoHoOGL9kCbuUyEf8WRR2OSPckI0+KUIPJL3oHRqO4SqSdTjfg==} + '@tiptap/starter-kit@2.5.4': + resolution: {integrity: sha512-IYnSETtBUSsy+Ece4kfVyzew+zyj7W9rP2Ronx0CbjeWQarfCAGxjuZ6uGLPB+tC5ZuMVt68Gyqb2y8GFes2Yw==} - '@tiptap/suggestion@2.4.0': - resolution: {integrity: sha512-6dCkjbL8vIzcLWtS6RCBx0jlYPKf2Beuyq5nNLrDDZZuyJow5qJAY0eGu6Xomp9z0WDK/BYOxT4hHNoGMDkoAg==} + '@tiptap/suggestion@2.5.4': + resolution: {integrity: sha512-mf0gC237PFz5l/hFRIetZoXemLMUXtmTPRbHTgBzqkTfaiJhfWsZZ3VeQNh4hoQ5AGYxRHWb9+zgRNGsH4jAEw==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.4 + '@tiptap/pm': ^2.5.4 '@tsconfig/node10@1.0.9': resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} @@ -3869,6 +3866,9 @@ packages: '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + '@types/file-saver@2.0.7': + resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==} + '@types/fs-extra@11.0.4': resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} @@ -3929,12 +3929,6 @@ packages: '@types/nodemailer@6.4.15': resolution: {integrity: sha512-0EBJxawVNjPkng1zm2vopRctuWVCxk34JcIlRuXSf54habUWdz1FB7wHDqOqvDa8Mtpt0Q3LTXQkAs2LNyK5jQ==} - '@types/object.omit@3.0.3': - resolution: {integrity: sha512-xrq4bQTBGYY2cw+gV4PzoG2Lv3L0pjZ1uXStRRDQoATOYW1lCsFQHhQ+OkPhIcQoqLjAq7gYif7D14Qaa6Zbew==} - - '@types/object.pick@1.3.4': - resolution: {integrity: sha512-5PjwB0uP2XDp3nt5u5NJAG2DORHIRClPzWT/TTZhJ2Ekwe8M5bA9tvPdi9NO/n2uvu2/ictat8kgqvLfcIE1SA==} - '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -3983,12 +3977,12 @@ packages: '@types/supertest@6.0.2': resolution: {integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==} - '@types/throttle-debounce@2.1.0': - resolution: {integrity: sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==} - '@types/unist@3.0.2': resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + '@types/uuid@10.0.0': resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} @@ -4503,10 +4497,6 @@ packages: caniuse-lite@1.0.30001600: resolution: {integrity: sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==} - case-anything@2.1.13: - resolution: {integrity: sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==} - engines: {node: '>=12.13'} - chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -4767,10 +4757,6 @@ packages: css-to-mat@1.1.1: resolution: {integrity: sha512-kvpxFYZb27jRd2vium35G7q5XZ2WJ9rWjDUMNT36M3Hc41qCrLXFM5iEKMGXcrPsKfXEN+8l/riB4QzwwwiEyQ==} - css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} - engines: {node: '>= 6'} - cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -4783,9 +4769,6 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - dash-get@1.0.2: - resolution: {integrity: sha512-4FbVrHDwfOASx7uQVxeiCTo7ggSdYZbqs8lH+WU6ViypPlDbe9y6IP5VVUDQBv9DcnyaiPT5XT0UWHgJ64zLeQ==} - data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} @@ -5466,6 +5449,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + happy-dom@14.12.3: + resolution: {integrity: sha512-vsYlEs3E9gLwA1Hp+w3qzu+RUDFf4VTT8cyKqVICoZ2k7WM++Qyd2LwzyTi5bqMJFiIC/vNpTDYuxdreENRK/g==} + engines: {node: '>=16.0.0'} + has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -5636,10 +5623,6 @@ packages: engines: {node: '>=8'} hasBin: true - is-extendable@1.0.1: - resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} - engines: {node: '>=0.10.0'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -5668,10 +5651,6 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} - is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -5697,10 +5676,6 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - isomorphic.js@0.2.5: resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} @@ -6207,6 +6182,11 @@ packages: resolution: {integrity: sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==} hasBin: true + marked@13.0.2: + resolution: {integrity: sha512-J6CPjP8pS5sgrRqxVRvkCIkZ6MFdRIjDkwUwgJ9nL2fbmM6qGQeB2C16hi8Cc9BOzj6xXzy0jyi0iPIfnMHYzA==} + engines: {node: '>= 18'} + hasBin: true + marked@7.0.4: resolution: {integrity: sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ==} engines: {node: '>= 16'} @@ -6487,14 +6467,6 @@ packages: object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - object.omit@3.0.0: - resolution: {integrity: sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==} - engines: {node: '>=0.10.0'} - - object.pick@1.3.0: - resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} - engines: {node: '>=0.10.0'} - obliterator@2.0.4: resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} @@ -6875,48 +6847,48 @@ packages: prosemirror-gapcursor@1.3.2: resolution: {integrity: sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==} - prosemirror-history@1.3.2: - resolution: {integrity: sha512-/zm0XoU/N/+u7i5zepjmZAEnpvjDtzoPWW6VmKptcAnPadN/SStsBjMImdCEbb3seiNTpveziPTIrXQbHLtU1g==} + prosemirror-history@1.4.1: + resolution: {integrity: sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==} - prosemirror-inputrules@1.3.0: - resolution: {integrity: sha512-z1GRP2vhh5CihYMQYsJSa1cOwXb3SYxALXOIfAkX8nZserARtl9LiL+CEl+T+OFIsXc3mJIHKhbsmRzC0HDAXA==} + prosemirror-inputrules@1.4.0: + resolution: {integrity: sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==} prosemirror-keymap@1.2.2: resolution: {integrity: sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==} - prosemirror-markdown@1.12.0: - resolution: {integrity: sha512-6F5HS8Z0HDYiS2VQDZzfZP6A0s/I0gbkJy8NCzzDMtcsz3qrfqyroMMeoSjAmOhDITyon11NbXSzztfKi+frSQ==} + prosemirror-markdown@1.13.0: + resolution: {integrity: sha512-UziddX3ZYSYibgx8042hfGKmukq5Aljp2qoBiJRejD/8MH70siQNz5RB1TrdTPheqLMy4aCe4GYNF10/3lQS5g==} prosemirror-menu@1.2.4: resolution: {integrity: sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==} - prosemirror-model@1.19.4: - resolution: {integrity: sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ==} + prosemirror-model@1.22.1: + resolution: {integrity: sha512-gMrxal+F3higDFxCkBK5iQXckRVYvIu/3dopERJ6b20xfwZ9cbYvQvuldqaN+v/XytNPGyURYUpUU23kBRxWCQ==} - prosemirror-schema-basic@1.2.2: - resolution: {integrity: sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==} + prosemirror-schema-basic@1.2.3: + resolution: {integrity: sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==} - prosemirror-schema-list@1.3.0: - resolution: {integrity: sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==} + prosemirror-schema-list@1.4.1: + resolution: {integrity: sha512-jbDyaP/6AFfDfu70VzySsD75Om2t3sXTOdl5+31Wlxlg62td1haUpty/ybajSfJ1pkGadlOfwQq9kgW5IMo1Rg==} prosemirror-state@1.4.3: resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==} - prosemirror-tables@1.3.5: - resolution: {integrity: sha512-JSZ2cCNlApu/ObAhdPyotrjBe2cimniniTpz60YXzbL0kZ+47nEYk2LWbfKU2lKpBkUNquta2PjteoNi4YCluQ==} + prosemirror-tables@1.3.7: + resolution: {integrity: sha512-oEwX1wrziuxMtwFvdDWSFHVUWrFJWt929kVVfHvtTi8yvw+5ppxjXZkMG/fuTdFo+3DXyIPSKfid+Be1npKXDA==} - prosemirror-trailing-node@2.0.7: - resolution: {integrity: sha512-8zcZORYj/8WEwsGo6yVCRXFMOfBo0Ub3hCUvmoWIZYfMP26WqENU0mpEP27w7mt8buZWuGrydBewr0tOArPb1Q==} + prosemirror-trailing-node@2.0.8: + resolution: {integrity: sha512-ujRYhSuhQb1Jsarh1IHqb2KoSnRiD7wAMDGucP35DN7j5af6X7B18PfdPIrbwsPTqIAj0fyOvxbuPsWhNvylmA==} peerDependencies: prosemirror-model: ^1.19.0 prosemirror-state: ^1.4.2 prosemirror-view: ^1.31.2 - prosemirror-transform@1.8.0: - resolution: {integrity: sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==} + prosemirror-transform@1.9.0: + resolution: {integrity: sha512-5UXkr1LIRx3jmpXXNKDhv8OyAOeLTGuXNwdVfg8x27uASna/wQkr9p6fD3eupGOi4PLJfbezxTyi/7fSJypXHg==} - prosemirror-view@1.32.7: - resolution: {integrity: sha512-pvxiOoD4shW41X5bYDjRQk3DSG4fMqxh36yPMt7VYgU3dWRmqFzWJM/R6zeo1KtC8nyk717ZbQND3CC9VNeptw==} + prosemirror-view@1.33.8: + resolution: {integrity: sha512-4PhMr/ufz2cdvFgpUAnZfs+0xij3RsFysreeG9V/utpwX7AJtYCDVyuRxzWoMJIEf4C7wVihuBNMPpFLPCiLQw==} proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} @@ -7641,16 +7613,15 @@ packages: thread-stream@3.0.2: resolution: {integrity: sha512-cBL4xF2A3lSINV4rD5tyqnKH4z/TgWPvT+NaVhJDSwK962oo/Ye7cHSMbDzwcu7tAE1SfU6Q4XtV6Hucmi6Hlw==} - throttle-debounce@3.0.1: - resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} - engines: {node: '>=10'} - through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} tippy.js@6.3.7: resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} + tiptap-extension-global-drag-handle@0.1.10: + resolution: {integrity: sha512-Bt6nzlQWp+Jw8ljvwO7dWqIgs2LupIzC6ar8SlXkfJ6MSGZ3+YMORrooSdbSysMlv2Zk1ypJc/kw/n9yGJMMEg==} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -7800,10 +7771,6 @@ packages: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} - type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - type-fest@4.12.0: resolution: {integrity: sha512-5Y2/pp2wtJk8o08G0CMkuFPCO354FGwk/vbidxrdhRGZfd0tFnb4Qb8anp9XxXriwBgVPjdWbKpGl4J9lJY2jQ==} engines: {node: '>=16'} @@ -7921,6 +7888,11 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 + use-sync-external-store@1.2.2: + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + utf8-byte-length@1.0.4: resolution: {integrity: sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==} @@ -8042,6 +8014,10 @@ packages: resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} engines: {node: '>=18'} + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} @@ -8184,10 +8160,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - zeed-dom@0.10.11: - resolution: {integrity: sha512-7ukbu6aQKx34OQ7PfUIxOuAhk2MvyZY/t4/IJsVzy76zuMzfhE74+Dbyp8SHiUJPTPkF0FflP1KVrGJ7gk9IHw==} - engines: {node: '>=14.13.1'} - zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} @@ -10153,12 +10125,12 @@ snapshots: - bufferutil - utf-8-validate - '@hocuspocus/transformer@2.13.5(@tiptap/pm@2.4.0)(y-prosemirror@1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18))(yjs@13.6.18)': + '@hocuspocus/transformer@2.13.5(@tiptap/pm@2.5.4)(y-prosemirror@1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18))(yjs@13.6.18)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 - '@tiptap/starter-kit': 2.4.0(@tiptap/pm@2.4.0) - y-prosemirror: 1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 + '@tiptap/starter-kit': 2.5.4(@tiptap/pm@2.5.4) + y-prosemirror: 1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18) yjs: 13.6.18 '@humanwhocodes/module-importer@1.0.1': {} @@ -11329,26 +11301,6 @@ snapshots: '@remirror/core-constants@2.0.2': {} - '@remirror/core-helpers@3.0.0': - dependencies: - '@remirror/core-constants': 2.0.2 - '@remirror/types': 1.0.1 - '@types/object.omit': 3.0.3 - '@types/object.pick': 1.3.4 - '@types/throttle-debounce': 2.1.0 - case-anything: 2.1.13 - dash-get: 1.0.2 - deepmerge: 4.3.1 - fast-deep-equal: 3.1.3 - make-error: 1.3.6 - object.omit: 3.0.0 - object.pick: 1.3.0 - throttle-debounce: 3.0.1 - - '@remirror/types@1.0.1': - dependencies: - type-fest: 2.19.0 - '@remix-run/router@1.17.0': {} '@rollup/rollup-android-arm-eabi@4.13.2': @@ -11909,268 +11861,264 @@ snapshots: '@tanstack/query-core': 5.48.0 react: 18.3.1 - '@tiptap/core@2.4.0(@tiptap/pm@2.4.0)': + '@tiptap/core@2.5.4(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/pm': 2.4.0 + '@tiptap/pm': 2.5.4 - '@tiptap/extension-blockquote@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-blockquote@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-bold@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-bold@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-bubble-menu@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-bubble-menu@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 tippy.js: 6.3.7 - '@tiptap/extension-bullet-list@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-bullet-list@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-code-block-lowlight@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/extension-code-block@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-code-block-lowlight@2.4.0(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/extension-code-block@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/extension-code-block': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/extension-code-block': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 - '@tiptap/extension-code-block@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-code-block@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 - '@tiptap/extension-code@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-code@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-collaboration-cursor@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(y-prosemirror@1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18))': + '@tiptap/extension-collaboration-cursor@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(y-prosemirror@1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - y-prosemirror: 1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + y-prosemirror: 1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18) - '@tiptap/extension-collaboration@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)(y-prosemirror@1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18))': + '@tiptap/extension-collaboration@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)(y-prosemirror@1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 - y-prosemirror: 1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 + y-prosemirror: 1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18) - '@tiptap/extension-color@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/extension-text-style@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)))': + '@tiptap/extension-color@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/extension-text-style@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/extension-text-style': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/extension-text-style': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) - '@tiptap/extension-document@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-document@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-dropcursor@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-dropcursor@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 - '@tiptap/extension-floating-menu@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-floating-menu@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 tippy.js: 6.3.7 - '@tiptap/extension-gapcursor@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-gapcursor@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 - '@tiptap/extension-hard-break@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-hard-break@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-heading@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-heading@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-highlight@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-highlight@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-history@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-history@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 - '@tiptap/extension-horizontal-rule@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-horizontal-rule@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 - '@tiptap/extension-image@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-image@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-italic@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-italic@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-link@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-link@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 linkifyjs: 4.1.3 - '@tiptap/extension-list-item@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-list-item@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-list-keymap@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-list-keymap@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-mention@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)(@tiptap/suggestion@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0))': + '@tiptap/extension-mention@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)(@tiptap/suggestion@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 - '@tiptap/suggestion': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 + '@tiptap/suggestion': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) - '@tiptap/extension-ordered-list@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-ordered-list@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-paragraph@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-paragraph@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-placeholder@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-placeholder@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 - '@tiptap/extension-strike@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-strike@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-subscript@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-subscript@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-superscript@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-superscript@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-table-cell@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-table-cell@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-table-header@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-table-header@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-table-row@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-table-row@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-table@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-table@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 - '@tiptap/extension-task-item@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/extension-task-item@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 - '@tiptap/extension-task-list@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-task-list@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-text-align@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-text-align@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-text-style@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-text-style@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-text@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-text@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-typography@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-typography@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-underline@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-underline@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/extension-youtube@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))': + '@tiptap/extension-youtube@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) - '@tiptap/html@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': - dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 - zeed-dom: 0.10.11 - - '@tiptap/pm@2.4.0': + '@tiptap/pm@2.5.4': dependencies: prosemirror-changeset: 2.2.1 prosemirror-collab: 1.3.1 prosemirror-commands: 1.5.2 prosemirror-dropcursor: 1.8.1 prosemirror-gapcursor: 1.3.2 - prosemirror-history: 1.3.2 - prosemirror-inputrules: 1.3.0 + prosemirror-history: 1.4.1 + prosemirror-inputrules: 1.4.0 prosemirror-keymap: 1.2.2 - prosemirror-markdown: 1.12.0 + prosemirror-markdown: 1.13.0 prosemirror-menu: 1.2.4 - prosemirror-model: 1.19.4 - prosemirror-schema-basic: 1.2.2 - prosemirror-schema-list: 1.3.0 + prosemirror-model: 1.22.1 + prosemirror-schema-basic: 1.2.3 + prosemirror-schema-list: 1.4.1 prosemirror-state: 1.4.3 - prosemirror-tables: 1.3.5 - prosemirror-trailing-node: 2.0.7(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7) - prosemirror-transform: 1.8.0 - prosemirror-view: 1.32.7 + prosemirror-tables: 1.3.7 + prosemirror-trailing-node: 2.0.8(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8) + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.8 - '@tiptap/react@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@tiptap/react@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/extension-bubble-menu': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) - '@tiptap/extension-floating-menu': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/extension-bubble-menu': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) + '@tiptap/extension-floating-menu': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 + '@types/use-sync-external-store': 0.0.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + use-sync-external-store: 1.2.2(react@18.3.1) - '@tiptap/starter-kit@2.4.0(@tiptap/pm@2.4.0)': + '@tiptap/starter-kit@2.5.4(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/extension-blockquote': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-bold': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-bullet-list': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-code': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-code-block': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) - '@tiptap/extension-document': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-dropcursor': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) - '@tiptap/extension-gapcursor': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) - '@tiptap/extension-hard-break': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-heading': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-history': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) - '@tiptap/extension-horizontal-rule': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0) - '@tiptap/extension-italic': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-list-item': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-ordered-list': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-paragraph': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-strike': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) - '@tiptap/extension-text': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0)) + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/extension-blockquote': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-bold': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-bullet-list': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-code': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-code-block': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) + '@tiptap/extension-document': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-dropcursor': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) + '@tiptap/extension-gapcursor': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) + '@tiptap/extension-hard-break': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-heading': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-history': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) + '@tiptap/extension-horizontal-rule': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4) + '@tiptap/extension-italic': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-list-item': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-ordered-list': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-paragraph': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-strike': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) + '@tiptap/extension-text': 2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4)) transitivePeerDependencies: - '@tiptap/pm' - '@tiptap/suggestion@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)': + '@tiptap/suggestion@2.5.4(@tiptap/core@2.5.4(@tiptap/pm@2.5.4))(@tiptap/pm@2.5.4)': dependencies: - '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0) - '@tiptap/pm': 2.4.0 + '@tiptap/core': 2.5.4(@tiptap/pm@2.5.4) + '@tiptap/pm': 2.5.4 '@tsconfig/node10@1.0.9': {} @@ -12258,6 +12206,8 @@ snapshots: '@types/qs': 6.9.14 '@types/serve-static': 1.15.5 + '@types/file-saver@2.0.7': {} + '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 @@ -12322,10 +12272,6 @@ snapshots: dependencies: '@types/node': 20.14.9 - '@types/object.omit@3.0.3': {} - - '@types/object.pick@1.3.4': {} - '@types/parse-json@4.0.2': {} '@types/passport-jwt@4.0.1': @@ -12389,10 +12335,10 @@ snapshots: '@types/methods': 1.1.4 '@types/superagent': 8.1.6 - '@types/throttle-debounce@2.1.0': {} - '@types/unist@3.0.2': {} + '@types/use-sync-external-store@0.0.6': {} + '@types/uuid@10.0.0': {} '@types/validator@13.12.0': {} @@ -13070,8 +13016,6 @@ snapshots: caniuse-lite@1.0.30001600: {} - case-anything@2.1.13: {} - chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -13328,8 +13272,6 @@ snapshots: '@daybrush/utils': 1.13.0 '@scena/matrix': 1.1.1 - css-what@6.1.0: {} - cssesc@3.0.0: {} cssstyle@3.0.0: @@ -13338,8 +13280,6 @@ snapshots: csstype@3.1.3: {} - dash-get@1.0.2: {} - data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 @@ -14126,6 +14066,12 @@ snapshots: graphemer@1.4.0: {} + happy-dom@14.12.3: + dependencies: + entities: 4.5.0 + webidl-conversions: 7.0.0 + whatwg-mimetype: 3.0.0 + has-flag@3.0.0: {} has-flag@4.0.0: {} @@ -14338,10 +14284,6 @@ snapshots: is-docker@2.2.1: {} - is-extendable@1.0.1: - dependencies: - is-plain-object: 2.0.4 - is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -14358,10 +14300,6 @@ snapshots: is-path-inside@3.0.3: {} - is-plain-object@2.0.4: - dependencies: - isobject: 3.0.1 - is-potential-custom-element-name@1.0.1: {} is-stream@2.0.1: {} @@ -14379,8 +14317,6 @@ snapshots: isexe@2.0.0: {} - isobject@3.0.1: {} - isomorphic.js@0.2.5: {} istanbul-lib-coverage@3.2.2: {} @@ -15067,6 +15003,8 @@ snapshots: punycode.js: 2.3.1 uc.micro: 2.0.0 + marked@13.0.2: {} + marked@7.0.4: {} md-to-react-email@5.0.2(react@18.3.1): @@ -15347,14 +15285,6 @@ snapshots: object-inspect@1.13.1: {} - object.omit@3.0.0: - dependencies: - is-extendable: 1.0.1 - - object.pick@1.3.0: - dependencies: - isobject: 3.0.1 - obliterator@2.0.4: {} obuf@1.1.2: {} @@ -15716,7 +15646,7 @@ snapshots: prosemirror-changeset@2.2.1: dependencies: - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 prosemirror-collab@1.3.1: dependencies: @@ -15724,98 +15654,97 @@ snapshots: prosemirror-commands@1.5.2: dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 prosemirror-dropcursor@1.8.1: dependencies: prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 - prosemirror-view: 1.32.7 + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.8 prosemirror-gapcursor@1.3.2: dependencies: prosemirror-keymap: 1.2.2 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 prosemirror-state: 1.4.3 - prosemirror-view: 1.32.7 + prosemirror-view: 1.33.8 - prosemirror-history@1.3.2: + prosemirror-history@1.4.1: dependencies: prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 - prosemirror-view: 1.32.7 + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.8 rope-sequence: 1.3.4 - prosemirror-inputrules@1.3.0: + prosemirror-inputrules@1.4.0: dependencies: prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 prosemirror-keymap@1.2.2: dependencies: prosemirror-state: 1.4.3 w3c-keyname: 2.2.8 - prosemirror-markdown@1.12.0: + prosemirror-markdown@1.13.0: dependencies: markdown-it: 14.0.0 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 prosemirror-menu@1.2.4: dependencies: crelt: 1.0.6 prosemirror-commands: 1.5.2 - prosemirror-history: 1.3.2 + prosemirror-history: 1.4.1 prosemirror-state: 1.4.3 - prosemirror-model@1.19.4: + prosemirror-model@1.22.1: dependencies: orderedmap: 2.1.1 - prosemirror-schema-basic@1.2.2: + prosemirror-schema-basic@1.2.3: dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 - prosemirror-schema-list@1.3.0: + prosemirror-schema-list@1.4.1: dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 prosemirror-state@1.4.3: dependencies: - prosemirror-model: 1.19.4 - prosemirror-transform: 1.8.0 - prosemirror-view: 1.32.7 + prosemirror-model: 1.22.1 + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.8 - prosemirror-tables@1.3.5: + prosemirror-tables@1.3.7: dependencies: prosemirror-keymap: 1.2.2 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 - prosemirror-view: 1.32.7 + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.8 - prosemirror-trailing-node@2.0.7(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7): + prosemirror-trailing-node@2.0.8(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8): dependencies: '@remirror/core-constants': 2.0.2 - '@remirror/core-helpers': 3.0.0 escape-string-regexp: 4.0.0 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 prosemirror-state: 1.4.3 - prosemirror-view: 1.32.7 + prosemirror-view: 1.33.8 - prosemirror-transform@1.8.0: + prosemirror-transform@1.9.0: dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 - prosemirror-view@1.32.7: + prosemirror-view@1.33.8: dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 proto-list@1.2.4: {} @@ -16687,14 +16616,14 @@ snapshots: dependencies: real-require: 0.2.0 - throttle-debounce@3.0.1: {} - through@2.3.8: {} tippy.js@6.3.7: dependencies: '@popperjs/core': 2.11.8 + tiptap-extension-global-drag-handle@0.1.10: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -16841,8 +16770,6 @@ snapshots: type-fest@0.7.1: {} - type-fest@2.19.0: {} - type-fest@4.12.0: {} typescript@5.1.6: {} @@ -16927,6 +16854,10 @@ snapshots: dependencies: react: 18.3.1 + use-sync-external-store@1.2.2(react@18.3.1): + dependencies: + react: 18.3.1 + utf8-byte-length@1.0.4: {} util-deprecate@1.0.2: {} @@ -17058,6 +16989,8 @@ snapshots: dependencies: iconv-lite: 0.6.3 + whatwg-mimetype@3.0.0: {} + whatwg-mimetype@4.0.0: {} whatwg-url@14.0.0: @@ -17124,12 +17057,12 @@ snapshots: lib0: 0.2.88 yjs: 13.6.18 - y-prosemirror@1.2.3(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.32.7)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18): + y-prosemirror@1.2.3(prosemirror-model@1.22.1)(prosemirror-state@1.4.3)(prosemirror-view@1.33.8)(y-protocols@1.0.6(yjs@13.6.18))(yjs@13.6.18): dependencies: lib0: 0.2.93 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.1 prosemirror-state: 1.4.3 - prosemirror-view: 1.32.7 + prosemirror-view: 1.33.8 y-protocols: 1.0.6(yjs@13.6.18) yjs: 13.6.18 @@ -17168,8 +17101,4 @@ snapshots: yocto-queue@0.1.0: {} - zeed-dom@0.10.11: - dependencies: - css-what: 6.1.0 - zod@3.23.8: {}