mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-28 21:49:40 +02:00
feat(editor): integrate Monaco Editor for local file editing and enhance language inference
This commit is contained in:
parent
864f6f798a
commit
bbc1c76c0d
5 changed files with 166 additions and 0 deletions
|
|
@ -7,6 +7,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { closeEditorPanelAtom, editorPanelAtom } from "@/atoms/editor/editor-panel.atom";
|
import { closeEditorPanelAtom, editorPanelAtom } from "@/atoms/editor/editor-panel.atom";
|
||||||
import { VersionHistoryButton } from "@/components/documents/version-history";
|
import { VersionHistoryButton } from "@/components/documents/version-history";
|
||||||
|
import { LocalFileMonaco } from "@/components/editor/local-file-monaco";
|
||||||
import { MarkdownViewer } from "@/components/markdown-viewer";
|
import { MarkdownViewer } from "@/components/markdown-viewer";
|
||||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
@ -14,6 +15,7 @@ import { Drawer, DrawerContent, DrawerHandle, DrawerTitle } from "@/components/u
|
||||||
import { useMediaQuery } from "@/hooks/use-media-query";
|
import { useMediaQuery } from "@/hooks/use-media-query";
|
||||||
import { useElectronAPI } from "@/hooks/use-platform";
|
import { useElectronAPI } from "@/hooks/use-platform";
|
||||||
import { authenticatedFetch, getBearerToken, redirectToLogin } from "@/lib/auth-utils";
|
import { authenticatedFetch, getBearerToken, redirectToLogin } from "@/lib/auth-utils";
|
||||||
|
import { inferMonacoLanguageFromPath } from "@/lib/editor-language";
|
||||||
|
|
||||||
const PlateEditor = dynamic(
|
const PlateEditor = dynamic(
|
||||||
() => import("@/components/editor/plate-editor").then((m) => ({ default: m.PlateEditor })),
|
() => import("@/components/editor/plate-editor").then((m) => ({ default: m.PlateEditor })),
|
||||||
|
|
@ -77,6 +79,7 @@ export function EditorPanelContent({
|
||||||
const [downloading, setDownloading] = useState(false);
|
const [downloading, setDownloading] = useState(false);
|
||||||
|
|
||||||
const [editedMarkdown, setEditedMarkdown] = useState<string | null>(null);
|
const [editedMarkdown, setEditedMarkdown] = useState<string | null>(null);
|
||||||
|
const [localFileContent, setLocalFileContent] = useState("");
|
||||||
const markdownRef = useRef<string>("");
|
const markdownRef = useRef<string>("");
|
||||||
const initialLoadDone = useRef(false);
|
const initialLoadDone = useRef(false);
|
||||||
const changeCountRef = useRef(0);
|
const changeCountRef = useRef(0);
|
||||||
|
|
@ -91,6 +94,7 @@ export function EditorPanelContent({
|
||||||
setError(null);
|
setError(null);
|
||||||
setEditorDoc(null);
|
setEditorDoc(null);
|
||||||
setEditedMarkdown(null);
|
setEditedMarkdown(null);
|
||||||
|
setLocalFileContent("");
|
||||||
initialLoadDone.current = false;
|
initialLoadDone.current = false;
|
||||||
changeCountRef.current = 0;
|
changeCountRef.current = 0;
|
||||||
|
|
||||||
|
|
@ -115,6 +119,7 @@ export function EditorPanelContent({
|
||||||
source_markdown: readResult.content,
|
source_markdown: readResult.content,
|
||||||
};
|
};
|
||||||
markdownRef.current = content.source_markdown;
|
markdownRef.current = content.source_markdown;
|
||||||
|
setLocalFileContent(content.source_markdown);
|
||||||
setDisplayTitle(title || inferredTitle);
|
setDisplayTitle(title || inferredTitle);
|
||||||
setEditorDoc(content);
|
setEditorDoc(content);
|
||||||
initialLoadDone.current = true;
|
initialLoadDone.current = true;
|
||||||
|
|
@ -244,6 +249,7 @@ export function EditorPanelContent({
|
||||||
? (isLocalFileMode || EDITABLE_DOCUMENT_TYPES.has(editorDoc.document_type ?? "")) &&
|
? (isLocalFileMode || EDITABLE_DOCUMENT_TYPES.has(editorDoc.document_type ?? "")) &&
|
||||||
!isLargeDocument
|
!isLargeDocument
|
||||||
: false;
|
: false;
|
||||||
|
const localFileLanguage = inferMonacoLanguageFromPath(localFilePath);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -348,6 +354,20 @@ export function EditorPanelContent({
|
||||||
</Alert>
|
</Alert>
|
||||||
<MarkdownViewer content={editorDoc.source_markdown} />
|
<MarkdownViewer content={editorDoc.source_markdown} />
|
||||||
</div>
|
</div>
|
||||||
|
) : isLocalFileMode ? (
|
||||||
|
<div className="h-full overflow-hidden">
|
||||||
|
<LocalFileMonaco
|
||||||
|
filePath={localFilePath ?? "local-file.txt"}
|
||||||
|
language={localFileLanguage}
|
||||||
|
value={localFileContent}
|
||||||
|
onChange={(next) => {
|
||||||
|
markdownRef.current = next;
|
||||||
|
setLocalFileContent(next);
|
||||||
|
if (!initialLoadDone.current) return;
|
||||||
|
setEditedMarkdown(next === (editorDoc?.source_markdown ?? "") ? null : next);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
) : isEditableType ? (
|
) : isEditableType ? (
|
||||||
<PlateEditor
|
<PlateEditor
|
||||||
key={isLocalFileMode ? localFilePath ?? "local-file" : documentId}
|
key={isLocalFileMode ? localFilePath ?? "local-file" : documentId}
|
||||||
|
|
|
||||||
56
surfsense_web/components/editor/local-file-monaco.tsx
Normal file
56
surfsense_web/components/editor/local-file-monaco.tsx
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
|
||||||
|
const MonacoEditor = dynamic(() => import("@monaco-editor/react"), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
interface LocalFileMonacoProps {
|
||||||
|
filePath: string;
|
||||||
|
language: string;
|
||||||
|
value: string;
|
||||||
|
onChange: (next: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function LocalFileMonaco({ filePath, language, value, onChange }: LocalFileMonacoProps) {
|
||||||
|
const { resolvedTheme } = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="h-full w-full overflow-hidden bg-sidebar">
|
||||||
|
<MonacoEditor
|
||||||
|
path={filePath}
|
||||||
|
language={language}
|
||||||
|
value={value}
|
||||||
|
theme={resolvedTheme === "dark" ? "vs-dark" : "vs"}
|
||||||
|
onChange={(next) => onChange(next ?? "")}
|
||||||
|
options={{
|
||||||
|
automaticLayout: true,
|
||||||
|
minimap: { enabled: false },
|
||||||
|
lineNumbers: "on",
|
||||||
|
lineNumbersMinChars: 3,
|
||||||
|
lineDecorationsWidth: 12,
|
||||||
|
glyphMargin: false,
|
||||||
|
folding: true,
|
||||||
|
overviewRulerLanes: 0,
|
||||||
|
hideCursorInOverviewRuler: true,
|
||||||
|
scrollBeyondLastLine: false,
|
||||||
|
wordWrap: "off",
|
||||||
|
scrollbar: {
|
||||||
|
vertical: "hidden",
|
||||||
|
horizontal: "hidden",
|
||||||
|
alwaysConsumeMouseWheel: false,
|
||||||
|
},
|
||||||
|
tabSize: 2,
|
||||||
|
insertSpaces: true,
|
||||||
|
fontSize: 12,
|
||||||
|
fontFamily:
|
||||||
|
"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace",
|
||||||
|
renderWhitespace: "selection",
|
||||||
|
smoothScrolling: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
34
surfsense_web/lib/editor-language.ts
Normal file
34
surfsense_web/lib/editor-language.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
const EXTENSION_TO_MONACO_LANGUAGE: Record<string, string> = {
|
||||||
|
css: "css",
|
||||||
|
csv: "plaintext",
|
||||||
|
cjs: "javascript",
|
||||||
|
html: "html",
|
||||||
|
htm: "html",
|
||||||
|
ini: "ini",
|
||||||
|
js: "javascript",
|
||||||
|
json: "json",
|
||||||
|
markdown: "markdown",
|
||||||
|
md: "markdown",
|
||||||
|
mjs: "javascript",
|
||||||
|
py: "python",
|
||||||
|
sql: "sql",
|
||||||
|
toml: "plaintext",
|
||||||
|
ts: "typescript",
|
||||||
|
tsx: "typescript",
|
||||||
|
xml: "xml",
|
||||||
|
yaml: "yaml",
|
||||||
|
yml: "yaml",
|
||||||
|
};
|
||||||
|
|
||||||
|
export function inferMonacoLanguageFromPath(filePath: string | null | undefined): string {
|
||||||
|
if (!filePath) return "plaintext";
|
||||||
|
|
||||||
|
const fileName = filePath.split("/").pop() ?? filePath;
|
||||||
|
const extensionIndex = fileName.lastIndexOf(".");
|
||||||
|
if (extensionIndex <= 0 || extensionIndex === fileName.length - 1) {
|
||||||
|
return "plaintext";
|
||||||
|
}
|
||||||
|
|
||||||
|
const extension = fileName.slice(extensionIndex + 1).toLowerCase();
|
||||||
|
return EXTENSION_TO_MONACO_LANGUAGE[extension] ?? "plaintext";
|
||||||
|
}
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
"@babel/standalone": "^7.29.2",
|
"@babel/standalone": "^7.29.2",
|
||||||
"@hookform/resolvers": "^5.2.2",
|
"@hookform/resolvers": "^5.2.2",
|
||||||
"@marsidev/react-turnstile": "^1.5.0",
|
"@marsidev/react-turnstile": "^1.5.0",
|
||||||
|
"@monaco-editor/react": "^4.7.0",
|
||||||
"@number-flow/react": "^0.5.10",
|
"@number-flow/react": "^0.5.10",
|
||||||
"@platejs/autoformat": "^52.0.11",
|
"@platejs/autoformat": "^52.0.11",
|
||||||
"@platejs/basic-nodes": "^52.0.11",
|
"@platejs/basic-nodes": "^52.0.11",
|
||||||
|
|
@ -106,6 +107,7 @@
|
||||||
"lenis": "^1.3.17",
|
"lenis": "^1.3.17",
|
||||||
"lowlight": "^3.3.0",
|
"lowlight": "^3.3.0",
|
||||||
"lucide-react": "^0.577.0",
|
"lucide-react": "^0.577.0",
|
||||||
|
"monaco-editor": "^0.55.1",
|
||||||
"motion": "^12.23.22",
|
"motion": "^12.23.22",
|
||||||
"next": "^16.1.0",
|
"next": "^16.1.0",
|
||||||
"next-intl": "^4.6.1",
|
"next-intl": "^4.6.1",
|
||||||
|
|
|
||||||
54
surfsense_web/pnpm-lock.yaml
generated
54
surfsense_web/pnpm-lock.yaml
generated
|
|
@ -29,6 +29,9 @@ importers:
|
||||||
'@marsidev/react-turnstile':
|
'@marsidev/react-turnstile':
|
||||||
specifier: ^1.5.0
|
specifier: ^1.5.0
|
||||||
version: 1.5.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
version: 1.5.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
|
'@monaco-editor/react':
|
||||||
|
specifier: ^4.7.0
|
||||||
|
version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
'@number-flow/react':
|
'@number-flow/react':
|
||||||
specifier: ^0.5.10
|
specifier: ^0.5.10
|
||||||
version: 0.5.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
version: 0.5.14(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
|
|
@ -263,6 +266,9 @@ importers:
|
||||||
lucide-react:
|
lucide-react:
|
||||||
specifier: ^0.577.0
|
specifier: ^0.577.0
|
||||||
version: 0.577.0(react@19.2.4)
|
version: 0.577.0(react@19.2.4)
|
||||||
|
monaco-editor:
|
||||||
|
specifier: ^0.55.1
|
||||||
|
version: 0.55.1
|
||||||
motion:
|
motion:
|
||||||
specifier: ^12.23.22
|
specifier: ^12.23.22
|
||||||
version: 12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
version: 12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||||
|
|
@ -1980,6 +1986,16 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
mediabunny: ^1.0.0
|
mediabunny: ^1.0.0
|
||||||
|
|
||||||
|
'@monaco-editor/loader@1.7.0':
|
||||||
|
resolution: {integrity: sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==}
|
||||||
|
|
||||||
|
'@monaco-editor/react@4.7.0':
|
||||||
|
resolution: {integrity: sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==}
|
||||||
|
peerDependencies:
|
||||||
|
monaco-editor: '>= 0.25.0 < 1'
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
'@napi-rs/canvas-android-arm64@0.1.97':
|
'@napi-rs/canvas-android-arm64@0.1.97':
|
||||||
resolution: {integrity: sha512-V1c/WVw+NzH8vk7ZK/O8/nyBSCQimU8sfMsB/9qeSvdkGKNU7+mxy/bIF0gTgeBFmHpj30S4E9WHMSrxXGQuVQ==}
|
resolution: {integrity: sha512-V1c/WVw+NzH8vk7ZK/O8/nyBSCQimU8sfMsB/9qeSvdkGKNU7+mxy/bIF0gTgeBFmHpj30S4E9WHMSrxXGQuVQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
|
|
@ -5368,6 +5384,9 @@ packages:
|
||||||
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
|
|
||||||
|
dompurify@3.2.7:
|
||||||
|
resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==}
|
||||||
|
|
||||||
dompurify@3.3.1:
|
dompurify@3.3.1:
|
||||||
resolution: {integrity: sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==}
|
resolution: {integrity: sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==}
|
||||||
|
|
||||||
|
|
@ -6745,6 +6764,11 @@ packages:
|
||||||
markdown-table@3.0.4:
|
markdown-table@3.0.4:
|
||||||
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
|
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
|
||||||
|
|
||||||
|
marked@14.0.0:
|
||||||
|
resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
marked@15.0.12:
|
marked@15.0.12:
|
||||||
resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==}
|
resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==}
|
||||||
engines: {node: '>= 18'}
|
engines: {node: '>= 18'}
|
||||||
|
|
@ -6965,6 +6989,9 @@ packages:
|
||||||
module-details-from-path@1.0.4:
|
module-details-from-path@1.0.4:
|
||||||
resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==}
|
resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==}
|
||||||
|
|
||||||
|
monaco-editor@0.55.1:
|
||||||
|
resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==}
|
||||||
|
|
||||||
motion-dom@12.34.3:
|
motion-dom@12.34.3:
|
||||||
resolution: {integrity: sha512-sYgFe+pR9aIM7o4fhs2aXtOI+oqlUd33N9Yoxcgo1Fv7M20sRkHtCmzE/VRNIcq7uNJ+qio+Xubt1FXH3pQ+eQ==}
|
resolution: {integrity: sha512-sYgFe+pR9aIM7o4fhs2aXtOI+oqlUd33N9Yoxcgo1Fv7M20sRkHtCmzE/VRNIcq7uNJ+qio+Xubt1FXH3pQ+eQ==}
|
||||||
|
|
||||||
|
|
@ -7943,6 +7970,9 @@ packages:
|
||||||
stable-hash@0.0.5:
|
stable-hash@0.0.5:
|
||||||
resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==}
|
resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==}
|
||||||
|
|
||||||
|
state-local@1.0.7:
|
||||||
|
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
|
||||||
|
|
||||||
stop-iteration-iterator@1.1.0:
|
stop-iteration-iterator@1.1.0:
|
||||||
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
|
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
@ -10050,6 +10080,17 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
mediabunny: 1.39.2
|
mediabunny: 1.39.2
|
||||||
|
|
||||||
|
'@monaco-editor/loader@1.7.0':
|
||||||
|
dependencies:
|
||||||
|
state-local: 1.0.7
|
||||||
|
|
||||||
|
'@monaco-editor/react@4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
||||||
|
dependencies:
|
||||||
|
'@monaco-editor/loader': 1.7.0
|
||||||
|
monaco-editor: 0.55.1
|
||||||
|
react: 19.2.4
|
||||||
|
react-dom: 19.2.4(react@19.2.4)
|
||||||
|
|
||||||
'@napi-rs/canvas-android-arm64@0.1.97':
|
'@napi-rs/canvas-android-arm64@0.1.97':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
@ -13748,6 +13789,10 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype: 2.3.0
|
domelementtype: 2.3.0
|
||||||
|
|
||||||
|
dompurify@3.2.7:
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/trusted-types': 2.0.7
|
||||||
|
|
||||||
dompurify@3.3.1:
|
dompurify@3.3.1:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/trusted-types': 2.0.7
|
'@types/trusted-types': 2.0.7
|
||||||
|
|
@ -15327,6 +15372,8 @@ snapshots:
|
||||||
|
|
||||||
markdown-table@3.0.4: {}
|
markdown-table@3.0.4: {}
|
||||||
|
|
||||||
|
marked@14.0.0: {}
|
||||||
|
|
||||||
marked@15.0.12: {}
|
marked@15.0.12: {}
|
||||||
|
|
||||||
marked@17.0.3: {}
|
marked@17.0.3: {}
|
||||||
|
|
@ -15822,6 +15869,11 @@ snapshots:
|
||||||
|
|
||||||
module-details-from-path@1.0.4: {}
|
module-details-from-path@1.0.4: {}
|
||||||
|
|
||||||
|
monaco-editor@0.55.1:
|
||||||
|
dependencies:
|
||||||
|
dompurify: 3.2.7
|
||||||
|
marked: 14.0.0
|
||||||
|
|
||||||
motion-dom@12.34.3:
|
motion-dom@12.34.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
motion-utils: 12.29.2
|
motion-utils: 12.29.2
|
||||||
|
|
@ -17073,6 +17125,8 @@ snapshots:
|
||||||
|
|
||||||
stable-hash@0.0.5: {}
|
stable-hash@0.0.5: {}
|
||||||
|
|
||||||
|
state-local@1.0.7: {}
|
||||||
|
|
||||||
stop-iteration-iterator@1.1.0:
|
stop-iteration-iterator@1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue