From e6492e079672a253d9b02164f3e4dacc40682ae3 Mon Sep 17 00:00:00 2001 From: Palanikannan M Date: Wed, 5 Feb 2025 17:13:47 +0530 Subject: [PATCH 1/7] fix: make floating link generic and use it for all editors --- .gitignore | 2 + .../editors/document/page-renderer.tsx | 159 ++---------------- .../components/editors/editor-container.tsx | 144 ++++++++++++++-- .../core/components/links/link-edit-view.tsx | 97 +++++------ .../core/components/links/link-preview.tsx | 2 +- .../src/core/components/links/link-view.tsx | 2 +- .../src/core/components/menus/menu-items.ts | 69 ++++++++ .../src/core/extensions/image/extension.tsx | 2 + packages/editor/src/core/helpers/common.ts | 34 +++- .../src/core/helpers/editor-commands.ts | 25 ++- packages/editor/src/core/types/editor.ts | 19 ++- .../pages/editor/header/toolbar.tsx | 2 - web/core/constants/editor.ts | 11 +- 13 files changed, 352 insertions(+), 216 deletions(-) diff --git a/.gitignore b/.gitignore index 80607b92f2d..8d30d1d5dc5 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,5 @@ deploy/selfhost/plane-app/ ## Storybook *storybook.log output.css + +dev-editor diff --git a/packages/editor/src/core/components/editors/document/page-renderer.tsx b/packages/editor/src/core/components/editors/document/page-renderer.tsx index a297686564d..31a31fe3d88 100644 --- a/packages/editor/src/core/components/editors/document/page-renderer.tsx +++ b/packages/editor/src/core/components/editors/document/page-renderer.tsx @@ -1,20 +1,6 @@ -import { useCallback, useRef, useState } from "react"; -import { - autoUpdate, - computePosition, - flip, - hide, - shift, - useDismiss, - useFloating, - useInteractions, -} from "@floating-ui/react"; -import { Node } from "@tiptap/pm/model"; -import { EditorView } from "@tiptap/pm/view"; -import { Editor, ReactRenderer } from "@tiptap/react"; +import { Editor } from "@tiptap/react"; // components import { EditorContainer, EditorContentWrapper } from "@/components/editors"; -import { LinkView, LinkViewProps } from "@/components/links"; import { AIFeaturesMenu, BlockMenu, EditorBubbleMenu } from "@/components/menus"; // types import { TAIHandler, TDisplayConfig } from "@/types"; @@ -31,133 +17,24 @@ type IPageRenderer = { export const PageRenderer = (props: IPageRenderer) => { const { aiHandler, bubbleMenuEnabled, displayConfig, editor, editorContainerClassName, id, tabIndex } = props; - // states - const [linkViewProps, setLinkViewProps] = useState(); - const [isOpen, setIsOpen] = useState(false); - const [coordinates, setCoordinates] = useState<{ x: number; y: number }>(); - const [cleanup, setCleanup] = useState(() => () => {}); - - const { refs, floatingStyles, context } = useFloating({ - open: isOpen, - onOpenChange: setIsOpen, - middleware: [flip(), shift(), hide({ strategy: "referenceHidden" })], - whileElementsMounted: autoUpdate, - }); - - const dismiss = useDismiss(context, { - ancestorScroll: true, - }); - - const { getFloatingProps } = useInteractions([dismiss]); - - const floatingElementRef = useRef(null); - - const closeLinkView = () => setIsOpen(false); - - const handleLinkHover = useCallback( - (event: React.MouseEvent) => { - if (!editor) return; - const target = event.target as HTMLElement; - const view = editor.view as EditorView; - - if (!target || !view) return; - const pos = view.posAtDOM(target, 0); - if (!pos || pos < 0) return; - - if (target.nodeName !== "A") return; - - const node = view.state.doc.nodeAt(pos) as Node; - if (!node || !node.isAtom) return; - - // we need to check if any of the marks are links - const marks = node.marks; - - if (!marks) return; - - const linkMark = marks.find((mark) => mark.type.name === "link"); - - if (!linkMark) return; - - if (floatingElementRef.current) { - floatingElementRef.current?.remove(); - } - - if (cleanup) cleanup(); - - const href = linkMark.attrs.href; - const componentLink = new ReactRenderer(LinkView, { - props: { - view: "LinkPreview", - url: href, - editor: editor, - from: pos, - to: pos + node.nodeSize, - }, - editor, - }); - - const referenceElement = target as HTMLElement; - const floatingElement = componentLink.element as HTMLElement; - - floatingElementRef.current = floatingElement; - - const cleanupFunc = autoUpdate(referenceElement, floatingElement, () => { - computePosition(referenceElement, floatingElement, { - placement: "bottom", - middleware: [ - flip(), - shift(), - hide({ - strategy: "referenceHidden", - }), - ], - }).then(({ x, y }) => { - setCoordinates({ x: x - 300, y: y - 50 }); - setIsOpen(true); - setLinkViewProps({ - closeLinkView: closeLinkView, - view: "LinkPreview", - url: href, - editor: editor, - from: pos, - to: pos + node.nodeSize, - }); - }); - }); - - setCleanup(cleanupFunc); - }, - [editor, cleanup] - ); return ( - <> -
- - - {editor.isEditable && ( -
- {bubbleMenuEnabled && } - - -
- )} -
-
- {isOpen && linkViewProps && coordinates && ( -
- -
- )} - +
+ + + {editor.isEditable && ( +
+ {bubbleMenuEnabled && } + + +
+ )} +
+
); }; diff --git a/packages/editor/src/core/components/editors/editor-container.tsx b/packages/editor/src/core/components/editors/editor-container.tsx index d6563f7b085..9c57866f322 100644 --- a/packages/editor/src/core/components/editors/editor-container.tsx +++ b/packages/editor/src/core/components/editors/editor-container.tsx @@ -1,7 +1,12 @@ -import { FC, ReactNode } from "react"; -import { Editor } from "@tiptap/react"; +import { autoUpdate, flip, hide, shift, useDismiss, useFloating, useInteractions } from "@floating-ui/react"; +import { Node } from "@tiptap/pm/model"; +import { EditorView } from "@tiptap/pm/view"; +import { Editor, useEditorState } from "@tiptap/react"; +import { FC, ReactNode, useCallback, useEffect, useState } from "react"; // plane utils import { cn } from "@plane/utils"; +// components +import { LinkView, LinkViewProps } from "@/components/links"; // constants import { DEFAULT_DISPLAY_CONFIG } from "@/constants/config"; // types @@ -17,6 +22,103 @@ interface EditorContainerProps { export const EditorContainer: FC = (props) => { const { children, displayConfig, editor, editorContainerClassName, id } = props; + // states for link hover functionality + const [linkViewProps, setLinkViewProps] = useState(); + const [isOpen, setIsOpen] = useState(false); + const [virtualElement, setVirtualElement] = useState(null); + + const editorState = useEditorState({ + editor, + selector: ({ editor }: { editor: Editor }) => ({ + openLink: editor.storage.image?.openLink, + linkPosition: editor.storage.image?.linkPosition, + }), + }); + + useEffect(() => { + if (editorState.openLink) { + setIsOpen(true); + if (editorState.linkPosition) { + const element = editor?.view.domAtPos(editorState.linkPosition)?.node as HTMLElement; + setVirtualElement(element); + } + setLinkViewProps({ + url: "", + view: "LinkEditView", + editor: editor, + from: editorState.linkPosition.from, + to: editorState.linkPosition.to, + closeLinkView: () => { + setIsOpen(false); + if (editor) editor.storage.image.openLink = false; + }, + }); + } else { + setIsOpen(false); + } + }, [editorState.openLink, editorState.linkPosition, editor]); + + const { refs, floatingStyles, context } = useFloating({ + open: isOpen, + onOpenChange: setIsOpen, + elements: { + reference: virtualElement, + }, + middleware: [ + flip({ + fallbackPlacements: ["top", "bottom"], + }), + shift({ + padding: 5, + }), + hide(), + ], + whileElementsMounted: autoUpdate, + placement: "bottom-start", + }); + + const dismiss = useDismiss(context); + const { getFloatingProps } = useInteractions([dismiss]); + + const handleLinkHover = useCallback( + (event: React.MouseEvent) => { + if (!editor || editorState.openLink) return; // Don't handle hover if link edit is open + const target = event.target as HTMLElement; + const view = editor.view as EditorView; + + if (!target || !view) return; + const pos = view.posAtDOM(target, 0); + if (!pos || pos < 0) return; + + if (target.nodeName !== "A") return; + + const node = view.state.doc.nodeAt(pos) as Node; + if (!node || !node.isAtom) return; + + const marks = node.marks; + if (!marks) return; + + const linkMark = marks.find((mark) => mark.type.name === "link"); + if (!linkMark) return; + + setVirtualElement(target); + + setLinkViewProps({ + view: "LinkPreview", + url: linkMark.attrs.href, + editor: editor, + from: pos, + to: pos + node.nodeSize, + closeLinkView: () => { + setIsOpen(false); + editor.storage.image.openLink = false; + }, + }); + + setIsOpen(true); + }, + [editor, editorState.openLink] + ); const handleContainerClick = (event: React.MouseEvent) => { if (event.target !== event.currentTarget) return; @@ -66,21 +168,29 @@ export const EditorContainer: FC = (props) => { }; return ( -
+
+ {children} +
+ {isOpen && linkViewProps && virtualElement && ( +
+ +
)} - > - {children} -
+ ); }; diff --git a/packages/editor/src/core/components/links/link-edit-view.tsx b/packages/editor/src/core/components/links/link-edit-view.tsx index 665e7500a7a..cb69bd9a615 100644 --- a/packages/editor/src/core/components/links/link-edit-view.tsx +++ b/packages/editor/src/core/components/links/link-edit-view.tsx @@ -1,6 +1,6 @@ -import { useEffect, useRef, useState } from "react"; import { Node } from "@tiptap/pm/model"; import { Link2Off } from "lucide-react"; +import { useState } from "react"; // components import { LinkViewProps } from "@/components/links"; // helpers @@ -39,75 +39,76 @@ export const LinkEditView = ({ }) => { const { editor, from, to } = viewProps; - const [positionRef, setPositionRef] = useState({ from: from, to: to }); - const [localUrl, setLocalUrl] = useState(viewProps.url); - - const linkRemoved = useRef(); - const getText = (from: number, to: number) => { if (to >= editor.state.doc.content.size) return ""; - const text = editor.state.doc.textBetween(from, to, "\n"); return text; }; + const [positionRef] = useState({ from, to }); + const [localUrl, setLocalUrl] = useState(viewProps.url); + const [localText, setLocalText] = useState(getText(from, to)); + const [linkRemoved, setLinkRemoved] = useState(false); + const handleUpdateLink = (url: string) => { setLocalUrl(url); }; - useEffect( - () => () => { - if (linkRemoved.current) return; - - const url = isValidHttpUrl(localUrl) ? localUrl : viewProps.url; - - if (to >= editor.state.doc.content.size) return; - - editor.view.dispatch(editor.state.tr.removeMark(from, to, editor.schema.marks.link)); - editor.view.dispatch(editor.state.tr.addMark(from, to, editor.schema.marks.link.create({ href: url }))); - }, - [localUrl, editor, from, to, viewProps.url] - ); - const handleUpdateText = (text: string) => { - if (text === "") { - return; - } - - const node = editor.view.state.doc.nodeAt(from) as Node; - if (!node) return; - const marks = node.marks; - if (!marks) return; - - editor.chain().setTextSelection(from).run(); - - editor.chain().deleteRange({ from: positionRef.from, to: positionRef.to }).run(); - editor.chain().insertContent(text).run(); + if (text === "") return; + setLocalText(text); + }; - editor - .chain() - .setTextSelection({ - from: from, - to: from + text.length, - }) - .run(); + const applyChanges = () => { + if (linkRemoved) return; - setPositionRef({ from: from, to: from + text.length }); + console.log("localUrl", localUrl); + const { url, isValid } = isValidHttpUrl(localUrl); + console.log("url", url); + if (to >= editor.state.doc.content.size || !isValid) return; - marks.forEach((mark) => { - editor.chain().setMark(mark.type.name, mark.attrs).run(); - }); + // Apply URL change + editor.view.dispatch(editor.state.tr.removeMark(from, to, editor.schema.marks.link)); + editor.view.dispatch(editor.state.tr.addMark(from, to, editor.schema.marks.link.create({ href: url }))); + + // Apply text change if different + if (localText !== getText(from, to)) { + const node = editor.view.state.doc.nodeAt(from) as Node; + if (!node) return; + const marks = node.marks; + if (!marks) return; + + editor + .chain() + .setTextSelection(from) + .deleteRange({ from: positionRef.from, to: positionRef.to }) + .insertContent(localText) + .setTextSelection({ from, to: from + localText.length }) + .run(); + + marks.forEach((mark) => { + editor.chain().setMark(mark.type.name, mark.attrs).run(); + }); + } }; const removeLink = () => { editor.view.dispatch(editor.state.tr.removeMark(from, to, editor.schema.marks.link)); - linkRemoved.current = true; + setLinkRemoved(true); viewProps.closeLinkView(); }; return (
e.key === "Enter" && viewProps.closeLinkView()} + onKeyDown={(e) => { + if (e.key === "Enter") { + applyChanges(); + viewProps.closeLinkView(); + e.stopPropagation(); + setLocalUrl(""); + setLocalText(""); + } + }} className="shadow-md rounded p-2 flex flex-col gap-3 bg-custom-background-90 border-custom-border-100 border-2" > handleUpdateText(e.target.value)} />
diff --git a/packages/editor/src/core/components/links/link-preview.tsx b/packages/editor/src/core/components/links/link-preview.tsx index 1237c7c9804..aadcb4539e9 100644 --- a/packages/editor/src/core/components/links/link-preview.tsx +++ b/packages/editor/src/core/components/links/link-preview.tsx @@ -25,7 +25,7 @@ export const LinkPreview = ({
-

{url.length > 40 ? url.slice(0, 40) + "..." : url}

+

{url?.length > 40 ? url.slice(0, 40) + "..." : url}

{isOpen && linkViewProps && virtualElement && ( -
+
)} diff --git a/packages/editor/src/core/components/links/link-edit-view.tsx b/packages/editor/src/core/components/links/link-edit-view.tsx index cb69bd9a615..a7cfb20c00c 100644 --- a/packages/editor/src/core/components/links/link-edit-view.tsx +++ b/packages/editor/src/core/components/links/link-edit-view.tsx @@ -1,6 +1,6 @@ import { Node } from "@tiptap/pm/model"; import { Link2Off } from "lucide-react"; -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; // components import { LinkViewProps } from "@/components/links"; // helpers @@ -49,6 +49,15 @@ export const LinkEditView = ({ const [localUrl, setLocalUrl] = useState(viewProps.url); const [localText, setLocalText] = useState(getText(from, to)); const [linkRemoved, setLinkRemoved] = useState(false); + const hasSubmitted = useRef(false); + + useEffect(() => { + return () => { + if (!hasSubmitted.current && !linkRemoved && viewProps.url === "") { + removeLink(); + } + }; + }, []); const handleUpdateLink = (url: string) => { setLocalUrl(url); @@ -61,10 +70,9 @@ export const LinkEditView = ({ const applyChanges = () => { if (linkRemoved) return; + hasSubmitted.current = true; - console.log("localUrl", localUrl); const { url, isValid } = isValidHttpUrl(localUrl); - console.log("url", url); if (to >= editor.state.doc.content.size || !isValid) return; // Apply URL change @@ -124,12 +132,14 @@ export const LinkEditView = ({ onChange={(e) => handleUpdateText(e.target.value)} />
-
- - -
+ {viewProps.url !== "" && ( +
+ + +
+ )}
); }; diff --git a/packages/editor/src/core/components/menus/menu-items.ts b/packages/editor/src/core/components/menus/menu-items.ts index df52abd21e5..30adba1aa5a 100644 --- a/packages/editor/src/core/components/menus/menu-items.ts +++ b/packages/editor/src/core/components/menus/menu-items.ts @@ -54,6 +54,8 @@ import { import { TCommandWithProps, TEditorCommands } from "@/types"; import { TextSelection } from "@tiptap/pm/state"; import { ResolvedPos } from "@tiptap/pm/model"; +import { CustomLinkStorage } from "@/extensions"; +import { getExtensionStorage } from "@/helpers/get-extension-storage"; type isActiveFunction = (params?: TCommandWithProps) => boolean; type commandFunction = (params?: TCommandWithProps) => void; @@ -234,15 +236,19 @@ export const LinkItem = (editor: Editor): EditorMenuItem<"link"> => isActive: () => editor?.isActive("link"), command: ({ url, text }) => { // create selection on the current word - const { from, to } = selectCurrentWord(editor); - - editor.storage.image = { - ...editor.storage.image, - linkPosition: from, - openLink: true, - }; - editor.storage.image.openLink = true; - editor.storage.image.linkPosition = { from, to }; + const { empty } = editor.state.selection; + let position: { from: number; to: number }; + if (empty) { + position = selectCurrentWord(editor); + } else { + position = { from: editor.state.selection.from, to: editor.state.selection.to }; + } + if (!position) return; + const { from, to } = position; + + const editorLinkStorage = getExtensionStorage(editor, "link"); + editorLinkStorage.isPreviewOpen = true; + editorLinkStorage.posToInsert = { from, to }; setLinkEditor(editor, url, text); }, @@ -264,7 +270,7 @@ const selectCurrentWord = (editor: Editor) => { // If we're on a space, return early if (text[posInNode] === " ") { - return false; + return { to: posInNode, from: posInNode }; } // Find word boundaries diff --git a/packages/editor/src/core/extensions/core-without-props.ts b/packages/editor/src/core/extensions/core-without-props.ts index 8864f49f703..1d2efd790b9 100644 --- a/packages/editor/src/core/extensions/core-without-props.ts +++ b/packages/editor/src/core/extensions/core-without-props.ts @@ -66,7 +66,7 @@ export const CoreEditorExtensionsWithoutProps = [ autolink: true, linkOnPaste: true, protocols: ["http", "https"], - validate: (url: string) => isValidHttpUrl(url), + validate: (url: string) => isValidHttpUrl(url).isValid, HTMLAttributes: { class: "text-custom-primary-300 underline underline-offset-[3px] hover:text-custom-primary-500 transition-colors cursor-pointer", diff --git a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx index 2bd84fcb310..e525bc6da4b 100644 --- a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx +++ b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx @@ -2,6 +2,7 @@ import { Editor, NodeViewProps, NodeViewWrapper } from "@tiptap/react"; import { useEffect, useRef, useState } from "react"; // extensions import { CustomImageBlock, CustomImageUploader, ImageAttributes } from "@/extensions/custom-image"; +import { getExtensionStorage } from "@/helpers/get-extension-storage"; export type CustoBaseImageNodeViewProps = { getPos: () => number; @@ -76,7 +77,7 @@ export const CustomImageNode = (props: CustomImageNodeProps) => { failedToLoadImage={failedToLoadImage} getPos={getPos} loadImageFromFileSystem={setImageFromFileSystem} - maxFileSize={editor.storage.imageComponent.maxFileSize} + maxFileSize={getExtensionStorage(editor, "imageComponent").maxFileSize} node={node} setIsUploaded={setIsUploaded} selected={selected} diff --git a/packages/editor/src/core/extensions/custom-image/custom-image.ts b/packages/editor/src/core/extensions/custom-image/custom-image.ts index 3b64db8d098..14735254f81 100644 --- a/packages/editor/src/core/extensions/custom-image/custom-image.ts +++ b/packages/editor/src/core/extensions/custom-image/custom-image.ts @@ -30,9 +30,11 @@ declare module "@tiptap/core" { export const getImageComponentImageFileMap = (editor: Editor) => (editor.storage.imageComponent as UploadImageExtensionStorage | undefined)?.fileMap; - -export interface UploadImageExtensionStorage { +export interface CustomImageExtensionStorage { fileMap: Map; + deletedImageSet: Map; + uploadInProgress: boolean; + maxFileSize: number; } export type UploadEntity = ({ event: "insert" } | { event: "drop"; file: File }) & { hasOpenedFileInputOnce?: boolean }; @@ -46,7 +48,7 @@ export const CustomImageExtension = (props: TFileHandler) => { validation: { maxFileSize }, } = props; - return Image.extend, UploadImageExtensionStorage>({ + return Image.extend, CustomImageExtensionStorage>({ name: "imageComponent", selectable: true, group: "block", diff --git a/packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts b/packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts index c27970d9287..ee97747929e 100644 --- a/packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts +++ b/packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts @@ -2,14 +2,14 @@ import { mergeAttributes } from "@tiptap/core"; import { Image } from "@tiptap/extension-image"; import { ReactNodeViewRenderer } from "@tiptap/react"; // components -import { CustomImageNode, UploadImageExtensionStorage } from "@/extensions/custom-image"; +import { CustomImageExtensionStorage, CustomImageNode } from "@/extensions/custom-image"; // types import { TFileHandler } from "@/types"; export const CustomReadOnlyImageExtension = (props: Pick) => { const { getAssetSrc } = props; - return Image.extend, UploadImageExtensionStorage>({ + return Image.extend, CustomImageExtensionStorage>({ name: "imageComponent", selectable: false, group: "block", @@ -52,6 +52,9 @@ export const CustomReadOnlyImageExtension = (props: Pick(), + uploadInProgress: false, + maxFileSize: 0, // escape markdown for images markdown: { serialize() {}, diff --git a/packages/editor/src/core/extensions/custom-link/extension.tsx b/packages/editor/src/core/extensions/custom-link/extension.tsx index ee065f512b9..6c94eeaef72 100644 --- a/packages/editor/src/core/extensions/custom-link/extension.tsx +++ b/packages/editor/src/core/extensions/custom-link/extension.tsx @@ -73,7 +73,12 @@ declare module "@tiptap/core" { } } -export const CustomLinkExtension = Mark.create({ +export type CustomLinkStorage = { + isPreviewOpen: boolean; + posToInsert: { from: number; to: number }; +}; + +export const CustomLinkExtension = Mark.create({ name: "link", priority: 1000, @@ -242,4 +247,11 @@ export const CustomLinkExtension = Mark.create({ return plugins; }, + + addStorage() { + return { + isPreviewOpen: false, + posToInsert: { from: 0, to: 0 }, + }; + }, }); diff --git a/packages/editor/src/core/extensions/extensions.tsx b/packages/editor/src/core/extensions/extensions.tsx index 0b772baf9db..7cfbf29eff1 100644 --- a/packages/editor/src/core/extensions/extensions.tsx +++ b/packages/editor/src/core/extensions/extensions.tsx @@ -102,7 +102,7 @@ export const CoreEditorExtensions = (args: TArguments): Extensions => { autolink: true, linkOnPaste: true, protocols: ["http", "https"], - validate: (url: string) => isValidHttpUrl(url), + validate: (url: string) => isValidHttpUrl(url).isValid, HTMLAttributes: { class: "text-custom-primary-300 underline underline-offset-[3px] hover:text-custom-primary-500 transition-colors cursor-pointer", diff --git a/packages/editor/src/core/extensions/headers.ts b/packages/editor/src/core/extensions/headers.ts index 3960d5f039c..958cf6ca32b 100644 --- a/packages/editor/src/core/extensions/headers.ts +++ b/packages/editor/src/core/extensions/headers.ts @@ -8,7 +8,11 @@ export interface IMarking { sequence: number; } -export const HeadingListExtension = Extension.create({ +export type HeadingExtensionStorage = { + headings: IMarking[]; +}; + +export const HeadingListExtension = Extension.create({ name: "headingList", addStorage() { diff --git a/packages/editor/src/core/extensions/image/extension.tsx b/packages/editor/src/core/extensions/image/extension.tsx index 252433a3cf0..6766b4d0c03 100644 --- a/packages/editor/src/core/extensions/image/extension.tsx +++ b/packages/editor/src/core/extensions/image/extension.tsx @@ -1,13 +1,13 @@ import ImageExt from "@tiptap/extension-image"; import { ReactNodeViewRenderer } from "@tiptap/react"; +// extensions +import { CustomImageNode } from "@/extensions"; // helpers import { insertEmptyParagraphAtNodeBoundaries } from "@/helpers/insert-empty-paragraph-at-node-boundary"; // plugins import { ImageExtensionStorage, TrackImageDeletionPlugin, TrackImageRestorationPlugin } from "@/plugins/image"; // types import { TFileHandler } from "@/types"; -// extensions -import { CustomImageNode } from "@/extensions"; export const ImageExtension = (fileHandler: TFileHandler) => { const { @@ -56,8 +56,6 @@ export const ImageExtension = (fileHandler: TFileHandler) => { deletedImageSet: new Map(), uploadInProgress: false, maxFileSize, - openLink: false, - linkPosition: 0, }; }, diff --git a/packages/editor/src/core/extensions/image/image-component-without-props.tsx b/packages/editor/src/core/extensions/image/image-component-without-props.tsx index b6dbd4c308d..1d7a61663ae 100644 --- a/packages/editor/src/core/extensions/image/image-component-without-props.tsx +++ b/packages/editor/src/core/extensions/image/image-component-without-props.tsx @@ -1,10 +1,10 @@ import { mergeAttributes } from "@tiptap/core"; import { Image } from "@tiptap/extension-image"; // extensions -import { UploadImageExtensionStorage } from "@/extensions"; +import { ImageExtensionStorage } from "@/plugins/image"; export const CustomImageComponentWithoutProps = () => - Image.extend, UploadImageExtensionStorage>({ + Image.extend, ImageExtensionStorage>({ name: "imageComponent", selectable: true, group: "block", @@ -48,6 +48,8 @@ export const CustomImageComponentWithoutProps = () => return { fileMap: new Map(), deletedImageSet: new Map(), + uploadInProgress: false, + maxFileSize: 0, }; }, }); diff --git a/packages/editor/src/core/extensions/mentions/extension-config.ts b/packages/editor/src/core/extensions/mentions/extension-config.ts index 827137a1df1..bd43c885cac 100644 --- a/packages/editor/src/core/extensions/mentions/extension-config.ts +++ b/packages/editor/src/core/extensions/mentions/extension-config.ts @@ -9,7 +9,11 @@ export type TMentionExtensionOptions = MentionOptions & { renderComponent: TMentionHandler["renderComponent"]; }; -export const CustomMentionExtensionConfig = Mention.extend({ +export type MentionExtensionStorage = { + mentionsOpen: boolean; +}; + +export const CustomMentionExtensionConfig = Mention.extend({ addAttributes() { return { [EMentionComponentAttributeNames.ID]: { diff --git a/packages/editor/src/core/extensions/read-only-extensions.tsx b/packages/editor/src/core/extensions/read-only-extensions.tsx index e39973f9c90..2a66bde1032 100644 --- a/packages/editor/src/core/extensions/read-only-extensions.tsx +++ b/packages/editor/src/core/extensions/read-only-extensions.tsx @@ -87,7 +87,7 @@ export const CoreReadOnlyEditorExtensions = (props: Props): Extensions => { autolink: true, linkOnPaste: true, protocols: ["http", "https"], - validate: (url: string) => isValidHttpUrl(url), + validate: (url: string) => isValidHttpUrl(url).isValid, HTMLAttributes: { class: "text-custom-primary-300 underline underline-offset-[3px] hover:text-custom-primary-500 transition-colors cursor-pointer", diff --git a/packages/editor/src/core/helpers/editor-commands.ts b/packages/editor/src/core/helpers/editor-commands.ts index d82d10760b3..8d8aeb716e7 100644 --- a/packages/editor/src/core/helpers/editor-commands.ts +++ b/packages/editor/src/core/helpers/editor-commands.ts @@ -1,10 +1,11 @@ import { Editor, Range } from "@tiptap/core"; +// types +import { InsertImageComponentProps } from "@/extensions"; // extensions import { replaceCodeWithText } from "@/extensions/code/utils/replace-code-block-with-text"; // helpers import { findTableAncestor } from "@/helpers/common"; -// types -import { InsertImageComponentProps } from "@/extensions"; +import { getExtensionStorage } from "@/helpers/get-extension-storage"; export const setText = (editor: Editor, range?: Range) => { if (range) editor.chain().focus().deleteRange(range).setNode("paragraph").run(); @@ -183,7 +184,6 @@ export const toggleTextColor = (color: string | undefined, editor: Editor, range }; export const setLinkEditor = (editor: Editor, url: string, text?: string) => { - editor.storage.image.openLink = true; const { selection } = editor.state; const previousSelection = { from: selection.from, to: selection.to }; if (text) { @@ -199,6 +199,7 @@ export const setLinkEditor = (editor: Editor, url: string, text?: string) => { editor.commands.setTextSelection({ from: previousFrom, to: previousFrom + text.length }); } editor.chain().focus().setLink({ href: url }).run(); + getExtensionStorage(editor, "link").isPreviewOpen = true; }; export const toggleBackgroundColor = (color: string | undefined, editor: Editor, range?: Range) => { diff --git a/packages/editor/src/core/helpers/get-extension-storage.ts b/packages/editor/src/core/helpers/get-extension-storage.ts new file mode 100644 index 00000000000..d5dcebf742c --- /dev/null +++ b/packages/editor/src/core/helpers/get-extension-storage.ts @@ -0,0 +1,23 @@ +import { Editor } from "@tiptap/core"; +import { + CustomImageExtensionStorage, + CustomLinkStorage, + HeadingExtensionStorage, + MentionExtensionStorage, +} from "@/extensions"; +import { ImageExtensionStorage } from "@/plugins/image"; + +type ExtensionNames = "imageComponent" | "image" | "link" | "headingList" | "mention"; + +interface ExtensionStorageMap { + imageComponent: CustomImageExtensionStorage; + image: ImageExtensionStorage; + link: CustomLinkStorage; + headingList: HeadingExtensionStorage; + mention: MentionExtensionStorage; +} + +export const getExtensionStorage = ( + editor: Editor, + extensionName: K +): ExtensionStorageMap[K] => editor.storage[extensionName]; From aeb3f54a646abcf064252b9477be8e0802892e06 Mon Sep 17 00:00:00 2001 From: Palanikannan M Date: Thu, 6 Feb 2025 22:00:53 +0530 Subject: [PATCH 3/7] chore: link view seperated --- .../components/editors/editor-container.tsx | 123 +-------------- .../components/editors/editor-content.tsx | 2 +- .../editors/link-view-container.tsx | 147 ++++++++++++++++++ .../core/components/links/link-edit-view.tsx | 31 ++-- .../core/components/links/link-preview.tsx | 16 +- .../extensions/custom-image/custom-image.ts | 7 +- 6 files changed, 188 insertions(+), 138 deletions(-) create mode 100644 packages/editor/src/core/components/editors/link-view-container.tsx diff --git a/packages/editor/src/core/components/editors/editor-container.tsx b/packages/editor/src/core/components/editors/editor-container.tsx index a32245503b3..ae3d05b20e3 100644 --- a/packages/editor/src/core/components/editors/editor-container.tsx +++ b/packages/editor/src/core/components/editors/editor-container.tsx @@ -1,18 +1,13 @@ -import { autoUpdate, flip, hide, shift, useDismiss, useFloating, useInteractions } from "@floating-ui/react"; -import { Node } from "@tiptap/pm/model"; -import { EditorView } from "@tiptap/pm/view"; -import { Editor, useEditorState } from "@tiptap/react"; -import { FC, ReactNode, useCallback, useEffect, useState } from "react"; +import { Editor } from "@tiptap/react"; +import { FC, ReactNode, useRef } from "react"; // plane utils import { cn } from "@plane/utils"; -// components -import { LinkView, LinkViewProps } from "@/components/links"; // constants import { DEFAULT_DISPLAY_CONFIG } from "@/constants/config"; -// storage -import { getExtensionStorage } from "@/helpers/get-extension-storage"; // types import { TDisplayConfig } from "@/types"; +// components +import { LinkViewContainer } from "./link-view-container"; interface EditorContainerProps { children: ReactNode; @@ -24,107 +19,7 @@ interface EditorContainerProps { export const EditorContainer: FC = (props) => { const { children, displayConfig, editor, editorContainerClassName, id } = props; - // states for link hover functionality - const [linkViewProps, setLinkViewProps] = useState(); - const [isOpen, setIsOpen] = useState(false); - const [virtualElement, setVirtualElement] = useState(null); - - const editorState = useEditorState({ - editor, - selector: ({ editor }: { editor: Editor }) => ({ - linkExtensionStorage: getExtensionStorage(editor, "link"), - }), - }); - - useEffect(() => { - if (editorState.linkExtensionStorage.isPreviewOpen && editor && editorState.linkExtensionStorage.posToInsert) { - // Get the coordinates of the selection - const coords = editor.view.coordsAtPos(editorState.linkExtensionStorage.posToInsert.from); - const rect = new DOMRect(coords.left, coords.top, 0, coords.bottom - coords.top); - - setVirtualElement({ - getBoundingClientRect() { - return rect; - }, - }); - - setLinkViewProps({ - url: "", - view: "LinkEditView", - editor: editor, - from: editorState.linkExtensionStorage.posToInsert.from, - to: editorState.linkExtensionStorage.posToInsert.to, - closeLinkView: () => { - setIsOpen(false); - if (editor) editorState.linkExtensionStorage.isPreviewOpen = false; - }, - }); - - setIsOpen(true); - } - }, [editorState.linkExtensionStorage.isPreviewOpen, editorState.linkExtensionStorage.posToInsert, editor]); - - const { refs, floatingStyles, context } = useFloating({ - open: isOpen, - onOpenChange: setIsOpen, - elements: { - reference: virtualElement, - }, - middleware: [ - flip({ - fallbackPlacements: ["top", "bottom"], - }), - shift({ - padding: 5, - }), - hide(), - ], - whileElementsMounted: autoUpdate, - placement: "bottom-start", - }); - - const dismiss = useDismiss(context); - const { getFloatingProps } = useInteractions([dismiss]); - - const handleLinkHover = useCallback( - (event: React.MouseEvent) => { - if (!editor || editorState.linkExtensionStorage.isPreviewOpen) return; // Don't handle hover if link edit is open - const target = event.target as HTMLElement; - const view = editor.view as EditorView; - - if (!target || !view) return; - const pos = view.posAtDOM(target, 0); - if (!pos || pos < 0) return; - - if (target.nodeName !== "A") return; - - const node = view.state.doc.nodeAt(pos) as Node; - if (!node || !node.isAtom) return; - - const marks = node.marks; - if (!marks) return; - - const linkMark = marks.find((mark) => mark.type.name === "link"); - if (!linkMark) return; - - setVirtualElement(target); - - setLinkViewProps({ - view: "LinkPreview", - url: linkMark.attrs.href, - editor: editor, - from: pos, - to: pos + node.nodeSize, - closeLinkView: () => { - setIsOpen(false); - editorState.linkExtensionStorage.isPreviewOpen = false; - }, - }); - - setIsOpen(true); - }, - [editor, editorState.linkExtensionStorage.isPreviewOpen] - ); + const containerRef = useRef(null); const handleContainerClick = (event: React.MouseEvent) => { if (event.target !== event.currentTarget) return; @@ -176,10 +71,10 @@ export const EditorContainer: FC = (props) => { return ( <>
= (props) => { > {children}
- {isOpen && linkViewProps && virtualElement && ( -
- -
- )} + ); }; diff --git a/packages/editor/src/core/components/editors/editor-content.tsx b/packages/editor/src/core/components/editors/editor-content.tsx index b05457f2e63..8171d06d9d2 100644 --- a/packages/editor/src/core/components/editors/editor-content.tsx +++ b/packages/editor/src/core/components/editors/editor-content.tsx @@ -1,5 +1,5 @@ -import { FC, ReactNode } from "react"; import { Editor, EditorContent } from "@tiptap/react"; +import { FC, ReactNode } from "react"; interface EditorContentProps { children?: ReactNode; diff --git a/packages/editor/src/core/components/editors/link-view-container.tsx b/packages/editor/src/core/components/editors/link-view-container.tsx new file mode 100644 index 00000000000..12455e8bc25 --- /dev/null +++ b/packages/editor/src/core/components/editors/link-view-container.tsx @@ -0,0 +1,147 @@ +import { autoUpdate, flip, hide, shift, useDismiss, useFloating, useInteractions } from "@floating-ui/react"; +import { Editor, useEditorState } from "@tiptap/react"; +import { FC, useCallback, useEffect, useState } from "react"; + +// components +import { LinkView, LinkViewProps } from "@/components/links"; +// storage +import { getExtensionStorage } from "@/helpers/get-extension-storage"; + +interface LinkViewContainerProps { + editor: Editor | null; + containerRef: React.RefObject; +} + +export const LinkViewContainer: FC = ({ editor, containerRef }) => { + // states for link hover functionality + const [linkViewProps, setLinkViewProps] = useState(); + const [isOpen, setIsOpen] = useState(false); + const [virtualElement, setVirtualElement] = useState(null); + + const editorState = useEditorState({ + editor, + selector: ({ editor }: { editor: Editor }) => ({ + linkExtensionStorage: getExtensionStorage(editor, "link"), + }), + }); + + useEffect(() => { + if (editorState.linkExtensionStorage.isPreviewOpen && editor && editorState.linkExtensionStorage.posToInsert) { + // Get the coordinates of the selection + const coords = editor.view.coordsAtPos(editorState.linkExtensionStorage.posToInsert.from); + const rect = new DOMRect(coords.left, coords.top, 0, coords.bottom - coords.top); + + setVirtualElement({ + getBoundingClientRect() { + return rect; + }, + }); + + setLinkViewProps({ + url: "", + view: "LinkEditView", + editor: editor, + from: editorState.linkExtensionStorage.posToInsert.from, + to: editorState.linkExtensionStorage.posToInsert.to, + closeLinkView: () => { + setIsOpen(false); + if (editor) editorState.linkExtensionStorage.isPreviewOpen = false; + }, + }); + + setIsOpen(true); + } + }, [editorState.linkExtensionStorage.isPreviewOpen, editorState.linkExtensionStorage.posToInsert, editor]); + + const { refs, floatingStyles, context } = useFloating({ + open: isOpen, + onOpenChange: setIsOpen, + elements: { + reference: virtualElement, + }, + middleware: [ + flip({ + fallbackPlacements: ["top", "bottom"], + }), + shift({ + padding: 5, + }), + hide(), + ], + whileElementsMounted: autoUpdate, + placement: "bottom-start", + onEscapeKeyDown: (e) => { + e.preventDefault(); + e.stopPropagation(); + setIsOpen(false); + if (editor) editorState.linkExtensionStorage.isPreviewOpen = false; + }, + }); + + const dismiss = useDismiss(context); + const { getFloatingProps } = useInteractions([dismiss]); + + const handleLinkHover = useCallback( + (event: MouseEvent) => { + if (!editor || editorState.linkExtensionStorage.isPreviewOpen) return; + + // Find the closest anchor tag from the event target + const target = (event.target as HTMLElement)?.closest("a"); + if (!target) return; + + const view = editor.view; + if (!view) return; + + try { + const pos = view.posAtDOM(target, 0); + if (pos === undefined || pos < 0) return; + + const node = view.state.doc.nodeAt(pos); + if (!node) return; + + const linkMark = node.marks?.find((mark) => mark.type.name === "link"); + if (!linkMark) return; + + setVirtualElement(target); + setLinkViewProps({ + view: "LinkPreview", + url: linkMark.attrs.href, + editor: editor, + from: pos, + to: pos + node.nodeSize, + closeLinkView: () => { + setIsOpen(false); + editorState.linkExtensionStorage.isPreviewOpen = false; + }, + }); + + setIsOpen(true); + } catch (error) { + console.error("Error handling link hover:", error); + } + }, + [editor, editorState.linkExtensionStorage.isPreviewOpen] + ); + + // Set up event listeners + useEffect(() => { + const container = containerRef.current; + if (!container) return; + + container.addEventListener("mouseover", handleLinkHover); + + return () => { + container.removeEventListener("mouseover", handleLinkHover); + }; + }, [handleLinkHover, containerRef]); + + return ( + <> + {isOpen && linkViewProps && virtualElement && ( +
+ +
+ )} + + ); +}; diff --git a/packages/editor/src/core/components/links/link-edit-view.tsx b/packages/editor/src/core/components/links/link-edit-view.tsx index a7cfb20c00c..56c881f6a70 100644 --- a/packages/editor/src/core/components/links/link-edit-view.tsx +++ b/packages/editor/src/core/components/links/link-edit-view.tsx @@ -5,17 +5,20 @@ import { useEffect, useRef, useState } from "react"; import { LinkViewProps } from "@/components/links"; // helpers import { isValidHttpUrl } from "@/helpers/common"; +import { preventDefault } from "jsx-dom-cjs"; const InputView = ({ label, defaultValue, placeholder, onChange, + autoFocus, }: { label: string; defaultValue: string; placeholder: string; onChange: (e: React.ChangeEvent) => void; + autoFocus?: boolean; }) => (
@@ -27,6 +30,7 @@ const InputView = ({ className="w-[280px] outline-none bg-custom-background-90 text-custom-text-900 text-sm" defaultValue={defaultValue} onChange={onChange} + autoFocus={autoFocus} />
); @@ -51,13 +55,14 @@ export const LinkEditView = ({ const [linkRemoved, setLinkRemoved] = useState(false); const hasSubmitted = useRef(false); - useEffect(() => { - return () => { + useEffect( + () => () => { if (!hasSubmitted.current && !linkRemoved && viewProps.url === "") { removeLink(); } - }; - }, []); + }, + [linkRemoved, viewProps.url] + ); const handleUpdateLink = (url: string) => { setLocalUrl(url); @@ -118,12 +123,14 @@ export const LinkEditView = ({ } }} className="shadow-md rounded p-2 flex flex-col gap-3 bg-custom-background-90 border-custom-border-100 border-2" + tabIndex={0} > handleUpdateLink(e.target.value)} + autoFocus /> handleUpdateText(e.target.value)} />
- {viewProps.url !== "" && ( -
- - -
- )} + {/* {viewProps.url !== "" && ( */} +
+ + +
+ {/* )} */}
); }; diff --git a/packages/editor/src/core/components/links/link-preview.tsx b/packages/editor/src/core/components/links/link-preview.tsx index aadcb4539e9..93815edaec1 100644 --- a/packages/editor/src/core/components/links/link-preview.tsx +++ b/packages/editor/src/core/components/links/link-preview.tsx @@ -30,12 +30,16 @@ export const LinkPreview = ({ - - + {editor.isEditable && ( + <> + + + + )}
diff --git a/packages/editor/src/core/extensions/custom-image/custom-image.ts b/packages/editor/src/core/extensions/custom-image/custom-image.ts index 14735254f81..5649bdd8ed2 100644 --- a/packages/editor/src/core/extensions/custom-image/custom-image.ts +++ b/packages/editor/src/core/extensions/custom-image/custom-image.ts @@ -4,12 +4,12 @@ import { ReactNodeViewRenderer } from "@tiptap/react"; import { v4 as uuidv4 } from "uuid"; // extensions import { CustomImageNode } from "@/extensions/custom-image"; +// helpers +import { insertEmptyParagraphAtNodeBoundaries } from "@/helpers/insert-empty-paragraph-at-node-boundary"; // plugins import { TrackImageDeletionPlugin, TrackImageRestorationPlugin, isFileValid } from "@/plugins/image"; // types import { TFileHandler } from "@/types"; -// helpers -import { insertEmptyParagraphAtNodeBoundaries } from "@/helpers/insert-empty-paragraph-at-node-boundary"; export type InsertImageComponentProps = { file?: File; @@ -29,7 +29,8 @@ declare module "@tiptap/core" { } export const getImageComponentImageFileMap = (editor: Editor) => - (editor.storage.imageComponent as UploadImageExtensionStorage | undefined)?.fileMap; + (editor.storage.imageComponent as CustomImageExtensionStorage | undefined)?.fileMap; + export interface CustomImageExtensionStorage { fileMap: Map; deletedImageSet: Map; From f9cc0a5b10687acb24fcd422adfe9bde67bb0b18 Mon Sep 17 00:00:00 2001 From: Palanikannan M Date: Mon, 10 Feb 2025 17:42:39 +0530 Subject: [PATCH 4/7] fix: editor link edit view across multiple links resets now --- .../editors/document/page-renderer.tsx | 16 +- .../editors/link-view-container.tsx | 48 +- .../core/components/links/link-edit-view.tsx | 146 +- .../src/core/components/links/link-view.tsx | 1 + yarn.lock | 1304 ++++++++++++++++- 5 files changed, 1374 insertions(+), 141 deletions(-) diff --git a/packages/editor/src/core/components/editors/document/page-renderer.tsx b/packages/editor/src/core/components/editors/document/page-renderer.tsx index 31a31fe3d88..cb7d3ce3745 100644 --- a/packages/editor/src/core/components/editors/document/page-renderer.tsx +++ b/packages/editor/src/core/components/editors/document/page-renderer.tsx @@ -1,7 +1,9 @@ -import { Editor } from "@tiptap/react"; +import { Editor, useEditorState } from "@tiptap/react"; // components import { EditorContainer, EditorContentWrapper } from "@/components/editors"; import { AIFeaturesMenu, BlockMenu, EditorBubbleMenu } from "@/components/menus"; +// helpers +import { getExtensionStorage } from "@/helpers/get-extension-storage"; // types import { TAIHandler, TDisplayConfig } from "@/types"; @@ -18,6 +20,14 @@ type IPageRenderer = { export const PageRenderer = (props: IPageRenderer) => { const { aiHandler, bubbleMenuEnabled, displayConfig, editor, editorContainerClassName, id, tabIndex } = props; + const editorState = useEditorState({ + editor, + selector: ({ editor }: { editor: Editor }) => ({ + linkExtensionStorage: getExtensionStorage(editor, "link"), + }), + }); + + console.log("!editorState.linkExtensionStorage.isPreviewOpen", editorState.linkExtensionStorage); return (
{ {editor.isEditable && (
- {bubbleMenuEnabled && } + {bubbleMenuEnabled && !editorState.linkExtensionStorage.isPreviewOpen && ( + + )}
diff --git a/packages/editor/src/core/components/editors/link-view-container.tsx b/packages/editor/src/core/components/editors/link-view-container.tsx index 12455e8bc25..8669e988268 100644 --- a/packages/editor/src/core/components/editors/link-view-container.tsx +++ b/packages/editor/src/core/components/editors/link-view-container.tsx @@ -37,9 +37,11 @@ export const LinkViewContainer: FC = ({ editor, containe }, }); + const node = editor.state.doc.nodeAt(editorState.linkExtensionStorage.posToInsert.from); setLinkViewProps({ url: "", view: "LinkEditView", + text: node?.text || "", editor: editor, from: editorState.linkExtensionStorage.posToInsert.from, to: editorState.linkExtensionStorage.posToInsert.to, @@ -70,16 +72,11 @@ export const LinkViewContainer: FC = ({ editor, containe ], whileElementsMounted: autoUpdate, placement: "bottom-start", - onEscapeKeyDown: (e) => { - e.preventDefault(); - e.stopPropagation(); - setIsOpen(false); - if (editor) editorState.linkExtensionStorage.isPreviewOpen = false; - }, }); const dismiss = useDismiss(context); - const { getFloatingProps } = useInteractions([dismiss]); + + const { getReferenceProps, getFloatingProps } = useInteractions([dismiss]); const handleLinkHover = useCallback( (event: MouseEvent) => { @@ -89,6 +86,11 @@ export const LinkViewContainer: FC = ({ editor, containe const target = (event.target as HTMLElement)?.closest("a"); if (!target) return; + const referenceProps = getReferenceProps(); + Object.entries(referenceProps).forEach(([key, value]) => { + target.setAttribute(key, value as string); + }); + const view = editor.view; if (!view) return; @@ -103,24 +105,28 @@ export const LinkViewContainer: FC = ({ editor, containe if (!linkMark) return; setVirtualElement(target); - setLinkViewProps({ - view: "LinkPreview", - url: linkMark.attrs.href, - editor: editor, - from: pos, - to: pos + node.nodeSize, - closeLinkView: () => { - setIsOpen(false); - editorState.linkExtensionStorage.isPreviewOpen = false; - }, - }); - - setIsOpen(true); + + // Only update if not already open or if hovering over a different link + if (!isOpen || (linkViewProps && (linkViewProps.from !== pos || linkViewProps.to !== pos + node.nodeSize))) { + setLinkViewProps({ + view: "LinkPreview", // Always start with preview for new links + url: linkMark.attrs.href, + text: node.text || "", + editor: editor, + from: pos, + to: pos + node.nodeSize, + closeLinkView: () => { + setIsOpen(false); + editorState.linkExtensionStorage.isPreviewOpen = false; + }, + }); + setIsOpen(true); + } } catch (error) { console.error("Error handling link hover:", error); } }, - [editor, editorState.linkExtensionStorage.isPreviewOpen] + [editor, editorState.linkExtensionStorage.isPreviewOpen, getReferenceProps, isOpen, linkViewProps] ); // Set up event listeners diff --git a/packages/editor/src/core/components/links/link-edit-view.tsx b/packages/editor/src/core/components/links/link-edit-view.tsx index 56c881f6a70..4334bdb0c3d 100644 --- a/packages/editor/src/core/components/links/link-edit-view.tsx +++ b/packages/editor/src/core/components/links/link-edit-view.tsx @@ -5,91 +5,88 @@ import { useEffect, useRef, useState } from "react"; import { LinkViewProps } from "@/components/links"; // helpers import { isValidHttpUrl } from "@/helpers/common"; -import { preventDefault } from "jsx-dom-cjs"; - -const InputView = ({ - label, - defaultValue, - placeholder, - onChange, - autoFocus, -}: { + +interface InputViewProps { label: string; - defaultValue: string; + value: string; placeholder: string; - onChange: (e: React.ChangeEvent) => void; + onChange: (value: string) => void; autoFocus?: boolean; -}) => ( +} + +const InputView = ({ label, value, placeholder, onChange, autoFocus }: InputViewProps) => (
{ - e.stopPropagation(); - }} - className="w-[280px] outline-none bg-custom-background-90 text-custom-text-900 text-sm" - defaultValue={defaultValue} - onChange={onChange} + onClick={(e) => e.stopPropagation()} + className="w-[280px] outline-none bg-custom-background-90 text-custom-text-900 text-sm border border-custom-border-300 rounded-md p-2" + value={value} + onChange={(e) => onChange(e.target.value)} autoFocus={autoFocus} />
); -export const LinkEditView = ({ - viewProps, -}: { +interface LinkEditViewProps { viewProps: LinkViewProps; switchView: (view: "LinkPreview" | "LinkEditView" | "LinkInputView") => void; -}) => { - const { editor, from, to } = viewProps; +} - const getText = (from: number, to: number) => { - if (to >= editor.state.doc.content.size) return ""; - const text = editor.state.doc.textBetween(from, to, "\n"); - return text; - }; +export const LinkEditView = ({ viewProps }: LinkEditViewProps) => { + const { editor, from, to, url: initialUrl, text: initialText, closeLinkView } = viewProps; + // State const [positionRef] = useState({ from, to }); - const [localUrl, setLocalUrl] = useState(viewProps.url); - const [localText, setLocalText] = useState(getText(from, to)); + const [localUrl, setLocalUrl] = useState(initialUrl); + const [localText, setLocalText] = useState(initialText ?? ""); const [linkRemoved, setLinkRemoved] = useState(false); const hasSubmitted = useRef(false); + // Effects useEffect( - () => () => { - if (!hasSubmitted.current && !linkRemoved && viewProps.url === "") { - removeLink(); - } - }, - [linkRemoved, viewProps.url] + () => + // Cleanup effect: Remove link if not submitted and url is empty + () => { + if (!hasSubmitted.current && !linkRemoved && initialUrl === "") { + try { + removeLink(); + } catch (e) {} + } + }, + [linkRemoved, initialUrl] ); - const handleUpdateLink = (url: string) => { - setLocalUrl(url); - }; + // Sync state with props + useEffect(() => { + setLocalUrl(initialUrl); + }, [initialUrl]); + + useEffect(() => { + if (initialText) setLocalText(initialText); + }, [initialText]); - const handleUpdateText = (text: string) => { - if (text === "") return; - setLocalText(text); + // Handlers + const handleTextChange = (value: string) => { + if (value.trim() !== "") setLocalText(value); }; - const applyChanges = () => { - if (linkRemoved) return; + const applyChanges = (): boolean => { + if (linkRemoved) return false; hasSubmitted.current = true; const { url, isValid } = isValidHttpUrl(localUrl); - if (to >= editor.state.doc.content.size || !isValid) return; + if (to >= editor.state.doc.content.size || !isValid) return false; // Apply URL change - editor.view.dispatch(editor.state.tr.removeMark(from, to, editor.schema.marks.link)); - editor.view.dispatch(editor.state.tr.addMark(from, to, editor.schema.marks.link.create({ href: url }))); + const tr = editor.state.tr; + tr.removeMark(from, to, editor.schema.marks.link).addMark(from, to, editor.schema.marks.link.create({ href: url })); + editor.view.dispatch(tr); // Apply text change if different - if (localText !== getText(from, to)) { + if (localText !== initialText) { const node = editor.view.state.doc.nodeAt(from) as Node; - if (!node) return; - const marks = node.marks; - if (!marks) return; + if (!node || !node.marks) return false; editor .chain() @@ -99,54 +96,47 @@ export const LinkEditView = ({ .setTextSelection({ from, to: from + localText.length }) .run(); - marks.forEach((mark) => { + // Restore marks + node.marks.forEach((mark) => { editor.chain().setMark(mark.type.name, mark.attrs).run(); }); } + + return true; }; const removeLink = () => { editor.view.dispatch(editor.state.tr.removeMark(from, to, editor.schema.marks.link)); setLinkRemoved(true); - viewProps.closeLinkView(); + closeLinkView(); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + e.stopPropagation(); + if (applyChanges()) { + closeLinkView(); + setLocalUrl(""); + setLocalText(""); + } + } }; return (
{ - if (e.key === "Enter") { - applyChanges(); - viewProps.closeLinkView(); - e.stopPropagation(); - setLocalUrl(""); - setLocalText(""); - } - }} + onKeyDown={handleKeyDown} className="shadow-md rounded p-2 flex flex-col gap-3 bg-custom-background-90 border-custom-border-100 border-2" tabIndex={0} > - handleUpdateLink(e.target.value)} - autoFocus - /> - handleUpdateText(e.target.value)} - /> + +
- {/* {viewProps.url !== "" && ( */}
-
- {/* )} */}
); }; diff --git a/packages/editor/src/core/components/links/link-view.tsx b/packages/editor/src/core/components/links/link-view.tsx index faa911e99c4..abe0e487df3 100644 --- a/packages/editor/src/core/components/links/link-view.tsx +++ b/packages/editor/src/core/components/links/link-view.tsx @@ -9,6 +9,7 @@ export interface LinkViewProps { from: number; to: number; url: string; + text?: string; closeLinkView: () => void; } diff --git a/yarn.lock b/yarn.lock index cbdb3473d17..306d41b8cd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -86,6 +86,11 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz" integrity sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g== +"@babel/compat-data@^7.26.5": + version "7.26.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.8.tgz#821c1d35641c355284d4a870b8a4a7b0c141e367" + integrity sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ== + "@babel/core@^7.18.5", "@babel/core@^7.18.9", "@babel/core@^7.25.2": version "7.26.0" resolved "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz" @@ -107,6 +112,28 @@ json5 "^2.2.3" semver "^6.3.1" +"@babel/core@^7.26.0": + version "7.26.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.8.tgz#7742f11c75acea6b08a8e24c5c0c8c89e89bf53e" + integrity sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.26.2" + "@babel/generator" "^7.26.8" + "@babel/helper-compilation-targets" "^7.26.5" + "@babel/helper-module-transforms" "^7.26.0" + "@babel/helpers" "^7.26.7" + "@babel/parser" "^7.26.8" + "@babel/template" "^7.26.8" + "@babel/traverse" "^7.26.8" + "@babel/types" "^7.26.8" + "@types/gensync" "^1.0.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/generator@^7.26.0", "@babel/generator@^7.26.3": version "7.26.3" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz" @@ -118,6 +145,17 @@ "@jridgewell/trace-mapping" "^0.3.25" jsesc "^3.0.2" +"@babel/generator@^7.26.8": + version "7.26.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.8.tgz#f9c5e770309e12e3099ad8271e52f6caa15442ab" + integrity sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA== + dependencies: + "@babel/parser" "^7.26.8" + "@babel/types" "^7.26.8" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^3.0.2" + "@babel/helper-annotate-as-pure@^7.25.9": version "7.25.9" resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz" @@ -136,6 +174,17 @@ lru-cache "^5.1.1" semver "^6.3.1" +"@babel/helper-compilation-targets@^7.26.5": + version "7.26.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz#75d92bb8d8d51301c0d49e52a65c9a7fe94514d8" + integrity sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA== + dependencies: + "@babel/compat-data" "^7.26.5" + "@babel/helper-validator-option" "^7.25.9" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.25.9": version "7.25.9" resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz" @@ -264,6 +313,14 @@ "@babel/template" "^7.25.9" "@babel/types" "^7.26.0" +"@babel/helpers@^7.26.7": + version "7.26.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.7.tgz#fd1d2a7c431b6e39290277aacfd8367857c576a4" + integrity sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A== + dependencies: + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.7" + "@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.3": version "7.26.3" resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz" @@ -271,6 +328,13 @@ dependencies: "@babel/types" "^7.26.3" +"@babel/parser@^7.26.8": + version "7.26.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.8.tgz#deca2b4d99e5e1b1553843b99823f118da6107c2" + integrity sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw== + dependencies: + "@babel/types" "^7.26.8" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9": version "7.25.9" resolved "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz" @@ -648,6 +712,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.25.9" +"@babel/plugin-transform-react-jsx-self@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz#c0b6cae9c1b73967f7f9eb2fca9536ba2fad2858" + integrity sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-react-jsx-source@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz#4c6b8daa520b5f155b5fb55547d7c9fa91417503" + integrity sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-transform-regenerator@^7.25.9": version "7.25.9" resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz" @@ -860,6 +938,15 @@ "@babel/parser" "^7.25.9" "@babel/types" "^7.25.9" +"@babel/template@^7.26.8": + version "7.26.8" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.26.8.tgz#db3898f47a17bab2f4c78ec1d0de38527c2ffe19" + integrity sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q== + dependencies: + "@babel/code-frame" "^7.26.2" + "@babel/parser" "^7.26.8" + "@babel/types" "^7.26.8" + "@babel/traverse@^7.18.9", "@babel/traverse@^7.25.9": version "7.26.4" resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz" @@ -873,6 +960,19 @@ debug "^4.3.1" globals "^11.1.0" +"@babel/traverse@^7.26.8": + version "7.26.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.8.tgz#0a8a9c2b7cc9519eed14275f4fd2278ad46e8cc9" + integrity sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA== + dependencies: + "@babel/code-frame" "^7.26.2" + "@babel/generator" "^7.26.8" + "@babel/parser" "^7.26.8" + "@babel/template" "^7.26.8" + "@babel/types" "^7.26.8" + debug "^4.3.1" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.18.9", "@babel/types@^7.20.7", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.26.3", "@babel/types@^7.4.4": version "7.26.3" resolved "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz" @@ -881,6 +981,14 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" +"@babel/types@^7.26.7", "@babel/types@^7.26.8": + version "7.26.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.8.tgz#97dcdc190fab45be7f3dc073e3c11160d677c127" + integrity sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@blueprintjs/colors@^4.2.1": version "4.2.1" resolved "https://registry.npmjs.org/@blueprintjs/colors/-/colors-4.2.1.tgz" @@ -1104,6 +1212,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + "@esbuild/aix-ppc64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz#b57697945b50e99007b4c2521507dc613d4a648c" @@ -1114,6 +1227,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + "@esbuild/android-arm64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz#1add7e0af67acefd556e407f8497e81fddad79c0" @@ -1124,6 +1242,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + "@esbuild/android-arm@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz#ab7263045fa8e090833a8e3c393b60d59a789810" @@ -1134,6 +1257,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + "@esbuild/android-x64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz#e8f8b196cfdfdd5aeaebbdb0110983460440e705" @@ -1144,6 +1272,11 @@ resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz" integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + "@esbuild/darwin-arm64@0.24.0": version "0.24.0" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz" @@ -1154,6 +1287,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + "@esbuild/darwin-x64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz#33087aab31a1eb64c89daf3d2cf8ce1775656107" @@ -1164,6 +1302,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + "@esbuild/freebsd-arm64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz#bb76e5ea9e97fa3c753472f19421075d3a33e8a7" @@ -1174,6 +1317,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + "@esbuild/freebsd-x64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz#e0e2ce9249fdf6ee29e5dc3d420c7007fa579b93" @@ -1184,6 +1332,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + "@esbuild/linux-arm64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz#d1b2aa58085f73ecf45533c07c82d81235388e75" @@ -1194,6 +1347,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + "@esbuild/linux-arm@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz#8e4915df8ea3e12b690a057e77a47b1d5935ef6d" @@ -1204,6 +1362,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + "@esbuild/linux-ia32@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz#8200b1110666c39ab316572324b7af63d82013fb" @@ -1214,6 +1377,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + "@esbuild/linux-loong64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz#6ff0c99cf647504df321d0640f0d32e557da745c" @@ -1224,6 +1392,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + "@esbuild/linux-mips64el@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz#3f720ccd4d59bfeb4c2ce276a46b77ad380fa1f3" @@ -1234,6 +1407,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + "@esbuild/linux-ppc64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz#9d6b188b15c25afd2e213474bf5f31e42e3aa09e" @@ -1244,6 +1422,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + "@esbuild/linux-riscv64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz#f989fdc9752dfda286c9cd87c46248e4dfecbc25" @@ -1254,6 +1437,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + "@esbuild/linux-s390x@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz#29ebf87e4132ea659c1489fce63cd8509d1c7319" @@ -1264,6 +1452,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + "@esbuild/linux-x64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz#4af48c5c0479569b1f359ffbce22d15f261c0cef" @@ -1274,6 +1467,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + "@esbuild/netbsd-x64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz#1ae73d23cc044a0ebd4f198334416fb26c31366c" @@ -1289,6 +1487,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + "@esbuild/openbsd-x64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz#4c8aa88c49187c601bae2971e71c6dc5e0ad1cdf" @@ -1299,6 +1502,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + "@esbuild/sunos-x64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz#8ddc35a0ea38575fa44eda30a5ee01ae2fa54dd4" @@ -1309,6 +1517,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + "@esbuild/win32-arm64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz#6e79c8543f282c4539db684a207ae0e174a9007b" @@ -1319,6 +1532,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + "@esbuild/win32-ia32@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz#057af345da256b7192d18b676a02e95d0fa39103" @@ -1329,6 +1547,11 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + "@esbuild/win32-x64@0.24.0": version "0.24.0" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz#168ab1c7e1c318b922637fad8f339d48b01e1244" @@ -1341,11 +1564,34 @@ dependencies: eslint-visitor-keys "^3.4.3" -"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.12.1", "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": version "4.12.1" resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz" integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== +"@eslint/config-array@^0.19.0": + version "0.19.2" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.2.tgz#3060b809e111abfc97adb0bb1172778b90cb46aa" + integrity sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w== + dependencies: + "@eslint/object-schema" "^2.1.6" + debug "^4.3.1" + minimatch "^3.1.2" + +"@eslint/core@^0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.10.0.tgz#23727063c21b335f752dbb3a16450f6f9cbc9091" + integrity sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw== + dependencies: + "@types/json-schema" "^7.0.15" + +"@eslint/core@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.11.0.tgz#7a9226e850922e42cbd2ba71361eacbe74352a12" + integrity sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA== + dependencies: + "@types/json-schema" "^7.0.15" + "@eslint/eslintrc@^2.1.4": version "2.1.4" resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz" @@ -1361,11 +1607,44 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/eslintrc@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c" + integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^10.0.1" + globals "^14.0.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + "@eslint/js@8.57.1": version "8.57.1" resolved "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz" integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== +"@eslint/js@9.20.0", "@eslint/js@^9.9.0": + version "9.20.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.20.0.tgz#7421bcbe74889fcd65d1be59f00130c289856eb4" + integrity sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ== + +"@eslint/object-schema@^2.1.6": + version "2.1.6" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f" + integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== + +"@eslint/plugin-kit@^0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz#ee07372035539e7847ef834e3f5e7b79f09e3a81" + integrity sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A== + dependencies: + "@eslint/core" "^0.10.0" + levn "^0.4.1" + "@floating-ui/core@^1.6.0": version "1.6.9" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.9.tgz#64d1da251433019dafa091de9b2886ff35ec14e6" @@ -1506,6 +1785,19 @@ uuid "^11.0.3" ws "^8.5.0" +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== + +"@humanfs/node@^0.16.6": + version "0.16.6" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" + integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== + dependencies: + "@humanfs/core" "^0.19.1" + "@humanwhocodes/retry" "^0.3.0" + "@humanwhocodes/config-array@^0.13.0": version "0.13.0" resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz" @@ -1525,6 +1817,16 @@ resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@humanwhocodes/retry@^0.3.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" + integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== + +"@humanwhocodes/retry@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b" + integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA== + "@hypnosphi/create-react-context@^0.3.1": version "0.3.1" resolved "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz" @@ -2656,6 +2958,15 @@ magic-string "^0.30.3" picomatch "^4.0.2" +"@rollup/plugin-inject@^5.0.5": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz#616f3a73fe075765f91c5bec90176608bed277a3" + integrity sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg== + dependencies: + "@rollup/pluginutils" "^5.0.1" + estree-walker "^2.0.2" + magic-string "^0.30.3" + "@rollup/pluginutils@^5.0.1": version "5.1.3" resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz" @@ -2670,96 +2981,191 @@ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz#14c737dc19603a096568044eadaa60395eefb809" integrity sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q== +"@rollup/rollup-android-arm-eabi@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz#9b726b4dcafb9332991e9ca49d54bafc71d9d87f" + integrity sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg== + "@rollup/rollup-android-arm64@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz#9d81ea54fc5650eb4ebbc0a7d84cee331bfa30ad" integrity sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w== +"@rollup/rollup-android-arm64@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz#88326ff46168a47851077ca0bf0c442689ec088f" + integrity sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA== + "@rollup/rollup-darwin-arm64@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz#29448cb1370cf678b50743d2e392be18470abc23" integrity sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q== +"@rollup/rollup-darwin-arm64@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz#b8fbcc9389bc6fad3334a1d16dbeaaa5637c5772" + integrity sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg== + "@rollup/rollup-darwin-x64@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz#0ca99741c3ed096700557a43bb03359450c7857d" integrity sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA== +"@rollup/rollup-darwin-x64@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz#1aa2bcad84c0fb5902e945d88822e17a4f661d51" + integrity sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg== + "@rollup/rollup-freebsd-arm64@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz#233f8e4c2f54ad9b719cd9645887dcbd12b38003" integrity sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ== +"@rollup/rollup-freebsd-arm64@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz#29c54617e0929264dcb6416597d6d7481696e49f" + integrity sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ== + "@rollup/rollup-freebsd-x64@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz#dfba762a023063dc901610722995286df4a48360" integrity sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw== +"@rollup/rollup-freebsd-x64@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz#a8b58ab7d31882559d93f2d1b5863d9e4b4b2678" + integrity sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ== + "@rollup/rollup-linux-arm-gnueabihf@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz#b9da54171726266c5ef4237f462a85b3c3cf6ac9" integrity sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg== +"@rollup/rollup-linux-arm-gnueabihf@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz#a844e1978c8b9766b169ecb1cb5cc0d8a3f05930" + integrity sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg== + "@rollup/rollup-linux-arm-musleabihf@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz#b9db69b3f85f5529eb992936d8f411ee6d04297b" integrity sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug== +"@rollup/rollup-linux-arm-musleabihf@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz#6b44c3b7257985d71b087fcb4ef01325e2fff201" + integrity sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg== + "@rollup/rollup-linux-arm64-gnu@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz#2550cf9bb4d47d917fd1ab4af756d7bbc3ee1528" integrity sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw== +"@rollup/rollup-linux-arm64-gnu@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz#ebb499cf1720115256d0c9ae7598c90cc2251bc5" + integrity sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA== + "@rollup/rollup-linux-arm64-musl@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz#9d06b26d286c7dded6336961a2f83e48330e0c80" integrity sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA== +"@rollup/rollup-linux-arm64-musl@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz#9658221b59d9e5643348f9a52fa5ef35b4dc07b1" + integrity sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q== + "@rollup/rollup-linux-loongarch64-gnu@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz#e957bb8fee0c8021329a34ca8dfa825826ee0e2e" integrity sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ== +"@rollup/rollup-linux-loongarch64-gnu@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz#19418cc57579a5655af2d850a89d74b3f7e9aa92" + integrity sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw== + "@rollup/rollup-linux-powerpc64le-gnu@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz#e8585075ddfb389222c5aada39ea62d6d2511ccc" integrity sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw== +"@rollup/rollup-linux-powerpc64le-gnu@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz#fe0bce7778cb6ce86898c781f3f11369d1a4952c" + integrity sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ== + "@rollup/rollup-linux-riscv64-gnu@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz#7d0d40cee7946ccaa5a4e19a35c6925444696a9e" integrity sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw== +"@rollup/rollup-linux-riscv64-gnu@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz#9c158360abf6e6f7794285642ba0898c580291f6" + integrity sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg== + "@rollup/rollup-linux-s390x-gnu@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz#c2dcd8a4b08b2f2778eceb7a5a5dfde6240ebdea" integrity sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA== +"@rollup/rollup-linux-s390x-gnu@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz#f9113498d22962baacdda008b5587d568b05aa34" + integrity sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw== + "@rollup/rollup-linux-x64-gnu@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz#183637d91456877cb83d0a0315eb4788573aa588" integrity sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg== +"@rollup/rollup-linux-x64-gnu@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz#aec8d4cdf911cd869a72b8bd00833cb426664e0c" + integrity sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw== + "@rollup/rollup-linux-x64-musl@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz#036a4c860662519f1f9453807547fd2a11d5bb01" integrity sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow== +"@rollup/rollup-linux-x64-musl@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz#61c0a146bdd1b5e0dcda33690dd909b321d8f20f" + integrity sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A== + "@rollup/rollup-win32-arm64-msvc@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz#51cad812456e616bfe4db5238fb9c7497e042a52" integrity sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw== +"@rollup/rollup-win32-arm64-msvc@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz#c6c5bf290a3a459c18871110bc2e7009ce35b15a" + integrity sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA== + "@rollup/rollup-win32-ia32-msvc@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz#661c8b3e4cd60f51deaa39d153aac4566e748e5e" integrity sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw== +"@rollup/rollup-win32-ia32-msvc@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz#16ca6bdadc9e054818b9c51f8dac82f6b8afab81" + integrity sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA== + "@rollup/rollup-win32-x64-msvc@4.30.1": version "4.30.1" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz#73bf1885ff052b82fbb0f82f8671f73c36e9137c" integrity sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og== +"@rollup/rollup-win32-x64-msvc@4.34.6": + version "4.34.6" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz#f3d03ce2d82723eb089188ea1494a719b09e1561" + integrity sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w== + "@rtsao/scc@^1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz" @@ -3745,7 +4151,7 @@ resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz" integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== -"@types/babel__core@^7.18.0": +"@types/babel__core@^7.18.0", "@types/babel__core@^7.20.5": version "7.20.5" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== @@ -3807,6 +4213,11 @@ dependencies: "@types/node" "*" +"@types/cookie@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" + integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== + "@types/cors@^2.8.17": version "2.8.17" resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz" @@ -3996,6 +4407,11 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/gensync@^1.0.0": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/gensync/-/gensync-1.0.4.tgz#7122d8f0cd3bf437f9725cc95b180197190cf50b" + integrity sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA== + "@types/hast@^2.0.0": version "2.3.10" resolved "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz" @@ -4010,6 +4426,14 @@ dependencies: "@types/unist" "*" +"@types/hoist-non-react-statics@^3.3.5": + version "3.3.6" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz#6bba74383cdab98e8db4e20ce5b4a6b98caed010" + integrity sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + "@types/html-minifier-terser@^6.0.0": version "6.1.0" resolved "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz" @@ -4020,7 +4444,7 @@ resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz" integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== -"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -4201,6 +4625,11 @@ dependencies: "@types/react" "^18" +"@types/react-dom@^18.3.0": + version "18.3.5" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.5.tgz#45f9f87398c5dcea085b715c58ddcf1faf65f716" + integrity sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q== + "@types/react-transition-group@^4.4.10": version "4.4.11" resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz" @@ -4224,6 +4653,14 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/react@^18.3.3": + version "18.3.18" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.18.tgz#9b382c4cd32e13e463f97df07c2ee3bbcd26904b" + integrity sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + "@types/reactcss@*": version "1.2.12" resolved "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.12.tgz" @@ -4317,6 +4754,21 @@ resolved "https://registry.npmjs.org/@types/zxcvbn/-/zxcvbn-4.4.5.tgz" integrity sha512-FZJgC5Bxuqg7Rhsm/bx6gAruHHhDQ55r+s0JhDh8CQ16fD7NsJJ+p8YMMQDhSQoIrSmjpqqYWA96oQVMNkjRyA== +"@typescript-eslint/eslint-plugin@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz#7745f4e3e4a7ae5f6f73fefcd856fd6a074189b7" + integrity sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.23.0" + "@typescript-eslint/type-utils" "8.23.0" + "@typescript-eslint/utils" "8.23.0" + "@typescript-eslint/visitor-keys" "8.23.0" + graphemer "^1.4.0" + ignore "^5.3.1" + natural-compare "^1.4.0" + ts-api-utils "^2.0.1" + "@typescript-eslint/eslint-plugin@^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/eslint-plugin@^8.6.0": version "8.19.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.19.1.tgz#5f26c0a833b27bcb1aa402b82e76d3b8dda0b247" @@ -4348,6 +4800,17 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/parser@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.23.0.tgz#57acb3b65fce48d12b70d119436e145842a30081" + integrity sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q== + dependencies: + "@typescript-eslint/scope-manager" "8.23.0" + "@typescript-eslint/types" "8.23.0" + "@typescript-eslint/typescript-estree" "8.23.0" + "@typescript-eslint/visitor-keys" "8.23.0" + debug "^4.3.4" + "@typescript-eslint/parser@^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser@^8.6.0": version "8.19.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.19.1.tgz#b836fcfe7a704c8c65f5a50e5b0ff8acfca5c21b" @@ -4375,6 +4838,14 @@ "@typescript-eslint/types" "8.19.1" "@typescript-eslint/visitor-keys" "8.19.1" +"@typescript-eslint/scope-manager@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz#ee3bb7546421ca924b9b7a8b62a77d388193ddec" + integrity sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw== + dependencies: + "@typescript-eslint/types" "8.23.0" + "@typescript-eslint/visitor-keys" "8.23.0" + "@typescript-eslint/type-utils@5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz" @@ -4395,6 +4866,16 @@ debug "^4.3.4" ts-api-utils "^2.0.0" +"@typescript-eslint/type-utils@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz#271e1eecece072d92679dfda5ccfceac3faa9f76" + integrity sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA== + dependencies: + "@typescript-eslint/typescript-estree" "8.23.0" + "@typescript-eslint/utils" "8.23.0" + debug "^4.3.4" + ts-api-utils "^2.0.1" + "@typescript-eslint/types@5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz" @@ -4405,6 +4886,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.19.1.tgz#015a991281754ed986f2e549263a1188d6ed0a8c" integrity sha512-JBVHMLj7B1K1v1051ZaMMgLW4Q/jre5qGK0Ew6UgXz1Rqh+/xPzV1aW581OM00X6iOfyr1be+QyW8LOUf19BbA== +"@typescript-eslint/types@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.23.0.tgz#3355f6bcc5ebab77ef6dcbbd1113ec0a683a234a" + integrity sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ== + "@typescript-eslint/typescript-estree@5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz" @@ -4432,6 +4918,20 @@ semver "^7.6.0" ts-api-utils "^2.0.0" +"@typescript-eslint/typescript-estree@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz#f633ef08efa656e386bc44b045ffcf9537cc6924" + integrity sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ== + dependencies: + "@typescript-eslint/types" "8.23.0" + "@typescript-eslint/visitor-keys" "8.23.0" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^2.0.1" + "@typescript-eslint/utils@5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz" @@ -4456,6 +4956,16 @@ "@typescript-eslint/types" "8.19.1" "@typescript-eslint/typescript-estree" "8.19.1" +"@typescript-eslint/utils@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.23.0.tgz#b269cbdc77129fd6e0e600b168b5ef740a625554" + integrity sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "8.23.0" + "@typescript-eslint/types" "8.23.0" + "@typescript-eslint/typescript-estree" "8.23.0" + "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz" @@ -4472,11 +4982,30 @@ "@typescript-eslint/types" "8.19.1" eslint-visitor-keys "^4.2.0" +"@typescript-eslint/visitor-keys@8.23.0": + version "8.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz#40405fd26a61d23f5f4c2ed0f016a47074781df8" + integrity sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ== + dependencies: + "@typescript-eslint/types" "8.23.0" + eslint-visitor-keys "^4.2.0" + "@ungap/structured-clone@^1.2.0": version "1.2.1" resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz" integrity sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA== +"@vitejs/plugin-react@^4.3.1": + version "4.3.4" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz#c64be10b54c4640135a5b28a2432330e88ad7c20" + integrity sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug== + dependencies: + "@babel/core" "^7.26.0" + "@babel/plugin-transform-react-jsx-self" "^7.25.9" + "@babel/plugin-transform-react-jsx-source" "^7.25.9" + "@types/babel__core" "^7.20.5" + react-refresh "^0.14.2" + "@vitest/expect@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz" @@ -4950,6 +5479,26 @@ arraybuffer.prototype.slice@^1.0.4: get-intrinsic "^1.2.6" is-array-buffer "^3.0.4" +asn1.js@^4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +assert@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" + integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== + dependencies: + call-bind "^1.0.2" + is-nan "^1.3.2" + object-is "^1.1.5" + object.assign "^4.1.4" + util "^0.12.5" + assertion-error@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz" @@ -5004,7 +5553,7 @@ autoprefixer@10.4.14: picocolors "^1.0.0" postcss-value-parser "^4.2.0" -autoprefixer@^10.4.14, autoprefixer@^10.4.19: +autoprefixer@^10.4.14, autoprefixer@^10.4.19, autoprefixer@^10.4.20: version "10.4.20" resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz" integrity sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g== @@ -5189,6 +5738,16 @@ bluebird@^3.7.2: resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.1.tgz#215741fe3c9dba2d7e12c001d0cfdbae43975ba7" + integrity sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg== + +bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + body-parser@1.20.3: version "1.20.3" resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz" @@ -5234,6 +5793,11 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + brotli@^1.3.2: version "1.3.3" resolved "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz" @@ -5246,6 +5810,69 @@ browser-assert@^1.2.1: resolved "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz" integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== +browser-resolve@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-2.0.0.tgz#99b7304cb392f8d73dba741bb2d7da28c6d7842b" + integrity sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ== + dependencies: + resolve "^1.17.0" + +browserify-aes@^1.0.4, browserify-aes@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.1.tgz#06e530907fe2949dc21fc3c2e2302e10b1437238" + integrity sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ== + dependencies: + bn.js "^5.2.1" + randombytes "^2.1.0" + safe-buffer "^5.2.1" + +browserify-sign@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.3.tgz#7afe4c01ec7ee59a89a558a4b75bd85ae62d4208" + integrity sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw== + dependencies: + bn.js "^5.2.1" + browserify-rsa "^4.1.0" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.5" + hash-base "~3.0" + inherits "^2.0.4" + parse-asn1 "^5.1.7" + readable-stream "^2.3.8" + safe-buffer "^5.2.1" + browserify-zlib@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz" @@ -5268,7 +5895,12 @@ buffer-from@^1.0.0: resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.5.0: +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + +buffer@^5.5.0, buffer@^5.7.1: version "5.7.1" resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -5284,6 +5916,11 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== + bundle-require@^4.0.0: version "4.2.1" resolved "https://registry.npmjs.org/bundle-require/-/bundle-require-4.2.1.tgz" @@ -5316,7 +5953,7 @@ call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1: es-errors "^1.3.0" function-bind "^1.1.2" -call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7, call-bind@^1.0.8: +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7, call-bind@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz" integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== @@ -5456,6 +6093,14 @@ chrome-trace-event@^1.0.2: resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz" integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.6.tgz#8fe672437d01cd6c4561af5334e0cc50ff1955f7" + integrity sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + cjs-module-lexer@^1.2.2, cjs-module-lexer@^1.2.3: version "1.4.1" resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz" @@ -5665,6 +6310,11 @@ concurrently@^9.0.1: tree-kill "^1.2.2" yargs "^17.7.2" +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + constant-case@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz" @@ -5711,6 +6361,11 @@ cookie@0.7.1: resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz" integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== +cookie@^0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== + core-js-compat@^3.38.0, core-js-compat@^3.38.1: version "3.40.0" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.40.0.tgz#7485912a5a4a4315c2fdb2cbdc623e6881c88b38" @@ -5723,6 +6378,11 @@ core-js@^3.38.1: resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.40.0.tgz#2773f6b06877d8eda102fc42f828176437062476" integrity sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cors@^2.8.5: version "2.8.5" resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" @@ -5742,6 +6402,37 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" +create-ecdh@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + create-react-class@^15.6.2: version "15.7.0" resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.7.0.tgz#7499d7ca2e69bb51d13faf59bd04f0c65a1d6c1e" @@ -5750,7 +6441,7 @@ create-react-class@^15.6.2: loose-envify "^1.3.1" object-assign "^4.1.1" -create-require@^1.1.0: +create-require@^1.1.0, create-require@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== @@ -5767,7 +6458,7 @@ cross-fetch@^3.1.5: dependencies: node-fetch "^2.6.12" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -5776,6 +6467,24 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +crypto-browserify@^3.12.1: + version "3.12.1" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.1.tgz#bb8921bec9acc81633379aa8f52d69b0b69e0dac" + integrity sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ== + dependencies: + browserify-cipher "^1.0.1" + browserify-sign "^4.2.3" + create-ecdh "^4.0.4" + create-hash "^1.2.0" + create-hmac "^1.1.7" + diffie-hellman "^5.0.3" + hash-base "~3.0.4" + inherits "^2.0.4" + pbkdf2 "^3.1.2" + public-encrypt "^4.0.3" + randombytes "^2.1.0" + randomfill "^1.0.4" + crypto-js@^4.2.0: version "4.2.0" resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz" @@ -6194,6 +6903,14 @@ dequal@^2.0.0, dequal@^2.0.2, dequal@^2.0.3: resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== +des.js@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + desandro-matches-selector@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/desandro-matches-selector/-/desandro-matches-selector-2.0.2.tgz#717beed4dc13e7d8f3762f707a6d58a6774218e1" @@ -6241,6 +6958,15 @@ diff@^5.0.0: resolved "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz" integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== +diffie-hellman@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" @@ -6315,6 +7041,11 @@ dom4@^2.1.5: resolved "https://registry.npmjs.org/dom4/-/dom4-2.1.6.tgz" integrity sha512-JkCVGnN4ofKGbjf5Uvc8mmxaATIErKQKSgACdBXpsQ3fY6DlIpAyWfiBSrGkttATssbDCp3psiAKWXk5gmjycA== +domain-browser@4.22.0: + version "4.22.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.22.0.tgz#6ddd34220ec281f9a65d3386d267ddd35c491f9f" + integrity sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw== + domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" @@ -6417,6 +7148,19 @@ element-resize-detector@^1.1.9: dependencies: batch-processor "1.0.0" +elliptic@^6.5.3, elliptic@^6.5.5: + version "6.6.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06" + integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + emoji-picker-react@^4.5.16: version "4.12.0" resolved "https://registry.npmjs.org/emoji-picker-react/-/emoji-picker-react-4.12.0.tgz" @@ -6745,6 +7489,35 @@ esbuild@^0.19.2: "@esbuild/win32-ia32" "0.19.12" "@esbuild/win32-x64" "0.19.12" +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" @@ -6869,6 +7642,16 @@ eslint-plugin-jsx-a11y@^6.7.1: resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz" integrity sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw== +eslint-plugin-react-hooks@^5.1.0-rc.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz#3d34e37d5770866c34b87d5b499f5f0b53bf0854" + integrity sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw== + +eslint-plugin-react-refresh@^0.4.9: + version "0.4.19" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.19.tgz#f15020c0caa58e33fc4efda27d328281ca74e53d" + integrity sha512-eyy8pcr/YxSYjBoqIFSrlbn9i/xvxUFa8CjzAYo9cFjgGXqq1hyjihcpZvxRLalpaWmueWR81xn7vuKmAFijDQ== + eslint-plugin-react@^7.33.2: version "7.37.3" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.3.tgz#567549e9251533975c4ea9706f986c3a64832031" @@ -6916,6 +7699,14 @@ eslint-scope@^7.2.2: esrecurse "^4.3.0" estraverse "^5.2.0" +eslint-scope@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442" + integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" @@ -6970,6 +7761,55 @@ eslint@8.57.1: strip-ansi "^6.0.1" text-table "^0.2.0" +eslint@^9.9.0: + version "9.20.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.20.0.tgz#6244c46c1640cd5e577a31ebc460fca87838c0b7" + integrity sha512-aL4F8167Hg4IvsW89ejnpTwx+B/UQRzJPGgbIOl+4XqffWsahVVsLEWoZvnrVuwpWmnRd7XeXmQI1zlKcFDteA== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.19.0" + "@eslint/core" "^0.11.0" + "@eslint/eslintrc" "^3.2.0" + "@eslint/js" "9.20.0" + "@eslint/plugin-kit" "^0.2.5" + "@humanfs/node" "^0.16.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.4.1" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.6" + debug "^4.3.2" + escape-string-regexp "^4.0.0" + eslint-scope "^8.2.0" + eslint-visitor-keys "^4.2.0" + espree "^10.3.0" + esquery "^1.5.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^8.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + json-stable-stringify-without-jsonify "^1.0.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + +espree@^10.0.1, espree@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== + dependencies: + acorn "^8.14.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.0" + espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" @@ -6984,7 +7824,7 @@ esprima@~4.0.0: resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.2: +esquery@^1.4.2, esquery@^1.5.0: version "1.6.0" resolved "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz" integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== @@ -7045,11 +7885,19 @@ eventemitter3@^4.0.1: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -events@^3.2.0, events@^3.3.0: +events@^3.0.0, events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + execa@^5.0.0: version "5.1.1" resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" @@ -7216,6 +8064,13 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== + dependencies: + flat-cache "^4.0.0" + file-selector@^2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz" @@ -7320,6 +8175,14 @@ flat-cache@^3.0.4: keyv "^4.5.3" rimraf "^3.0.2" +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.4" + flatted@^3.2.9: version "3.3.2" resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz" @@ -7460,7 +8323,7 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: +fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -7671,6 +8534,16 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== + +globals@^15.9.0: + version "15.14.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.14.0.tgz#b8fd3a8941ff3b4d38f3319d433b61bbb482e73f" + integrity sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig== + globalthis@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz" @@ -7764,6 +8637,31 @@ has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: dependencies: has-symbols "^1.0.3" +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash-base@~3.0, hash-base@~3.0.4: + version "3.0.5" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.5.tgz#52480e285395cf7fba17dc4c9e47acdc7f248a8a" + integrity sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + hasown@^2.0.0, hasown@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" @@ -7814,7 +8712,16 @@ highlight.js@~11.8.0: resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-11.8.0.tgz" integrity sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg== -hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -7898,6 +8805,11 @@ http-proxy-agent@^7.0.2: agent-base "^7.1.0" debug "^4.3.4" +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" @@ -8001,7 +8913,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -8197,6 +9109,13 @@ is-core-module@^2.13.0, is-core-module@^2.15.1: dependencies: hasown "^2.0.2" +is-core-module@^2.16.0: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== + dependencies: + hasown "^2.0.2" + is-data-view@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz" @@ -8272,6 +9191,14 @@ is-map@^2.0.3: resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz" integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== +is-nan@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + is-negative-zero@^2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz" @@ -8456,6 +9383,11 @@ isarray@^2.0.5: resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -8469,6 +9401,11 @@ isomorphic-dompurify@^2.12.0, isomorphic-dompurify@^2.16.0: dompurify "^3.2.2" jsdom "^25.0.1" +isomorphic-timers-promises@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-timers-promises/-/isomorphic-timers-promises-1.0.1.tgz#e4137c24dbc54892de8abae3a4b5c1ffff381598" + integrity sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ== + isomorphic.js@^0.2.4: version "0.2.5" resolved "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz" @@ -8642,7 +9579,7 @@ jsx-dom-cjs@^8.0.3: dependencies: csstype "^3.1.3" -keyv@^4.5.3: +keyv@^4.5.3, keyv@^4.5.4: version "4.5.4" resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== @@ -8856,21 +9793,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lucide-react@^0.356.0: - version "0.356.0" - resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.356.0.tgz" - integrity sha512-MDInjLrmZToccH2UxEshntujBlFwtOofGB22FN/eg39FfGVYV1TT1eMIv2j4rdaTJBpYjUuX7fEo9pwYkNFgwA== - -lucide-react@^0.378.0: - version "0.378.0" - resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.378.0.tgz" - integrity sha512-u6EPU8juLUk9ytRcyapkWI18epAv3RU+6+TC23ivjR0e+glWKBobFeSgRwOIJihzktILQuy6E0E80P2jVTDR5g== - -lucide-react@^0.379.0: - version "0.379.0" - resolved "https://registry.npmjs.org/lucide-react/-/lucide-react-0.379.0.tgz" - integrity sha512-KcdeVPqmhRldldAAgptb8FjIunM2x2Zy26ZBh1RsEUcdLIvsEmbcw7KpzFYUy5BbpGeWhPu9Z9J5YXfStiXwhg== - lucide-react@^0.469.0: version "0.469.0" resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.469.0.tgz#f16936ca6521482fef754a7eabb310e6c68e1482" @@ -8955,6 +9877,15 @@ math-intrinsics@^1.1.0: resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + mdast-util-definitions@^5.0.0: version "5.1.2" resolved "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz" @@ -9259,6 +10190,14 @@ micromatch@^4.0.2, micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" @@ -9296,6 +10235,16 @@ min-indent@^1.0.0, min-indent@^1.0.1: resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" @@ -9406,7 +10355,7 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nanoid@^3.3.6, nanoid@^3.3.7: +nanoid@^3.3.6, nanoid@^3.3.7, nanoid@^3.3.8: version "3.3.8" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz" integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== @@ -9514,6 +10463,39 @@ node-releases@^2.0.19: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== +node-stdlib-browser@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-stdlib-browser/-/node-stdlib-browser-1.3.1.tgz#f41fa554f720a3df951e40339f4d92ac512222ac" + integrity sha512-X75ZN8DCLftGM5iKwoYLA3rjnrAEs97MkzvSd4q2746Tgpg8b8XWiBGiBG4ZpgcAqBgtgPHTiAc8ZMCvZuikDw== + dependencies: + assert "^2.0.0" + browser-resolve "^2.0.0" + browserify-zlib "^0.2.0" + buffer "^5.7.1" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + create-require "^1.1.1" + crypto-browserify "^3.12.1" + domain-browser "4.22.0" + events "^3.0.0" + https-browserify "^1.0.0" + isomorphic-timers-promises "^1.0.1" + os-browserify "^0.3.0" + path-browserify "^1.0.1" + pkg-dir "^5.0.0" + process "^0.11.10" + punycode "^1.4.1" + querystring-es3 "^0.2.1" + readable-stream "^3.6.0" + stream-browserify "^3.0.0" + stream-http "^3.2.0" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.1" + url "^0.11.4" + util "^0.12.4" + vm-browserify "^1.0.1" + nodemon@^3.1.7: version "3.1.7" resolved "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz" @@ -9745,6 +10727,11 @@ orderedmap@^2.0.0: resolved "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz" integrity sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g== +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== + outlayer@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/outlayer/-/outlayer-2.1.1.tgz#29863b6de10ea5dadfffcadfa0d728907387e9a2" @@ -9838,6 +10825,18 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-asn1@^5.0.0, parse-asn1@^5.1.7: + version "5.1.7" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.7.tgz#73cdaaa822125f9647165625eb45f8a051d2df06" + integrity sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg== + dependencies: + asn1.js "^4.10.1" + browserify-aes "^1.2.0" + evp_bytestokey "^1.0.3" + hash-base "~3.0" + pbkdf2 "^3.1.2" + safe-buffer "^5.2.1" + parse-json@^5.0.0: version "5.2.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" @@ -9939,6 +10938,17 @@ pathval@^2.0.0: resolved "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz" integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== +pbkdf2@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + pg-int8@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz" @@ -10074,6 +11084,13 @@ pkg-dir@^4.1.0: dependencies: find-up "^4.0.0" +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + pkg-up@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz" @@ -10238,6 +11255,15 @@ postcss@^8.4.33, postcss@^8.4.38, postcss@^8.4.47: picocolors "^1.1.1" source-map-js "^1.2.1" +postcss@^8.4.43, postcss@^8.4.45: + version "8.5.1" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.1.tgz#e2272a1f8a807fafa413218245630b5db10a3214" + integrity sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ== + dependencies: + nanoid "^3.3.8" + picocolors "^1.1.1" + source-map-js "^1.2.1" + postgres-array@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz" @@ -10367,6 +11393,11 @@ pretty-hrtime@^1.0.3: resolved "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz" integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + process-warning@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-4.0.1.tgz#5c1db66007c67c756e4e09eb170cdece15da32fb" @@ -10578,6 +11609,18 @@ pstree.remy@^1.1.8: resolved "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz" integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== +public-encrypt@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + pump@^3.0.0: version "3.0.2" resolved "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz" @@ -10615,6 +11658,11 @@ qs@^6.12.3: dependencies: side-channel "^1.0.6" +querystring-es3@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" @@ -10642,13 +11690,21 @@ raf-schd@^4.0.3: resolved "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz" integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ== -randombytes@^2.1.0: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" +randomfill@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" @@ -10694,6 +11750,15 @@ react-confetti@^6.1.0: dependencies: tween-functions "^1.2.0" +react-cookie@^7.2.1: + version "7.2.2" + resolved "https://registry.yarnpkg.com/react-cookie/-/react-cookie-7.2.2.tgz#a7559e552ea9cca39a4b3686723a5acf504b8f84" + integrity sha512-e+hi6axHcw9VODoeVu8WyMWyoosa1pzpyjfvrLdF7CexfU+WSGZdDuRfHa4RJgTpfv3ZjdIpHE14HpYBieHFhg== + dependencies: + "@types/hoist-non-react-statics" "^3.3.5" + hoist-non-react-statics "^3.3.2" + universal-cookie "^7.0.0" + react-day-picker@^9.5.0: version "9.5.1" resolved "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.5.1.tgz#ec40acdcc3ffbf7c0b9bfea8b6f97924249ea974" @@ -10833,6 +11898,11 @@ react-popper@^2.3.0: react-fast-compare "^3.0.1" warning "^4.0.2" +react-refresh@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" + integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== + react-remove-scroll-bar@^2.3.6: version "2.3.6" resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz" @@ -10901,7 +11971,20 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.2: +readable-stream@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0, readable-stream@^3.6.2: version "3.6.2" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -11154,6 +12237,15 @@ resolve@1.22.8, resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.22. path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.17.0: + version "1.22.10" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" + integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== + dependencies: + is-core-module "^2.16.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^2.0.0-next.5: version "2.0.0-next.5" resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz" @@ -11180,6 +12272,14 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + robust-predicates@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz" @@ -11220,6 +12320,34 @@ rollup@^4.0.2: "@rollup/rollup-win32-x64-msvc" "4.30.1" fsevents "~2.3.2" +rollup@^4.20.0: + version "4.34.6" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.34.6.tgz#a07e4d2621759e29034d909655e7a32eee9195c9" + integrity sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ== + dependencies: + "@types/estree" "1.0.6" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.34.6" + "@rollup/rollup-android-arm64" "4.34.6" + "@rollup/rollup-darwin-arm64" "4.34.6" + "@rollup/rollup-darwin-x64" "4.34.6" + "@rollup/rollup-freebsd-arm64" "4.34.6" + "@rollup/rollup-freebsd-x64" "4.34.6" + "@rollup/rollup-linux-arm-gnueabihf" "4.34.6" + "@rollup/rollup-linux-arm-musleabihf" "4.34.6" + "@rollup/rollup-linux-arm64-gnu" "4.34.6" + "@rollup/rollup-linux-arm64-musl" "4.34.6" + "@rollup/rollup-linux-loongarch64-gnu" "4.34.6" + "@rollup/rollup-linux-powerpc64le-gnu" "4.34.6" + "@rollup/rollup-linux-riscv64-gnu" "4.34.6" + "@rollup/rollup-linux-s390x-gnu" "4.34.6" + "@rollup/rollup-linux-x64-gnu" "4.34.6" + "@rollup/rollup-linux-x64-musl" "4.34.6" + "@rollup/rollup-win32-arm64-msvc" "4.34.6" + "@rollup/rollup-win32-ia32-msvc" "4.34.6" + "@rollup/rollup-win32-x64-msvc" "4.34.6" + fsevents "~2.3.2" + rope-sequence@^1.3.0: version "1.3.4" resolved "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz" @@ -11277,12 +12405,12 @@ safe-array-concat@^1.1.3: has-symbols "^1.1.0" isarray "^2.0.5" -safe-buffer@5.1.2: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -11458,11 +12586,24 @@ set-proto@^1.0.0: es-errors "^1.3.0" es-object-atoms "^1.0.0" +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + sharp@^0.32.1: version "0.32.6" resolved "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz" @@ -11703,6 +12844,24 @@ storybook@^8.1.1: dependencies: "@storybook/core" "8.4.7" +stream-browserify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + +stream-http@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.2.0.tgz#1872dfcf24cb15752677e40e5c3f9cc1926028b5" + integrity sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.4" + readable-stream "^3.6.0" + xtend "^4.0.2" + streamsearch@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" @@ -11833,13 +12992,20 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string_decoder@^1.1.1, string_decoder@^1.3.0: +string_decoder@^1.0.0, string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -11998,7 +13164,7 @@ tailwindcss-animate@^1.0.6, tailwindcss-animate@^1.0.7: resolved "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz" integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA== -tailwindcss@^3.4.17: +tailwindcss@^3.4.10, tailwindcss@^3.4.17: version "3.4.17" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.17.tgz#ae8406c0f96696a631c790768ff319d46d5e5a63" integrity sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og== @@ -12136,6 +13302,13 @@ thread-stream@^3.0.0: dependencies: real-require "^0.2.0" +timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + tiny-inflate@^1.0.0, tiny-inflate@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz" @@ -12258,6 +13431,11 @@ ts-api-utils@^2.0.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.0.0.tgz#b9d7d5f7ec9f736f4d0f09758b8607979044a900" integrity sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ== +ts-api-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.0.1.tgz#660729385b625b939aaa58054f45c058f33f10cd" + integrity sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w== + ts-dedent@^2.0.0, ts-dedent@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz" @@ -12348,6 +13526,11 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tty-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" @@ -12515,12 +13698,21 @@ typed-styles@^0.0.7: resolved "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz" integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== +typescript-eslint@^8.0.1: + version "8.23.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.23.0.tgz#796deb48f040146b68fcc8cb07db68b87219a8d2" + integrity sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ== + dependencies: + "@typescript-eslint/eslint-plugin" "8.23.0" + "@typescript-eslint/parser" "8.23.0" + "@typescript-eslint/utils" "8.23.0" + typescript@5.3.3: version "5.3.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== -typescript@^5.3.3: +typescript@^5.3.3, typescript@^5.5.3: version "5.7.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.3.tgz#919b44a7dbb8583a9b856d162be24a54bf80073e" integrity sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw== @@ -12665,6 +13857,14 @@ unist-util-visit@^4.0.0: unist-util-is "^5.0.0" unist-util-visit-parents "^5.1.1" +universal-cookie@^7.0.0: + version "7.2.2" + resolved "https://registry.yarnpkg.com/universal-cookie/-/universal-cookie-7.2.2.tgz#93ae9ec55baab89b24300473543170bb8112773c" + integrity sha512-fMiOcS3TmzP2x5QV26pIH3mvhexLIT0HmPa3V7Q7knRfT9HG6kTwq02HZGLPw0sAOXrAmotElGRvTLCMbJsvxQ== + dependencies: + "@types/cookie" "^0.6.0" + cookie "^0.7.2" + universalify@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" @@ -12722,7 +13922,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -url@^0.11.0: +url@^0.11.0, url@^0.11.4: version "0.11.4" resolved "https://registry.npmjs.org/url/-/url-0.11.4.tgz" integrity sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg== @@ -12762,7 +13962,7 @@ use-sync-external-store@^1, use-sync-external-store@^1.2.0, use-sync-external-st resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz" integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw== -util-deprecate@^1.0.1, util-deprecate@^1.0.2: +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== @@ -12870,6 +14070,30 @@ vite-compatible-readable-stream@^3.6.1: string_decoder "^1.1.1" util-deprecate "^1.0.1" +vite-plugin-node-polyfills@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.22.0.tgz#d0afcf82eb985fc02244620d7cec1ddd1c6e0864" + integrity sha512-F+G3LjiGbG8QpbH9bZ//GSBr9i1InSTkaulfUHFa9jkLqVGORFBoqc2A/Yu5Mmh1kNAbiAeKeK+6aaQUf3x0JA== + dependencies: + "@rollup/plugin-inject" "^5.0.5" + node-stdlib-browser "^1.2.0" + +vite@^5.4.1: + version "5.4.14" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.14.tgz#ff8255edb02134df180dcfca1916c37a6abe8408" + integrity sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" + optionalDependencies: + fsevents "~2.3.3" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + w3c-keyname@^2.2.0: version "2.2.8" resolved "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz" @@ -13192,7 +14416,7 @@ xmlchars@^2.2.0: resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xtend@^4.0.0: +xtend@^4.0.0, xtend@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== From 4a195ded002f91aeb63f85ad46cfff01f0c82602 Mon Sep 17 00:00:00 2001 From: Palanikannan M Date: Wed, 2 Apr 2025 12:16:25 +0530 Subject: [PATCH 5/7] fix: link view container --- .../editors/document/page-renderer.tsx | 20 +---- .../components/editors/editor-container.tsx | 7 +- .../editors/link-view-container.tsx | 48 +++--------- .../editor/src/core/components/links/index.ts | 1 - .../core/components/links/link-edit-view.tsx | 51 ++++++------ .../core/components/links/link-input-view.tsx | 7 -- .../core/components/links/link-preview.tsx | 21 +++-- .../src/core/components/links/link-view.tsx | 28 +++---- .../components/menus/bubble-menu/root.tsx | 5 ++ .../src/core/components/menus/menu-items.ts | 77 +------------------ .../extensions/custom-image/custom-image.ts | 2 +- .../custom-image/read-only-custom-image.ts | 4 +- .../core/extensions/custom-link/extension.tsx | 1 + packages/editor/src/core/helpers/common.ts | 13 ---- .../src/core/helpers/editor-commands.ts | 25 +----- .../src/core/helpers/get-extension-storage.ts | 4 +- packages/editor/src/core/types/editor.ts | 5 -- web/core/constants/editor.ts | 11 +-- 18 files changed, 92 insertions(+), 238 deletions(-) delete mode 100644 packages/editor/src/core/components/links/link-input-view.tsx diff --git a/packages/editor/src/core/components/editors/document/page-renderer.tsx b/packages/editor/src/core/components/editors/document/page-renderer.tsx index cb7d3ce3745..dcbcc7b5295 100644 --- a/packages/editor/src/core/components/editors/document/page-renderer.tsx +++ b/packages/editor/src/core/components/editors/document/page-renderer.tsx @@ -1,9 +1,7 @@ -import { Editor, useEditorState } from "@tiptap/react"; +import { Editor } from "@tiptap/react"; // components import { EditorContainer, EditorContentWrapper } from "@/components/editors"; import { AIFeaturesMenu, BlockMenu, EditorBubbleMenu } from "@/components/menus"; -// helpers -import { getExtensionStorage } from "@/helpers/get-extension-storage"; // types import { TAIHandler, TDisplayConfig } from "@/types"; @@ -20,14 +18,6 @@ type IPageRenderer = { export const PageRenderer = (props: IPageRenderer) => { const { aiHandler, bubbleMenuEnabled, displayConfig, editor, editorContainerClassName, id, tabIndex } = props; - const editorState = useEditorState({ - editor, - selector: ({ editor }: { editor: Editor }) => ({ - linkExtensionStorage: getExtensionStorage(editor, "link"), - }), - }); - - console.log("!editorState.linkExtensionStorage.isPreviewOpen", editorState.linkExtensionStorage); return (
{ > {editor.isEditable && ( -
- {bubbleMenuEnabled && !editorState.linkExtensionStorage.isPreviewOpen && ( - - )} + <> + {bubbleMenuEnabled && } -
+ )}
diff --git a/packages/editor/src/core/components/editors/editor-container.tsx b/packages/editor/src/core/components/editors/editor-container.tsx index 379cea232bc..ea6d4d05f61 100644 --- a/packages/editor/src/core/components/editors/editor-container.tsx +++ b/packages/editor/src/core/components/editors/editor-container.tsx @@ -1,4 +1,4 @@ -import { Editor } from "@tiptap/react"; +import { Editor, useEditorState } from "@tiptap/react"; import { FC, ReactNode, useRef } from "react"; // plane utils import { cn } from "@plane/utils"; @@ -8,11 +8,12 @@ import { DEFAULT_DISPLAY_CONFIG } from "@/constants/config"; import { TDisplayConfig } from "@/types"; // components import { LinkViewContainer } from "./link-view-container"; +import { getExtensionStorage } from "@/helpers/get-extension-storage"; interface EditorContainerProps { children: ReactNode; displayConfig: TDisplayConfig; - editor: Editor | null; + editor: Editor; editorContainerClassName: string; id: string; } @@ -87,8 +88,8 @@ export const EditorContainer: FC = (props) => { )} > {children} +
- ); }; diff --git a/packages/editor/src/core/components/editors/link-view-container.tsx b/packages/editor/src/core/components/editors/link-view-container.tsx index 8669e988268..19bf8d109ec 100644 --- a/packages/editor/src/core/components/editors/link-view-container.tsx +++ b/packages/editor/src/core/components/editors/link-view-container.tsx @@ -5,10 +5,9 @@ import { FC, useCallback, useEffect, useState } from "react"; // components import { LinkView, LinkViewProps } from "@/components/links"; // storage -import { getExtensionStorage } from "@/helpers/get-extension-storage"; interface LinkViewContainerProps { - editor: Editor | null; + editor: Editor; containerRef: React.RefObject; } @@ -21,40 +20,10 @@ export const LinkViewContainer: FC = ({ editor, containe const editorState = useEditorState({ editor, selector: ({ editor }: { editor: Editor }) => ({ - linkExtensionStorage: getExtensionStorage(editor, "link"), + linkExtensionStorage: editor.storage.link, }), }); - useEffect(() => { - if (editorState.linkExtensionStorage.isPreviewOpen && editor && editorState.linkExtensionStorage.posToInsert) { - // Get the coordinates of the selection - const coords = editor.view.coordsAtPos(editorState.linkExtensionStorage.posToInsert.from); - const rect = new DOMRect(coords.left, coords.top, 0, coords.bottom - coords.top); - - setVirtualElement({ - getBoundingClientRect() { - return rect; - }, - }); - - const node = editor.state.doc.nodeAt(editorState.linkExtensionStorage.posToInsert.from); - setLinkViewProps({ - url: "", - view: "LinkEditView", - text: node?.text || "", - editor: editor, - from: editorState.linkExtensionStorage.posToInsert.from, - to: editorState.linkExtensionStorage.posToInsert.to, - closeLinkView: () => { - setIsOpen(false); - if (editor) editorState.linkExtensionStorage.isPreviewOpen = false; - }, - }); - - setIsOpen(true); - } - }, [editorState.linkExtensionStorage.isPreviewOpen, editorState.linkExtensionStorage.posToInsert, editor]); - const { refs, floatingStyles, context } = useFloating({ open: isOpen, onOpenChange: setIsOpen, @@ -80,7 +49,7 @@ export const LinkViewContainer: FC = ({ editor, containe const handleLinkHover = useCallback( (event: MouseEvent) => { - if (!editor || editorState.linkExtensionStorage.isPreviewOpen) return; + if (!editor || editorState.linkExtensionStorage.isBubbleMenuOpen) return; // Find the closest anchor tag from the event target const target = (event.target as HTMLElement)?.closest("a"); @@ -126,7 +95,7 @@ export const LinkViewContainer: FC = ({ editor, containe console.error("Error handling link hover:", error); } }, - [editor, editorState.linkExtensionStorage.isPreviewOpen, getReferenceProps, isOpen, linkViewProps] + [editor, editorState.linkExtensionStorage, getReferenceProps, isOpen, linkViewProps] ); // Set up event listeners @@ -139,7 +108,14 @@ export const LinkViewContainer: FC = ({ editor, containe return () => { container.removeEventListener("mouseover", handleLinkHover); }; - }, [handleLinkHover, containerRef]); + }, [handleLinkHover]); + + // Close link view when bubble menu opens + useEffect(() => { + if (editorState.linkExtensionStorage.isBubbleMenuOpen && isOpen) { + setIsOpen(false); + } + }, [editorState.linkExtensionStorage, isOpen]); return ( <> diff --git a/packages/editor/src/core/components/links/index.ts b/packages/editor/src/core/components/links/index.ts index 8e123098e8f..4bd24e373d2 100644 --- a/packages/editor/src/core/components/links/index.ts +++ b/packages/editor/src/core/components/links/index.ts @@ -1,4 +1,3 @@ export * from "./link-edit-view"; -export * from "./link-input-view"; export * from "./link-preview"; export * from "./link-view"; diff --git a/packages/editor/src/core/components/links/link-edit-view.tsx b/packages/editor/src/core/components/links/link-edit-view.tsx index 4334bdb0c3d..2e23e2bca40 100644 --- a/packages/editor/src/core/components/links/link-edit-view.tsx +++ b/packages/editor/src/core/components/links/link-edit-view.tsx @@ -1,8 +1,8 @@ import { Node } from "@tiptap/pm/model"; import { Link2Off } from "lucide-react"; -import { useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; // components -import { LinkViewProps } from "@/components/links"; +import { LinkViewProps, LinkViews } from "@/components/links"; // helpers import { isValidHttpUrl } from "@/helpers/common"; @@ -30,7 +30,7 @@ const InputView = ({ label, value, placeholder, onChange, autoFocus }: InputView interface LinkEditViewProps { viewProps: LinkViewProps; - switchView: (view: "LinkPreview" | "LinkEditView" | "LinkInputView") => void; + switchView: (view: LinkViews) => void; } export const LinkEditView = ({ viewProps }: LinkEditViewProps) => { @@ -67,11 +67,11 @@ export const LinkEditView = ({ viewProps }: LinkEditViewProps) => { }, [initialText]); // Handlers - const handleTextChange = (value: string) => { + const handleTextChange = useCallback((value: string) => { if (value.trim() !== "") setLocalText(value); - }; + }, []); - const applyChanges = (): boolean => { + const applyChanges = useCallback((): boolean => { if (linkRemoved) return false; hasSubmitted.current = true; @@ -95,7 +95,7 @@ export const LinkEditView = ({ viewProps }: LinkEditViewProps) => { .insertContent(localText) .setTextSelection({ from, to: from + localText.length }) .run(); - + // // Restore marks node.marks.forEach((mark) => { editor.chain().setMark(mark.type.name, mark.attrs).run(); @@ -103,29 +103,36 @@ export const LinkEditView = ({ viewProps }: LinkEditViewProps) => { } return true; - }; + }, [editor, from, to, initialText, localText, localUrl]); - const removeLink = () => { + const removeLink = useCallback(() => { editor.view.dispatch(editor.state.tr.removeMark(from, to, editor.schema.marks.link)); setLinkRemoved(true); closeLinkView(); - }; - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === "Enter") { - e.stopPropagation(); - if (applyChanges()) { - closeLinkView(); - setLocalUrl(""); - setLocalText(""); + }, [editor, from, to, closeLinkView]); + + const handleKeyDown = useCallback( + (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + e.stopPropagation(); + if (applyChanges()) { + closeLinkView(); + setLocalUrl(""); + setLocalText(""); + } } - } - }; + }, + [applyChanges, closeLinkView] + ); return (
@@ -133,7 +140,7 @@ export const LinkEditView = ({ viewProps }: LinkEditViewProps) => {
-
diff --git a/packages/editor/src/core/components/links/link-input-view.tsx b/packages/editor/src/core/components/links/link-input-view.tsx deleted file mode 100644 index a66d80e6d2e..00000000000 --- a/packages/editor/src/core/components/links/link-input-view.tsx +++ /dev/null @@ -1,7 +0,0 @@ -// components -import { LinkViewProps } from "@/components/links"; - -export const LinkInputView = ({}: { - viewProps: LinkViewProps; - switchView: (view: "LinkPreview" | "LinkEditView" | "LinkInputView") => void; -}) =>

LinkInputView

; diff --git a/packages/editor/src/core/components/links/link-preview.tsx b/packages/editor/src/core/components/links/link-preview.tsx index 93815edaec1..30205005dea 100644 --- a/packages/editor/src/core/components/links/link-preview.tsx +++ b/packages/editor/src/core/components/links/link-preview.tsx @@ -1,13 +1,13 @@ import { Copy, GlobeIcon, Link2Off, PencilIcon } from "lucide-react"; // components -import { LinkViewProps } from "@/components/links"; +import { LinkViewProps, LinkViews } from "@/components/links"; export const LinkPreview = ({ viewProps, switchView, }: { viewProps: LinkViewProps; - switchView: (view: "LinkPreview" | "LinkEditView" | "LinkInputView") => void; + switchView: (view: LinkViews) => void; }) => { const { editor, from, to, url } = viewProps; @@ -22,20 +22,29 @@ export const LinkPreview = ({ }; return ( -
+

{url?.length > 40 ? url.slice(0, 40) + "..." : url}

- {editor.isEditable && ( <> - - diff --git a/packages/editor/src/core/components/links/link-view.tsx b/packages/editor/src/core/components/links/link-view.tsx index abe0e487df3..699f94e400d 100644 --- a/packages/editor/src/core/components/links/link-view.tsx +++ b/packages/editor/src/core/components/links/link-view.tsx @@ -1,10 +1,12 @@ import { Editor } from "@tiptap/react"; import { CSSProperties, useEffect, useState } from "react"; // components -import { LinkEditView, LinkInputView, LinkPreview } from "@/components/links"; +import { LinkEditView, LinkPreview } from "@/components/links"; + +export type LinkViews = "LinkPreview" | "LinkEditView"; export interface LinkViewProps { - view?: "LinkPreview" | "LinkEditView" | "LinkInputView"; + view?: LinkViews; editor: Editor; from: number; to: number; @@ -14,10 +16,10 @@ export interface LinkViewProps { } export const LinkView = (props: LinkViewProps & { style: CSSProperties }) => { - const [currentView, setCurrentView] = useState(props.view ?? "LinkInputView"); + const [currentView, setCurrentView] = useState(props.view ?? "LinkPreview"); const [prevFrom, setPrevFrom] = useState(props.from); - const switchView = (view: "LinkPreview" | "LinkEditView" | "LinkInputView") => { + const switchView = (view: LinkViews) => { setCurrentView(view); }; @@ -28,16 +30,10 @@ export const LinkView = (props: LinkViewProps & { style: CSSProperties }) => { } }, []); - const renderView = () => { - switch (currentView) { - case "LinkPreview": - return ; - case "LinkEditView": - return ; - case "LinkInputView": - return ; - } - }; - - return renderView(); + return ( + <> + {currentView === "LinkPreview" && } + {currentView === "LinkEditView" && } + + ); }; diff --git a/packages/editor/src/core/components/menus/bubble-menu/root.tsx b/packages/editor/src/core/components/menus/bubble-menu/root.tsx index 149c6f6c24b..59e795cbb0a 100644 --- a/packages/editor/src/core/components/menus/bubble-menu/root.tsx +++ b/packages/editor/src/core/components/menus/bubble-menu/root.tsx @@ -91,6 +91,7 @@ export const EditorBubbleMenu: FC = (props: { editor: Edi empty || !editor.isEditable || editor.isActive("image") || + editor.isActive("imageComponent") || isNodeSelection(selection) || isCellSelection(selection) || isSelecting @@ -102,7 +103,11 @@ export const EditorBubbleMenu: FC = (props: { editor: Edi tippyOptions: { moveTransition: "transform 0.15s ease-out", duration: [300, 0], + onShow: () => { + props.editor.storage.link.isBubbleMenuOpen = true; + }, onHidden: () => { + props.editor.storage.link.isBubbleMenuOpen = false; setIsNodeSelectorOpen(false); setIsLinkSelectorOpen(false); setIsColorSelectorOpen(false); diff --git a/packages/editor/src/core/components/menus/menu-items.ts b/packages/editor/src/core/components/menus/menu-items.ts index 1f2584429ae..4268ccb6c48 100644 --- a/packages/editor/src/core/components/menus/menu-items.ts +++ b/packages/editor/src/core/components/menus/menu-items.ts @@ -28,7 +28,6 @@ import { insertHorizontalRule, insertImage, insertTableCommand, - setLinkEditor, setText, setTextAlign, toggleBackgroundColor, @@ -48,14 +47,9 @@ import { toggleTaskList, toggleTextColor, toggleUnderline, - unsetLinkEditor, } from "@/helpers/editor-commands"; // types import { TCommandWithProps, TEditorCommands } from "@/types"; -import { TextSelection } from "@tiptap/pm/state"; -import { ResolvedPos } from "@tiptap/pm/model"; -import { CustomLinkStorage } from "@/extensions"; -import { getExtensionStorage } from "@/helpers/get-extension-storage"; type isActiveFunction = (params?: TCommandWithProps) => boolean; type commandFunction = (params?: TCommandWithProps) => void; @@ -151,7 +145,7 @@ export const UnderLineItem = (editor: Editor): EditorMenuItem<"underline"> => ({ export const StrikeThroughItem = (editor: Editor): EditorMenuItem<"strikethrough"> => ({ key: "strikethrough", name: "Strikethrough", - isActive: () => editor?.isActive("strikes"), + isActive: () => editor?.isActive("strike"), command: () => toggleStrike(editor), icon: StrikethroughIcon, }); @@ -232,74 +226,6 @@ export const TextColorItem = (editor: Editor): EditorMenuItem<"text-color"> => ( icon: Palette, }); -export const LinkItem = (editor: Editor): EditorMenuItem<"link"> => - ({ - key: "link", - name: "Link", - isActive: () => editor?.isActive("link"), - command: ({ url, text }) => { - // create selection on the current word - const { empty } = editor.state.selection; - let position: { from: number; to: number }; - if (empty) { - position = selectCurrentWord(editor); - } else { - position = { from: editor.state.selection.from, to: editor.state.selection.to }; - } - if (!position) return; - const { from, to } = position; - - const editorLinkStorage = getExtensionStorage(editor, "link"); - editorLinkStorage.isPreviewOpen = true; - editorLinkStorage.posToInsert = { from, to }; - - setLinkEditor(editor, url, text); - }, - icon: MinusSquare, - }) as const; - -const selectCurrentWord = (editor: Editor) => { - // Get current selection - const { $from } = editor.state.selection; - - // Get the current text block - const textBlock = $from.parent; - - // Get the position within the current node - const posInNode = $from.parentOffset; - - // Get the text content - const text = textBlock.textContent; - - // If we're on a space, return early - if (text[posInNode] === " ") { - return { to: posInNode, from: posInNode }; - } - - // Find word boundaries - let start = posInNode; - let end = posInNode; - - // Move start backwards until we hit a space or start of text - while (start > 0 && text[start - 1] !== " ") { - start--; - } - - // Move end forwards until we hit a space or end of text - while (end < text.length && text[end] !== " ") { - end++; - } - - // Calculate absolute positions - const from = $from.start() + start; - const to = $from.start() + end; - - // Set the text selection - editor.commands.setTextSelection({ from, to }); - - return { from, to }; -}; - export const BackgroundColorItem = (editor: Editor): EditorMenuItem<"background-color"> => ({ key: "background-color", name: "Background color", @@ -348,6 +274,5 @@ export const getEditorMenuItems = (editor: Editor | null): EditorMenuItem { validation: { maxFileSize }, } = props; - return Image.extend, CustomImageExtensionStorage>({ + return Image.extend, UploadImageExtensionStorage>({ name: "imageComponent", selectable: true, group: "block", diff --git a/packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts b/packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts index 2f56fb9342b..0f77ff9e57c 100644 --- a/packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts +++ b/packages/editor/src/core/extensions/custom-image/read-only-custom-image.ts @@ -2,14 +2,14 @@ import { mergeAttributes } from "@tiptap/core"; import { Image } from "@tiptap/extension-image"; import { ReactNodeViewRenderer } from "@tiptap/react"; // components -import { CustomImageExtensionStorage, CustomImageNode } from "@/extensions/custom-image"; +import { CustomImageNode, UploadImageExtensionStorage } from "@/extensions/custom-image"; // types import { TReadOnlyFileHandler } from "@/types"; export const CustomReadOnlyImageExtension = (props: TReadOnlyFileHandler) => { const { getAssetSrc } = props; - return Image.extend, CustomImageExtensionStorage>({ + return Image.extend, UploadImageExtensionStorage>({ name: "imageComponent", selectable: false, group: "block", diff --git a/packages/editor/src/core/extensions/custom-link/extension.tsx b/packages/editor/src/core/extensions/custom-link/extension.tsx index 6c94eeaef72..27c1bb598da 100644 --- a/packages/editor/src/core/extensions/custom-link/extension.tsx +++ b/packages/editor/src/core/extensions/custom-link/extension.tsx @@ -251,6 +251,7 @@ export const CustomLinkExtension = Mark.create({ addStorage() { return { isPreviewOpen: false, + isBubbleMenuOpen: false, posToInsert: { from: 0, to: 0 }, }; }, diff --git a/packages/editor/src/core/helpers/common.ts b/packages/editor/src/core/helpers/common.ts index beaf3563b97..ce2da74aebb 100644 --- a/packages/editor/src/core/helpers/common.ts +++ b/packages/editor/src/core/helpers/common.ts @@ -62,7 +62,6 @@ export const isValidHttpUrl = (string: string): { isValid: boolean; url: string // Try again with https:// prefix try { const urlWithHttps = `https://${string}`; - console.log("urlWithHttps", urlWithHttps); new URL(urlWithHttps); return { isValid: true, @@ -76,18 +75,6 @@ export const isValidHttpUrl = (string: string): { isValid: boolean; url: string } }; -export const isValidHttpUrl2 = (string: string): boolean => { - let url: URL; - - try { - url = new URL(string); - } catch { - return false; - } - - return url.protocol === "http:" || url.protocol === "https:"; -}; - export const getParagraphCount = (editorState: EditorState | undefined) => { if (!editorState) return 0; let paragraphCount = 0; diff --git a/packages/editor/src/core/helpers/editor-commands.ts b/packages/editor/src/core/helpers/editor-commands.ts index 8d8aeb716e7..93d5f828d76 100644 --- a/packages/editor/src/core/helpers/editor-commands.ts +++ b/packages/editor/src/core/helpers/editor-commands.ts @@ -169,9 +169,9 @@ export const unsetLinkEditor = (editor: Editor) => { editor.chain().focus().unsetLink().run(); }; -// export const setLinkEditor = (editor: Editor, url: string) => { -// editor.chain().focus().setLink({ href: url }).run(); -// }; +export const setLinkEditor = (editor: Editor, url: string) => { + editor.chain().focus().setLink({ href: url }).run(); +}; export const toggleTextColor = (color: string | undefined, editor: Editor, range?: Range) => { if (color) { @@ -183,25 +183,6 @@ export const toggleTextColor = (color: string | undefined, editor: Editor, range } }; -export const setLinkEditor = (editor: Editor, url: string, text?: string) => { - const { selection } = editor.state; - const previousSelection = { from: selection.from, to: selection.to }; - if (text) { - editor - .chain() - .focus() - .deleteRange({ from: selection.from, to: selection.to }) - .insertContentAt(previousSelection.from, text) - .run(); - // Extracting the new selection start point. - const previousFrom = previousSelection.from; - - editor.commands.setTextSelection({ from: previousFrom, to: previousFrom + text.length }); - } - editor.chain().focus().setLink({ href: url }).run(); - getExtensionStorage(editor, "link").isPreviewOpen = true; -}; - export const toggleBackgroundColor = (color: string | undefined, editor: Editor, range?: Range) => { if (color) { if (range) { diff --git a/packages/editor/src/core/helpers/get-extension-storage.ts b/packages/editor/src/core/helpers/get-extension-storage.ts index d5dcebf742c..0107f8425c9 100644 --- a/packages/editor/src/core/helpers/get-extension-storage.ts +++ b/packages/editor/src/core/helpers/get-extension-storage.ts @@ -1,16 +1,16 @@ import { Editor } from "@tiptap/core"; import { - CustomImageExtensionStorage, CustomLinkStorage, HeadingExtensionStorage, MentionExtensionStorage, + UploadImageExtensionStorage, } from "@/extensions"; import { ImageExtensionStorage } from "@/plugins/image"; type ExtensionNames = "imageComponent" | "image" | "link" | "headingList" | "mention"; interface ExtensionStorageMap { - imageComponent: CustomImageExtensionStorage; + imageComponent: UploadImageExtensionStorage; image: ImageExtensionStorage; link: CustomLinkStorage; headingList: HeadingExtensionStorage; diff --git a/packages/editor/src/core/types/editor.ts b/packages/editor/src/core/types/editor.ts index 445d44b1ba1..a55a1a84aa1 100644 --- a/packages/editor/src/core/types/editor.ts +++ b/packages/editor/src/core/types/editor.ts @@ -31,7 +31,6 @@ export type TEditorCommands = | "h6" | "bold" | "italic" - | "link" | "underline" | "strikethrough" | "bulleted-list" @@ -65,10 +64,6 @@ export type TCommandExtraProps = { "text-align": { alignment: TTextAlign; }; - link: { - url: string; - text: string; - }; }; // Create a utility type that maps a command to its extra props or an empty object if none are defined diff --git a/web/core/constants/editor.ts b/web/core/constants/editor.ts index 9805a79c751..5e8c723d71d 100644 --- a/web/core/constants/editor.ts +++ b/web/core/constants/editor.ts @@ -14,7 +14,6 @@ import { Heading6, Image, Italic, - LinkIcon, List, ListOrdered, ListTodo, @@ -94,7 +93,7 @@ export const TEXT_ALIGNMENT_ITEMS: ToolbarMenuItem<"text-align">[] = [ }, ]; -const BASIC_MARK_ITEMS: ToolbarMenuItem<"bold" | "italic" | "underline" | "strikethrough" | "link">[] = [ +const BASIC_MARK_ITEMS: ToolbarMenuItem<"bold" | "italic" | "underline" | "strikethrough">[] = [ { itemKey: "bold", renderKey: "bold", @@ -127,14 +126,6 @@ const BASIC_MARK_ITEMS: ToolbarMenuItem<"bold" | "italic" | "underline" | "strik shortcut: ["Cmd", "Shift", "S"], editors: ["lite", "document"], }, - { - itemKey: "link", - renderKey: "link", - name: "Link", - icon: LinkIcon, - shortcut: ["Cmd", "Shift", "S"], - editors: ["lite", "document"], - }, ]; const LIST_ITEMS: ToolbarMenuItem<"bulleted-list" | "numbered-list" | "to-do-list">[] = [ From de6f5a0928ce56399971b021131baa78d131eb46 Mon Sep 17 00:00:00 2001 From: Palanikannan M Date: Wed, 2 Apr 2025 12:22:25 +0530 Subject: [PATCH 6/7] fix: cleaning up --- .../src/core/components/editors/document/page-renderer.tsx | 2 +- .../editor/src/core/components/editors/editor-container.tsx | 3 +-- .../editor/src/core/components/editors/link-view-container.tsx | 3 --- packages/editor/src/core/helpers/editor-commands.ts | 1 - 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/editor/src/core/components/editors/document/page-renderer.tsx b/packages/editor/src/core/components/editors/document/page-renderer.tsx index dcbcc7b5295..5a95fe5cabb 100644 --- a/packages/editor/src/core/components/editors/document/page-renderer.tsx +++ b/packages/editor/src/core/components/editors/document/page-renderer.tsx @@ -19,7 +19,7 @@ export const PageRenderer = (props: IPageRenderer) => { const { aiHandler, bubbleMenuEnabled, displayConfig, editor, editorContainerClassName, id, tabIndex } = props; return ( -
+
= ({ editor, containerRef }) => { - // states for link hover functionality const [linkViewProps, setLinkViewProps] = useState(); const [isOpen, setIsOpen] = useState(false); const [virtualElement, setVirtualElement] = useState(null); diff --git a/packages/editor/src/core/helpers/editor-commands.ts b/packages/editor/src/core/helpers/editor-commands.ts index 93d5f828d76..39796ac245a 100644 --- a/packages/editor/src/core/helpers/editor-commands.ts +++ b/packages/editor/src/core/helpers/editor-commands.ts @@ -5,7 +5,6 @@ import { InsertImageComponentProps } from "@/extensions"; import { replaceCodeWithText } from "@/extensions/code/utils/replace-code-block-with-text"; // helpers import { findTableAncestor } from "@/helpers/common"; -import { getExtensionStorage } from "@/helpers/get-extension-storage"; export const setText = (editor: Editor, range?: Range) => { if (range) editor.chain().focus().deleteRange(range).setNode("paragraph").run(); From 1a885c1148e73621c2c7623a85caae014b7b4f59 Mon Sep 17 00:00:00 2001 From: Palanikannan M Date: Wed, 2 Apr 2025 12:29:31 +0530 Subject: [PATCH 7/7] fix: url validation --- .../menus/bubble-menu/link-selector.tsx | 8 ++++---- packages/editor/src/core/helpers/common.ts | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx index 333edf78a1d..1dd47c5bb33 100644 --- a/packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx +++ b/packages/editor/src/core/components/menus/bubble-menu/link-selector.tsx @@ -23,11 +23,11 @@ export const BubbleMenuLinkSelector: FC = (props) => { const handleLinkSubmit = useCallback(() => { const input = inputRef.current; if (!input) return; - let url = input.value; + const url = input.value; if (!url) return; - if (!url.startsWith("http")) url = `http://${url}`; - if (isValidHttpUrl(url)) { - setLinkEditor(editor, url); + const { isValid, url: validatedUrl } = isValidHttpUrl(url); + if (isValid) { + setLinkEditor(editor, validatedUrl); setIsOpen(false); setError(false); } else { diff --git a/packages/editor/src/core/helpers/common.ts b/packages/editor/src/core/helpers/common.ts index ce2da74aebb..36075caf23d 100644 --- a/packages/editor/src/core/helpers/common.ts +++ b/packages/editor/src/core/helpers/common.ts @@ -45,11 +45,24 @@ export const getTrimmedHTML = (html: string) => { }; export const isValidHttpUrl = (string: string): { isValid: boolean; url: string } => { + // List of potentially dangerous protocols to block + const blockedProtocols = ["javascript:", "data:", "vbscript:", "file:", "about:"]; + // First try with the original string try { const url = new URL(string); - // If URL is valid and has a protocol, return as is - if (url.protocol === "http:" || url.protocol === "https:") { + + // Check for potentially dangerous protocols + const protocol = url.protocol.toLowerCase(); + if (blockedProtocols.some((p) => protocol === p)) { + return { + isValid: false, + url: string, + }; + } + + // If URL has any valid protocol, return as is + if (url.protocol && url.protocol !== "") { return { isValid: true, url: string,