From d462546055e96efc56b81f44fbd0d0b1398802ae Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Thu, 20 Nov 2025 14:46:12 +0530 Subject: [PATCH] [WIKI-788] fix: editor markdown copy rules (#8140) --- .../components/editor/lite-text-editor.tsx | 10 +- .../components/editor/rich-text-editor.tsx | 12 +- .../core/hooks/use-parse-editor-content.ts | 69 ++ .../components/editor/document/editor.tsx | 9 +- .../components/editor/lite-text/editor.tsx | 9 +- .../components/editor/rich-text/editor.tsx | 11 +- .../editor/sticky-editor/editor.tsx | 10 +- .../components/pages/editor/editor-body.tsx | 10 +- .../components/pages/editor/header/root.tsx | 2 +- .../components/pages/editor/page-root.tsx | 2 +- .../pages/modals/export-page-modal.tsx | 9 +- .../core/hooks/use-parse-editor-content.ts | 76 +- .../editors/document/collaborative-editor.tsx | 2 + .../components/editors/document/editor.tsx | 4 +- .../components/editors/editor-wrapper.tsx | 2 + .../editor/src/core/extensions/extensions.ts | 3 + .../editor/src/core/extensions/utility.ts | 13 +- .../core/hooks/use-collaborative-editor.ts | 2 + packages/editor/src/core/hooks/use-editor.ts | 2 + .../src/core/plugins/markdown-clipboard.ts | 105 +- packages/editor/src/core/types/editor.ts | 4 +- packages/editor/src/core/types/hook.ts | 1 + packages/utils/package.json | 10 + .../utils/src/{editor.ts => editor/common.ts} | 2 +- packages/utils/src/editor/index.ts | 2 + .../src/editor/markdown-parser/common.ts | 6 + .../custom-components-handler.ts | 41 + .../utils/src/editor/markdown-parser/index.ts | 2 + .../editor/markdown-parser/marks-handler.ts | 42 + .../utils/src/editor/markdown-parser/root.ts | 143 +++ .../utils/src/editor/markdown-parser/types.ts | 16 + pnpm-lock.yaml | 1025 +++++++++++++++-- 32 files changed, 1467 insertions(+), 189 deletions(-) create mode 100644 apps/space/core/hooks/use-parse-editor-content.ts rename packages/utils/src/{editor.ts => editor/common.ts} (98%) create mode 100644 packages/utils/src/editor/index.ts create mode 100644 packages/utils/src/editor/markdown-parser/common.ts create mode 100644 packages/utils/src/editor/markdown-parser/custom-components-handler.ts create mode 100644 packages/utils/src/editor/markdown-parser/index.ts create mode 100644 packages/utils/src/editor/markdown-parser/marks-handler.ts create mode 100644 packages/utils/src/editor/markdown-parser/root.ts create mode 100644 packages/utils/src/editor/markdown-parser/types.ts diff --git a/apps/space/core/components/editor/lite-text-editor.tsx b/apps/space/core/components/editor/lite-text-editor.tsx index 5b33b5811..c338ae5b2 100644 --- a/apps/space/core/components/editor/lite-text-editor.tsx +++ b/apps/space/core/components/editor/lite-text-editor.tsx @@ -6,6 +6,9 @@ import type { MakeOptional } from "@plane/types"; import { cn, isCommentEmpty } from "@plane/utils"; // helpers import { getEditorFileHandlers } from "@/helpers/editor.helper"; +// hooks +import { useParseEditorContent } from "@/hooks/use-parse-editor-content"; +// plane web imports import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; // local imports import { EditorMentionsRoot } from "./embeds/mentions"; @@ -13,7 +16,7 @@ import { IssueCommentToolbar } from "./toolbar"; type LiteTextEditorWrapperProps = MakeOptional< Omit, - "disabledExtensions" | "flaggedExtensions" + "disabledExtensions" | "flaggedExtensions" | "getEditorMetaData" > & { anchor: string; isSubmitting?: boolean; @@ -47,6 +50,10 @@ export const LiteTextEditor = React.forwardRef(ref) ? ref.current : null; const { liteText: liteTextEditorExtensions } = useEditorFlagging(anchor); + // parse content + const { getEditorMetaData } = useParseEditorContent({ + anchor, + }); return (
@@ -60,6 +67,7 @@ export const LiteTextEditor = React.forwardRef "", workspaceId, })} + getEditorMetaData={getEditorMetaData} mentionHandler={{ renderComponent: (props) => , }} diff --git a/apps/space/core/components/editor/rich-text-editor.tsx b/apps/space/core/components/editor/rich-text-editor.tsx index 1d48d7da2..c5c538674 100644 --- a/apps/space/core/components/editor/rich-text-editor.tsx +++ b/apps/space/core/components/editor/rich-text-editor.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef } from "react"; +import { forwardRef } from "react"; // plane imports import { RichTextEditorWithRef } from "@plane/editor"; import type { EditorRefApi, IRichTextEditorProps, TFileHandler } from "@plane/editor"; @@ -7,6 +7,7 @@ import type { MakeOptional } from "@plane/types"; import { getEditorFileHandlers } from "@/helpers/editor.helper"; // hooks import { useMember } from "@/hooks/store/use-member"; +import { useParseEditorContent } from "@/hooks/use-parse-editor-content"; // plane web imports import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; // local imports @@ -14,7 +15,7 @@ import { EditorMentionsRoot } from "./embeds/mentions"; type RichTextEditorWrapperProps = MakeOptional< Omit, - "disabledExtensions" | "flaggedExtensions" + "disabledExtensions" | "flaggedExtensions" | "getEditorMetaData" > & { anchor: string; workspaceId: string; @@ -37,7 +38,13 @@ export const RichTextEditor = forwardRef "", workspaceId, })} + getEditorMetaData={getEditorMetaData} flaggedExtensions={richTextEditorExtensions.flagged} extendedEditorProps={{}} {...rest} diff --git a/apps/space/core/hooks/use-parse-editor-content.ts b/apps/space/core/hooks/use-parse-editor-content.ts new file mode 100644 index 000000000..e540aad63 --- /dev/null +++ b/apps/space/core/hooks/use-parse-editor-content.ts @@ -0,0 +1,69 @@ +import { useCallback } from "react"; +// helpers +import type { TCustomComponentsMetaData } from "@plane/utils"; +// helpers +import { getEditorAssetSrc } from "@/helpers/editor.helper"; +// hooks +import { useMember } from "@/hooks/store/use-member"; + +type TArgs = { + anchor: string; +}; + +export const useParseEditorContent = (args: TArgs) => { + const { anchor } = args; + // store hooks + const { getMemberById } = useMember(); + + const getEditorMetaData = useCallback( + (htmlContent: string): TCustomComponentsMetaData => { + const parser = new DOMParser(); + const doc = parser.parseFromString(htmlContent, "text/html"); + const imageMetaData: TCustomComponentsMetaData["file_assets"] = []; + // process image components + const imageComponents = doc.querySelectorAll("image-component"); + imageComponents.forEach((element) => { + const src = element.getAttribute("src"); + if (src) { + const assetSrc = src.startsWith("http") ? src : getEditorAssetSrc(anchor, src); + if (assetSrc) { + imageMetaData.push({ + id: src, + name: src, + url: assetSrc, + }); + } + } + }); + // process user mentions + const userMentions: TCustomComponentsMetaData["user_mentions"] = []; + const mentionComponents = doc.querySelectorAll("mention-component"); + mentionComponents.forEach((element) => { + const id = element.getAttribute("entity_identifier"); + if (id) { + const userDetails = getMemberById(id); + const originUrl = typeof window !== "undefined" && (window.location.origin ?? ""); + const path = `profile/${id}`; + const url = `${originUrl}/${path}`; + if (userDetails) { + userMentions.push({ + id, + display_name: userDetails.member__display_name, + url, + }); + } + } + }); + + return { + file_assets: imageMetaData, + user_mentions: userMentions, + }; + }, + [anchor, getMemberById] + ); + + return { + getEditorMetaData, + }; +}; diff --git a/apps/web/core/components/editor/document/editor.tsx b/apps/web/core/components/editor/document/editor.tsx index 573d96d3d..199e93179 100644 --- a/apps/web/core/components/editor/document/editor.tsx +++ b/apps/web/core/components/editor/document/editor.tsx @@ -7,6 +7,7 @@ import { cn } from "@plane/utils"; // hooks import { useEditorConfig, useEditorMention } from "@/hooks/editor"; import { useMember } from "@/hooks/store/use-member"; +import { useParseEditorContent } from "@/hooks/use-parse-editor-content"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; // local imports @@ -14,7 +15,7 @@ import { EditorMentionsRoot } from "../embeds/mentions"; type DocumentEditorWrapperProps = MakeOptional< Omit, - "disabledExtensions" | "editable" | "flaggedExtensions" + "disabledExtensions" | "editable" | "flaggedExtensions" | "getEditorMetaData" > & { extendedEditorProps?: Partial; workspaceSlug: string; @@ -44,6 +45,11 @@ export const DocumentEditor = forwardRef { const res = await fetchMentions(query); diff --git a/apps/web/core/components/editor/lite-text/editor.tsx b/apps/web/core/components/editor/lite-text/editor.tsx index 82e531506..2fb676440 100644 --- a/apps/web/core/components/editor/lite-text/editor.tsx +++ b/apps/web/core/components/editor/lite-text/editor.tsx @@ -13,6 +13,7 @@ import { IssueCommentToolbar } from "@/components/editor/lite-text/toolbar"; // hooks import { useEditorConfig, useEditorMention } from "@/hooks/editor"; import { useMember } from "@/hooks/store/use-member"; +import { useParseEditorContent } from "@/hooks/use-parse-editor-content"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; // plane web service @@ -22,7 +23,7 @@ const workspaceService = new WorkspaceService(); type LiteTextEditorWrapperProps = MakeOptional< Omit, - "disabledExtensions" | "flaggedExtensions" + "disabledExtensions" | "flaggedExtensions" | "getEditorMetaData" > & { workspaceSlug: string; workspaceId: string; @@ -80,6 +81,11 @@ export const LiteTextEditor = React.forwardRef @@ -124,6 +130,7 @@ export const LiteTextEditor = React.forwardRef { if (ready) { setEditorRef(isMutableRefObject(ref) ? ref.current : null); diff --git a/apps/web/core/components/editor/rich-text/editor.tsx b/apps/web/core/components/editor/rich-text/editor.tsx index 8595aa58e..a78e4266d 100644 --- a/apps/web/core/components/editor/rich-text/editor.tsx +++ b/apps/web/core/components/editor/rich-text/editor.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef } from "react"; +import { forwardRef } from "react"; // plane imports import { RichTextEditorWithRef } from "@plane/editor"; import type { EditorRefApi, IRichTextEditorProps, TFileHandler } from "@plane/editor"; @@ -9,12 +9,13 @@ import { EditorMentionsRoot } from "@/components/editor/embeds/mentions"; // hooks import { useEditorConfig, useEditorMention } from "@/hooks/editor"; import { useMember } from "@/hooks/store/use-member"; +import { useParseEditorContent } from "@/hooks/use-parse-editor-content"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; type RichTextEditorWrapperProps = MakeOptional< Omit, - "disabledExtensions" | "editable" | "flaggedExtensions" + "disabledExtensions" | "editable" | "flaggedExtensions" | "getEditorMetaData" > & { workspaceSlug: string; workspaceId: string; @@ -53,6 +54,11 @@ export const RichTextEditor = forwardRef { const res = await fetchMentions(query); diff --git a/apps/web/core/components/editor/sticky-editor/editor.tsx b/apps/web/core/components/editor/sticky-editor/editor.tsx index 7a6d52614..49ca1ed3d 100644 --- a/apps/web/core/components/editor/sticky-editor/editor.tsx +++ b/apps/web/core/components/editor/sticky-editor/editor.tsx @@ -10,6 +10,7 @@ import type { TSticky } from "@plane/types"; import { cn } from "@plane/utils"; // hooks import { useEditorConfig } from "@/hooks/editor"; +import { useParseEditorContent } from "@/hooks/use-parse-editor-content"; // plane web hooks import { useEditorFlagging } from "@/plane-web/hooks/use-editor-flagging"; import { StickyEditorToolbar } from "./toolbar"; @@ -17,7 +18,7 @@ import { StickyEditorToolbar } from "./toolbar"; interface StickyEditorWrapperProps extends Omit< Omit, - "disabledExtensions" | "editable" | "flaggedExtensions" | "fileHandler" | "mentionHandler" + "disabledExtensions" | "editable" | "flaggedExtensions" | "fileHandler" | "mentionHandler" | "getEditorMetaData" > { workspaceSlug: string; workspaceId: string; @@ -55,6 +56,11 @@ export const StickyEditor = React.forwardRef(ref: React.ForwardedRef): ref is React.MutableRefObject { @@ -62,6 +68,7 @@ export const StickyEditor = React.forwardRef(ref) ? ref.current : null; + return (
<>, }} diff --git a/apps/web/core/components/pages/editor/editor-body.tsx b/apps/web/core/components/pages/editor/editor-body.tsx index 598a9e1fc..a69d8c194 100644 --- a/apps/web/core/components/pages/editor/editor-body.tsx +++ b/apps/web/core/components/pages/editor/editor-body.tsx @@ -24,6 +24,7 @@ import { useMember } from "@/hooks/store/use-member"; import { useWorkspace } from "@/hooks/store/use-workspace"; import { useUser } from "@/hooks/store/user"; import { usePageFilters } from "@/hooks/use-page-filters"; +import { useParseEditorContent } from "@/hooks/use-parse-editor-content"; // plane web imports import { EditorAIMenu } from "@/plane-web/components/pages"; import type { TExtendedEditorExtensionsConfig } from "@/plane-web/hooks/pages"; @@ -57,10 +58,9 @@ type Props = { isNavigationPaneOpen: boolean; page: TPageInstance; webhookConnectionParams: TWebhookConnectionQueryParams; - projectId: string; + projectId?: string; workspaceSlug: string; storeType: EPageStoreType; - extendedEditorProps: TExtendedEditorExtensionsConfig; }; @@ -103,6 +103,11 @@ export const PageEditorBody: React.FC = observer((props) => { workspaceSlug, storeType, }); + // parse content + const { getEditorMetaData } = useParseEditorContent({ + projectId, + workspaceSlug, + }); // page filters const { fontSize, fontStyle, isFullWidth } = usePageFilters(); // translation @@ -235,6 +240,7 @@ export const PageEditorBody: React.FC = observer((props) => { ref={editorForwardRef} containerClassName="h-full p-0 pb-64" displayConfig={displayConfig} + getEditorMetaData={getEditorMetaData} mentionHandler={{ searchCallback: async (query) => { const res = await fetchMentions(query); diff --git a/apps/web/core/components/pages/editor/header/root.tsx b/apps/web/core/components/pages/editor/header/root.tsx index 36fe19521..12fb604ac 100644 --- a/apps/web/core/components/pages/editor/header/root.tsx +++ b/apps/web/core/components/pages/editor/header/root.tsx @@ -11,7 +11,7 @@ import { PageEditorHeaderLogoPicker } from "./logo-picker"; type Props = { page: TPageInstance; - projectId: string; + projectId?: string; }; export const PageEditorHeaderRoot: React.FC = observer((props) => { diff --git a/apps/web/core/components/pages/editor/page-root.tsx b/apps/web/core/components/pages/editor/page-root.tsx index 7d7d74a00..d8ca1ebb2 100644 --- a/apps/web/core/components/pages/editor/page-root.tsx +++ b/apps/web/core/components/pages/editor/page-root.tsx @@ -37,7 +37,7 @@ type TPageRootProps = { page: TPageInstance; storeType: EPageStoreType; webhookConnectionParams: TWebhookConnectionQueryParams; - projectId: string; + projectId?: string; workspaceSlug: string; }; diff --git a/apps/web/core/components/pages/modals/export-page-modal.tsx b/apps/web/core/components/pages/modals/export-page-modal.tsx index 1f179723e..390bfce1b 100644 --- a/apps/web/core/components/pages/modals/export-page-modal.tsx +++ b/apps/web/core/components/pages/modals/export-page-modal.tsx @@ -4,6 +4,7 @@ import { useState } from "react"; import type { PageProps } from "@react-pdf/renderer"; import { pdf } from "@react-pdf/renderer"; import { Controller, useForm } from "react-hook-form"; +import { useParams } from "react-router"; // plane editor import type { EditorRefApi } from "@plane/editor"; // plane ui @@ -100,13 +101,17 @@ export const ExportPageModal: React.FC = (props) => { const { editorRef, isOpen, onClose, pageTitle } = props; // states const [isExporting, setIsExporting] = useState(false); + // params + const { workspaceSlug, projectId } = useParams(); // form info const { control, reset, watch } = useForm({ defaultValues, }); // parse editor content - const { replaceCustomComponentsFromHTMLContent, replaceCustomComponentsFromMarkdownContent } = - useParseEditorContent(); + const { replaceCustomComponentsFromHTMLContent, replaceCustomComponentsFromMarkdownContent } = useParseEditorContent({ + projectId, + workspaceSlug: workspaceSlug ?? "", + }); // derived values const selectedExportFormat = watch("export_format"); const selectedPageFormat = watch("page_format"); diff --git a/apps/web/core/hooks/use-parse-editor-content.ts b/apps/web/core/hooks/use-parse-editor-content.ts index bf52fff08..840317fa6 100644 --- a/apps/web/core/hooks/use-parse-editor-content.ts +++ b/apps/web/core/hooks/use-parse-editor-content.ts @@ -1,17 +1,21 @@ import { useCallback } from "react"; -import { useParams } from "next/navigation"; // plane types import type { TSearchEntities } from "@plane/types"; // helpers -import { getBase64Image } from "@plane/utils"; +import { getBase64Image, getEditorAssetSrc } from "@plane/utils"; +import type { TCustomComponentsMetaData } from "@plane/utils"; // hooks import { useMember } from "@/hooks/store/use-member"; // plane web hooks import { useAdditionalEditorMention } from "@/plane-web/hooks/use-additional-editor-mention"; -export const useParseEditorContent = () => { - // params - const { workspaceSlug } = useParams(); +type TArgs = { + projectId?: string; + workspaceSlug: string; +}; + +export const useParseEditorContent = (args: TArgs) => { + const { projectId, workspaceSlug } = args; // store hooks const { getUserDetails } = useMember(); // parse additional content @@ -150,7 +154,7 @@ export const useParseEditorContent = () => { serializedDoc = serializedDoc.replace(/background-color: null/g, "").replace(/color: null/g, ""); return serializedDoc; }, - [getUserDetails] + [getUserDetails, parseAdditionalEditorContent] ); /** @@ -160,7 +164,6 @@ export const useParseEditorContent = () => { */ const replaceCustomComponentsFromMarkdownContent = useCallback( (props: { markdownContent: string; noAssets?: boolean }): string => { - const start = performance.now(); const { markdownContent, noAssets = false } = props; let parsedMarkdownContent = markdownContent; // replace the matched mention components with [display_name](redirect_url) @@ -203,15 +206,68 @@ export const useParseEditorContent = () => { // remove all issue-embed components const issueEmbedRegex = /]*>[^]*<\/issue-embed-component>/g; parsedMarkdownContent = parsedMarkdownContent.replace(issueEmbedRegex, ""); - const end = performance.now(); - console.log("Exec time:", end - start); return parsedMarkdownContent; }, - [getUserDetails, workspaceSlug] + [getUserDetails, parseAdditionalEditorContent, workspaceSlug] + ); + + const getEditorMetaData = useCallback( + (htmlContent: string): TCustomComponentsMetaData => { + const parser = new DOMParser(); + const doc = parser.parseFromString(htmlContent, "text/html"); + const imageMetaData: TCustomComponentsMetaData["file_assets"] = []; + // process image components + const imageComponents = doc.querySelectorAll("image-component"); + imageComponents.forEach((element) => { + const src = element.getAttribute("src"); + if (src) { + const assetSrc = src.startsWith("http") + ? src + : getEditorAssetSrc({ + assetId: src, + projectId, + workspaceSlug, + }); + if (assetSrc) { + imageMetaData.push({ + id: src, + name: src, + url: assetSrc, + }); + } + } + }); + // process user mentions + const userMentions: TCustomComponentsMetaData["user_mentions"] = []; + const mentionComponents = doc.querySelectorAll("mention-component"); + mentionComponents.forEach((element) => { + const id = element.getAttribute("entity_identifier"); + if (id) { + const userDetails = getUserDetails(id); + const originUrl = typeof window !== "undefined" && (window.location.origin ?? ""); + const path = `${workspaceSlug}/profile/${id}`; + const url = `${originUrl}/${path}`; + if (userDetails) { + userMentions.push({ + id, + display_name: userDetails.display_name, + url, + }); + } + } + }); + + return { + file_assets: imageMetaData, + user_mentions: userMentions, + }; + }, + [getUserDetails, projectId, workspaceSlug] ); return { replaceCustomComponentsFromHTMLContent, replaceCustomComponentsFromMarkdownContent, + getEditorMetaData, }; }; diff --git a/packages/editor/src/core/components/editors/document/collaborative-editor.tsx b/packages/editor/src/core/components/editors/document/collaborative-editor.tsx index ea78216b8..776011cf3 100644 --- a/packages/editor/src/core/components/editors/document/collaborative-editor.tsx +++ b/packages/editor/src/core/components/editors/document/collaborative-editor.tsx @@ -30,6 +30,7 @@ const CollaborativeDocumentEditor: React.FC = fileHandler, flaggedExtensions, forwardedRef, + getEditorMetaData, handleEditorReady, id, dragDropEnabled = true, @@ -57,6 +58,7 @@ const CollaborativeDocumentEditor: React.FC = extensions, fileHandler, flaggedExtensions, + getEditorMetaData, forwardedRef, handleEditorReady, id, diff --git a/packages/editor/src/core/components/editors/document/editor.tsx b/packages/editor/src/core/components/editors/document/editor.tsx index a4adf49f3..0279d1b61 100644 --- a/packages/editor/src/core/components/editors/document/editor.tsx +++ b/packages/editor/src/core/components/editors/document/editor.tsx @@ -30,9 +30,10 @@ const DocumentEditor = (props: IDocumentEditorProps) => { fileHandler, flaggedExtensions, forwardedRef, + getEditorMetaData, + handleEditorReady, id, isTouchDevice, - handleEditorReady, mentionHandler, onChange, user, @@ -72,6 +73,7 @@ const DocumentEditor = (props: IDocumentEditorProps) => { fileHandler, flaggedExtensions, forwardedRef, + getEditorMetaData, handleEditorReady, id, initialValue: value, diff --git a/packages/editor/src/core/components/editors/editor-wrapper.tsx b/packages/editor/src/core/components/editors/editor-wrapper.tsx index 617cb3b15..dfeb54d45 100644 --- a/packages/editor/src/core/components/editors/editor-wrapper.tsx +++ b/packages/editor/src/core/components/editors/editor-wrapper.tsx @@ -27,6 +27,7 @@ export const EditorWrapper: React.FC = (props) => { editorProps, extendedEditorProps, extensions, + getEditorMetaData, id, initialValue, isTouchDevice, @@ -55,6 +56,7 @@ export const EditorWrapper: React.FC = (props) => { fileHandler, flaggedExtensions, forwardedRef, + getEditorMetaData, id, isTouchDevice, initialValue, diff --git a/packages/editor/src/core/extensions/extensions.ts b/packages/editor/src/core/extensions/extensions.ts index 855440df8..5d6b0284b 100644 --- a/packages/editor/src/core/extensions/extensions.ts +++ b/packages/editor/src/core/extensions/extensions.ts @@ -43,6 +43,7 @@ type TArguments = Pick< | "disabledExtensions" | "flaggedExtensions" | "fileHandler" + | "getEditorMetaData" | "isTouchDevice" | "mentionHandler" | "placeholder" @@ -60,6 +61,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => { enableHistory, fileHandler, flaggedExtensions, + getEditorMetaData, isTouchDevice = false, mentionHandler, placeholder, @@ -114,6 +116,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => { UtilityExtension({ disabledExtensions, fileHandler, + getEditorMetaData, isEditable: editable, isTouchDevice, }), diff --git a/packages/editor/src/core/extensions/utility.ts b/packages/editor/src/core/extensions/utility.ts index 347f1800a..ef833e4e7 100644 --- a/packages/editor/src/core/extensions/utility.ts +++ b/packages/editor/src/core/extensions/utility.ts @@ -1,7 +1,7 @@ import { Extension } from "@tiptap/core"; import codemark from "prosemirror-codemark"; // helpers -import type { CORE_EXTENSIONS } from "@/constants/extension"; +import { CORE_EXTENSIONS } from "@/constants/extension"; import { restorePublicImages } from "@/helpers/image-helpers"; // plugins import type { TAdditionalActiveDropbarExtensions } from "@/plane-editor/types/utils"; @@ -50,18 +50,18 @@ export type UtilityExtensionStorage = { isTouchDevice: boolean; }; -type Props = Pick & { +type Props = Pick & { fileHandler: TFileHandler; isEditable: boolean; isTouchDevice: boolean; }; export const UtilityExtension = (props: Props) => { - const { disabledExtensions, fileHandler, isEditable, isTouchDevice } = props; + const { disabledExtensions, fileHandler, getEditorMetaData, isEditable, isTouchDevice } = props; const { restore } = fileHandler; return Extension.create, UtilityExtensionStorage>({ - name: "utility", + name: CORE_EXTENSIONS.UTILITY, priority: 1000, addProseMirrorPlugins() { @@ -72,7 +72,10 @@ export const UtilityExtension = (props: Props) => { fileHandler, }), ...codemark({ markType: this.editor.schema.marks.code }), - MarkdownClipboardPlugin(this.editor), + MarkdownClipboardPlugin({ + editor: this.editor, + getEditorMetaData, + }), DropHandlerPlugin({ disabledExtensions, editor: this.editor, diff --git a/packages/editor/src/core/hooks/use-collaborative-editor.ts b/packages/editor/src/core/hooks/use-collaborative-editor.ts index abbb3a82a..4549f7ea6 100644 --- a/packages/editor/src/core/hooks/use-collaborative-editor.ts +++ b/packages/editor/src/core/hooks/use-collaborative-editor.ts @@ -24,6 +24,7 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorHookProps) => extensions = [], fileHandler, flaggedExtensions, + getEditorMetaData, forwardedRef, handleEditorReady, id, @@ -109,6 +110,7 @@ export const useCollaborativeEditor = (props: TCollaborativeEditorHookProps) => fileHandler, flaggedExtensions, forwardedRef, + getEditorMetaData, handleEditorReady, isTouchDevice, mentionHandler, diff --git a/packages/editor/src/core/hooks/use-editor.ts b/packages/editor/src/core/hooks/use-editor.ts index db1966beb..b0cdb30e0 100644 --- a/packages/editor/src/core/hooks/use-editor.ts +++ b/packages/editor/src/core/hooks/use-editor.ts @@ -29,6 +29,7 @@ export const useEditor = (props: TEditorHookProps) => { fileHandler, flaggedExtensions, forwardedRef, + getEditorMetaData, handleEditorReady, id = "", initialValue, @@ -65,6 +66,7 @@ export const useEditor = (props: TEditorHookProps) => { extendedEditorProps, fileHandler, flaggedExtensions, + getEditorMetaData, isTouchDevice, mentionHandler, placeholder, diff --git a/packages/editor/src/core/plugins/markdown-clipboard.ts b/packages/editor/src/core/plugins/markdown-clipboard.ts index b87c7270a..de34a027b 100644 --- a/packages/editor/src/core/plugins/markdown-clipboard.ts +++ b/packages/editor/src/core/plugins/markdown-clipboard.ts @@ -1,81 +1,44 @@ import type { Editor } from "@tiptap/core"; -import type { Fragment } from "@tiptap/pm/model"; -import { Node } from "@tiptap/pm/model"; import { Plugin, PluginKey } from "@tiptap/pm/state"; -// constants -import { CORE_EXTENSIONS } from "@/constants/extension"; +// plane imports +import { convertHTMLToMarkdown } from "@plane/utils"; +import type { TCustomComponentsMetaData } from "@plane/utils"; -export const MarkdownClipboardPlugin = (editor: Editor): Plugin => - new Plugin({ +type TArgs = { + editor: Editor; + getEditorMetaData: (htmlContent: string) => TCustomComponentsMetaData; +}; + +export const MarkdownClipboardPlugin = (args: TArgs): Plugin => { + const { editor, getEditorMetaData } = args; + + return new Plugin({ key: new PluginKey("markdownClipboard"), props: { - clipboardTextSerializer: (slice) => { - const markdownSerializer = editor.storage.markdown.serializer; - const isTableRow = slice.content.firstChild?.type?.name === CORE_EXTENSIONS.TABLE_ROW; - const nodeSelect = slice.openStart === 0 && slice.openEnd === 0; - - if (nodeSelect) { - return markdownSerializer.serialize(slice.content); - } - - const processTableContent = (tableNode: Node | Fragment) => { - let result = ""; - tableNode.content?.forEach?.((tableRowNode: Node | Fragment) => { - tableRowNode.content?.forEach?.((cell: Node) => { - const cellContent = cell.content ? markdownSerializer.serialize(cell.content) : ""; - result += cellContent + "\n"; + handleDOMEvents: { + copy: (view, event) => { + try { + event.preventDefault(); + event.clipboardData?.clearData(); + // editor meta data + const editorHTML = editor.getHTML(); + const metaData = getEditorMetaData(editorHTML); + // meta data from selection + const clipboardHTML = view.serializeForClipboard(view.state.selection.content()).dom.innerHTML; + // convert to markdown + const markdown = convertHTMLToMarkdown({ + description_html: clipboardHTML, + metaData, }); - }); - return result; - }; - - if (isTableRow) { - const rowsCount = slice.content?.childCount || 0; - const cellsCount = slice.content?.firstChild?.content?.childCount || 0; - if (rowsCount === 1 || cellsCount === 1) { - return processTableContent(slice.content); - } else { - return markdownSerializer.serialize(slice.content); + event.clipboardData?.setData("text/plain", markdown); + event.clipboardData?.setData("text/html", clipboardHTML); + return true; + } catch (error) { + console.error("Failed to copy markdown content to clipboard:", error); + return false; } - } - - const traverseToParentOfLeaf = (node: Node | null, parent: Fragment | Node, depth: number): Node | Fragment => { - let currentNode = node; - let currentParent = parent; - let currentDepth = depth; - - while (currentNode && currentDepth > 1 && currentNode.content?.firstChild) { - if (currentNode.content?.childCount > 1) { - if (currentNode.content.firstChild?.type?.name === CORE_EXTENSIONS.LIST_ITEM) { - return currentParent; - } else { - return currentNode.content; - } - } - - currentParent = currentNode; - currentNode = currentNode.content?.firstChild || null; - currentDepth--; - } - - return currentParent; - }; - - if (slice.content.childCount > 1) { - return markdownSerializer.serialize(slice.content); - } else { - const targetNode = traverseToParentOfLeaf(slice.content.firstChild, slice.content, slice.openStart); - - let currentNode = targetNode; - while (currentNode && currentNode.content && currentNode.childCount === 1 && currentNode.firstChild) { - currentNode = currentNode.firstChild; - } - if (currentNode instanceof Node && currentNode.isText) { - return currentNode.text; - } - - return markdownSerializer.serialize(targetNode); - } + }, }, }, }); +}; diff --git a/packages/editor/src/core/types/editor.ts b/packages/editor/src/core/types/editor.ts index 27d538819..be7cc6afe 100644 --- a/packages/editor/src/core/types/editor.ts +++ b/packages/editor/src/core/types/editor.ts @@ -3,6 +3,8 @@ import type { MarkType, NodeType } from "@tiptap/pm/model"; import type { Selection } from "@tiptap/pm/state"; import type { EditorProps, EditorView } from "@tiptap/pm/view"; import type { NodeViewProps as TNodeViewProps } from "@tiptap/react"; +// plane imports +import type { TCustomComponentsMetaData } from "@plane/utils"; // extension types import type { TTextAlign } from "@/extensions"; // plane editor imports @@ -19,7 +21,6 @@ import type { TDocumentEventEmitter, TDocumentEventsServer, TEditorAsset, - TEmbedConfig, TExtensions, TFileHandler, TMentionHandler, @@ -151,6 +152,7 @@ export type IEditorProps = { flaggedExtensions: TExtensions[]; fileHandler: TFileHandler; forwardedRef?: React.MutableRefObject; + getEditorMetaData: (htmlContent: string) => TCustomComponentsMetaData; handleEditorReady?: (value: boolean) => void; id: string; initialValue: string; diff --git a/packages/editor/src/core/types/hook.ts b/packages/editor/src/core/types/hook.ts index 0b0a9bc91..bffd8d7e9 100644 --- a/packages/editor/src/core/types/hook.ts +++ b/packages/editor/src/core/types/hook.ts @@ -11,6 +11,7 @@ type TCoreHookProps = Pick< | "extendedEditorProps" | "extensions" | "flaggedExtensions" + | "getEditorMetaData" | "handleEditorReady" | "isTouchDevice" | "onEditorFocus" diff --git a/packages/utils/package.json b/packages/utils/package.json index 65e3165b8..9829ec8e5 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -28,16 +28,26 @@ "clsx": "^2.1.1", "date-fns": "^4.1.0", "dompurify": "3.2.7", + "hast": "^1.0.0", + "hast-util-to-mdast": "^10.1.2", "lodash-es": "catalog:", "lucide-react": "catalog:", + "mdast": "^3.0.0", "react": "catalog:", + "rehype-parse": "^9.0.1", + "rehype-remark": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-stringify": "^11.0.0", "tailwind-merge": "^2.5.5", + "unified": "^11.0.5", "uuid": "catalog:" }, "devDependencies": { "@plane/eslint-config": "workspace:*", "@plane/typescript-config": "workspace:*", + "@types/hast": "^3.0.4", "@types/lodash-es": "catalog:", + "@types/mdast": "^4.0.4", "@types/node": "catalog:", "@types/react": "catalog:", "tsdown": "catalog:", diff --git a/packages/utils/src/editor.ts b/packages/utils/src/editor/common.ts similarity index 98% rename from packages/utils/src/editor.ts rename to packages/utils/src/editor/common.ts index 4f770b9d8..9dd358911 100644 --- a/packages/utils/src/editor.ts +++ b/packages/utils/src/editor/common.ts @@ -1,5 +1,5 @@ // local imports -import { getFileURL } from "./file"; +import { getFileURL } from "../file"; type TEditorSrcArgs = { assetId: string; diff --git a/packages/utils/src/editor/index.ts b/packages/utils/src/editor/index.ts new file mode 100644 index 000000000..3d52959b1 --- /dev/null +++ b/packages/utils/src/editor/index.ts @@ -0,0 +1,2 @@ +export * from "./common"; +export * from "./markdown-parser"; diff --git a/packages/utils/src/editor/markdown-parser/common.ts b/packages/utils/src/editor/markdown-parser/common.ts new file mode 100644 index 000000000..5639dca9e --- /dev/null +++ b/packages/utils/src/editor/markdown-parser/common.ts @@ -0,0 +1,6 @@ +import type { Text as MDASTText } from "mdast"; + +export const createTextNode = (value: string): MDASTText => ({ + type: "text", + value, +}); diff --git a/packages/utils/src/editor/markdown-parser/custom-components-handler.ts b/packages/utils/src/editor/markdown-parser/custom-components-handler.ts new file mode 100644 index 000000000..0e769366f --- /dev/null +++ b/packages/utils/src/editor/markdown-parser/custom-components-handler.ts @@ -0,0 +1,41 @@ +import type { Handle } from "hast-util-to-mdast"; +// local imports +import { createTextNode } from "./common"; +import type { TCustomComponentsMetaData } from "./types"; + +type TArgs = { + metaData: TCustomComponentsMetaData; +}; + +export const parseCustomComponents = (args: TArgs): Record => { + const { metaData } = args; + + const getFileAssetDetails = (id: string) => metaData.file_assets.find((asset) => asset.id === id); + + return { + "image-component": (_state, node) => { + const properties = node.properties || {}; + const src = String(properties.src); + const fileAssetDetails = getFileAssetDetails(src); + if (!src || !fileAssetDetails) return createTextNode(""); + return createTextNode(`![${fileAssetDetails.name}](${fileAssetDetails.url})`); + }, + img: (_state, node) => { + const properties = node.properties || {}; + const src = String(properties.src); + const alt = String(properties.alt); + if (!src || !alt) return createTextNode(""); + return createTextNode(`![${alt || "Image"}](${src})`); + }, + "mention-component": (_state, node) => { + const properties = node.properties || {}; + const userId = String(properties.entity_identifier); + const userDetails = metaData.user_mentions.find((user) => user.id === userId); + if (!userDetails) return createTextNode(""); + return createTextNode(`[@${userDetails.display_name || "Unknown user"}](${userDetails.url || ""}) `); + }, + ...parseExtendedCustomComponents({ metaData }), + }; +}; + +export const parseExtendedCustomComponents = (_args: TArgs): Record => ({}); diff --git a/packages/utils/src/editor/markdown-parser/index.ts b/packages/utils/src/editor/markdown-parser/index.ts new file mode 100644 index 000000000..a3839f79b --- /dev/null +++ b/packages/utils/src/editor/markdown-parser/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./root"; diff --git a/packages/utils/src/editor/markdown-parser/marks-handler.ts b/packages/utils/src/editor/markdown-parser/marks-handler.ts new file mode 100644 index 000000000..7e3d5a6de --- /dev/null +++ b/packages/utils/src/editor/markdown-parser/marks-handler.ts @@ -0,0 +1,42 @@ +import type { Handle } from "hast-util-to-mdast"; +import type { PhrasingContent, Text as MDASTText } from "mdast"; +// local imports +import { createTextNode } from "./common"; + +const processMarkElement = (state: Parameters[0], node: Parameters[1], wrapper: string): MDASTText => { + if (node.children && node.children.length > 0) { + // Process all children and collect their text content + const processedChildren: PhrasingContent[] = []; + + for (const child of node.children) { + if (child.type === "text") { + // Direct text child - keep as is + processedChildren.push(child as MDASTText); + } else if (child.type === "element") { + // Element child - recursively process it + const processed = state.one(child, node); + if (processed) { + if (Array.isArray(processed)) { + processedChildren.push(...(processed as PhrasingContent[])); + } else { + processedChildren.push(processed as PhrasingContent); + } + } + } + } + + // Concatenate all text content and wrap with the specified wrapper + const combinedText = processedChildren.map((child) => (child.type === "text" ? child.value : "")).join(""); + + return createTextNode(`${wrapper}${combinedText}${wrapper}`); + } + + // Empty element - return empty text + return createTextNode(""); +}; + +export const parseMarks: Record = { + u: (state, node) => processMarkElement(state, node, ""), + i: (state, node) => processMarkElement(state, node, "_"), + em: (state, node) => processMarkElement(state, node, "_"), +}; diff --git a/packages/utils/src/editor/markdown-parser/root.ts b/packages/utils/src/editor/markdown-parser/root.ts new file mode 100644 index 000000000..f73ab84dc --- /dev/null +++ b/packages/utils/src/editor/markdown-parser/root.ts @@ -0,0 +1,143 @@ +// - Parses TipTap/ProseMirror HTML fragments +// - Removes tags (Markdown has no underline) +// - Adds a space after checkbox inputs for correct GFM task list rendering +// - Converts to Markdown using rehype→remark, GFM, and remark-stringify + +import type { Element as HASTElement, ElementContent, Parent as HASTParent } from "hast"; +import rehypeParse from "rehype-parse"; +import rehypeRemark from "rehype-remark"; +import remarkGfm from "remark-gfm"; +import remarkStringify from "remark-stringify"; +import { unified } from "unified"; +// local imports +import { parseCustomComponents } from "./custom-components-handler"; +import { parseMarks } from "./marks-handler"; +import type { TCustomComponentsMetaData } from "./types"; + +// Rehype plugin to handle TipTap task lists and convert them to GFM-compatible format +// TipTap structure:
  • text

  • +// We need:
  • text (with space after checkbox for proper GFM rendering) +function addSpacesToCheckboxes() { + return (tree: HASTParent) => { + const helper = (node: HASTParent): void => { + if (!Array.isArray(node.children) || node.children.length === 0) return; + + for (let i = 0; i < node.children.length; i++) { + const child = node.children[i]; + + // Check if this is a task list item + if ( + child && + child.type === "element" && + child.tagName === "li" && + child.properties && + child.properties["data-type"] === "taskItem" + ) { + const liElement = child as HASTElement; + + // Find the label and div elements + const label = liElement.children?.find( + (c) => c.type === "element" && (c as HASTElement).tagName === "label" + ) as HASTElement | undefined; + + const contentDiv = liElement.children?.find( + (c) => c.type === "element" && (c as HASTElement).tagName === "div" + ) as HASTElement | undefined; + + if (label && contentDiv) { + // Find the checkbox input + const checkbox = label.children?.find( + (c) => + c.type === "element" && + (c as HASTElement).tagName === "input" && + (c as HASTElement).properties?.type === "checkbox" + ) as HASTElement | undefined; + + if (checkbox) { + // Extract text content from the div, unwrapping any paragraph tags + const textContent: ElementContent[] = []; + if (contentDiv.children) { + for (const child of contentDiv.children) { + if (child.type === "element" && (child as HASTElement).tagName === "p") { + // Unwrap paragraph - add its children directly + const pElement = child as HASTElement; + if (pElement.children) { + textContent.push(...pElement.children); + } + } else { + // Keep other elements as-is + textContent.push(child); + } + } + } + + // Flatten the structure: move checkbox and content to be direct children of li + liElement.children = [ + checkbox, + { type: "text", value: " " }, // Add space after checkbox + ...textContent, + ]; + } + } + } else if (child && child.type === "element") { + helper(child as HASTElement); + } + } + }; + + helper(tree); + }; +} + +type TArgs = { + description_html: string; + metaData: TCustomComponentsMetaData; + name?: string; +}; + +/** + * Sanitizes a string by escaping HTML entities to prevent XSS attacks + * @param str - The string to sanitize + * @returns The sanitized string with escaped HTML entities + */ +function sanitizeHTML(str: string): string { + return str + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +export function convertHTMLToMarkdown(args: TArgs): string { + const { description_html, metaData, name } = args; + + let updatedDescriptionHtml = description_html; + if (name) { + const sanitizedName = sanitizeHTML(name); + updatedDescriptionHtml = `

    ${sanitizedName}

    \n\n${description_html}`; + } + + const result = unified() + .use(rehypeParse, { fragment: true }) + .use(addSpacesToCheckboxes) + .use(rehypeRemark, { + handlers: { + ...parseCustomComponents({ + metaData, + }), + ...parseMarks, + }, + }) + .use(remarkGfm) + .use(remarkStringify, { + handlers: { + text: (node: { value: string }): string => node.value, + }, + }) + .processSync(updatedDescriptionHtml); + + const markdown = String(result.value ?? result); + + return markdown; +} diff --git a/packages/utils/src/editor/markdown-parser/types.ts b/packages/utils/src/editor/markdown-parser/types.ts new file mode 100644 index 000000000..44a1a635d --- /dev/null +++ b/packages/utils/src/editor/markdown-parser/types.ts @@ -0,0 +1,16 @@ +export type TCoreCustomComponentsMetaData = { + file_assets: { + id: string; + name: string; + url: string; + }[]; + user_mentions: { + id: string; + display_name: string; + url: string; + }[]; +}; + +export type TExtendedCustomComponentsMetaData = unknown; + +export type TCustomComponentsMetaData = TCoreCustomComponentsMetaData & TExtendedCustomComponentsMetaData; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a2513289d..accbe2f4b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -170,7 +170,7 @@ importers: version: 9.1.1(mobx@6.12.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.2.1(next@14.2.32(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 'catalog:' version: 18.3.1 @@ -430,7 +430,7 @@ importers: version: 6.0.8(mobx@6.12.0) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.2.1(next@14.2.32(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 'catalog:' version: 18.3.1 @@ -605,7 +605,7 @@ importers: version: 6.0.8(mobx@6.12.0) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.2.1(next@14.2.32(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) posthog-js: specifier: ^1.255.1 version: 1.255.1 @@ -1438,18 +1438,42 @@ importers: dompurify: specifier: 3.2.7 version: 3.2.7 + hast: + specifier: ^1.0.0 + version: 1.0.0 + hast-util-to-mdast: + specifier: ^10.1.2 + version: 10.1.2 lodash-es: specifier: 'catalog:' version: 4.17.21 lucide-react: specifier: 'catalog:' version: 0.469.0(react@18.3.1) + mdast: + specifier: ^3.0.0 + version: 3.0.0 react: specifier: 'catalog:' version: 18.3.1 + rehype-parse: + specifier: ^9.0.1 + version: 9.0.1 + rehype-remark: + specifier: ^10.0.1 + version: 10.0.1 + remark-gfm: + specifier: ^4.0.1 + version: 4.0.1 + remark-stringify: + specifier: ^11.0.0 + version: 11.0.0 tailwind-merge: specifier: ^2.5.5 version: 2.6.0 + unified: + specifier: ^11.0.5 + version: 11.0.5 uuid: specifier: 'catalog:' version: 13.0.0 @@ -1460,9 +1484,15 @@ importers: '@plane/typescript-config': specifier: workspace:* version: link:../typescript-config + '@types/hast': + specifier: ^3.0.4 + version: 3.0.4 '@types/lodash-es': specifier: 'catalog:' version: 4.17.12 + '@types/mdast': + specifier: ^4.0.4 + version: 4.0.4 '@types/node': specifier: 'catalog:' version: 22.12.0 @@ -2127,8 +2157,8 @@ packages: '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@napi-rs/wasm-runtime@1.0.3': - resolution: {integrity: sha512-rZxtMsLwjdXkMUGC3WwsPwLNVqVqnTJT6MNIB6e+5fhMcSCPP0AOsNWuMQ5mdCq6HNjs/ZeWAEchpqeprqBD2Q==} + '@napi-rs/wasm-runtime@1.0.5': + resolution: {integrity: sha512-TBr9Cf9onSAS2LQ2+QHx6XcC6h9+RIzJgbqG3++9TUZSH204AwEy5jg3BTQ0VATsyoGj4ee49tN/y6rvaOOtcg==} '@next/env@14.2.32': resolution: {integrity: sha512-n9mQdigI6iZ/DF6pCTwMKeWgF2e8lg7qgt5M7HXMLtyhZYMnf/u905M18sSpPmHL9MKp9JHo56C6jrD2EvWxng==} @@ -2424,12 +2454,8 @@ packages: peerDependencies: '@opentelemetry/api': ^1.1.0 - '@oxc-project/runtime@0.82.3': - resolution: {integrity: sha512-LNh5GlJvYHAnMurO+EyA8jJwN1rki7l3PSHuosDh2I7h00T6/u9rCkUjg/SvPmT1CZzvhuW0y+gf7jcqUy/Usg==} - engines: {node: '>=6.9.0'} - - '@oxc-project/types@0.82.3': - resolution: {integrity: sha512-6nCUxBnGX0c6qfZW5MaF6/fmu5dHJDMiMPaioKHKs5mi5+8/FHQ7WGjgQIz1zxpmceMYfdIXkOaLYE+ejbuOtA==} + '@oxc-project/types@0.89.0': + resolution: {integrity: sha512-yuo+ECPIW5Q9mSeNmCDC2im33bfKuwW18mwkaHMQh8KakHYDzj4ci/q7wxf2qS3dMlVVCIyrs3kFtH5LmnlYnw==} '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -2800,78 +2826,91 @@ packages: '@remix-run/node-fetch-server@0.9.0': resolution: {integrity: sha512-SoLMv7dbH+njWzXnOY6fI08dFMI5+/dQ+vY3n8RnnbdG7MdJEgiP28Xj/xWlnRnED/aB6SFw56Zop+LbmaaKqA==} - '@rolldown/binding-android-arm64@1.0.0-beta.34': - resolution: {integrity: sha512-jf5GNe5jP3Sr1Tih0WKvg2bzvh5T/1TA0fn1u32xSH7ca/p5t+/QRr4VRFCV/na5vjwKEhwWrChsL2AWlY+eoA==} + '@rolldown/binding-android-arm64@1.0.0-beta.38': + resolution: {integrity: sha512-AE3HFQrjWCKLFZD1Vpiy+qsqTRwwoil1oM5WsKPSmfQ5fif/A+ZtOZetF32erZdsR7qyvns6qHEteEsF6g6rsQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-beta.34': - resolution: {integrity: sha512-2F/TqH4QuJQ34tgWxqBjFL3XV1gMzeQgUO8YRtCPGBSP0GhxtoFzsp7KqmQEothsxztlv+KhhT9Dbg3HHwHViQ==} + '@rolldown/binding-darwin-arm64@1.0.0-beta.38': + resolution: {integrity: sha512-RaoWOKc0rrFsVmKOjQpebMY6c6/I7GR1FBc25v7L/R7NlM0166mUotwGEv7vxu7ruXH4SJcFeVrfADFUUXUmmQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-beta.34': - resolution: {integrity: sha512-E1QuFslgLWbHQ8Qli/AqUKdfg0pockQPwRxVbhNQ74SciZEZpzLaujkdmOLSccMlSXDfFCF8RPnMoRAzQ9JV8Q==} + '@rolldown/binding-darwin-x64@1.0.0-beta.38': + resolution: {integrity: sha512-Ymojqc2U35iUc8NFU2XX1WQPfBRRHN6xHcrxAf9WS8BFFBn8pDrH5QPvH1tYs3lDkw6UGGbanr1RGzARqdUp1g==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-beta.34': - resolution: {integrity: sha512-VS8VInNCwnkpI9WeQaWu3kVBq9ty6g7KrHdLxYMzeqz24+w9hg712TcWdqzdY6sn+24lUoMD9jTZrZ/qfVpk0g==} + '@rolldown/binding-freebsd-x64@1.0.0-beta.38': + resolution: {integrity: sha512-0ermTQ//WzSI0nOL3z/LUWMNiE9xeM5cLGxjewPFEexqxV/0uM8/lNp9QageQ8jfc/VO1OURsGw34HYO5PaL8w==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.34': - resolution: {integrity: sha512-4St4emjcnULnxJYb/5ZDrH/kK/j6PcUgc3eAqH5STmTrcF+I9m/X2xvSF2a2bWv1DOQhxBewThu0KkwGHdgu5w==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.38': + resolution: {integrity: sha512-GADxzVUTCTp6EWI52831A29Tt7PukFe94nhg/SUsfkI33oTiNQtPxyLIT/3oRegizGuPSZSlrdBurkjDwxyEUQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.34': - resolution: {integrity: sha512-a737FTqhFUoWfnebS2SnQ2BS50p0JdukdkUBwy2J06j4hZ6Eej0zEB8vTfAqoCjn8BQKkXBy+3Sx0IRkgwz1gA==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.38': + resolution: {integrity: sha512-SKO7Exl5Yem/OSNoA5uLHzyrptUQ8Hg70kHDxuwEaH0+GUg+SQe9/7PWmc4hFKBMrJGdQtii8WZ0uIz9Dofg5Q==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.34': - resolution: {integrity: sha512-NH+FeQWKyuw0k+PbXqpFWNfvD8RPvfJk766B/njdaWz4TmiEcSB0Nb6guNw1rBpM1FmltQYb3fFnTumtC6pRfA==} + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.38': + resolution: {integrity: sha512-SOo6+WqhXPBaShLxLT0eCgH17d3Yu1lMAe4mFP0M9Bvr/kfMSOPQXuLxBcbBU9IFM9w3N6qP9xWOHO+oUJvi8Q==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.34': - resolution: {integrity: sha512-Q3RSCivp8pNadYK8ke3hLnQk08BkpZX9BmMjgwae2FWzdxhxxUiUzd9By7kneUL0vRQ4uRnhD9VkFQ+Haeqdvw==} + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.38': + resolution: {integrity: sha512-yvsQ3CyrodOX+lcoi+lejZGCOvJZa9xTsNB8OzpMDmHeZq3QzJfpYjXSAS6vie70fOkLVJb77UqYO193Cl8XBQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.0.0-beta.34': - resolution: {integrity: sha512-wDd/HrNcVoBhWWBUW3evJHoo7GJE/RofssBy3Dsiip05YUBmokQVrYAyrboOY4dzs/lJ7HYeBtWQ9hj8wlyF0A==} + '@rolldown/binding-linux-x64-musl@1.0.0-beta.38': + resolution: {integrity: sha512-84qzKMwUwikfYeOuJ4Kxm/3z15rt0nFGGQArHYIQQNSTiQdxGHxOkqXtzPFqrVfBJUdxBAf+jYzR1pttFJuWyg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-openharmony-arm64@1.0.0-beta.34': - resolution: {integrity: sha512-dH3FTEV6KTNWpYSgjSXZzeX7vLty9oBYn6R3laEdhwZftQwq030LKL+5wyQdlbX5pnbh4h127hpv3Hl1+sj8dg==} + '@rolldown/binding-openharmony-arm64@1.0.0-beta.38': + resolution: {integrity: sha512-QrNiWlce01DYH0rL8K3yUBu+lNzY+B0DyCbIc2Atan6/S6flxOL0ow5DLQvMamOI/oKhrJ4xG+9MkMb9dDHbLQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-beta.34': - resolution: {integrity: sha512-y5BUf+QtO0JsIDKA51FcGwvhJmv89BYjUl8AmN7jqD6k/eU55mH6RJYnxwCsODq5m7KSSTigVb6O7/GqB8wbPw==} + '@rolldown/binding-wasm32-wasi@1.0.0-beta.38': + resolution: {integrity: sha512-fnLtHyjwEsG4/aNV3Uv3Qd1ZbdH+CopwJNoV0RgBqrcQB8V6/Qdikd5JKvnO23kb3QvIpP+dAMGZMv1c2PJMzw==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.34': - resolution: {integrity: sha512-ga5hFhdTwpaNxEiuxZHWnD3ed0GBAzbgzS5tRHpe0ObptxM1a9Xrq6TVfNQirBLwb5Y7T/FJmJi3pmdLy95ljg==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.38': + resolution: {integrity: sha512-19cTfnGedem+RY+znA9J6ARBOCEFD4YSjnx0p5jiTm9tR6pHafRfFIfKlTXhun+NL0WWM/M0eb2IfPPYUa8+wg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.34': - resolution: {integrity: sha512-4/MBp9T9eRnZskxWr8EXD/xHvLhdjWaeX/qY9LPRG1JdCGV3DphkLTy5AWwIQ5jhAy2ZNJR5z2fYRlpWU0sIyQ==} + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.38': + resolution: {integrity: sha512-HcICm4YzFJZV+fI0O0bFLVVlsWvRNo/AB9EfUXvNYbtAxakCnQZ15oq22deFdz6sfi9Y4/SagH2kPU723dhCFA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.34': - resolution: {integrity: sha512-7O5iUBX6HSBKlQU4WykpUoEmb0wQmonb6ziKFr3dJTHud2kzDnWMqk344T0qm3uGv9Ddq6Re/94pInxo1G2d4w==} + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.38': + resolution: {integrity: sha512-4Qx6cgEPXLb0XsCyLoQcUgYBpfL0sjugftob+zhUH0EOk/NVCAIT+h0NJhY+jn7pFpeKxhNMqhvTNx3AesxIAQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-beta.34': - resolution: {integrity: sha512-LyAREkZHP5pMom7c24meKmJCdhf2hEyvam2q0unr3or9ydwDL+DJ8chTF6Av/RFPb3rH8UFBdMzO5MxTZW97oA==} + '@rolldown/pluginutils@1.0.0-beta.38': + resolution: {integrity: sha512-N/ICGKleNhA5nc9XXQG/kkKHJ7S55u0x0XUJbbkmdCnFuoRkM1Il12q9q0eX19+M7KKUEPw/daUPIRnxhcxAIw==} '@rollup/pluginutils@5.2.0': resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} @@ -3887,6 +3926,9 @@ packages: '@types/mdast@3.0.15': resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdurl@1.0.5': resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==} @@ -4586,6 +4628,9 @@ packages: resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} engines: {node: '>=4'} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} @@ -4613,6 +4658,12 @@ packages: change-case@4.1.2: resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} @@ -5201,6 +5252,10 @@ packages: resolution: {integrity: sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==} engines: {node: '>=0.12'} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} @@ -5267,6 +5322,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + eslint-config-next@14.2.32: resolution: {integrity: sha512-mP/NmYtDBsKlKIOBnH+CW+pYeyR3wBhE+26DAqQ0/aRtEBeTEjgY2wAFUugUELkTLmrX6PpuMSSTpOhz7j9kdQ==} peerDependencies: @@ -5769,9 +5828,55 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-embedded@3.0.0: + resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} + + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + + hast-util-is-body-ok-link@3.0.1: + resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-minify-whitespace@1.0.1: + resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-phrasing@3.0.1: + resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-mdast@10.1.2: + resolution: {integrity: sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + hast-util-whitespace@2.0.1: resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hast@1.0.0: + resolution: {integrity: sha512-vFUqlRV5C+xqP76Wwq2SrM0kipnmpxJm7OfvVXpB35Fp+Fn4MV+ozr+JZr5qFvyR1q/U+Foim2x+3P+x9S1PLA==} + deprecated: Renamed to rehype + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true @@ -5811,6 +5916,9 @@ packages: engines: {node: '>=12'} hasBin: true + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + html-webpack-plugin@5.6.4: resolution: {integrity: sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==} engines: {node: '>=10.13.0'} @@ -6265,6 +6373,9 @@ packages: resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} engines: {node: '>= 12.0.0'} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -6319,6 +6430,9 @@ packages: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + masonry-layout@4.2.2: resolution: {integrity: sha512-iGtAlrpHNyxaR19CvKC3npnEcAwszXoyJiI8ARV2ePi7fmYhIud25MHK8Zx4P0LCC4d3TNO9+rFa1KoK1OEOaA==} @@ -6332,15 +6446,55 @@ packages: mdast-util-definitions@5.1.2: resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + mdast-util-from-markdown@1.3.1: resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + mdast-util-to-hast@12.3.0: resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==} + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + mdast-util-to-string@3.2.0: resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdast@3.0.0: + resolution: {integrity: sha512-xySmf8g4fPKMeC07jXGz971EkLbWAJ83s4US2Tj9lEdnZ142UP5grN73H1Xd3HzrdbU5o9GYYP/y8F9ZSwLE9g==} + deprecated: '`mdast` was renamed to `remark`' + mdn-data@2.0.14: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} @@ -6378,66 +6532,150 @@ packages: micromark-core-commonmark@1.1.0: resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + micromark-factory-destination@1.1.0: resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + micromark-factory-label@1.1.0: resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + micromark-factory-space@1.1.0: resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + micromark-factory-title@1.1.0: resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + micromark-factory-whitespace@1.1.0: resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + micromark-util-character@1.2.0: resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + micromark-util-chunked@1.1.0: resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + micromark-util-classify-character@1.1.0: resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + micromark-util-combine-extensions@1.1.0: resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + micromark-util-decode-numeric-character-reference@1.1.0: resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + micromark-util-decode-string@1.1.0: resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + micromark-util-encode@1.1.0: resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + micromark-util-html-tag-name@1.2.0: resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + micromark-util-normalize-identifier@1.1.0: resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + micromark-util-resolve-all@1.1.0: resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + micromark-util-sanitize-uri@1.2.0: resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + micromark-util-subtokenize@1.1.0: resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + micromark-util-symbol@1.1.0: resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + micromark-util-types@1.1.0: resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + micromark@3.2.0: resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -6801,6 +7039,9 @@ packages: parse-svg-path@0.1.2: resolution: {integrity: sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==} + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -7148,6 +7389,9 @@ packages: property-information@6.5.0: resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + prosemirror-changeset@2.3.1: resolution: {integrity: sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==} @@ -7494,16 +7738,34 @@ packages: resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==} engines: {node: '>=0.10.0'} + rehype-minify-whitespace@6.0.2: + resolution: {integrity: sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw==} + + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + + rehype-remark@10.0.1: + resolution: {integrity: sha512-EmDndlb5NVwXGfUa4c9GPK+lXeItTilLhE6ADSaQuHr4JUlKw9MidzGzx4HpqZrNCt6vnHmEifXQiiA+CEnjYQ==} + relateurl@0.2.7: resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} engines: {node: '>= 0.10'} + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + remark-parse@10.0.2: resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==} + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + remark-rehype@10.1.0: resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==} + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + renderkid@3.0.0: resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} @@ -7573,8 +7835,9 @@ packages: vue-tsc: optional: true - rolldown@1.0.0-beta.34: - resolution: {integrity: sha512-Wwh7EwalMzzX3Yy3VN58VEajeR2Si8+HDNMf706jPLIqU7CxneRW+dQVfznf5O0TWTnJyu4npelwg2bzTXB1Nw==} + rolldown@1.0.0-beta.38: + resolution: {integrity: sha512-58frPNX55Je1YsyrtPJv9rOSR3G5efUZpRqok94Efsj0EUa8dnqJV3BldShyI7A+bVPleucOtzXHwVpJRcR0kQ==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true rollup@4.52.4: @@ -7833,6 +8096,9 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -8051,6 +8317,9 @@ packages: trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + trim-trailing-lines@2.1.0: + resolution: {integrity: sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==} + triple-beam@1.4.1: resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} engines: {node: '>= 14.0.0'} @@ -8223,24 +8492,45 @@ packages: unified@10.1.2: resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + unist-util-generated@2.0.1: resolution: {integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==} unist-util-is@5.2.1: resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + unist-util-position@4.0.4: resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==} + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + unist-util-stringify-position@3.0.3: resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + unist-util-visit-parents@5.1.3: resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + unist-util-visit@4.1.2: resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -8368,12 +8658,21 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + vfile-message@3.1.4: resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + vfile@5.3.7: resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + victory-vendor@36.9.2: resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} @@ -8444,6 +8743,9 @@ packages: resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} engines: {node: '>=10.13.0'} + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + web-vitals@4.2.4: resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} @@ -8642,6 +8944,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@adobe/css-tools@4.4.4': {} @@ -9411,7 +9716,7 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@napi-rs/wasm-runtime@1.0.3': + '@napi-rs/wasm-runtime@1.0.5': dependencies: '@emnapi/core': 1.5.0 '@emnapi/runtime': 1.5.0 @@ -9754,9 +10059,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) - '@oxc-project/runtime@0.82.3': {} - - '@oxc-project/types@0.82.3': {} + '@oxc-project/types@0.89.0': {} '@popperjs/core@2.11.8': {} @@ -10240,51 +10543,51 @@ snapshots: '@remix-run/node-fetch-server@0.9.0': {} - '@rolldown/binding-android-arm64@1.0.0-beta.34': + '@rolldown/binding-android-arm64@1.0.0-beta.38': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-beta.34': + '@rolldown/binding-darwin-arm64@1.0.0-beta.38': optional: true - '@rolldown/binding-darwin-x64@1.0.0-beta.34': + '@rolldown/binding-darwin-x64@1.0.0-beta.38': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-beta.34': + '@rolldown/binding-freebsd-x64@1.0.0-beta.38': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.34': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.38': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.34': + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.38': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.34': + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.38': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.34': + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.38': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-beta.34': + '@rolldown/binding-linux-x64-musl@1.0.0-beta.38': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-beta.34': + '@rolldown/binding-openharmony-arm64@1.0.0-beta.38': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-beta.34': + '@rolldown/binding-wasm32-wasi@1.0.0-beta.38': dependencies: - '@napi-rs/wasm-runtime': 1.0.3 + '@napi-rs/wasm-runtime': 1.0.5 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.34': + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.38': optional: true - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.34': + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.38': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.34': + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.38': optional: true - '@rolldown/pluginutils@1.0.0-beta.34': {} + '@rolldown/pluginutils@1.0.0-beta.38': {} '@rollup/pluginutils@5.2.0(rollup@4.52.4)': dependencies: @@ -11500,6 +11803,10 @@ snapshots: dependencies: '@types/unist': 2.0.11 + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/mdurl@1.0.5': {} '@types/mdurl@2.0.0': {} @@ -12273,6 +12580,8 @@ snapshots: case-sensitive-paths-webpack-plugin@2.4.0: {} + ccount@2.0.1: {} + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -12318,6 +12627,10 @@ snapshots: snake-case: 3.0.4 tslib: 2.8.1 + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + character-entities@2.0.2: {} check-error@2.1.1: {} @@ -12847,6 +13160,8 @@ snapshots: entities@5.0.0: {} + entities@6.0.1: {} + err-code@2.0.3: {} error-ex@1.3.4: @@ -12999,6 +13314,8 @@ snapshots: escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} + eslint-config-next@14.2.32(eslint@8.57.1)(typescript@5.8.3): dependencies: '@next/eslint-plugin-next': 14.2.32 @@ -13628,8 +13945,117 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-embedded@3.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-is-element: 3.0.0 + + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.3 + parse5: 7.3.0 + vfile: 6.0.3 + vfile-message: 4.0.3 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-has-property@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-body-ok-link@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-minify-whitespace@1.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-is-element: 3.0.0 + hast-util-whitespace: 3.0.0 + unist-util-is: 6.0.0 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-phrasing@3.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-has-property: 3.0.0 + hast-util-is-body-ok-link: 3.0.1 + hast-util-is-element: 3.0.0 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-mdast@10.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + hast-util-phrasing: 3.0.1 + hast-util-to-html: 9.0.5 + hast-util-to-text: 4.0.2 + hast-util-whitespace: 3.0.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-hast: 13.2.0 + mdast-util-to-string: 4.0.0 + rehype-minify-whitespace: 6.0.2 + trim-trailing-lines: 2.1.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + hast-util-whitespace@2.0.1: {} + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast@1.0.0: {} + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + he@1.2.0: {} header-case@2.0.4: @@ -13669,6 +14095,8 @@ snapshots: relateurl: 0.2.7 terser: 5.43.1 + html-void-elements@3.0.0: {} + html-webpack-plugin@5.6.4(webpack@5.101.3(@swc/core@1.13.5(@swc/helpers@0.5.17))(esbuild@0.25.0)): dependencies: '@types/html-minifier-terser': 6.1.0 @@ -14117,6 +14545,8 @@ snapshots: safe-stable-stringify: 2.5.0 triple-beam: 1.4.1 + longest-streak@3.1.0: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -14172,6 +14602,8 @@ snapshots: punycode.js: 2.3.1 uc.micro: 2.1.0 + markdown-table@3.0.4: {} + masonry-layout@4.2.2: dependencies: get-size: 2.0.3 @@ -14187,6 +14619,13 @@ snapshots: '@types/unist': 2.0.11 unist-util-visit: 4.1.2 + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + mdast-util-from-markdown@1.3.1: dependencies: '@types/mdast': 3.0.15 @@ -14204,6 +14643,85 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.0 + mdast-util-to-hast@12.3.0: dependencies: '@types/hast': 2.3.10 @@ -14215,10 +14733,40 @@ snapshots: unist-util-position: 4.0.4 unist-util-visit: 4.1.2 + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + mdast-util-to-string@3.2.0: dependencies: '@types/mdast': 3.0.15 + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdast@3.0.0: {} + mdn-data@2.0.14: {} mdurl@2.0.0: {} @@ -14262,12 +14810,95 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + micromark-factory-destination@1.1.0: dependencies: micromark-util-character: 1.2.0 micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-factory-label@1.1.0: dependencies: micromark-util-character: 1.2.0 @@ -14275,11 +14906,23 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-factory-space@1.1.0: dependencies: micromark-util-character: 1.2.0 micromark-util-types: 1.1.0 + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + micromark-factory-title@1.1.0: dependencies: micromark-factory-space: 1.1.0 @@ -14287,6 +14930,13 @@ snapshots: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-factory-whitespace@1.1.0: dependencies: micromark-factory-space: 1.1.0 @@ -14294,30 +14944,61 @@ snapshots: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-character@1.2.0: dependencies: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-chunked@1.1.0: dependencies: micromark-util-symbol: 1.1.0 + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-classify-character@1.1.0: dependencies: micromark-util-character: 1.2.0 micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-combine-extensions@1.1.0: dependencies: micromark-util-chunked: 1.1.0 micromark-util-types: 1.1.0 + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-decode-numeric-character-reference@1.1.0: dependencies: micromark-util-symbol: 1.1.0 + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-decode-string@1.1.0: dependencies: decode-named-character-reference: 1.2.0 @@ -14325,24 +15006,49 @@ snapshots: micromark-util-decode-numeric-character-reference: 1.1.0 micromark-util-symbol: 1.1.0 + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.2.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + micromark-util-encode@1.1.0: {} + micromark-util-encode@2.0.1: {} + micromark-util-html-tag-name@1.2.0: {} + micromark-util-html-tag-name@2.0.1: {} + micromark-util-normalize-identifier@1.1.0: dependencies: micromark-util-symbol: 1.1.0 + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-resolve-all@1.1.0: dependencies: micromark-util-types: 1.1.0 + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + micromark-util-sanitize-uri@1.2.0: dependencies: micromark-util-character: 1.2.0 micromark-util-encode: 1.1.0 micromark-util-symbol: 1.1.0 + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-subtokenize@1.1.0: dependencies: micromark-util-chunked: 1.1.0 @@ -14350,10 +15056,21 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + micromark-util-symbol@1.1.0: {} + micromark-util-symbol@2.0.1: {} + micromark-util-types@1.1.0: {} + micromark-util-types@2.0.2: {} + micromark@3.2.0: dependencies: '@types/debug': 4.1.12 @@ -14376,6 +15093,28 @@ snapshots: transitivePeerDependencies: - supports-color + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -14475,7 +15214,7 @@ snapshots: neo-async@2.6.2: {} - next-themes@0.2.1(next@14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-themes@0.2.1(next@14.2.32(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: next: 14.2.32(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 @@ -14726,6 +15465,10 @@ snapshots: parse-svg-path@0.1.2: {} + parse5@7.3.0: + dependencies: + entities: 6.0.1 + parseurl@1.3.3: {} pascal-case@3.1.2: @@ -14968,6 +15711,8 @@ snapshots: property-information@6.5.0: {} + property-information@7.1.0: {} + prosemirror-changeset@2.3.1: dependencies: prosemirror-transform: 1.10.4 @@ -15427,8 +16172,38 @@ snapshots: dependencies: rc: 1.2.8 + rehype-minify-whitespace@6.0.2: + dependencies: + '@types/hast': 3.0.4 + hast-util-minify-whitespace: 1.0.1 + + rehype-parse@9.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html: 2.0.3 + unified: 11.0.5 + + rehype-remark@10.0.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + hast-util-to-mdast: 10.1.2 + unified: 11.0.5 + vfile: 6.0.3 + relateurl@0.2.7: {} + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-parse@10.0.2: dependencies: '@types/mdast': 3.0.15 @@ -15437,6 +16212,15 @@ snapshots: transitivePeerDependencies: - supports-color + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-rehype@10.1.0: dependencies: '@types/hast': 2.3.10 @@ -15444,6 +16228,12 @@ snapshots: mdast-util-to-hast: 12.3.0 unified: 10.1.2 + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + renderkid@3.0.0: dependencies: css-select: 4.3.0 @@ -15492,7 +16282,7 @@ snapshots: dependencies: glob: 11.1.0 - rolldown-plugin-dts@0.16.11(rolldown@1.0.0-beta.34)(typescript@5.8.3): + rolldown-plugin-dts@0.16.11(rolldown@1.0.0-beta.38)(typescript@5.8.3): dependencies: '@babel/generator': 7.28.3 '@babel/parser': 7.28.4 @@ -15503,34 +16293,33 @@ snapshots: dts-resolver: 2.1.2 get-tsconfig: 4.10.1 magic-string: 0.30.19 - rolldown: 1.0.0-beta.34 + rolldown: 1.0.0-beta.38 optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: - oxc-resolver - supports-color - rolldown@1.0.0-beta.34: + rolldown@1.0.0-beta.38: dependencies: - '@oxc-project/runtime': 0.82.3 - '@oxc-project/types': 0.82.3 - '@rolldown/pluginutils': 1.0.0-beta.34 + '@oxc-project/types': 0.89.0 + '@rolldown/pluginutils': 1.0.0-beta.38 ansis: 4.2.0 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.34 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.34 - '@rolldown/binding-darwin-x64': 1.0.0-beta.34 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.34 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.34 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.34 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.34 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.34 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.34 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.34 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.34 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.34 - '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.34 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.34 + '@rolldown/binding-android-arm64': 1.0.0-beta.38 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.38 + '@rolldown/binding-darwin-x64': 1.0.0-beta.38 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.38 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.38 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.38 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.38 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.38 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.38 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.38 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.38 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.38 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.38 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.38 rollup@4.52.4: dependencies: @@ -15913,6 +16702,11 @@ snapshots: dependencies: safe-buffer: 5.2.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -16118,6 +16912,8 @@ snapshots: trim-lines@3.0.1: {} + trim-trailing-lines@2.1.0: {} + triple-beam@1.4.1: {} trough@2.2.0: {} @@ -16156,8 +16952,8 @@ snapshots: diff: 8.0.2 empathic: 2.0.0 hookable: 5.5.3 - rolldown: 1.0.0-beta.34 - rolldown-plugin-dts: 0.16.11(rolldown@1.0.0-beta.34)(typescript@5.8.3) + rolldown: 1.0.0-beta.38 + rolldown-plugin-dts: 0.16.11(rolldown@1.0.0-beta.38)(typescript@5.8.3) semver: 7.7.2 tinyexec: 1.0.1 tinyglobby: 0.2.15 @@ -16297,31 +17093,69 @@ snapshots: trough: 2.2.0 vfile: 5.3.7 + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-generated@2.0.1: {} unist-util-is@5.2.1: dependencies: '@types/unist': 2.0.11 + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-position@4.0.4: dependencies: '@types/unist': 2.0.11 + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position@3.0.3: dependencies: '@types/unist': 2.0.11 + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit-parents@5.1.3: dependencies: '@types/unist': 2.0.11 unist-util-is: 5.2.1 + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit@4.1.2: dependencies: '@types/unist': 2.0.11 unist-util-is: 5.2.1 unist-util-visit-parents: 5.1.3 + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + universalify@2.0.1: {} unpipe@1.0.0: {} @@ -16458,11 +17292,21 @@ snapshots: vary@1.1.2: {} + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + vfile-message@3.1.4: dependencies: '@types/unist': 2.0.11 unist-util-stringify-position: 3.0.3 + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + vfile@5.3.7: dependencies: '@types/unist': 2.0.11 @@ -16470,6 +17314,11 @@ snapshots: unist-util-stringify-position: 3.0.3 vfile-message: 3.1.4 + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + victory-vendor@36.9.2: dependencies: '@types/d3-array': 3.2.1 @@ -16551,6 +17400,8 @@ snapshots: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 + web-namespaces@2.0.1: {} + web-vitals@4.2.4: {} webidl-conversions@3.0.1: {} @@ -16770,3 +17621,5 @@ snapshots: zod: 3.25.76 zod@3.25.76: {} + + zwitch@2.0.4: {}