From 94e1d54b6784c12453d6c65de46600f04bf91e9f Mon Sep 17 00:00:00 2001 From: Flavien David Date: Fri, 22 Dec 2023 16:41:14 +0100 Subject: [PATCH] Revert "Refactor InputBar with Tip Tap Library (#2992)" (#3010) This reverts commit 2457d981dd80bb7089f016421a1b9ad270553ff7. --- .../assistant/conversation/InputBar.tsx | 994 ++++++++++++++++++ .../conversation/input_bar/InputBar.tsx | 298 ------ .../input_bar/InputBarContainer.tsx | 159 --- .../input_bar/editor/MentionList.tsx | 127 --- .../input_bar/editor/suggestion.ts | 80 -- .../editor/useAssistantSuggestions.ts | 26 - .../input_bar/editor/useCustomEditor.tsx | 216 ---- .../input_bar/editor/useHandleMentions.tsx | 67 -- front/package-lock.json | 789 +------------- front/package.json | 5 - front/pages/w/[wId]/assistant/[cId]/index.tsx | 2 +- front/pages/w/[wId]/assistant/new.tsx | 2 +- 12 files changed, 1001 insertions(+), 1764 deletions(-) create mode 100644 front/components/assistant/conversation/InputBar.tsx delete mode 100644 front/components/assistant/conversation/input_bar/InputBar.tsx delete mode 100644 front/components/assistant/conversation/input_bar/InputBarContainer.tsx delete mode 100644 front/components/assistant/conversation/input_bar/editor/MentionList.tsx delete mode 100644 front/components/assistant/conversation/input_bar/editor/suggestion.ts delete mode 100644 front/components/assistant/conversation/input_bar/editor/useAssistantSuggestions.ts delete mode 100644 front/components/assistant/conversation/input_bar/editor/useCustomEditor.tsx delete mode 100644 front/components/assistant/conversation/input_bar/editor/useHandleMentions.tsx diff --git a/front/components/assistant/conversation/InputBar.tsx b/front/components/assistant/conversation/InputBar.tsx new file mode 100644 index 000000000000..399868b3400a --- /dev/null +++ b/front/components/assistant/conversation/InputBar.tsx @@ -0,0 +1,994 @@ +import { + ArrowUpIcon, + AttachmentIcon, + Avatar, + Button, + Citation, + FullscreenExitIcon, + FullscreenIcon, + IconButton, + StopIcon, +} from "@dust-tt/sparkle"; +import { WorkspaceType } from "@dust-tt/types"; +import { AgentConfigurationType } from "@dust-tt/types"; +import { AgentMention, MentionType } from "@dust-tt/types"; +import { Transition } from "@headlessui/react"; +import { + createContext, + ForwardedRef, + forwardRef, + Fragment, + useContext, + useEffect, + useImperativeHandle, + useRef, + useState, +} from "react"; +import * as ReactDOMServer from "react-dom/server"; +import { mutate } from "swr"; + +import { AssistantPicker } from "@app/components/assistant/AssistantPicker"; +import { GenerationContext } from "@app/components/assistant/conversation/GenerationContextProvider"; +import { SendNotificationsContext } from "@app/components/sparkle/Notification"; +import { compareAgentsForSort } from "@app/lib/assistant"; +import { handleFileUploadToText } from "@app/lib/client/handle_file_upload"; +import { useAgentConfigurations } from "@app/lib/swr"; +import { classNames, filterAndSortAgents } from "@app/lib/utils"; + +// AGENT MENTION + +function AgentMention({ + agentConfiguration, +}: { + agentConfiguration: AgentConfigurationType; +}) { + return ( +
+ @{agentConfiguration.name} +
+ ); +} + +// AGENT LIST + +function AgentListImpl( + { + owner, + visible, + filter, + position, + conversationId, + }: { + owner: WorkspaceType; + visible: boolean; + filter: string; + position: { + bottom: number; + left: number; + }; + conversationId: string | null; + }, + ref: ForwardedRef<{ + prev: () => void; + next: () => void; + reset: () => void; + selected: () => AgentConfigurationType | null; + noMatch: () => boolean; + perfectMatch: () => boolean; + }> +) { + const [focus, setFocus] = useState(0); + + const focusRef = useRef(null); + + const { agentConfigurations } = useAgentConfigurations({ + workspaceId: owner.sId, + agentsGetView: conversationId ? { conversationId } : "list", + }); + + const activeAgents = agentConfigurations.filter((a) => a.status === "active"); + activeAgents.sort(compareAgentsForSort); + + const filtered = filterAndSortAgents(activeAgents, filter); + + useImperativeHandle(ref, () => ({ + prev: () => { + setFocus((f) => (f > 0 ? f - 1 : 0)); + }, + next: () => { + setFocus((f) => (f < filtered.length - 1 ? f + 1 : filtered.length - 1)); + }, + reset: () => { + setFocus(0); + }, + selected: () => { + if (focus < filtered.length) { + return filtered[focus]; + } + return null; + }, + noMatch: () => { + return filtered.length === 0; + }, + perfectMatch: () => { + return !!filtered.find( + (a) => a.name.toLowerCase() === filter.toLowerCase() + ); + }, + })); + + useEffect(() => { + if (focus > filtered.length - 1) { + if (filtered.length === 0) { + setFocus(0); + } else { + setFocus(filtered.length - 1); + } + } + if (focusRef.current) { + focusRef.current.scrollIntoView({ + // behavior: "smooth", + block: "nearest", + inline: "start", + }); + } + }, [focus, visible, filter, filtered]); + + return ( + +
+
+ {filtered.map((c, i) => ( +
+
{ + setFocus(i); + }} + > +
+ +
+ {"@"} + {c.name} +
+
+
+
+ ))} +
+
+
+ ); +} + +const AgentList = forwardRef(AgentListImpl); + +function moveCursorToEnd(el: HTMLElement) { + const range = document.createRange(); + const sel = window.getSelection(); + if (sel) { + range.selectNodeContents(el); + range.collapse(false); + sel.removeAllRanges(); + sel.addRange(range); + } +} + +function getAgentMentionNode( + agentConfiguration: AgentConfigurationType +): ChildNode | null { + const htmlString = ReactDOMServer.renderToStaticMarkup( + + ); + const wrapper = document.createElement("div"); + wrapper.innerHTML = htmlString.trim(); + return wrapper.firstChild; +} + +export function AssistantInputBar({ + owner, + onSubmit, + conversationId, + stickyMentions, +}: { + owner: WorkspaceType; + onSubmit: ( + input: string, + mentions: MentionType[], + contentFragment?: { title: string; content: string } + ) => void; + conversationId: string | null; + stickyMentions?: AgentMention[]; +}) { + const [agentListVisible, setAgentListVisible] = useState(false); + const [agentListFilter, setAgentListFilter] = useState(""); + const [agentListPosition, setAgentListPosition] = useState<{ + bottom: number; + left: number; + }>({ + bottom: 0, + left: 0, + }); + const [contentFragmentBody, setContentFragmentBody] = useState< + string | undefined + >(undefined); + const [contentFragmentFilename, setContentFragmentFilename] = useState< + string | undefined + >(undefined); + const fileInputRef = useRef(null); + const inputRef = useRef(null); + const agentListRef = useRef<{ + prev: () => void; + next: () => void; + reset: () => void; + selected: () => AgentConfigurationType | null; + noMatch: () => boolean; + perfectMatch: () => boolean; + }>(null); + + useEffect(() => { + inputRef.current?.focus(); + }, []); + + // Empty bar detection logic + const [empty, setEmpty] = useState( + !inputRef.current?.textContent || + inputRef.current.textContent.replace(/[\u200B\n]/g, "").length === 0 + ); + // MutationObserver is only defined after window is defined so observer cannot + // be defined in the useRef below + const observer = useRef(null); + useEffect(() => { + if (!observer.current && inputRef.current) { + observer.current = new MutationObserver(function () { + setEmpty( + !inputRef.current?.textContent || + inputRef.current.textContent.replace(/[\u200B\n]/g, "").length === 0 + ); + }); + observer.current.observe(inputRef.current, { + childList: true, + characterData: true, + subtree: true, + }); + } + }, []); + + const { agentConfigurations } = useAgentConfigurations({ + workspaceId: owner.sId, + agentsGetView: conversationId ? { conversationId } : "list", + }); + const sendNotification = useContext(SendNotificationsContext); + + const activeAgents = agentConfigurations.filter((a) => a.status === "active"); + activeAgents.sort(compareAgentsForSort); + + const [isExpanded, setIsExpanded] = useState(false); + + const handleSubmit = async () => { + if (empty) { + return; + } + const contentEditable = document.getElementById("dust-input-bar"); + if (contentEditable) { + const mentions: MentionType[] = []; + let content = ""; + Array.from(contentEditable.childNodes).forEach((node) => { + if (node.nodeType === Node.ELEMENT_NODE) { + // @ts-expect-error - parentNode is the contenteditable, it has a getAttribute. + const agentConfigurationId = node.getAttribute( + "data-agent-configuration-id" + ); + // @ts-expect-error - parentNode is the contenteditable, it has a getAttribute. + const agentName = node.getAttribute("data-agent-name"); + + if (agentConfigurationId && agentName) { + mentions.push({ + configurationId: agentConfigurationId, + }); + // Internal format for mentions is `:mention[agentName]{sId=agentConfigurationId}`. + content += `:mention[${agentName}]{sId=${agentConfigurationId}}`; + } + } + if (node.nodeType === Node.TEXT_NODE) { + content += node.textContent; + } + }); + + content = content.trim(); + content = content.replace(/\u200B/g, ""); + let contentFragment: + | { + title: string; + content: string; + url: string | null; + contentType: string; + } + | undefined = undefined; + if (contentFragmentBody && contentFragmentFilename) { + contentFragment = { + title: contentFragmentFilename, + content: contentFragmentBody, + url: null, + contentType: "file_attachment", + }; + } + setIsExpanded(false); + onSubmit(content, mentions, contentFragment); + contentEditable.innerHTML = ""; + setContentFragmentFilename(undefined); + setContentFragmentBody(undefined); + } + }; + + const [isAnimating, setIsAnimating] = useState(false); + const { animate, selectedAssistant } = useContext(InputBarContext); + + useEffect(() => { + if (animate && !isAnimating) { + setIsAnimating(true); + setTimeout(() => setIsAnimating(false), 1500); + } + }, [animate, isAnimating]); + + const stickyMentionsTextContent = useRef(null); + + const [isProcessing, setIsProcessing] = useState(false); + + // GenerationContext: to know if we are generating or not + const generationContext = useContext(GenerationContext); + if (!generationContext) { + throw new Error( + "FixedAssistantInputBar must be used within a GenerationContextProvider" + ); + } + + const handleStopGeneration = async () => { + if (!conversationId) { + return; + } + setIsProcessing(true); // we don't set it back to false immediately cause it takes a bit of time to cancel + await fetch( + `/api/w/${owner.sId}/assistant/conversations/${conversationId}/cancel`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + action: "cancel", + messageIds: generationContext.generatingMessageIds, + }), + } + ); + await mutate( + `/api/w/${owner.sId}/assistant/conversations/${conversationId}` + ); + }; + + useEffect(() => { + if (isProcessing && generationContext.generatingMessageIds.length === 0) { + setIsProcessing(false); + } + }, [isProcessing, generationContext.generatingMessageIds.length]); + + useEffect(() => { + if (!stickyMentions?.length && !selectedAssistant) { + return; + } + + const mentionsToInject = stickyMentions?.length + ? stickyMentions + : ([selectedAssistant] as [AgentMention]); + + const mentionedAgentConfigurationIds = new Set( + mentionsToInject?.map((m) => m.configurationId) + ); + + const contentEditable = document.getElementById("dust-input-bar"); + if (contentEditable) { + const textContent = contentEditable.textContent?.trim(); + + if (textContent?.length && !stickyMentionsTextContent.current) { + return; + } + + if ( + textContent?.length && + textContent !== stickyMentionsTextContent.current + ) { + // content has changed, we don't clear it (we preserve whatever the user typed) + return; + } + + // we clear the content of the input bar -- at this point, it's either already empty, + // or contains only the sticky mentions added by this hook + contentEditable.innerHTML = ""; + let lastTextNode = null; + for (const configurationId of mentionedAgentConfigurationIds) { + const agentConfiguration = agentConfigurations.find( + (agent) => agent.sId === configurationId + ); + if (!agentConfiguration) { + continue; + } + const mentionNode = getAgentMentionNode(agentConfiguration); + if (!mentionNode) { + continue; + } + contentEditable.appendChild(mentionNode); + lastTextNode = document.createTextNode(" "); + contentEditable.appendChild(lastTextNode); + + stickyMentionsTextContent.current = + contentEditable.textContent?.trim() || null; + } + // move the cursor to the end of the input bar + if (lastTextNode) { + moveCursorToEnd(contentEditable); + } + } + }, [ + stickyMentions, + agentConfigurations, + stickyMentionsTextContent, + selectedAssistant, + ]); + const contentEditableClasses = classNames( + "inline-block w-full", + "border-0 pr-1 py-3.5 pl-2 sm:pl-0 outline-none ring-0 focus:border-0 focus:outline-none focus:ring-0", + "whitespace-pre-wrap font-normal" + ); + return ( + <> + + + {generationContext.generatingMessageIds.length > 0 && ( +
+
+ )} + +
+
+
+
+ {/* Placeholder */} +
+
+ Ask a question or get some @help +
+
Ask a question
+
+ + {contentFragmentFilename && contentFragmentBody && ( +
+ { + setContentFragmentBody(undefined); + setContentFragmentFilename(undefined); + }} + /> +
+ )} + +
{ + e.preventDefault(); + + // Get the plain text. + const text = e.clipboardData.getData("text/plain"); + + const selection = window.getSelection(); + if (!selection) { + return; + } + const range = selection.getRangeAt(0); + let node = range.endContainer; + let offset = range.endOffset; + + if ( + // @ts-expect-error - parentNode is the contenteditable, it has a getAttribute. + node.getAttribute && + // @ts-expect-error - parentNode is the contenteditable, it has a getAttribute. + node.getAttribute("id") === "dust-input-bar" + ) { + const textNode = document.createTextNode(""); + node.appendChild(textNode); + node = textNode; + offset = 0; + } + + if ( + node.parentNode && + // @ts-expect-error - parentNode is the contenteditable, it has a getAttribute. + node.parentNode.getAttribute && + // @ts-expect-error - parentNode is the contenteditable, it has a getAttribute. + node.parentNode.getAttribute("id") === "dust-input-bar" + ) { + // Inject the text at the cursor position. + node.textContent = + node.textContent?.slice(0, offset) + + text + + node.textContent?.slice(offset); + } + + // Scroll to the end of the input + if (inputRef.current) { + setTimeout(() => { + const element = inputRef.current; + if (element) { + element.scrollTop = element.scrollHeight; + } + }, 0); + } + + // Move the cursor to the end of the paste. + const newRange = document.createRange(); + newRange.setStart(node, offset + text.length); + newRange.setEnd(node, offset + text.length); + selection.removeAllRanges(); + selection.addRange(newRange); + }} + onKeyDown={(e) => { + // We prevent the content editable from creating italics, bold and underline. + if (e.ctrlKey || e.metaKey) { + if (e.key === "u" || e.key === "b" || e.key === "i") { + e.preventDefault(); + } + } + if (!e.shiftKey && e.key === "Enter") { + e.preventDefault(); + e.stopPropagation(); + void handleSubmit(); + } + }} + onInput={() => { + const selection = window.getSelection(); + if ( + selection && + selection.rangeCount !== 0 && + selection.isCollapsed + ) { + const range = selection.getRangeAt(0); + const node = range.endContainer; + const offset = range.endOffset; + + const lastOne = node.textContent + ? node.textContent.slice(offset - 1, offset) + : null; + const preLastOne = node.textContent + ? node.textContent.slice(offset - 2, offset - 1) + : null; + + // Mention selection logic. + + if ( + lastOne === "@" && + (preLastOne === " " || preLastOne === "") && + node.textContent && + node.parentNode && + // @ts-expect-error - parentNode is the contenteditable, it has a getAttribute. + node.parentNode.getAttribute && + // @ts-expect-error - parentNode is the contenteditable, it has a getAttribute. + node.parentNode.getAttribute("id") === "dust-input-bar" + ) { + const mentionSelectNode = document.createElement("div"); + + mentionSelectNode.style.display = "inline-block"; + mentionSelectNode.setAttribute("key", "mentionSelect"); + mentionSelectNode.className = "text-brand font-medium"; + mentionSelectNode.textContent = "@"; + mentionSelectNode.contentEditable = "false"; + + const inputNode = document.createElement("span"); + inputNode.setAttribute("ignore", "none"); + inputNode.className = classNames( + "min-w-0 px-0 py-0", + "border-none outline-none focus:outline-none focus:border-none ring-0 focus:ring-0", + "text-brand font-medium" + ); + inputNode.contentEditable = "true"; + + mentionSelectNode.appendChild(inputNode); + + const beforeTextNode = document.createTextNode( + node.textContent.slice(0, offset - 1) + ); + const afterTextNode = document.createTextNode( + node.textContent.slice(offset) + ); + + node.parentNode.replaceChild(beforeTextNode, node); + + beforeTextNode.parentNode?.insertBefore( + afterTextNode, + beforeTextNode.nextSibling + ); + beforeTextNode.parentNode?.insertBefore( + mentionSelectNode, + afterTextNode + ); + + const rect = mentionSelectNode.getBoundingClientRect(); + const position = { + left: Math.floor(rect.left) - 24, + bottom: + Math.floor(window.innerHeight - rect.bottom) + 32, + }; + if (!isNaN(position.left) && !isNaN(position.bottom)) { + setAgentListPosition(position); + } + + setAgentListVisible(true); + inputNode.focus(); + + inputNode.onblur = () => { + let selected = agentListRef.current?.selected(); + setAgentListVisible(false); + setTimeout(() => { + setAgentListFilter(""); + agentListRef.current?.reset(); + }); + + if (inputNode.getAttribute("ignore") !== "none") { + selected = null; + } + + // console.log("SELECTED", selected); + + // We received a selected agent configration, recover the state of the + // contenteditable and inject an AgentMention component. + if (selected) { + // Construct an AgentMention component and inject it as HTML. + const mentionNode = getAgentMentionNode(selected); + + // This is mainly to please TypeScript. + if (!mentionNode || !mentionSelectNode.parentNode) { + return; + } + + // Replace mentionSelectNode with mentionNode. + mentionSelectNode.parentNode.replaceChild( + mentionNode, + mentionSelectNode + ); + + // Prepend a space to afterTextNode (this will be the space that comes after + // the mention). + afterTextNode.textContent = ` ${afterTextNode.textContent}`; + + // If afterTextNode is the last node add an invisible character to prevent a + // Chrome bugish behaviour ¯\_(ツ)_/¯ + if (afterTextNode.nextSibling === null) { + afterTextNode.textContent = `${afterTextNode.textContent}\u200B`; + } + + // Restore the cursor, taking into account the added space. + range.setStart(afterTextNode, 1); + range.setEnd(afterTextNode, 1); + selection.removeAllRanges(); + selection.addRange(range); + } + + // We didn't receive a selected agent configuration, restore the state of the + // contenteditable and re-inject the content that was created during the + // selection process into the contenteditable. + if (!selected && mentionSelectNode.parentNode) { + mentionSelectNode.parentNode.removeChild( + mentionSelectNode + ); + + range.setStart(afterTextNode, 0); + range.setEnd(afterTextNode, 0); + selection.removeAllRanges(); + selection.addRange(range); + + // Insert the content of mentionSelectNode after beforeTextNode only if + // we're not in ignore mode unless we are in ingnore mode (the user + // backspaced into the @) + if ( + inputNode.getAttribute("ignore") === "none" || + inputNode.getAttribute("ignore") === "space" + ) { + const newTextNode = document.createTextNode( + (mentionSelectNode.textContent || "") + + (inputNode.getAttribute("ignore") === "space" + ? " " + : "") + ); + beforeTextNode.parentNode?.insertBefore( + newTextNode, + beforeTextNode.nextSibling + ); + } + } + }; + + // These are events on the small contentEditable that receives the user input + // and drives the agent list selection. + inputNode.onkeydown = (e) => { + // console.log("KEYDOWN", e.key); + if (e.key === "Escape") { + agentListRef.current?.reset(); + inputNode.setAttribute("ignore", "escape"); + inputNode.blur(); + e.preventDefault(); + } + if (e.key === "ArrowDown") { + agentListRef.current?.next(); + e.preventDefault(); + } + if (e.key === "ArrowUp") { + agentListRef.current?.prev(); + e.preventDefault(); + } + if (e.key === "Backspace") { + if (inputNode.textContent === "") { + agentListRef.current?.reset(); + inputNode.setAttribute("ignore", "backspace"); + inputNode.blur(); + e.preventDefault(); + } + } + if (e.key === " ") { + if (agentListRef.current?.perfectMatch()) { + inputNode.blur(); + e.preventDefault(); + } else { + agentListRef.current?.reset(); + inputNode.setAttribute("ignore", "space"); + inputNode.blur(); + e.preventDefault(); + } + } + if (e.key === "Enter") { + inputNode.blur(); + e.preventDefault(); + } + }; + + // These are the event that drive the selection of the the agent list, if we + // have no more match we just blur to exit the selection process. + inputNode.oninput = (e) => { + const target = e.target as HTMLInputElement; + // console.log("INPUT", target.textContent); + setAgentListFilter(target.textContent || ""); + e.stopPropagation(); + setTimeout(() => { + if (agentListRef.current?.noMatch()) { + agentListRef.current?.reset(); + inputNode.blur(); + } + }); + }; + } + } + }} + // We aboslutely don't want any content in that div just below here. Do not add + // anyting to it. + >
+
+ {/* This div is a spacer to avoid having the text clash with the buttons */} +
+
+ +
+
+ { + // focus on the input text after the file selection interaction is over + inputRef.current?.focus(); + const file = e?.target?.files?.[0]; + if (!file) return; + if (file.size > 10_000_000) { + sendNotification({ + type: "error", + title: "File too large.", + description: + "PDF uploads are limited to 10Mb per file. Please consider uploading a smaller file.", + }); + return; + } + const res = await handleFileUploadToText(file); + + if (res.isErr()) { + sendNotification({ + type: "error", + title: "Error uploading file.", + description: res.error.message, + }); + return; + } + if (res.value.content.length > 1_000_000) { + // This error should pretty much never be triggered but it is a possible case, so here it is. + sendNotification({ + type: "error", + title: "File too large.", + description: + "The extracted text from your PDF has more than 1 million characters. This will overflow the assistant context. Please consider uploading a smaller file.", + }); + return; + } + setContentFragmentFilename(res.value.title); + setContentFragmentBody(res.value.content); + }} + /> + { + fileInputRef.current?.click(); + }} + /> + { + // We construct the HTML for an AgentMention and inject it in the content + // editable with an extra space after it. + const mentionNode = getAgentMentionNode(c); + const contentEditable = + document.getElementById("dust-input-bar"); + if (contentEditable && mentionNode) { + // Add mentionNode as last childe of contentEditable. + contentEditable.appendChild(mentionNode); + const afterTextNode = document.createTextNode(" "); + contentEditable.appendChild(afterTextNode); + contentEditable.focus(); + moveCursorToEnd(contentEditable); + } + }} + assistants={activeAgents} + showBuilderButtons={true} + /> +
+ { + setIsExpanded((e) => !e); + }} + /> +
+
+
+
+
+
+ + ); +} + +export function FixedAssistantInputBar({ + owner, + onSubmit, + stickyMentions, + conversationId, +}: { + owner: WorkspaceType; + onSubmit: ( + input: string, + mentions: MentionType[], + contentFragment?: { title: string; content: string } + ) => void; + stickyMentions?: AgentMention[]; + conversationId: string | null; +}) { + return ( +
+
+ +
+
+ ); +} + +export const InputBarContext = createContext<{ + animate: boolean; + selectedAssistant: AgentMention | null; +}>({ + animate: false, + selectedAssistant: null, +}); diff --git a/front/components/assistant/conversation/input_bar/InputBar.tsx b/front/components/assistant/conversation/input_bar/InputBar.tsx deleted file mode 100644 index 581976e3dcf3..000000000000 --- a/front/components/assistant/conversation/input_bar/InputBar.tsx +++ /dev/null @@ -1,298 +0,0 @@ -import { Button, Citation, StopIcon } from "@dust-tt/sparkle"; -import { WorkspaceType } from "@dust-tt/types"; -import { AgentConfigurationType } from "@dust-tt/types"; -import { AgentMention, MentionType } from "@dust-tt/types"; -import { - createContext, - Fragment, - useContext, - useEffect, - useState, -} from "react"; -import { mutate } from "swr"; - -import { GenerationContext } from "@app/components/assistant/conversation/GenerationContextProvider"; -import InputBarContainer, { - InputBarContainerProps, -} from "@app/components/assistant/conversation/input_bar/InputBarContainer"; -import { SendNotificationsContext } from "@app/components/sparkle/Notification"; -import { compareAgentsForSort } from "@app/lib/assistant"; -import { handleFileUploadToText } from "@app/lib/client/handle_file_upload"; -import { useAgentConfigurations } from "@app/lib/swr"; -import { classNames } from "@app/lib/utils"; - -// AGENT MENTION - -function AgentMention({ - agentConfiguration, -}: { - agentConfiguration: AgentConfigurationType; -}) { - return ( -
- @{agentConfiguration.name} -
- ); -} - -export function AssistantInputBar({ - owner, - onSubmit, - conversationId, - stickyMentions, -}: { - owner: WorkspaceType; - onSubmit: ( - input: string, - mentions: MentionType[], - contentFragment?: { title: string; content: string } - ) => void; - conversationId: string | null; - stickyMentions?: AgentMention[]; -}) { - const [contentFragmentBody, setContentFragmentBody] = useState< - string | undefined - >(undefined); - const [contentFragmentFilename, setContentFragmentFilename] = useState< - string | undefined - >(undefined); - const { agentConfigurations } = useAgentConfigurations({ - workspaceId: owner.sId, - agentsGetView: conversationId ? { conversationId } : "list", - }); - const sendNotification = useContext(SendNotificationsContext); - - const [isAnimating, setIsAnimating] = useState(false); - const { animate, selectedAssistant } = useContext(InputBarContext); - useEffect(() => { - let timeoutId: NodeJS.Timeout; - if (animate && !isAnimating) { - setIsAnimating(true); - timeoutId = setTimeout(() => setIsAnimating(false), 1500); - } - - // Cleanup function to clear the timeout - return () => { - if (timeoutId) { - clearTimeout(timeoutId); - } - }; - }, [animate, isAnimating]); - - const activeAgents = agentConfigurations.filter((a) => a.status === "active"); - activeAgents.sort(compareAgentsForSort); - - const handleSubmit: InputBarContainerProps["onEnterKeyDown"] = ( - isEmpty, - textAndMentions, - resetEditorText - ) => { - if (isEmpty) { - return; - } - - const { mentions: rawMentions, text } = textAndMentions; - const mentions: MentionType[] = rawMentions.map((m) => ({ - configurationId: m.id, - })); - - let contentFragment: - | { - title: string; - content: string; - url: string | null; - contentType: string; - } - | undefined = undefined; - if (contentFragmentFilename && contentFragmentBody) { - contentFragment = { - title: contentFragmentFilename, - content: contentFragmentBody, - url: null, - contentType: "file_attachment", - }; - } - onSubmit(text, mentions, contentFragment); - resetEditorText(); - setContentFragmentFilename(undefined); - setContentFragmentBody(undefined); - }; - - const onInputFileChange: InputBarContainerProps["onInputFileChange"] = async ( - event - ) => { - const file = (event?.target as HTMLInputElement)?.files?.[0]; - if (!file) return; - if (file.size > 10_000_000) { - sendNotification({ - type: "error", - title: "File too large.", - description: - "PDF uploads are limited to 10Mb per file. Please consider uploading a smaller file.", - }); - return; - } - const res = await handleFileUploadToText(file); - - if (res.isErr()) { - sendNotification({ - type: "error", - title: "Error uploading file.", - description: res.error.message, - }); - return; - } - if (res.value.content.length > 1_000_000) { - // This error should pretty much never be triggered but it is a possible case, so here it is. - sendNotification({ - type: "error", - title: "File too large.", - description: - "The extracted text from your PDF has more than 1 million characters. This will overflow the assistant context. Please consider uploading a smaller file.", - }); - return; - } - - setContentFragmentFilename(res.value.title); - setContentFragmentBody(res.value.content); - }; - - const [isProcessing, setIsProcessing] = useState(false); - - // GenerationContext: to know if we are generating or not - const generationContext = useContext(GenerationContext); - if (!generationContext) { - throw new Error( - "FixedAssistantInputBar must be used within a GenerationContextProvider" - ); - } - - const handleStopGeneration = async () => { - if (!conversationId) { - return; - } - setIsProcessing(true); // we don't set it back to false immediately cause it takes a bit of time to cancel - await fetch( - `/api/w/${owner.sId}/assistant/conversations/${conversationId}/cancel`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - action: "cancel", - messageIds: generationContext.generatingMessageIds, - }), - } - ); - await mutate( - `/api/w/${owner.sId}/assistant/conversations/${conversationId}` - ); - }; - - useEffect(() => { - if (isProcessing && generationContext.generatingMessageIds.length === 0) { - setIsProcessing(false); - } - }, [isProcessing, generationContext.generatingMessageIds.length]); - - return ( - <> - {generationContext.generatingMessageIds.length > 0 && ( -
-
- )} - -
-
-
-
- {contentFragmentFilename && contentFragmentBody && ( -
- { - setContentFragmentBody(undefined); - setContentFragmentFilename(undefined); - }} - /> -
- )} - - -
-
-
-
- - ); -} - -export function FixedAssistantInputBar({ - owner, - onSubmit, - stickyMentions, - conversationId, -}: { - owner: WorkspaceType; - onSubmit: ( - input: string, - mentions: MentionType[], - contentFragment?: { title: string; content: string } - ) => void; - stickyMentions?: AgentMention[]; - conversationId: string | null; -}) { - return ( -
-
- -
-
- ); -} - -export const InputBarContext = createContext<{ - animate: boolean; - selectedAssistant: AgentMention | null; -}>({ - animate: false, - selectedAssistant: null, -}); diff --git a/front/components/assistant/conversation/input_bar/InputBarContainer.tsx b/front/components/assistant/conversation/input_bar/InputBarContainer.tsx deleted file mode 100644 index 56320e6c67bb..000000000000 --- a/front/components/assistant/conversation/input_bar/InputBarContainer.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import { - ArrowUpIcon, - AttachmentIcon, - Button, - FullscreenExitIcon, - FullscreenIcon, - IconButton, -} from "@dust-tt/sparkle"; -import { - AgentConfigurationType, - AgentMention, - WorkspaceType, -} from "@dust-tt/types"; -import { EditorContent } from "@tiptap/react"; -import React, { useRef, useState } from "react"; - -import { AssistantPicker } from "@app/components/assistant/AssistantPicker"; -import useAssistantSuggestions from "@app/components/assistant/conversation/input_bar/editor/useAssistantSuggestions"; -import useCustomEditor, { - CustomEditorProps, -} from "@app/components/assistant/conversation/input_bar/editor/useCustomEditor"; -import useHandleMentions from "@app/components/assistant/conversation/input_bar/editor/useHandleMentions"; -import { classNames } from "@app/lib/utils"; - -export interface InputBarContainerProps { - allAssistants: AgentConfigurationType[]; - agentConfigurations: AgentConfigurationType[]; - disableAttachment: boolean; - onEnterKeyDown: CustomEditorProps["onEnterKeyDown"]; - onInputFileChange: (e: React.ChangeEvent) => Promise; - owner: WorkspaceType; - selectedAssistant: AgentMention | null; - stickyMentions: AgentMention[] | undefined; -} - -const InputBarContainer = ({ - allAssistants, - agentConfigurations, - disableAttachment, - onEnterKeyDown, - onInputFileChange, - owner, - selectedAssistant, - stickyMentions, -}: InputBarContainerProps) => { - const suggestions = useAssistantSuggestions(agentConfigurations); - - const [isExpanded, setIsExpanded] = useState(false); - function handleExpansionToggle() { - setIsExpanded((currentExpanded) => !currentExpanded); - - // Focus at the end of the document when toggling expansion. - editorService.focusEnd(); - } - - function resetEditorContainerSize() { - setIsExpanded(false); - } - - const { editor, editorService } = useCustomEditor({ - suggestions, - onEnterKeyDown, - resetEditorContainerSize, - }); - - useHandleMentions( - editorService, - agentConfigurations, - stickyMentions, - selectedAssistant - ); - - // TODO: Reset after loading. - const fileInputRef = useRef(null); - - const contentEditableClasses = classNames( - "inline-block w-full", - "border-0 pr-1 pl-2 sm:pl-0 outline-none ring-0 focus:border-0 focus:outline-none focus:ring-0 py-3.5", - "whitespace-pre-wrap font-normal" - ); - - return ( -
- - -
-
- { - await onInputFileChange(e); - editorService.focusEnd(); - }} - ref={fileInputRef} - style={{ display: "none" }} - type="file" - /> - { - fileInputRef.current?.click(); - }} - /> - { - editorService.insertMention({ id: c.sId, label: c.name }); - }} - assistants={allAssistants} - showBuilderButtons={true} - /> -
- -
-
-
-
- ); -}; - -export default InputBarContainer; diff --git a/front/components/assistant/conversation/input_bar/editor/MentionList.tsx b/front/components/assistant/conversation/input_bar/editor/MentionList.tsx deleted file mode 100644 index 49fb8db2b70a..000000000000 --- a/front/components/assistant/conversation/input_bar/editor/MentionList.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { Avatar } from "@dust-tt/sparkle"; -import React, { - forwardRef, - useEffect, - useImperativeHandle, - useState, -} from "react"; - -import { EditorSuggestion } from "@app/components/assistant/conversation/input_bar/editor/suggestion"; -import { classNames } from "@app/lib/utils"; - -interface MentionListProps { - command: any; - items: EditorSuggestion[]; - query: string; -} - -export const MentionList = forwardRef(function mentionList( - props: MentionListProps, - ref -) { - const [selectedIndex, setSelectedIndex] = useState(0); - - const selectItem = (index: number) => { - const item = props.items[index]; - - if (item) { - props.command({ id: item.id, label: item.label }); - } - }; - - const upHandler = () => { - setSelectedIndex( - (selectedIndex + props.items.length - 1) % props.items.length - ); - }; - - const downHandler = () => { - setSelectedIndex((selectedIndex + 1) % props.items.length); - }; - - const enterHandler = () => { - selectItem(selectedIndex); - }; - - const tabHandler = () => { - enterHandler(); - }; - - // Handler that selects the item if the current query matches its label exactly. - const selectItemOnExactMatch = () => { - const { query, items } = props; - - // Check if items are defined and not empty, and get the current selected item. - const currentSelectedItem = items?.[selectedIndex]; - - // Check if a selected item exists and if the query matches its label exactly. - if (currentSelectedItem && query === currentSelectedItem.label) { - selectItem(selectedIndex); - // Indicate that the default action of the Space key should be prevented - return true; - } - - // Allow the default Space key action when there's no exact match or items are undefined - return false; - }; - - const spaceHandler = () => { - return selectItemOnExactMatch(); - }; - - useEffect(() => setSelectedIndex(0), [props.items]); - - useImperativeHandle(ref, () => ({ - onKeyDown: ({ event }: { event: KeyboardEvent }) => { - switch (event.key) { - case "ArrowUp": - upHandler(); - return true; - case "ArrowDown": - downHandler(); - return true; - case "Enter": - enterHandler(); - return true; - case "Tab": - tabHandler(); - return true; - case " ": - if (spaceHandler()) { - event.preventDefault(); - } - break; - - default: - return false; - } - }, - })); - - return ( -
- {props.items.length ? ( - props.items.map((item, index) => ( -
- - -
- )) - ) : ( -
No result
- )} -
- ); -}); diff --git a/front/components/assistant/conversation/input_bar/editor/suggestion.ts b/front/components/assistant/conversation/input_bar/editor/suggestion.ts deleted file mode 100644 index bdc0711ddd95..000000000000 --- a/front/components/assistant/conversation/input_bar/editor/suggestion.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { ReactRenderer } from "@tiptap/react"; -import tippy from "tippy.js"; - -import { MentionList } from "@app/components/assistant/conversation/input_bar/editor/MentionList"; - -export interface EditorSuggestion { - id: string; - label: string; - pictureUrl: string; -} - -const SUGGESTION_DISPLAY_LIMIT = 7; - -export function makeGetAssistantSuggestions(suggestions: EditorSuggestion[]) { - return { - // TODO: Consider refactoring to eliminate the dependency on tippy. - items: ({ query }: { query: string }) => { - return suggestions - .filter((item) => - item.label.toLowerCase().startsWith(query.toLowerCase()) - ) - .slice(0, SUGGESTION_DISPLAY_LIMIT); - }, - - render: () => { - let reactRenderer: any; - let popup: any; - - return { - onStart: (props: any) => { - if (!props.clientRect) { - return; - } - - reactRenderer = new ReactRenderer(MentionList, { - props, - editor: props.editor, - }); - - popup = tippy("body", { - getReferenceClientRect: props.clientRect, - appendTo: () => document.body, - content: reactRenderer.element, - showOnCreate: true, - interactive: true, - trigger: "manual", - placement: "bottom-start", - }); - }, - - onUpdate(props: any) { - reactRenderer.updateProps(props); - - if (!props.clientRect) { - return; - } - - popup[0].setProps({ - getReferenceClientRect: props.clientRect, - }); - }, - - onKeyDown(props: any) { - if (props.event.key === "Escape") { - popup[0].hide(); - - return true; - } - - return reactRenderer.ref?.onKeyDown(props); - }, - - onExit() { - popup[0].destroy(); - reactRenderer.destroy(); - }, - }; - }, - }; -} diff --git a/front/components/assistant/conversation/input_bar/editor/useAssistantSuggestions.ts b/front/components/assistant/conversation/input_bar/editor/useAssistantSuggestions.ts deleted file mode 100644 index eaebf653bd82..000000000000 --- a/front/components/assistant/conversation/input_bar/editor/useAssistantSuggestions.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { AgentConfigurationType } from "@dust-tt/types"; -import { useMemo } from "react"; - -import { compareAgentsForSort } from "@app/lib/assistant"; - -const useAssistantSuggestions = ( - agentConfigurations: AgentConfigurationType[] -) => { - // `useMemo` will ensure that suggestions is only recalculated when `agentConfigurations` changes. - const suggestions = useMemo(() => { - const activeAgents = agentConfigurations.filter( - (a) => a.status === "active" - ); - activeAgents.sort(compareAgentsForSort); - - return activeAgents.map((agent) => ({ - id: agent.sId, - label: agent.name, - pictureUrl: agent.pictureUrl, - })); - }, [agentConfigurations]); - - return suggestions; -}; - -export default useAssistantSuggestions; diff --git a/front/components/assistant/conversation/input_bar/editor/useCustomEditor.tsx b/front/components/assistant/conversation/input_bar/editor/useCustomEditor.tsx deleted file mode 100644 index 2f32d7f5086c..000000000000 --- a/front/components/assistant/conversation/input_bar/editor/useCustomEditor.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import Mention from "@tiptap/extension-mention"; -import Placeholder from "@tiptap/extension-placeholder"; -import { Editor, JSONContent, useEditor } from "@tiptap/react"; -import { StarterKit } from "@tiptap/starter-kit"; -import { useMemo } from "react"; - -import { - EditorSuggestion, - makeGetAssistantSuggestions, -} from "@app/components/assistant/conversation/input_bar/editor/suggestion"; - -export interface EditorMention { - id: string; - label: string; -} - -function getTextAndMentionsFromNode(node?: JSONContent) { - let textContent = ""; - let mentions: EditorMention[] = []; - - if (!node) { - return { mentions, text: textContent }; - } - - // Check if the node is of type 'text' and concatenate its text. - if (node.type === "text") { - textContent += node.text; - } - - // If the node is a 'mention', concatenate the mention label and add to mentions array. - if (node.type === "mention") { - // TODO: We should not expose `sId` here. - textContent += `:mention[${node.attrs?.label}]{sId=${node.attrs?.id}}`; - mentions.push({ - id: node.attrs?.id, - label: node.attrs?.label, - }); - } - - // If the node is a 'hardBreak' or a 'paragraph', add a newline character. - if (node.type && ["hardBreak", "paragraph"].includes(node.type)) { - textContent += "\n"; - } - - // If the node has content, recursively get text and mentions from each child node - if (node.content) { - node.content.forEach((childNode) => { - const childResult = getTextAndMentionsFromNode(childNode); - textContent += childResult.text; - mentions = mentions.concat(childResult.mentions); - }); - } - - return { text: textContent, mentions: mentions }; -} - -const useEditorService = (editor: Editor | null) => { - const editorService = useMemo(() => { - // Return the service object with utility functions - return { - // Insert mention helper function - insertMention: ({ id, label }: { id: string; label: string }) => { - editor - ?.chain() - .focus() - .insertContent({ - type: "mention", - attrs: { id, label }, - }) - .insertContent(" ") // Add an extra space after the mention. - .run(); - }, - - resetWithMentions: (mentions: EditorMention[]) => { - editor?.commands.clearContent(); - const chainCommands = editor?.chain().focus(); - - mentions.forEach( - (m) => - chainCommands - ?.insertContent({ - type: "mention", - attrs: m, - }) - .insertContent(" ") // Add an extra space after the mention. - ); - - chainCommands?.run(); - }, - - focusEnd() { - editor?.commands.focus("end"); - }, - - isEmpty() { - return editor?.isEmpty ?? true; - }, - - getJSONContent() { - return editor?.getJSON(); - }, - - getTextAndMentions() { - const { mentions, text } = getTextAndMentionsFromNode( - editor?.getJSON() - ); - - return { - mentions, - text: text.trim(), - }; - }, - - getTrimmedText() { - return editor?.getText().trim(); - }, - - clearEditor() { - return editor?.commands.clearContent(); - }, - }; - }, [editor]); - - return editorService; -}; - -export type EditorService = ReturnType; - -export interface CustomEditorProps { - onEnterKeyDown: ( - isEmpty: boolean, - textAndMentions: ReturnType, - clearEditor: () => void - ) => void; - suggestions: EditorSuggestion[]; - resetEditorContainerSize: () => void; -} - -const useCustomEditor = ({ - onEnterKeyDown, - resetEditorContainerSize, - suggestions, -}: CustomEditorProps) => { - // Memoize the suggestion configuration to avoid recreating the object on every render - const getSuggestions = useMemo( - () => makeGetAssistantSuggestions(suggestions), - [suggestions] - ); - - const editor = useEditor( - { - autofocus: "end", - enableInputRules: false, // Disable Markdown when typing. - enablePasteRules: false, // Disable Markdown when pasting. - extensions: [ - StarterKit.configure({ - heading: false, - }), - Mention.configure({ - HTMLAttributes: { - class: - "min-w-0 px-0 py-0 border-none outline-none focus:outline-none focus:border-none ring-0 focus:ring-0 text-brand font-medium", - }, - suggestion: getSuggestions, - }), - Placeholder.configure({ - placeholder: "Ask a question or get some @help", - emptyNodeClass: - "first:before:text-gray-400 first:before:float-left first:before:content-[attr(data-placeholder)] first:before:pointer-events-none first:before:h-0", - }), - ], - }, - [getSuggestions] - ); - - editor?.setOptions({ - editorProps: { - attributes: { - class: "border-0 outline-none overflow-y-auto h-full", - }, - handleKeyDown: (view, event) => { - if (event.key === "Enter" && !event.shiftKey) { - // Prevent the default Enter key behavior - event.preventDefault(); - - const clearEditor = () => { - editor.commands.clearContent(); - resetEditorContainerSize(); - }; - - onEnterKeyDown( - editor.isEmpty, - getTextAndMentionsFromNode(editor.getJSON()), - clearEditor - ); - - // Return true to indicate that this key event has been handled - return true; - } - - // Return false to let other keydown handlers or TipTap's default behavior process the event - return false; - }, - }, - }); - - const editorService = useEditorService(editor); - - // Expose the editor instance and the editor service. - return { - editor, - editorService, - }; -}; - -export default useCustomEditor; diff --git a/front/components/assistant/conversation/input_bar/editor/useHandleMentions.tsx b/front/components/assistant/conversation/input_bar/editor/useHandleMentions.tsx deleted file mode 100644 index b61875282ce6..000000000000 --- a/front/components/assistant/conversation/input_bar/editor/useHandleMentions.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { AgentConfigurationType, AgentMention } from "@dust-tt/types"; -import { useEffect, useMemo, useRef } from "react"; - -import type { - EditorMention, - EditorService, -} from "@app/components/assistant/conversation/input_bar/editor/useCustomEditor"; - -const useHandleMentions = ( - editorService: EditorService, - agentConfigurations: AgentConfigurationType[], - stickyMentions: AgentMention[] | undefined, - selectedAssistant: AgentMention | null -) => { - const stickyMentionsTextContent = useRef(null); - - // Memoize the mentioned agents to avoid unnecessary recalculations. - const mentionedAgentConfigurationIds = useMemo(() => { - let mentions: AgentMention[] = []; - if (stickyMentions?.length) { - mentions = stickyMentions; - } else if (selectedAssistant) { - mentions = [selectedAssistant]; - } - - return Array.from(new Set(mentions.map((m) => m.configurationId))); - }, [stickyMentions, selectedAssistant]); - - useEffect(() => { - if (mentionedAgentConfigurationIds.length === 0) { - return; - } - - const editorIsEmpty = editorService.isEmpty(); - const onlyContainsPreviousStickyMention = - !editorIsEmpty && - editorService.getTrimmedText() === stickyMentionsTextContent.current; - - // Insert sticky mentions under two conditions: - // 1. The editor is currently empty. - // 2. The editor contains only the sticky mention from a previously selected assistant. - // This ensures that sticky mentions are maintained but not duplicated. - if (editorIsEmpty || onlyContainsPreviousStickyMention) { - const mentionsToInsert: EditorMention[] = []; - - for (const configurationId of mentionedAgentConfigurationIds) { - const agentConfiguration = agentConfigurations.find( - (agent) => agent.sId === configurationId - ); - if (agentConfiguration) { - mentionsToInsert.push({ - id: agentConfiguration.sId, - label: agentConfiguration.name, - }); - } - } - - if (mentionsToInsert.length !== 0) { - editorService.resetWithMentions(mentionsToInsert); - stickyMentionsTextContent.current = - editorService.getTrimmedText() ?? null; - } - } - }, [agentConfigurations, editorService, mentionedAgentConfigurationIds]); -}; - -export default useHandleMentions; diff --git a/front/package-lock.json b/front/package-lock.json index 5b8652553bb8..98bf90fcbf18 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -22,11 +22,6 @@ "@temporalio/worker": "^1.7.4", "@temporalio/workflow": "^1.7.4", "@textea/json-viewer": "^3.1.1", - "@tiptap/extension-mention": "^2.1.13", - "@tiptap/extension-placeholder": "^2.1.13", - "@tiptap/pm": "^2.1.13", - "@tiptap/react": "^2.1.13", - "@tiptap/starter-kit": "^2.1.13", "@types/emoji-mart": "^3.0.10", "@uiw/react-textarea-code-editor": "^2.1.7", "ajv": "^8.12.0", @@ -2337,6 +2332,7 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -2449,50 +2445,6 @@ "@redis/client": "^1.0.0" } }, - "node_modules/@remirror/core-constants": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-2.0.2.tgz", - "integrity": "sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==" - }, - "node_modules/@remirror/core-helpers": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@remirror/core-helpers/-/core-helpers-3.0.0.tgz", - "integrity": "sha512-tusEgQJIqg4qKj6HSBUFcyRnWnziw3neh4T9wOmsPGHFC3w9kl5KSrDb9UAgE8uX6y32FnS7vJ955mWOl3n50A==", - "dependencies": { - "@remirror/core-constants": "^2.0.2", - "@remirror/types": "^1.0.1", - "@types/object.omit": "^3.0.0", - "@types/object.pick": "^1.3.2", - "@types/throttle-debounce": "^2.1.0", - "case-anything": "^2.1.13", - "dash-get": "^1.0.2", - "deepmerge": "^4.3.1", - "fast-deep-equal": "^3.1.3", - "make-error": "^1.3.6", - "object.omit": "^3.0.0", - "object.pick": "^1.3.0", - "throttle-debounce": "^3.0.1" - } - }, - "node_modules/@remirror/types": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@remirror/types/-/types-1.0.1.tgz", - "integrity": "sha512-VlZQxwGnt1jtQ18D6JqdIF+uFZo525WEqrfp9BOc3COPpK4+AWCgdnAWL+ho6imWcoINlGjR/+3b6y5C1vBVEA==", - "dependencies": { - "type-fest": "^2.19.0" - } - }, - "node_modules/@remirror/types/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@rushstack/eslint-patch": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.1.tgz", @@ -2830,390 +2782,6 @@ "react-dom": "^17 || ^18" } }, - "node_modules/@tiptap/core": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.1.13.tgz", - "integrity": "sha512-cMC8bgTN63dj1Mv82iDeeLl6sa9kY0Pug8LSalxVEptRmyFVsVxGgu2/6Y3T+9aCYScxfS06EkA8SdzFMAwYTQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-blockquote": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.1.13.tgz", - "integrity": "sha512-oe6wSQACmODugoP9XH3Ouffjy4BsOBWfTC+dETHNCG6ZED6ShHN3CB9Vr7EwwRgmm2WLaKAjMO1sVumwH+Z1rg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-bold": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.1.13.tgz", - "integrity": "sha512-6cHsQTh/rUiG4jkbJer3vk7g60I5tBwEBSGpdxmEHh83RsvevD8+n92PjA24hYYte5RNlATB011E1wu8PVhSvw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-bubble-menu": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.1.13.tgz", - "integrity": "sha512-Hm7e1GX3AI6lfaUmr6WqsS9MMyXIzCkhh+VQi6K8jj4Q4s8kY4KPoAyD/c3v9pZ/dieUtm2TfqrOCkbHzsJQBg==", - "dependencies": { - "tippy.js": "^6.3.7" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-bullet-list": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.1.13.tgz", - "integrity": "sha512-NkWlQ5bLPUlcROj6G/d4oqAxMf3j3wfndGOPp0z8OoXJtVbVoXl/aMSlLbVgE6n8r6CS8MYxKhXNxrb7Ll2foA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-code": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.1.13.tgz", - "integrity": "sha512-f5fLYlSgliVVa44vd7lQGvo49+peC+Z2H0Fn84TKNCH7tkNZzouoJsHYn0/enLaQ9Sq+24YPfqulfiwlxyiT8w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-code-block": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.1.13.tgz", - "integrity": "sha512-E3tweNExPOV+t1ODKX0MDVsS0aeHGWc1ECt+uyp6XwzsN0bdF2A5+pttQqM7sTcMnQkVACGFbn9wDeLRRcfyQg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-document": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.1.13.tgz", - "integrity": "sha512-wLwiTWsVmZTGIE5duTcHRmW4ulVxNW4nmgfpk95+mPn1iKyNGtrVhGWleLhBlTj+DWXDtcfNWZgqZkZNzhkqYQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-dropcursor": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.1.13.tgz", - "integrity": "sha512-NAyJi4BJxH7vl/2LNS1X0ndwFKjEtX+cRgshXCnMyh7qNpIRW6Plczapc/W1OiMncOEhZJfpZfkRSfwG01FWFg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-floating-menu": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.1.13.tgz", - "integrity": "sha512-9Oz7pk1Nts2+EyY+rYfnREGbLzQ5UFazAvRhF6zAJdvyuDmAYm0Jp6s0GoTrpV0/dJEISoFaNpPdMJOb9EBNRw==", - "dependencies": { - "tippy.js": "^6.3.7" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-gapcursor": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.1.13.tgz", - "integrity": "sha512-Cl5apsoTcyPPCgE3ThufxQxZ1wyqqh+9uxUN9VF9AbeTkid6oPZvKXwaILf6AFnkSy+SuKrb9kZD2iaezxpzXw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-hard-break": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.1.13.tgz", - "integrity": "sha512-TGkMzMQayuKg+vN4du0x1ahEItBLcCT1jdWeRsjdM8gHfzbPLdo4PQhVsvm1I0xaZmbJZelhnVsUwRZcIu1WNA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-heading": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.1.13.tgz", - "integrity": "sha512-PEmc19QLmlVUTiHWoF0hpgNTNPNU0nlaFmMKskzO+cx5Df4xvHmv/UqoIwp7/UFbPMkfVJT1ozQU7oD1IWn9Hg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-history": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.1.13.tgz", - "integrity": "sha512-1ouitThGTBUObqw250aDwGLMNESBH5PRXIGybsCFO1bktdmWtEw7m72WY41EuX2BH8iKJpcYPerl3HfY1vmCNw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.1.13.tgz", - "integrity": "sha512-7OgjgNqZXvBejgULNdMSma2M1nzv4bbZG+FT5XMFZmEOxR9IB1x/RzChjPdeicff2ZK2sfhMBc4Y9femF5XkUg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-italic": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.1.13.tgz", - "integrity": "sha512-HyDJfuDn5hzwGKZiANcvgz6wcum6bEgb4wmJnfej8XanTMJatNVv63TVxCJ10dSc9KGpPVcIkg6W8/joNXIEbw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-list-item": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.1.13.tgz", - "integrity": "sha512-6e8iiCWXOiJTl1XOwVW2tc0YG18h70HUtEHFCx2m5HspOGFKsFEaSS3qYxOheM9HxlmQeDt8mTtqftRjEFRxPQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-mention": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-mention/-/extension-mention-2.1.13.tgz", - "integrity": "sha512-OYqaucyBiCN/CmDYjpOVX74RJcIEKmAqiZxUi8Gfaq7ryEO5a8Gk93nK+8uZ0onaqHE+mHpoLFFbcAFbOPgkUQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0", - "@tiptap/suggestion": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-ordered-list": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.1.13.tgz", - "integrity": "sha512-UO4ZAL5Vrr1WwER5VjgmeNIWHpqy9cnIRo1En07gZ0OWTjs1eITPcu+4TCn1ZG6DhoFvAQzE5DTxxdhIotg+qw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-paragraph": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.1.13.tgz", - "integrity": "sha512-cEoZBJrsQn69FPpUMePXG/ltGXtqKISgypj70PEHXt5meKDjpmMVSY4/8cXvFYEYsI9GvIwyAK0OrfAHiSoROA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-placeholder": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.1.13.tgz", - "integrity": "sha512-vIY7y7UbqsrAW/y8bDE9eRenbQEU16kNHB5Wri8RU1YiUZpkPgdXP/pLqyjIIq95SwP/vdTIHjHoQ77VLRl1hA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-strike": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.1.13.tgz", - "integrity": "sha512-VN6zlaCNCbyJUCDyBFxavw19XmQ4LkCh8n20M8huNqW77lDGXA2A7UcWLHaNBpqAijBRu9mWI8l4Bftyf2fcAw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-text": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.1.13.tgz", - "integrity": "sha512-zzsTTvu5U67a8WjImi6DrmpX2Q/onLSaj+LRWPh36A1Pz2WaxW5asZgaS+xWCnR+UrozlCALWa01r7uv69jq0w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/pm": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.1.13.tgz", - "integrity": "sha512-zNbA7muWsHuVg12GrTgN/j119rLePPq5M8dZgkKxUwdw8VmU3eUyBp1SihPEXJ2U0MGdZhNhFX7Y74g11u66sg==", - "dependencies": { - "prosemirror-changeset": "^2.2.0", - "prosemirror-collab": "^1.3.0", - "prosemirror-commands": "^1.3.1", - "prosemirror-dropcursor": "^1.5.0", - "prosemirror-gapcursor": "^1.3.1", - "prosemirror-history": "^1.3.0", - "prosemirror-inputrules": "^1.2.0", - "prosemirror-keymap": "^1.2.0", - "prosemirror-markdown": "^1.10.1", - "prosemirror-menu": "^1.2.1", - "prosemirror-model": "^1.18.1", - "prosemirror-schema-basic": "^1.2.0", - "prosemirror-schema-list": "^1.2.2", - "prosemirror-state": "^1.4.1", - "prosemirror-tables": "^1.3.0", - "prosemirror-trailing-node": "^2.0.2", - "prosemirror-transform": "^1.7.0", - "prosemirror-view": "^1.28.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - } - }, - "node_modules/@tiptap/react": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.1.13.tgz", - "integrity": "sha512-Dq3f8EtJnpImP3iDtJo+7bulnN9SJZRZcVVzxHXccLcC2MxtmDdlPGZjP+wxO800nd8toSIOd5734fPNf/YcfA==", - "dependencies": { - "@tiptap/extension-bubble-menu": "^2.1.13", - "@tiptap/extension-floating-menu": "^2.1.13" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - } - }, - "node_modules/@tiptap/starter-kit": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.1.13.tgz", - "integrity": "sha512-ph/mUR/OwPtPkZ5rNHINxubpABn8fHnvJSdhXFrY/q6SKoaO11NZXgegRaiG4aL7O6Sz4LsZVw6Sm0Ae+GJmrg==", - "dependencies": { - "@tiptap/core": "^2.1.13", - "@tiptap/extension-blockquote": "^2.1.13", - "@tiptap/extension-bold": "^2.1.13", - "@tiptap/extension-bullet-list": "^2.1.13", - "@tiptap/extension-code": "^2.1.13", - "@tiptap/extension-code-block": "^2.1.13", - "@tiptap/extension-document": "^2.1.13", - "@tiptap/extension-dropcursor": "^2.1.13", - "@tiptap/extension-gapcursor": "^2.1.13", - "@tiptap/extension-hard-break": "^2.1.13", - "@tiptap/extension-heading": "^2.1.13", - "@tiptap/extension-history": "^2.1.13", - "@tiptap/extension-horizontal-rule": "^2.1.13", - "@tiptap/extension-italic": "^2.1.13", - "@tiptap/extension-list-item": "^2.1.13", - "@tiptap/extension-ordered-list": "^2.1.13", - "@tiptap/extension-paragraph": "^2.1.13", - "@tiptap/extension-strike": "^2.1.13", - "@tiptap/extension-text": "^2.1.13" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - } - }, - "node_modules/@tiptap/suggestion": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/@tiptap/suggestion/-/suggestion-2.1.13.tgz", - "integrity": "sha512-Y05TsiXTFAJ5SrfoV+21MAxig5UNbY0AVa03lQlh/yicTRPpIc6hgZzblB0uxDSYoj6+kaHE4MIZvPvhUD8BJQ==", - "peer": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -3454,16 +3022,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.5.tgz", "integrity": "sha512-4slmbtwV59ZxitY4ixUZdy1uRLf9eSIvBWPQxNjhHYWEtn0FryfKpyS2cvADYXTayWdKEIsJengncrVvkI4I6A==" }, - "node_modules/@types/object.omit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/object.omit/-/object.omit-3.0.3.tgz", - "integrity": "sha512-xrq4bQTBGYY2cw+gV4PzoG2Lv3L0pjZ1uXStRRDQoATOYW1lCsFQHhQ+OkPhIcQoqLjAq7gYif7D14Qaa6Zbew==" - }, - "node_modules/@types/object.pick": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@types/object.pick/-/object.pick-1.3.4.tgz", - "integrity": "sha512-5PjwB0uP2XDp3nt5u5NJAG2DORHIRClPzWT/TTZhJ2Ekwe8M5bA9tvPdi9NO/n2uvu2/ictat8kgqvLfcIE1SA==" - }, "node_modules/@types/p5": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/@types/p5/-/p5-1.7.0.tgz", @@ -3590,11 +3148,6 @@ "meshoptimizer": "~0.18.1" } }, - "node_modules/@types/throttle-debounce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/throttle-debounce/-/throttle-debounce-2.1.0.tgz", - "integrity": "sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==" - }, "node_modules/@types/unist": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.8.tgz", @@ -4194,7 +3747,8 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/aria-query": { "version": "5.3.0", @@ -4940,17 +4494,6 @@ "cargo-cp-artifact": "bin/cargo-cp-artifact.js" } }, - "node_modules/case-anything": { - "version": "2.1.13", - "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.13.tgz", - "integrity": "sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==", - "engines": { - "node": ">=12.13" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -5301,11 +4844,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/crelt": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", - "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" - }, "node_modules/cropperjs": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.6.1.tgz", @@ -5357,11 +4895,6 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, - "node_modules/dash-get": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/dash-get/-/dash-get-1.0.2.tgz", - "integrity": "sha512-4FbVrHDwfOASx7uQVxeiCTo7ggSdYZbqs8lH+WU6ViypPlDbe9y6IP5VVUDQBv9DcnyaiPT5XT0UWHgJ64zLeQ==" - }, "node_modules/dateformat": { "version": "4.6.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", @@ -5745,17 +5278,6 @@ "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", "dev": true }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -8156,17 +7678,6 @@ "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==" }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -8309,17 +7820,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -8454,14 +7954,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -9391,14 +8883,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, - "node_modules/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", - "dependencies": { - "uc.micro": "^2.0.0" - } - }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -9568,7 +9052,8 @@ "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "node_modules/make-fetch-happen": { "version": "9.1.0", @@ -9618,22 +9103,6 @@ "tmpl": "1.0.5" } }, - "node_modules/markdown-it": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.0.0.tgz", - "integrity": "sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==", - "dependencies": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.0.0" - }, - "bin": { - "markdown-it": "bin/markdown-it.mjs" - } - }, "node_modules/markdown-table": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", @@ -9961,11 +9430,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" - }, "node_modules/memfs": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", @@ -11351,28 +10815,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.omit": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-3.0.0.tgz", - "integrity": "sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==", - "dependencies": { - "is-extendable": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.values": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", @@ -11487,11 +10929,6 @@ "node": ">= 0.8.0" } }, - "node_modules/orderedmap": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", - "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==" - }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -12419,183 +11856,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/prosemirror-changeset": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz", - "integrity": "sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==", - "dependencies": { - "prosemirror-transform": "^1.0.0" - } - }, - "node_modules/prosemirror-collab": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", - "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", - "dependencies": { - "prosemirror-state": "^1.0.0" - } - }, - "node_modules/prosemirror-commands": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz", - "integrity": "sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==", - "dependencies": { - "prosemirror-model": "^1.0.0", - "prosemirror-state": "^1.0.0", - "prosemirror-transform": "^1.0.0" - } - }, - "node_modules/prosemirror-dropcursor": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz", - "integrity": "sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==", - "dependencies": { - "prosemirror-state": "^1.0.0", - "prosemirror-transform": "^1.1.0", - "prosemirror-view": "^1.1.0" - } - }, - "node_modules/prosemirror-gapcursor": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", - "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", - "dependencies": { - "prosemirror-keymap": "^1.0.0", - "prosemirror-model": "^1.0.0", - "prosemirror-state": "^1.0.0", - "prosemirror-view": "^1.0.0" - } - }, - "node_modules/prosemirror-history": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.3.2.tgz", - "integrity": "sha512-/zm0XoU/N/+u7i5zepjmZAEnpvjDtzoPWW6VmKptcAnPadN/SStsBjMImdCEbb3seiNTpveziPTIrXQbHLtU1g==", - "dependencies": { - "prosemirror-state": "^1.2.2", - "prosemirror-transform": "^1.0.0", - "prosemirror-view": "^1.31.0", - "rope-sequence": "^1.3.0" - } - }, - "node_modules/prosemirror-inputrules": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.3.0.tgz", - "integrity": "sha512-z1GRP2vhh5CihYMQYsJSa1cOwXb3SYxALXOIfAkX8nZserARtl9LiL+CEl+T+OFIsXc3mJIHKhbsmRzC0HDAXA==", - "dependencies": { - "prosemirror-state": "^1.0.0", - "prosemirror-transform": "^1.0.0" - } - }, - "node_modules/prosemirror-keymap": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", - "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", - "dependencies": { - "prosemirror-state": "^1.0.0", - "w3c-keyname": "^2.2.0" - } - }, - "node_modules/prosemirror-markdown": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.12.0.tgz", - "integrity": "sha512-6F5HS8Z0HDYiS2VQDZzfZP6A0s/I0gbkJy8NCzzDMtcsz3qrfqyroMMeoSjAmOhDITyon11NbXSzztfKi+frSQ==", - "dependencies": { - "markdown-it": "^14.0.0", - "prosemirror-model": "^1.0.0" - } - }, - "node_modules/prosemirror-menu": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", - "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", - "dependencies": { - "crelt": "^1.0.0", - "prosemirror-commands": "^1.0.0", - "prosemirror-history": "^1.0.0", - "prosemirror-state": "^1.0.0" - } - }, - "node_modules/prosemirror-model": { - "version": "1.19.4", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.19.4.tgz", - "integrity": "sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ==", - "dependencies": { - "orderedmap": "^2.0.0" - } - }, - "node_modules/prosemirror-schema-basic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.2.tgz", - "integrity": "sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==", - "dependencies": { - "prosemirror-model": "^1.19.0" - } - }, - "node_modules/prosemirror-schema-list": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.3.0.tgz", - "integrity": "sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==", - "dependencies": { - "prosemirror-model": "^1.0.0", - "prosemirror-state": "^1.0.0", - "prosemirror-transform": "^1.7.3" - } - }, - "node_modules/prosemirror-state": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", - "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", - "dependencies": { - "prosemirror-model": "^1.0.0", - "prosemirror-transform": "^1.0.0", - "prosemirror-view": "^1.27.0" - } - }, - "node_modules/prosemirror-tables": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.3.5.tgz", - "integrity": "sha512-JSZ2cCNlApu/ObAhdPyotrjBe2cimniniTpz60YXzbL0kZ+47nEYk2LWbfKU2lKpBkUNquta2PjteoNi4YCluQ==", - "dependencies": { - "prosemirror-keymap": "^1.1.2", - "prosemirror-model": "^1.8.1", - "prosemirror-state": "^1.3.1", - "prosemirror-transform": "^1.2.1", - "prosemirror-view": "^1.13.3" - } - }, - "node_modules/prosemirror-trailing-node": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.7.tgz", - "integrity": "sha512-8zcZORYj/8WEwsGo6yVCRXFMOfBo0Ub3hCUvmoWIZYfMP26WqENU0mpEP27w7mt8buZWuGrydBewr0tOArPb1Q==", - "dependencies": { - "@remirror/core-constants": "^2.0.2", - "@remirror/core-helpers": "^3.0.0", - "escape-string-regexp": "^4.0.0" - }, - "peerDependencies": { - "prosemirror-model": "^1.19.0", - "prosemirror-state": "^1.4.2", - "prosemirror-view": "^1.31.2" - } - }, - "node_modules/prosemirror-transform": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.8.0.tgz", - "integrity": "sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==", - "dependencies": { - "prosemirror-model": "^1.0.0" - } - }, - "node_modules/prosemirror-view": { - "version": "1.32.6", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.32.6.tgz", - "integrity": "sha512-26r5LvyDlPgUNVf7ZdNdGrMJnylwjJtUJTfDuYOANIVx9lqWD1WCBlGg283weYQGKUC64DXR25LeAmliB9CrFQ==", - "dependencies": { - "prosemirror-model": "^1.16.0", - "prosemirror-state": "^1.0.0", - "prosemirror-transform": "^1.1.0" - } - }, "node_modules/proto3-json-serializer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-1.1.1.tgz", @@ -12652,14 +11912,6 @@ "node": ">=6" } }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "engines": { - "node": ">=6" - } - }, "node_modules/pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -13417,11 +12669,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rope-sequence": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", - "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==" - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -14653,22 +13900,6 @@ "resolved": "https://registry.npmjs.org/three/-/three-0.155.0.tgz", "integrity": "sha512-sNgCYmDijnIqkD/bMfk+1pHg3YzsxW7V2ChpuP6HCQ8NiZr3RufsXQr8M3SSUMjW4hG+sUk7YbyuY0DncaDTJQ==" }, - "node_modules/throttle-debounce": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", - "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/tippy.js": { - "version": "6.3.7", - "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", - "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", - "dependencies": { - "@popperjs/core": "^2.9.0" - } - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -14981,11 +14212,6 @@ "node": ">=14.17" } }, - "node_modules/uc.micro": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.0.0.tgz", - "integrity": "sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==" - }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -15356,11 +14582,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/w3c-keyname": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", diff --git a/front/package.json b/front/package.json index 5b10f1187c29..d4cb7f468a6d 100644 --- a/front/package.json +++ b/front/package.json @@ -30,11 +30,6 @@ "@temporalio/worker": "^1.7.4", "@temporalio/workflow": "^1.7.4", "@textea/json-viewer": "^3.1.1", - "@tiptap/extension-mention": "^2.1.13", - "@tiptap/extension-placeholder": "^2.1.13", - "@tiptap/pm": "^2.1.13", - "@tiptap/react": "^2.1.13", - "@tiptap/starter-kit": "^2.1.13", "@types/emoji-mart": "^3.0.10", "@uiw/react-textarea-code-editor": "^2.1.7", "ajv": "^8.12.0", diff --git a/front/pages/w/[wId]/assistant/[cId]/index.tsx b/front/pages/w/[wId]/assistant/[cId]/index.tsx index abd6d4f0a81a..8c6e3125e9ce 100644 --- a/front/pages/w/[wId]/assistant/[cId]/index.tsx +++ b/front/pages/w/[wId]/assistant/[cId]/index.tsx @@ -8,7 +8,7 @@ import { useContext, useEffect, useState } from "react"; import Conversation from "@app/components/assistant/conversation/Conversation"; import { ConversationTitle } from "@app/components/assistant/conversation/ConversationTitle"; import { GenerationContextProvider } from "@app/components/assistant/conversation/GenerationContextProvider"; -import { FixedAssistantInputBar } from "@app/components/assistant/conversation/input_bar/InputBar"; +import { FixedAssistantInputBar } from "@app/components/assistant/conversation/InputBar"; import { AssistantSidebarMenu } from "@app/components/assistant/conversation/SidebarMenu"; import AppLayout from "@app/components/sparkle/AppLayout"; import { subNavigationConversations } from "@app/components/sparkle/navigation"; diff --git a/front/pages/w/[wId]/assistant/new.tsx b/front/pages/w/[wId]/assistant/new.tsx index 1ee37c17968b..3d22844a295f 100644 --- a/front/pages/w/[wId]/assistant/new.tsx +++ b/front/pages/w/[wId]/assistant/new.tsx @@ -31,7 +31,7 @@ import { GenerationContextProvider } from "@app/components/assistant/conversatio import { FixedAssistantInputBar, InputBarContext, -} from "@app/components/assistant/conversation/input_bar/InputBar"; +} from "@app/components/assistant/conversation/InputBar"; import { AssistantSidebarMenu } from "@app/components/assistant/conversation/SidebarMenu"; import AppLayout from "@app/components/sparkle/AppLayout"; import { subNavigationConversations } from "@app/components/sparkle/navigation";