From e59e79babe2a316cf9a9de8f35d124cc5d63ae05 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Mon, 15 Sep 2025 15:43:10 +0900 Subject: [PATCH 01/13] feat: markdown editor and markdown renderer --- web/package.json | 1 + web/src/components/EvidenceCard.tsx | 22 +- web/src/components/MarkdownEditor.tsx | 223 ++ web/src/components/MarkdownRenderer.tsx | 196 ++ .../Evidence/SubmitEvidenceModal.tsx | 24 +- .../CaseDetails/Voting/Classic/Reveal.tsx | 5 +- .../CaseDetails/Voting/JustificationArea.tsx | 37 - .../CaseDetails/Voting/OptionsContainer.tsx | 9 +- .../CaseDetails/Voting/VotesDetails/index.tsx | 12 +- yarn.lock | 2498 ++++++++++++++++- 10 files changed, 2905 insertions(+), 122 deletions(-) create mode 100644 web/src/components/MarkdownEditor.tsx create mode 100644 web/src/components/MarkdownRenderer.tsx delete mode 100644 web/src/pages/Cases/CaseDetails/Voting/JustificationArea.tsx diff --git a/web/package.json b/web/package.json index 11d688844..35e5f6f29 100644 --- a/web/package.json +++ b/web/package.json @@ -91,6 +91,7 @@ "@kleros/ui-components-library": "^2.20.0", "@lifi/wallet-management": "^3.7.1", "@lifi/widget": "^3.18.1", + "@mdxeditor/editor": "^3.44.2", "@reown/appkit": "^1.7.1", "@reown/appkit-adapter-wagmi": "^1.7.1", "@sentry/react": "^7.120.0", diff --git a/web/src/components/EvidenceCard.tsx b/web/src/components/EvidenceCard.tsx index f17d97e26..90ea42f00 100644 --- a/web/src/components/EvidenceCard.tsx +++ b/web/src/components/EvidenceCard.tsx @@ -1,7 +1,6 @@ import React, { useMemo } from "react"; import styled, { css } from "styled-components"; -import ReactMarkdown from "react-markdown"; import { useParams } from "react-router-dom"; import { Card } from "@kleros/ui-components-library"; @@ -18,9 +17,11 @@ import { hoverShortTransitionTiming } from "styles/commonStyles"; import { landscapeStyle } from "styles/landscapeStyle"; import { responsiveSize } from "styles/responsiveSize"; +import JurorTitle from "pages/Home/TopJurors/JurorCard/JurorTitle"; + import { ExternalLink } from "./ExternalLink"; import { InternalLink } from "./InternalLink"; -import JurorTitle from "pages/Home/TopJurors/JurorCard/JurorTitle"; +import MarkdownRenderer from "./MarkdownRenderer"; const StyledCard = styled(Card)` width: 100%; @@ -66,17 +67,6 @@ const Index = styled.p` `; const ReactMarkdownWrapper = styled.div``; -const StyledReactMarkdown = styled(ReactMarkdown)` - a { - font-size: 16px; - } - code { - color: ${({ theme }) => theme.secondaryText}; - } - p { - margin: 0; - } -`; const BottomShade = styled.div` background-color: ${({ theme }) => theme.lightBlue}; @@ -227,10 +217,12 @@ const EvidenceCard: React.FC = ({ {name && description ? ( - {description} + ) : ( -

{evidence}

+ + + )} diff --git a/web/src/components/MarkdownEditor.tsx b/web/src/components/MarkdownEditor.tsx new file mode 100644 index 000000000..2a3fdb54e --- /dev/null +++ b/web/src/components/MarkdownEditor.tsx @@ -0,0 +1,223 @@ +import React, { useRef } from "react"; +import styled from "styled-components"; + +import { + MDXEditor, + type MDXEditorMethods, + type MDXEditorProps, + headingsPlugin, + listsPlugin, + quotePlugin, + thematicBreakPlugin, + markdownShortcutPlugin, + linkPlugin, + linkDialogPlugin, + tablePlugin, + toolbarPlugin, + UndoRedo, + BoldItalicUnderlineToggles, + CodeToggle, + ListsToggle, + CreateLink, + InsertTable, + BlockTypeSelect, + Separator, +} from "@mdxeditor/editor"; + +import "@mdxeditor/editor/style.css"; + +import InfoIcon from "svgs/icons/info-circle.svg"; + +const Container = styled.div<{ isEmpty: boolean }>` + width: 100%; + + [class*="mdxeditor"] { + background-color: ${({ theme }) => theme.whiteBackground} !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; + border-radius: 3px; + font-family: "Open Sans", sans-serif; + } + + [class*="toolbar"] { + background-color: ${({ theme }) => theme.lightGrey} !important; + border-bottom: none !important; + + button { + color: ${({ theme }) => theme.whiteBackground} !important; + } + + svg { + fill: ${({ theme }) => theme.whiteBackground} !important; + } + + select { + background-color: ${({ theme }) => theme.whiteBackground} !important; + color: ${({ theme }) => theme.primaryText} !important; + } + } + + [class*="contentEditable"] { + background-color: ${({ theme }) => theme.whiteBackground} !important; + color: ${({ theme }) => theme.primaryText} !important; + min-height: 200px; + padding: 16px; + font-size: 16px; + line-height: 1.5; + + p { + color: ${({ theme, isEmpty }) => (isEmpty ? theme.secondaryText : theme.primaryText)} !important; + margin: 0 0 12px 0; + } + + p:empty::before { + color: ${({ theme }) => theme.secondaryText} !important; + opacity: 0.6 !important; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + color: ${({ theme }) => theme.primaryText} !important; + font-weight: 600; + margin: 16px 0 8px 0; + } + + blockquote { + color: ${({ theme }) => theme.secondaryText} !important; + border-left: 3px solid ${({ theme }) => theme.mediumBlue} !important; + font-style: italic; + margin: 16px 0; + padding-left: 12px; + } + + code { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.primaryText} !important; + } + + pre { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.primaryText} !important; + } + + a { + color: ${({ theme }) => theme.primaryBlue} !important; + } + + th { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.primaryText} !important; + } + + td { + color: ${({ theme }) => theme.primaryText} !important; + } + } +`; + +const MessageContainer = styled.div` + display: flex; + align-items: flex-start; + gap: 8px; + margin-top: 8px; +`; + +const MessageText = styled.small` + font-size: 14px; + font-weight: 400; + color: ${({ theme }) => theme.secondaryText}; + hyphens: auto; + line-height: 1.4; +`; + +const StyledInfoIcon = styled(InfoIcon)` + width: 16px; + height: 16px; + fill: ${({ theme }) => theme.secondaryText} !important; + flex-shrink: 0; + margin-top: 2px; + + path { + fill: ${({ theme }) => theme.secondaryText} !important; + } + + * { + fill: ${({ theme }) => theme.secondaryText} !important; + } +`; + +interface IMarkdownEditor { + value: string; + onChange: (value: string) => void; + placeholder?: string; + showMessage?: boolean; +} + +const MarkdownEditor: React.FC = ({ + value, + onChange, + placeholder = "Justify your vote...", + showMessage = true, +}) => { + const editorRef = useRef(null); + + const handleChange = (markdown: string) => { + onChange(markdown); + }; + + const isEmpty = !value || value.trim() === ""; + + const editorProps: MDXEditorProps = { + markdown: value, + onChange: handleChange, + placeholder, + plugins: [ + headingsPlugin(), + listsPlugin(), + quotePlugin(), + thematicBreakPlugin(), + markdownShortcutPlugin(), + linkPlugin(), + linkDialogPlugin(), + tablePlugin(), + toolbarPlugin({ + toolbarContents: () => ( + <> + + + + + + + + + + + + + ), + }), + ], + }; + + return ( + + + {showMessage && ( + + + + Please provide a comprehensive justification for your decision. Quality explanations are essential for the + parties involved and may be eligible for additional compensation in accordance with our justification + policy. + + + )} + + ); +}; + +export default MarkdownEditor; diff --git a/web/src/components/MarkdownRenderer.tsx b/web/src/components/MarkdownRenderer.tsx new file mode 100644 index 000000000..8df425279 --- /dev/null +++ b/web/src/components/MarkdownRenderer.tsx @@ -0,0 +1,196 @@ +import React from "react"; +import styled from "styled-components"; + +import { + MDXEditor, + type MDXEditorProps, + headingsPlugin, + listsPlugin, + quotePlugin, + thematicBreakPlugin, + markdownShortcutPlugin, + linkPlugin, + tablePlugin, +} from "@mdxeditor/editor"; + +import "@mdxeditor/editor/style.css"; + +const Container = styled.div` + width: 100%; + + [class*="mdxeditor"] { + background: transparent !important; + border: none !important; + } + + [class*="toolbar"] { + display: none !important; + } + + [class*="contentEditable"] { + background: transparent !important; + border: none !important; + padding: 0 !important; + font-size: 16px; + line-height: 1.5; + + p { + margin: 0 0 12px 0; + color: ${({ theme }) => theme.primaryText} !important; + } + + p:last-child { + margin-bottom: 0; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + margin: 16px 0 8px 0; + font-weight: 600; + color: ${({ theme }) => theme.primaryText} !important; + } + + h1 { + font-size: 24px; + } + h2 { + font-size: 20px; + } + h3 { + font-size: 18px; + } + h4 { + font-size: 16px; + } + h5 { + font-size: 14px; + } + h6 { + font-size: 12px; + } + + ul, + ol { + margin: 8px 0; + padding-left: 24px; + } + + li { + margin: 4px 0; + color: ${({ theme }) => theme.primaryText} !important; + } + + blockquote { + border-left: 3px solid ${({ theme }) => theme.mediumBlue} !important; + padding-left: 12px; + margin: 16px 0; + color: ${({ theme }) => theme.secondaryText} !important; + font-style: italic; + } + + code { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.primaryText} !important; + padding: 2px 4px; + border-radius: 3px; + font-family: "Monaco", "Consolas", monospace; + font-size: 14px; + } + + pre { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.primaryText} !important; + padding: 12px; + border-radius: 3px; + overflow-x: auto; + margin: 16px 0; + } + + pre code { + background: transparent !important; + padding: 0; + } + + table { + border-collapse: collapse; + width: 100%; + margin: 16px 0; + } + + th, + td { + border: 1px solid ${({ theme }) => theme.stroke} !important; + padding: 8px 12px; + text-align: left; + color: ${({ theme }) => theme.primaryText} !important; + } + + th { + background-color: ${({ theme }) => theme.lightGrey} !important; + font-weight: 600; + } + + a { + color: ${({ theme }) => theme.primaryBlue} !important; + text-decoration: none; + } + + a:hover { + text-decoration: underline; + color: ${({ theme }) => theme.secondaryBlue} !important; + } + + hr { + border: none; + border-top: 1px solid ${({ theme }) => theme.stroke} !important; + margin: 24px 0; + } + + img { + max-width: 100%; + height: auto; + } + + * { + cursor: default !important; + user-select: text !important; + } + } +`; + +interface IMarkdownRenderer { + content: string; + className?: string; +} + +const MarkdownRenderer: React.FC = ({ content, className }) => { + if (!content || content.trim() === "") { + return null; + } + + const editorProps: MDXEditorProps = { + markdown: content, + readOnly: true, + plugins: [ + headingsPlugin(), + listsPlugin(), + quotePlugin(), + thematicBreakPlugin(), + markdownShortcutPlugin(), + linkPlugin(), + tablePlugin(), + ], + }; + + return ( + + + + ); +}; + +export default MarkdownRenderer; diff --git a/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx b/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx index 12916f302..e163d77a9 100644 --- a/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx +++ b/web/src/pages/Cases/CaseDetails/Evidence/SubmitEvidenceModal.tsx @@ -5,7 +5,7 @@ import Modal from "react-modal"; import { useWalletClient, usePublicClient, useConfig } from "wagmi"; import { Roles, useAtlasProvider } from "@kleros/kleros-app"; -import { Textarea, Button, FileUploader } from "@kleros/ui-components-library"; +import { Button, FileUploader } from "@kleros/ui-components-library"; import { simulateEvidenceModuleSubmitEvidence } from "hooks/contracts/generated"; import { wrapWithToast, errorToast, infoToast, successToast } from "utils/wrapWithToast"; @@ -14,6 +14,7 @@ import { getFileUploaderMsg, isEmpty } from "src/utils"; import EnsureAuth from "components/EnsureAuth"; import { EnsureChain } from "components/EnsureChain"; +import MarkdownEditor from "components/MarkdownEditor"; const StyledModal = styled(Modal)` position: absolute; @@ -36,9 +37,12 @@ const StyledModal = styled(Modal)` gap: 16px; `; -const StyledTextArea = styled(Textarea)` +const EditorContainer = styled.div` width: 100%; - height: 200px; + + [class*="contentEditable"] { + min-height: 200px; + } `; const StyledFileUploader = styled(FileUploader)` @@ -93,12 +97,14 @@ const SubmitEvidenceModal: React.FC<{ return (

Submit New Evidence

- setMessage(e.target.value)} - placeholder="Your Arguments" - /> + + + setFile(file)} msg={getFileUploaderMsg(Roles.Evidence, roleRestrictions)} diff --git a/web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx b/web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx index 3bea21339..e95ee1bd3 100644 --- a/web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx +++ b/web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx @@ -20,8 +20,7 @@ import { useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery"; import { EnsureChain } from "components/EnsureChain"; import InfoCard from "components/InfoCard"; - -import JustificationArea from "../JustificationArea"; +import MarkdownEditor from "components/MarkdownEditor"; const Container = styled.div` width: 100%; @@ -114,7 +113,7 @@ const Reveal: React.FC = ({ arbitrable, voteIDs, setIsOpen, commit, isR {disputeDetails?.question ?? ""} - + theme.stroke}; - } - small { - font-weight: 400; - hyphens: auto; - } -`; - -interface IJustificationArea { - justification: string; - setJustification: (arg0: string) => void; -} - -const JustificationArea: React.FC = ({ justification, setJustification }) => ( - setJustification(e.target.value)} - placeholder="Justify your vote..." - message={ - "A good justification contributes to case comprehension. " + "Low quality justifications can be challenged." - } - variant="info" - /> -); - -export default JustificationArea; diff --git a/web/src/pages/Cases/CaseDetails/Voting/OptionsContainer.tsx b/web/src/pages/Cases/CaseDetails/Voting/OptionsContainer.tsx index f58d132b0..2e8a5ecf1 100644 --- a/web/src/pages/Cases/CaseDetails/Voting/OptionsContainer.tsx +++ b/web/src/pages/Cases/CaseDetails/Voting/OptionsContainer.tsx @@ -4,16 +4,15 @@ import styled from "styled-components"; import ReactMarkdown from "react-markdown"; import { useParams } from "react-router-dom"; +import { Answer } from "@kleros/kleros-sdk"; +import { RefuseToArbitrateAnswer } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsSchema"; import { Button, Tooltip } from "@kleros/ui-components-library"; import { usePopulatedDisputeData } from "hooks/queries/usePopulatedDisputeData"; import { isUndefined } from "utils/index"; import { EnsureChain } from "components/EnsureChain"; - -import JustificationArea from "./JustificationArea"; -import { Answer } from "@kleros/kleros-sdk"; -import { RefuseToArbitrateAnswer } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsSchema"; +import MarkdownEditor from "components/MarkdownEditor"; const MainContainer = styled.div` width: 100%; @@ -87,7 +86,7 @@ const Options: React.FC = ({ arbitrable, handleSelection, justificatio {disputeDetails?.question ?? ""} {!isUndefined(justification) && !isUndefined(setJustification) ? ( - + ) : null} {isUndefined(disputeDetails?.answers) ? null : ( diff --git a/web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx b/web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx index 7396d610e..d380be531 100644 --- a/web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx +++ b/web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx @@ -14,6 +14,7 @@ import { landscapeStyle } from "styles/landscapeStyle"; import { ExternalLink } from "components/ExternalLink"; import InfoCard from "components/InfoCard"; +import MarkdownRenderer from "components/MarkdownRenderer"; import AccordionTitle from "./AccordionTitle"; @@ -84,10 +85,13 @@ const VotedText = styled.label` } `; -const JustificationText = styled(VotedText)` +const JustificationContainer = styled.div` line-height: 1.25; - ::before { + + &::before { content: "Justification: "; + color: ${({ theme }) => theme.primaryText}; + font-size: 16px; } `; @@ -117,7 +121,9 @@ const AccordionContent: React.FC<{ {!isUndefined(choice) && {getVoteChoice(choice, answers)}} {justification ? ( - {justification} + + + ) : ( No justification provided )} diff --git a/yarn.lock b/yarn.lock index c2cb4f2d5..ebb0d8076 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1811,6 +1811,13 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.14.8": + version: 7.28.4 + resolution: "@babel/runtime@npm:7.28.4" + checksum: 10/6c9a70452322ea80b3c9b2a412bcf60771819213a67576c8cec41e88a95bb7bf01fc983754cda35dc19603eef52df22203ccbf7777b9d6316932f9fb77c25163 + languageName: node + linkType: hard + "@babel/runtime@npm:^7.26.10": version: 7.27.0 resolution: "@babel/runtime@npm:7.27.0" @@ -2271,6 +2278,18 @@ __metadata: languageName: node linkType: hard +"@codemirror/autocomplete@npm:^6.0.0, @codemirror/autocomplete@npm:^6.3.2, @codemirror/autocomplete@npm:^6.4.0, @codemirror/autocomplete@npm:^6.7.1": + version: 6.18.7 + resolution: "@codemirror/autocomplete@npm:6.18.7" + dependencies: + "@codemirror/language": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.17.0" + "@lezer/common": "npm:^1.0.0" + checksum: 10/e50e3345d7d33e762d9abd2e6b1ea4ff54afe1630310464a5ddb42cab52fd5bac783ec0dc8a328cb746be6a7f9f711b6fcd8ef311af123511e8307b4c056cb9d + languageName: node + linkType: hard + "@codemirror/autocomplete@npm:^6.18.1": version: 6.18.6 resolution: "@codemirror/autocomplete@npm:6.18.6" @@ -2283,7 +2302,7 @@ __metadata: languageName: node linkType: hard -"@codemirror/commands@npm:^6.7.1": +"@codemirror/commands@npm:^6.0.0, @codemirror/commands@npm:^6.1.3, @codemirror/commands@npm:^6.2.4, @codemirror/commands@npm:^6.7.1": version: 6.8.1 resolution: "@codemirror/commands@npm:6.8.1" dependencies: @@ -2295,6 +2314,108 @@ __metadata: languageName: node linkType: hard +"@codemirror/lang-angular@npm:^0.1.0": + version: 0.1.4 + resolution: "@codemirror/lang-angular@npm:0.1.4" + dependencies: + "@codemirror/lang-html": "npm:^6.0.0" + "@codemirror/lang-javascript": "npm:^6.1.2" + "@codemirror/language": "npm:^6.0.0" + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.3.3" + checksum: 10/94f8e03a7636918a74cb18cb695538b8609732c0c39ac255b822dfd06cc55238bc488146e16b9f051e88949208e032045882f1feabac78e2968d2890056b08c7 + languageName: node + linkType: hard + +"@codemirror/lang-cpp@npm:^6.0.0": + version: 6.0.3 + resolution: "@codemirror/lang-cpp@npm:6.0.3" + dependencies: + "@codemirror/language": "npm:^6.0.0" + "@lezer/cpp": "npm:^1.0.0" + checksum: 10/982b9a9624367a0086520e1d499b7ad2fba2a14bdd57df88520bac279bd980e12154fd281659226fbcfa530edb5dd72edd114481365e6224bf53e97bc972f3b8 + languageName: node + linkType: hard + +"@codemirror/lang-css@npm:^6.0.0, @codemirror/lang-css@npm:^6.0.1, @codemirror/lang-css@npm:^6.2.0": + version: 6.3.1 + resolution: "@codemirror/lang-css@npm:6.3.1" + dependencies: + "@codemirror/autocomplete": "npm:^6.0.0" + "@codemirror/language": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@lezer/common": "npm:^1.0.2" + "@lezer/css": "npm:^1.1.7" + checksum: 10/709994b0a787fe06ebac7a47c6a6a92c9680fe2b4479bbe2a72b27ad4d863953ad64a61b36f15098d00bd9a655bc9b3a3ecf2877354351ff873a01186fb38386 + languageName: node + linkType: hard + +"@codemirror/lang-go@npm:^6.0.0": + version: 6.0.1 + resolution: "@codemirror/lang-go@npm:6.0.1" + dependencies: + "@codemirror/autocomplete": "npm:^6.0.0" + "@codemirror/language": "npm:^6.6.0" + "@codemirror/state": "npm:^6.0.0" + "@lezer/common": "npm:^1.0.0" + "@lezer/go": "npm:^1.0.0" + checksum: 10/6e361bddb35683b225e1367807f598044b861c6858c9a011227fb73a872735985141746b3c410dcd8ef11b4c0e54819e720c5e663201a6a5e69ba8a9519fa287 + languageName: node + linkType: hard + +"@codemirror/lang-html@npm:^6.0.0, @codemirror/lang-html@npm:^6.4.0": + version: 6.4.10 + resolution: "@codemirror/lang-html@npm:6.4.10" + dependencies: + "@codemirror/autocomplete": "npm:^6.0.0" + "@codemirror/lang-css": "npm:^6.0.0" + "@codemirror/lang-javascript": "npm:^6.0.0" + "@codemirror/language": "npm:^6.4.0" + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.17.0" + "@lezer/common": "npm:^1.0.0" + "@lezer/css": "npm:^1.1.0" + "@lezer/html": "npm:^1.3.0" + checksum: 10/258ba6f90dee9fb7cefe32926b59cc4a9223b8c7bac8fea14518daa5195cffb8383efac2102f7769c50c45d0d93c17c67cdcebaea43c81511b61447f743ffc2d + languageName: node + linkType: hard + +"@codemirror/lang-java@npm:^6.0.0": + version: 6.0.2 + resolution: "@codemirror/lang-java@npm:6.0.2" + dependencies: + "@codemirror/language": "npm:^6.0.0" + "@lezer/java": "npm:^1.0.0" + checksum: 10/ed884f5e1a90c0d487bc4e5073c6154f3abf51b0b652c3d015e8cb322e171a38307427a85ecc16d5be82bd3243577e77e202325d84394a9c5ac356ee358c56c9 + languageName: node + linkType: hard + +"@codemirror/lang-javascript@npm:^6.0.0, @codemirror/lang-javascript@npm:^6.1.2": + version: 6.2.4 + resolution: "@codemirror/lang-javascript@npm:6.2.4" + dependencies: + "@codemirror/autocomplete": "npm:^6.0.0" + "@codemirror/language": "npm:^6.6.0" + "@codemirror/lint": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.17.0" + "@lezer/common": "npm:^1.0.0" + "@lezer/javascript": "npm:^1.0.0" + checksum: 10/7d0b7fdacc90f89d1a5f2b9c575c61b6ee7813005cde32c1f35aedb0da71ad298998e116126ba19ca0bb02cdb14064945c31e24c57ef60bcbd5c19dae955ccb6 + languageName: node + linkType: hard + +"@codemirror/lang-json@npm:^6.0.0": + version: 6.0.2 + resolution: "@codemirror/lang-json@npm:6.0.2" + dependencies: + "@codemirror/language": "npm:^6.0.0" + "@lezer/json": "npm:^1.0.0" + checksum: 10/a8e57ad5c6cc53edd0d8bce4c26fa189dd5a95c371e72d32957d4a5c857f814761d9dfab81361f8e8ae9da7bcf657e7e1343f39694f9cffb1c144dd3ef7092a0 + languageName: node + linkType: hard + "@codemirror/lang-json@npm:^6.0.1": version: 6.0.1 resolution: "@codemirror/lang-json@npm:6.0.1" @@ -2305,6 +2426,198 @@ __metadata: languageName: node linkType: hard +"@codemirror/lang-less@npm:^6.0.0": + version: 6.0.2 + resolution: "@codemirror/lang-less@npm:6.0.2" + dependencies: + "@codemirror/lang-css": "npm:^6.2.0" + "@codemirror/language": "npm:^6.0.0" + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/233aa03e0bfb57e4f23fdb2a8d52ad3143a52553895b97cb2901f66d59fc40246b525a21b7be72d873efa98783f6da5f4e8e042da442b092fab9eb63c69524c8 + languageName: node + linkType: hard + +"@codemirror/lang-liquid@npm:^6.0.0": + version: 6.3.0 + resolution: "@codemirror/lang-liquid@npm:6.3.0" + dependencies: + "@codemirror/autocomplete": "npm:^6.0.0" + "@codemirror/lang-html": "npm:^6.0.0" + "@codemirror/language": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.0.0" + "@lezer/common": "npm:^1.0.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.3.1" + checksum: 10/da6bd8108598db397bb11fe13e81b0517cf63181d8e3f10d7e7c7775cbe0c32e3babd1d0c96e96640952c94e9dc4c0d0242dce1acc445b837044c7d5dcf17729 + languageName: node + linkType: hard + +"@codemirror/lang-markdown@npm:^6.0.0, @codemirror/lang-markdown@npm:^6.2.3": + version: 6.3.4 + resolution: "@codemirror/lang-markdown@npm:6.3.4" + dependencies: + "@codemirror/autocomplete": "npm:^6.7.1" + "@codemirror/lang-html": "npm:^6.0.0" + "@codemirror/language": "npm:^6.3.0" + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.0.0" + "@lezer/common": "npm:^1.2.1" + "@lezer/markdown": "npm:^1.0.0" + checksum: 10/8e23721a6c113cd56eca183a1089a01b19ad8cfe16b0604c0d9d825f285e2a3dc8de18a763c6a1aaf37947a890fc3ddd3cac3d25e912a506d310e4a01ceb8ab0 + languageName: node + linkType: hard + +"@codemirror/lang-php@npm:^6.0.0": + version: 6.0.2 + resolution: "@codemirror/lang-php@npm:6.0.2" + dependencies: + "@codemirror/lang-html": "npm:^6.0.0" + "@codemirror/language": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@lezer/common": "npm:^1.0.0" + "@lezer/php": "npm:^1.0.0" + checksum: 10/ae697fa8101f034244467ffc812a0de9c944bab1b141da2c55a4a80e5cedfd2fcbe9d1dcd36d4d3593ff9fb8e1963d7c3fb4fa307d652a73aa7607322aec1ce7 + languageName: node + linkType: hard + +"@codemirror/lang-python@npm:^6.0.0": + version: 6.2.1 + resolution: "@codemirror/lang-python@npm:6.2.1" + dependencies: + "@codemirror/autocomplete": "npm:^6.3.2" + "@codemirror/language": "npm:^6.8.0" + "@codemirror/state": "npm:^6.0.0" + "@lezer/common": "npm:^1.2.1" + "@lezer/python": "npm:^1.1.4" + checksum: 10/8651972fcfc194c0da028bea0162eb070f8f9b6241a9ec7771b3061bd7f3c4122ca0eed2e5fcf4c46e731cb31d4af1fb7f1d2949387ba9133826aa0253a9dddb + languageName: node + linkType: hard + +"@codemirror/lang-rust@npm:^6.0.0": + version: 6.0.2 + resolution: "@codemirror/lang-rust@npm:6.0.2" + dependencies: + "@codemirror/language": "npm:^6.0.0" + "@lezer/rust": "npm:^1.0.0" + checksum: 10/4cb7528c723ec3f421bd82a5324c56d836f3675e3b28e2b2d3c9d251e8f206bf9d932d52696c310dca51d71644063441fb8330d5ad1278c68002f8598b4bc067 + languageName: node + linkType: hard + +"@codemirror/lang-sass@npm:^6.0.0": + version: 6.0.2 + resolution: "@codemirror/lang-sass@npm:6.0.2" + dependencies: + "@codemirror/lang-css": "npm:^6.2.0" + "@codemirror/language": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@lezer/common": "npm:^1.0.2" + "@lezer/sass": "npm:^1.0.0" + checksum: 10/de5c72f62714960961b616c8fe25b4f127906b0c05ec2e8e633d0b896fb2da979732cad0f51b1c0bc058494db5447664234b7910a3345fb5080d8222d4011818 + languageName: node + linkType: hard + +"@codemirror/lang-sql@npm:^6.0.0": + version: 6.9.1 + resolution: "@codemirror/lang-sql@npm:6.9.1" + dependencies: + "@codemirror/autocomplete": "npm:^6.0.0" + "@codemirror/language": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/2fa0f61d8253f9dd28c255fa13ac27181fd42782160aeadfb72fdded426820c2ca49cf5057cfa92fc1016318bdf1008d0c33e23522f555ed802694ae73f3a137 + languageName: node + linkType: hard + +"@codemirror/lang-vue@npm:^0.1.1": + version: 0.1.3 + resolution: "@codemirror/lang-vue@npm:0.1.3" + dependencies: + "@codemirror/lang-html": "npm:^6.0.0" + "@codemirror/lang-javascript": "npm:^6.1.2" + "@codemirror/language": "npm:^6.0.0" + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.3.1" + checksum: 10/f08c04c47671de0b65568cbc0f9e517c7c443bd097eb0ca63ecdc1b81f842dbfd0b81b208ee5c31e3293ebc377b4b271c89cf18bf04bb898ecac538df22aff3a + languageName: node + linkType: hard + +"@codemirror/lang-wast@npm:^6.0.0": + version: 6.0.2 + resolution: "@codemirror/lang-wast@npm:6.0.2" + dependencies: + "@codemirror/language": "npm:^6.0.0" + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/c7f9820191ca8d8877b38a6205f7e46721c0deeb552c3f234a7166bfd4581e071718cbf395749f271bd5c0da879285a7829a5843c052dd52e8a4e41509777e35 + languageName: node + linkType: hard + +"@codemirror/lang-xml@npm:^6.0.0": + version: 6.1.0 + resolution: "@codemirror/lang-xml@npm:6.1.0" + dependencies: + "@codemirror/autocomplete": "npm:^6.0.0" + "@codemirror/language": "npm:^6.4.0" + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.0.0" + "@lezer/common": "npm:^1.0.0" + "@lezer/xml": "npm:^1.0.0" + checksum: 10/f5e54668c30efbb8a78a51e49ccec92a06931f2b98dce35c90be94ded30da02dac525124ce3c40f65c7b071f8db72d16b10a5a1795ccbf10e69939c0a9c1cac8 + languageName: node + linkType: hard + +"@codemirror/lang-yaml@npm:^6.0.0": + version: 6.1.2 + resolution: "@codemirror/lang-yaml@npm:6.1.2" + dependencies: + "@codemirror/autocomplete": "npm:^6.0.0" + "@codemirror/language": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.2.0" + "@lezer/lr": "npm:^1.0.0" + "@lezer/yaml": "npm:^1.0.0" + checksum: 10/1a1ad16554b27d9f66ad2a342170e7c7e51781876280727790e763e9a770163772d4880a9c344705ca65acc2b5fb228962dc3281ba05a71d2c071515541258ae + languageName: node + linkType: hard + +"@codemirror/language-data@npm:^6.5.1": + version: 6.5.1 + resolution: "@codemirror/language-data@npm:6.5.1" + dependencies: + "@codemirror/lang-angular": "npm:^0.1.0" + "@codemirror/lang-cpp": "npm:^6.0.0" + "@codemirror/lang-css": "npm:^6.0.0" + "@codemirror/lang-go": "npm:^6.0.0" + "@codemirror/lang-html": "npm:^6.0.0" + "@codemirror/lang-java": "npm:^6.0.0" + "@codemirror/lang-javascript": "npm:^6.0.0" + "@codemirror/lang-json": "npm:^6.0.0" + "@codemirror/lang-less": "npm:^6.0.0" + "@codemirror/lang-liquid": "npm:^6.0.0" + "@codemirror/lang-markdown": "npm:^6.0.0" + "@codemirror/lang-php": "npm:^6.0.0" + "@codemirror/lang-python": "npm:^6.0.0" + "@codemirror/lang-rust": "npm:^6.0.0" + "@codemirror/lang-sass": "npm:^6.0.0" + "@codemirror/lang-sql": "npm:^6.0.0" + "@codemirror/lang-vue": "npm:^0.1.1" + "@codemirror/lang-wast": "npm:^6.0.0" + "@codemirror/lang-xml": "npm:^6.0.0" + "@codemirror/lang-yaml": "npm:^6.0.0" + "@codemirror/language": "npm:^6.0.0" + "@codemirror/legacy-modes": "npm:^6.4.0" + checksum: 10/a46f4015da2c213ebe7cc685b5c657b92a340e3f12ed26a9f8c3a04cf3e46063c86141c6f9dca4faeaaf6de068b4e797d40c9a572ca317a122f84ad7ceb5e684 + languageName: node + linkType: hard + "@codemirror/language@npm:^6.0.0": version: 6.10.3 resolution: "@codemirror/language@npm:6.10.3" @@ -2333,7 +2646,30 @@ __metadata: languageName: node linkType: hard -"@codemirror/lint@npm:^6.8.2": +"@codemirror/language@npm:^6.3.0, @codemirror/language@npm:^6.3.2, @codemirror/language@npm:^6.4.0, @codemirror/language@npm:^6.6.0, @codemirror/language@npm:^6.8.0": + version: 6.11.3 + resolution: "@codemirror/language@npm:6.11.3" + dependencies: + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.23.0" + "@lezer/common": "npm:^1.1.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + style-mod: "npm:^4.0.0" + checksum: 10/8538a2835c1de6ca2d520ff66449185f2ea3a93e7d69382d9db3b4db6460f4c46b44f19724458c50230abfa87cf2c225834d39c3fe3119c48370db6b3de0b772 + languageName: node + linkType: hard + +"@codemirror/legacy-modes@npm:^6.4.0": + version: 6.5.1 + resolution: "@codemirror/legacy-modes@npm:6.5.1" + dependencies: + "@codemirror/language": "npm:^6.0.0" + checksum: 10/585de2a47a4ac10b3f96ef1616c849167cc6bae2a337a58a9a85c094cb95c4c27b8429c6bf2edf6a072946eb65b8169d090333003592c0b1ad0a51bc5a438c2a + languageName: node + linkType: hard + +"@codemirror/lint@npm:^6.0.0, @codemirror/lint@npm:^6.8.2": version: 6.8.5 resolution: "@codemirror/lint@npm:6.8.5" dependencies: @@ -2344,6 +2680,30 @@ __metadata: languageName: node linkType: hard +"@codemirror/merge@npm:^6.4.0": + version: 6.10.2 + resolution: "@codemirror/merge@npm:6.10.2" + dependencies: + "@codemirror/language": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.17.0" + "@lezer/highlight": "npm:^1.0.0" + style-mod: "npm:^4.1.0" + checksum: 10/b19b9fb4ae7dca94d87d7884c1ec7c33835b0a87081aa733deeb37c2930589222eb431f5a2e2c61f7d791ba2e73e002076480342790d0f64ab76033acb8ff98b + languageName: node + linkType: hard + +"@codemirror/search@npm:^6.0.0": + version: 6.5.11 + resolution: "@codemirror/search@npm:6.5.11" + dependencies: + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.0.0" + crelt: "npm:^1.0.5" + checksum: 10/d057f37cb369460b25625d7eb72f40636bf78ecd140608da53010cf3660f982a9e613826e38d85d87c9c2ff11e45c9482429987bfd4f29cbbd192f1ee3fd2695 + languageName: node + linkType: hard + "@codemirror/search@npm:^6.5.6": version: 6.5.7 resolution: "@codemirror/search@npm:6.5.7" @@ -2397,6 +2757,72 @@ __metadata: languageName: node linkType: hard +"@codemirror/view@npm:^6.7.1": + version: 6.38.2 + resolution: "@codemirror/view@npm:6.38.2" + dependencies: + "@codemirror/state": "npm:^6.5.0" + crelt: "npm:^1.0.6" + style-mod: "npm:^4.1.0" + w3c-keyname: "npm:^2.2.4" + checksum: 10/300608850a29215d7b47fe8ade183fc2241457a924335bd127e29e1af11da9314369c65ec0da968177086f3529abbcd71a609c1af673ea8951c32a523cab358c + languageName: node + linkType: hard + +"@codesandbox/nodebox@npm:0.1.8": + version: 0.1.8 + resolution: "@codesandbox/nodebox@npm:0.1.8" + dependencies: + outvariant: "npm:^1.4.0" + strict-event-emitter: "npm:^0.4.3" + checksum: 10/3de00d306ae0236524c436b8640c442a4541f0eb696820aa5f6fc66018dc66431d8d78edd9305986aa2877befca292a3906bb4c6af2ecba5f15dbd587d1c916d + languageName: node + linkType: hard + +"@codesandbox/sandpack-client@npm:^2.19.8": + version: 2.19.8 + resolution: "@codesandbox/sandpack-client@npm:2.19.8" + dependencies: + "@codesandbox/nodebox": "npm:0.1.8" + buffer: "npm:^6.0.3" + dequal: "npm:^2.0.2" + mime-db: "npm:^1.52.0" + outvariant: "npm:1.4.0" + static-browser-server: "npm:1.0.3" + checksum: 10/7913fa4a7bbaf925f4ab0ad1969a4da1f52c093b1b71229dd8ecf3f50462bd004fcf3fddccdb15225b55737305d3f6727a187353f12cb39a75336fa7229eb4dd + languageName: node + linkType: hard + +"@codesandbox/sandpack-react@npm:^2.20.0": + version: 2.20.0 + resolution: "@codesandbox/sandpack-react@npm:2.20.0" + dependencies: + "@codemirror/autocomplete": "npm:^6.4.0" + "@codemirror/commands": "npm:^6.1.3" + "@codemirror/lang-css": "npm:^6.0.1" + "@codemirror/lang-html": "npm:^6.4.0" + "@codemirror/lang-javascript": "npm:^6.1.2" + "@codemirror/language": "npm:^6.3.2" + "@codemirror/state": "npm:^6.2.0" + "@codemirror/view": "npm:^6.7.1" + "@codesandbox/sandpack-client": "npm:^2.19.8" + "@lezer/highlight": "npm:^1.1.3" + "@react-hook/intersection-observer": "npm:^3.1.1" + "@stitches/core": "npm:^1.2.6" + anser: "npm:^2.1.1" + clean-set: "npm:^1.1.2" + dequal: "npm:^2.0.2" + escape-carriage: "npm:^1.3.1" + lz-string: "npm:^1.4.4" + react-devtools-inline: "npm:4.4.0" + react-is: "npm:^17.0.2" + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + react-dom: ^16.8.0 || ^17 || ^18 || ^19 + checksum: 10/313c937dacaafcc18622f54a274835aa3a444ff697e9e511c52d548d7ba4e233d19ef8bb1da081668251020bd9afd480641194032504b4b3d20ac3cb0cbcd03b + languageName: node + linkType: hard + "@coinbase/wallet-sdk@npm:4.3.0": version: 4.3.0 resolution: "@coinbase/wallet-sdk@npm:4.3.0" @@ -4583,6 +5009,58 @@ __metadata: languageName: node linkType: hard +"@floating-ui/core@npm:^1.7.3": + version: 1.7.3 + resolution: "@floating-ui/core@npm:1.7.3" + dependencies: + "@floating-ui/utils": "npm:^0.2.10" + checksum: 10/a8952ff2673ddf28f12feeb86d90c54949e45bcb1af5758b7672850ac0dadb36d4bd61aa45dad1b6a35ba40d4756d3573afac6610b90502639d7266b91e0864e + languageName: node + linkType: hard + +"@floating-ui/dom@npm:^1.7.4": + version: 1.7.4 + resolution: "@floating-ui/dom@npm:1.7.4" + dependencies: + "@floating-ui/core": "npm:^1.7.3" + "@floating-ui/utils": "npm:^0.2.10" + checksum: 10/d3d6a23e7b9804ba56338c7c666590258683af14b6026270d32afc1202f72b5b82cca359004bdc7830bf2463a045da6c7bd4e7d5351218cf270ff94206197971 + languageName: node + linkType: hard + +"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.1.6": + version: 2.1.6 + resolution: "@floating-ui/react-dom@npm:2.1.6" + dependencies: + "@floating-ui/dom": "npm:^1.7.4" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10/fbfd3319b42edb9c156e4e872f500d2edb112bc9cfd1b45892bff16ccf21c2484ddc9c416f7631c2aaaadec1b2f98b205db8a3f89eb78ca870905fcfe3917c35 + languageName: node + linkType: hard + +"@floating-ui/react@npm:^0.27.8": + version: 0.27.16 + resolution: "@floating-ui/react@npm:0.27.16" + dependencies: + "@floating-ui/react-dom": "npm:^2.1.6" + "@floating-ui/utils": "npm:^0.2.10" + tabbable: "npm:^6.0.0" + peerDependencies: + react: ">=17.0.0" + react-dom: ">=17.0.0" + checksum: 10/b9baedee124035323a8f74794ec782678faf52af1c88731ce7d2641b7e7c97748fda1e711a3c4db007a0153d93158d867f4726ee632d713d3de76ec4bdfd84e1 + languageName: node + linkType: hard + +"@floating-ui/utils@npm:^0.2.10": + version: 0.2.10 + resolution: "@floating-ui/utils@npm:0.2.10" + checksum: 10/b635ea865a8be2484b608b7157f5abf9ed439f351011a74b7e988439e2898199a9a8b790f52291e05bdcf119088160dc782d98cff45cc98c5a271bc6f51327ae + languageName: node + linkType: hard + "@fortawesome/fontawesome-common-types@npm:6.7.2": version: 6.7.2 resolution: "@fortawesome/fontawesome-common-types@npm:6.7.2" @@ -6313,6 +6791,7 @@ __metadata: "@kleros/ui-components-library": "npm:^2.20.0" "@lifi/wallet-management": "npm:^3.7.1" "@lifi/widget": "npm:^3.18.1" + "@mdxeditor/editor": "npm:^3.44.2" "@reown/appkit": "npm:^1.7.1" "@reown/appkit-adapter-wagmi": "npm:^1.7.1" "@sentry/react": "npm:^7.120.0" @@ -6416,23 +6895,315 @@ __metadata: languageName: node linkType: hard -"@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.2.0": - version: 1.2.1 - resolution: "@lezer/common@npm:1.2.1" - checksum: 10/b362ed2e97664e4b36b3dbff49b52d1bfc5accc0152b577fefd46e585d012ff685d1fd336d75d80066e01c0505b1135d4cf69be5e330b5bfec2e2650c437bcae +"@lexical/clipboard@npm:0.35.0, @lexical/clipboard@npm:^0.35.0": + version: 0.35.0 + resolution: "@lexical/clipboard@npm:0.35.0" + dependencies: + "@lexical/html": "npm:0.35.0" + "@lexical/list": "npm:0.35.0" + "@lexical/selection": "npm:0.35.0" + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/acde7547e5ad3ffa60f339a697952e3dc785c90f638bcd0e996221174a09209d584ac22ae6fe3f92814cd1cf4991546d82ce6d401ccc2084b4f0aac8b480bb88 languageName: node linkType: hard -"@lezer/highlight@npm:^1.0.0": - version: 1.2.0 - resolution: "@lezer/highlight@npm:1.2.0" +"@lexical/code@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/code@npm:0.35.0" + dependencies: + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + prismjs: "npm:^1.30.0" + checksum: 10/4eea3cd640b33af2971d1e6ea893046b93c686873fa450c442837a03277b31c217a37e17d115be5e6ea8a1a9fe3a00df495403918b9fff68aef873f66413def1 + languageName: node + linkType: hard + +"@lexical/devtools-core@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/devtools-core@npm:0.35.0" + dependencies: + "@lexical/html": "npm:0.35.0" + "@lexical/link": "npm:0.35.0" + "@lexical/mark": "npm:0.35.0" + "@lexical/table": "npm:0.35.0" + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + peerDependencies: + react: ">=17.x" + react-dom: ">=17.x" + checksum: 10/d14ef05df4c7b0ec67b8da820904db695747548e45064e2bd8af25c42b44b4d5835964402b1830396587acdd79a43e98224c650193bc04798225815ca273c580 + languageName: node + linkType: hard + +"@lexical/dragon@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/dragon@npm:0.35.0" + dependencies: + lexical: "npm:0.35.0" + checksum: 10/6c89b2c79e1aa59188d01561a59107f3816f31587e21be38f98a8508f2f4caeabf4fd54acc6aca42b27ee4ad49ce44d952f517a0bac25d9e7c1411db375b6698 + languageName: node + linkType: hard + +"@lexical/hashtag@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/hashtag@npm:0.35.0" + dependencies: + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/ed12a1b61ad05bc7288beb5a3e89fb88e55f7710c2ba22c27aea7e26078756e8c2d69f32856bb5dca64f383dd47b028206b0d36d8ffc7ec979b8ed23df8b32fb + languageName: node + linkType: hard + +"@lexical/history@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/history@npm:0.35.0" + dependencies: + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/7cecef8407a7cdd478c82d9314aecbaa7fef8bc9c6993bfbad7edc80658a35c1b7061132c9d876edafdd066dd40b6a2ca1bdba5eda05bed2f22729356e7bdc15 + languageName: node + linkType: hard + +"@lexical/html@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/html@npm:0.35.0" + dependencies: + "@lexical/selection": "npm:0.35.0" + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/458beee56f4ea157d8bb56b1f8c74fe58da87b6b5a64e666f7356247f7cf62e9fab643f4c3d84f1043539c1c3165be604bbf30bc8d002443d067801a32ef8cac + languageName: node + linkType: hard + +"@lexical/link@npm:0.35.0, @lexical/link@npm:^0.35.0": + version: 0.35.0 + resolution: "@lexical/link@npm:0.35.0" + dependencies: + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/670ae6d2b24b56bcefacb2fd6159c17bf07a6bd2fe84e3f5a6a002cab4359c90f2e1478284bca108650be9f9c52d070d0a3a09601fc6682cb834e7119633a026 + languageName: node + linkType: hard + +"@lexical/list@npm:0.35.0, @lexical/list@npm:^0.35.0": + version: 0.35.0 + resolution: "@lexical/list@npm:0.35.0" + dependencies: + "@lexical/selection": "npm:0.35.0" + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/8ad774ffc041cb6d2277cc160e1f04ef0cbcfee1b74dc9888c316ebf00675c68c583961993a2a3ea506674f947896adc6c2d07fa7512eedfb1caa6009b8f3af4 + languageName: node + linkType: hard + +"@lexical/mark@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/mark@npm:0.35.0" + dependencies: + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/e20244127316f03d0383dd3f3762d5d3daf904aeab28a49b54c826210ef03077ee9004304bba643735b0bc451c93f95b085b8ab2a62d8382e40636868f6acc91 + languageName: node + linkType: hard + +"@lexical/markdown@npm:0.35.0, @lexical/markdown@npm:^0.35.0": + version: 0.35.0 + resolution: "@lexical/markdown@npm:0.35.0" + dependencies: + "@lexical/code": "npm:0.35.0" + "@lexical/link": "npm:0.35.0" + "@lexical/list": "npm:0.35.0" + "@lexical/rich-text": "npm:0.35.0" + "@lexical/text": "npm:0.35.0" + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/79a72aa37cc66ab8878a594cc74251b0755ead239364194177c9f34ac4eaa1c3864bbd11d19733771bdb92bbf6a5a764bda43e4f182838d54666724b0a1db7d0 + languageName: node + linkType: hard + +"@lexical/offset@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/offset@npm:0.35.0" + dependencies: + lexical: "npm:0.35.0" + checksum: 10/588bf20540e69138cd30a441a374d6248b97a618026c3afe1d3e75a45cb47623d8010faa86491ed3bbdd57f0ae95f39372fbfb406fb7b97d663ee029b8028590 + languageName: node + linkType: hard + +"@lexical/overflow@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/overflow@npm:0.35.0" + dependencies: + lexical: "npm:0.35.0" + checksum: 10/05b0700d96d3a43614278fa11a3834881a1c37d4904c5731b59cc3483bffe558b6e307e2363067c59457e16776756ebb792912f3eb1c9896b5755b30eb2843a4 + languageName: node + linkType: hard + +"@lexical/plain-text@npm:0.35.0, @lexical/plain-text@npm:^0.35.0": + version: 0.35.0 + resolution: "@lexical/plain-text@npm:0.35.0" + dependencies: + "@lexical/clipboard": "npm:0.35.0" + "@lexical/selection": "npm:0.35.0" + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/2dfa06123fc93a41fa8c53f87e162f04e92fa38db5107c4680ff80049a1b7fc3516252fd993163235cc58a5f007d374642aaa5cb039269e31c0eb73b5c708670 + languageName: node + linkType: hard + +"@lexical/react@npm:^0.35.0": + version: 0.35.0 + resolution: "@lexical/react@npm:0.35.0" + dependencies: + "@floating-ui/react": "npm:^0.27.8" + "@lexical/devtools-core": "npm:0.35.0" + "@lexical/dragon": "npm:0.35.0" + "@lexical/hashtag": "npm:0.35.0" + "@lexical/history": "npm:0.35.0" + "@lexical/link": "npm:0.35.0" + "@lexical/list": "npm:0.35.0" + "@lexical/mark": "npm:0.35.0" + "@lexical/markdown": "npm:0.35.0" + "@lexical/overflow": "npm:0.35.0" + "@lexical/plain-text": "npm:0.35.0" + "@lexical/rich-text": "npm:0.35.0" + "@lexical/table": "npm:0.35.0" + "@lexical/text": "npm:0.35.0" + "@lexical/utils": "npm:0.35.0" + "@lexical/yjs": "npm:0.35.0" + lexical: "npm:0.35.0" + react-error-boundary: "npm:^3.1.4" + peerDependencies: + react: ">=17.x" + react-dom: ">=17.x" + checksum: 10/a1a9a174c12b2df338355fab6a7d8995f3ef082c11fd7f6eaea728885c2d1e53881cf3df3977cb2a798c296b9ae91a9ef71db893bf12ed723897949f3707b860 + languageName: node + linkType: hard + +"@lexical/rich-text@npm:0.35.0, @lexical/rich-text@npm:^0.35.0": + version: 0.35.0 + resolution: "@lexical/rich-text@npm:0.35.0" + dependencies: + "@lexical/clipboard": "npm:0.35.0" + "@lexical/selection": "npm:0.35.0" + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/d06e08bb441c991a4729720d6e974e7e427271cacd79268e7a92bb820c6ff5f682a76eaaab837f1057a028c3d592a28dc31d27e3436f99a28ad8cc0a974432eb + languageName: node + linkType: hard + +"@lexical/selection@npm:0.35.0, @lexical/selection@npm:^0.35.0": + version: 0.35.0 + resolution: "@lexical/selection@npm:0.35.0" + dependencies: + lexical: "npm:0.35.0" + checksum: 10/36285d042e5f883197a2e05e39159b7515926622eaf489ba28249565eaaccd2415e94e1b888a376cbda0556f8073438736c222433d4d499f534af449ce24d89a + languageName: node + linkType: hard + +"@lexical/table@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/table@npm:0.35.0" + dependencies: + "@lexical/clipboard": "npm:0.35.0" + "@lexical/utils": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/ace388cfe706860e789421d192eb30183c63afb01d90c1b2f328b3f3ed7ce032ae45698bf94f2e5e4e340a73c53fed7a27cbf3b72a3d91ef5382e879a1df26bf + languageName: node + linkType: hard + +"@lexical/text@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/text@npm:0.35.0" + dependencies: + lexical: "npm:0.35.0" + checksum: 10/6de985ca932d141d79cf47f0678ab40363d2a3be326e61d2dc25b9abff1b012aab299b819c489ede92f1bb72bc4bce37a1c563e9a44ffef5ebb05d0285a0e0e0 + languageName: node + linkType: hard + +"@lexical/utils@npm:0.35.0, @lexical/utils@npm:^0.35.0": + version: 0.35.0 + resolution: "@lexical/utils@npm:0.35.0" + dependencies: + "@lexical/list": "npm:0.35.0" + "@lexical/selection": "npm:0.35.0" + "@lexical/table": "npm:0.35.0" + lexical: "npm:0.35.0" + checksum: 10/be81f3e809285ebf3838200d6c00a787ba216097672555a8cab00edf8c401be9f6004032562b6432bd52a6ab5dc552486488d21636661795bcf8694ac46f51c6 + languageName: node + linkType: hard + +"@lexical/yjs@npm:0.35.0": + version: 0.35.0 + resolution: "@lexical/yjs@npm:0.35.0" + dependencies: + "@lexical/offset": "npm:0.35.0" + "@lexical/selection": "npm:0.35.0" + lexical: "npm:0.35.0" + peerDependencies: + yjs: ">=13.5.22" + checksum: 10/7a926fffa929e757dbf7da9d058e7ef315ff3691f3656f00d18ac1aeba5bceb357ac3dd4d2baeb74c16033802b7087f524bd3e7666f25840c88a98245590c13e + languageName: node + linkType: hard + +"@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.2.0": + version: 1.2.1 + resolution: "@lezer/common@npm:1.2.1" + checksum: 10/b362ed2e97664e4b36b3dbff49b52d1bfc5accc0152b577fefd46e585d012ff685d1fd336d75d80066e01c0505b1135d4cf69be5e330b5bfec2e2650c437bcae + languageName: node + linkType: hard + +"@lezer/common@npm:^1.0.2, @lezer/common@npm:^1.2.1": + version: 1.2.3 + resolution: "@lezer/common@npm:1.2.3" + checksum: 10/dad24e353e4e67d88b203191361ca1dff26c01c2b7b4ae829b668a1d115929334d077217367683e39180c0556510ed2066ea8ddba2b079be7c08a7152208cc87 + languageName: node + linkType: hard + +"@lezer/cpp@npm:^1.0.0": + version: 1.1.3 + resolution: "@lezer/cpp@npm:1.1.3" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/4ffe11d08a142fd1cf710e7a01222ab63ecd3da9a3de954f462bac55db22cce1ce7667055295149bd386afd698228f355b07b0335745579fe659c7af4978d645 + languageName: node + linkType: hard + +"@lezer/css@npm:^1.1.0, @lezer/css@npm:^1.1.7": + version: 1.3.0 + resolution: "@lezer/css@npm:1.3.0" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.3.0" + checksum: 10/142609b690b9fef139ea947faf43253df596834805c0805c69bc8866c4366790eb1b392d65a25dae5f840ff3de676768cc3b808013435c82db20d6a0f3917e97 + languageName: node + linkType: hard + +"@lezer/go@npm:^1.0.0": + version: 1.0.1 + resolution: "@lezer/go@npm:1.0.1" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.3.0" + checksum: 10/1b96969679a16973fc112027fb28301328454e739621e0695f0011b1e5f159bc792e829dd8d586b8fd1c34218be4d9dee2ae73fa8802dcba98da9219a38a92d9 + languageName: node + linkType: hard + +"@lezer/highlight@npm:^1.0.0": + version: 1.2.0 + resolution: "@lezer/highlight@npm:1.2.0" dependencies: "@lezer/common": "npm:^1.0.0" checksum: 10/14a80cbfb0cd1ce716decb4f3a045d42e7146f539cfd483b62ce46c4586a26d2f4fbdc35ace1cad81645304be4d30eafb95a2b057c34dfd471d56c7fbd82df3a languageName: node linkType: hard -"@lezer/highlight@npm:^1.2.1": +"@lezer/highlight@npm:^1.1.3, @lezer/highlight@npm:^1.2.0, @lezer/highlight@npm:^1.2.1": version: 1.2.1 resolution: "@lezer/highlight@npm:1.2.1" dependencies: @@ -6441,6 +7212,39 @@ __metadata: languageName: node linkType: hard +"@lezer/html@npm:^1.3.0": + version: 1.3.10 + resolution: "@lezer/html@npm:1.3.10" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/b69f796492c0a2c000ebba88e1b1f0dc0885ed3392c11b46a9d7c638da1a325d6a288375fbeec52d0d05437b801302299e0e57359f95a494db1e251b3d66d29c + languageName: node + linkType: hard + +"@lezer/java@npm:^1.0.0": + version: 1.1.3 + resolution: "@lezer/java@npm:1.1.3" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/52865205f67c9d00630c72028d2d6bbb734da04f80e6febe6edb9bbd3ba55a3c0d6cfbdfa7db0ccf7e090b59040047aa9b752ff2d4ab714f3a0139c4d45e0f80 + languageName: node + linkType: hard + +"@lezer/javascript@npm:^1.0.0": + version: 1.5.3 + resolution: "@lezer/javascript@npm:1.5.3" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.1.3" + "@lezer/lr": "npm:^1.3.0" + checksum: 10/1cc3a719b7edda14bd816b9e4efab51fcf7392b7800ccdc0f135fb9652349b93c8f3bec50b82a200ac037ee8b9387efbe2d00c9870f7e0cb62ae8036635d6115 + languageName: node + linkType: hard + "@lezer/json@npm:^1.0.0": version: 1.0.2 resolution: "@lezer/json@npm:1.0.2" @@ -6461,6 +7265,91 @@ __metadata: languageName: node linkType: hard +"@lezer/lr@npm:^1.1.0, @lezer/lr@npm:^1.3.0, @lezer/lr@npm:^1.3.1, @lezer/lr@npm:^1.3.3, @lezer/lr@npm:^1.4.0": + version: 1.4.2 + resolution: "@lezer/lr@npm:1.4.2" + dependencies: + "@lezer/common": "npm:^1.0.0" + checksum: 10/f7b505906c8d8df14c07866553cf3dae1e065b1da8b28fbb4193fd67ab8d187eb45f92759e29a2cfe4283296f0aa864b38a0a91708ecfc3e24b8f662d626e0c6 + languageName: node + linkType: hard + +"@lezer/markdown@npm:^1.0.0": + version: 1.4.3 + resolution: "@lezer/markdown@npm:1.4.3" + dependencies: + "@lezer/common": "npm:^1.0.0" + "@lezer/highlight": "npm:^1.0.0" + checksum: 10/5a638b0caa0a38007de1900196059f1f165a6684e050e7187e05c45c94cbbf90ad44eb82e5f45df3a7b69022dc4b5d9162e61232ba6f0759f5620328a6e0216e + languageName: node + linkType: hard + +"@lezer/php@npm:^1.0.0": + version: 1.0.4 + resolution: "@lezer/php@npm:1.0.4" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.1.0" + checksum: 10/d76ea8459958aac41abf53d9dd3e1899d663690134042f4b0095abbb2e404c3841dabbab27edfe29c32c3856c33ab62a238576c7e48701ccbf69bf9bf5e12a04 + languageName: node + linkType: hard + +"@lezer/python@npm:^1.1.4": + version: 1.1.18 + resolution: "@lezer/python@npm:1.1.18" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/9570c661fe2cee649a6aca2ae528e75ee9fccd828eab0987b64702d7057b2e8ec2be71abd274059decb51c6a4b3748c6242c2cabc83d71f94f751362550d90c6 + languageName: node + linkType: hard + +"@lezer/rust@npm:^1.0.0": + version: 1.0.2 + resolution: "@lezer/rust@npm:1.0.2" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/ea6152f65e42afed45e780c4adc87e19e33586de6790ac8dd2012309f22721f87454e6bfee1690e222ce30436ae380270e93cdfc9eb8cdda52930d86e1eb0c07 + languageName: node + linkType: hard + +"@lezer/sass@npm:^1.0.0": + version: 1.1.0 + resolution: "@lezer/sass@npm:1.1.0" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/2f42dfaf5a328d4626a0a8ff8cd5973b7f52e8112541281cf1cbb1970acdc52c7c9f55c71f635bcff75a6151a55f7653d277306a15494b23b652e87d16df9ce3 + languageName: node + linkType: hard + +"@lezer/xml@npm:^1.0.0": + version: 1.0.6 + resolution: "@lezer/xml@npm:1.0.6" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + checksum: 10/ffdc3fd587c992f86de84bd828e1d92216484a571423b6edb7b0b1f2eb495ff14e9a234ce5fcba4bce1cb00683af50c0e7f5dfb017a0d3da77607b42e77548a2 + languageName: node + linkType: hard + +"@lezer/yaml@npm:^1.0.0": + version: 1.0.3 + resolution: "@lezer/yaml@npm:1.0.3" + dependencies: + "@lezer/common": "npm:^1.2.0" + "@lezer/highlight": "npm:^1.0.0" + "@lezer/lr": "npm:^1.4.0" + checksum: 10/6697b964403dc5dec9186732c5997675e5140ef5dddc8371dd28fa194d8431d8a7d5f18670be47b81a0b4ad6cbfe82e4f7c9c6f06e6f763bd100f7a38908baf5 + languageName: node + linkType: hard + "@libp2p/crypto@npm:^5.0.0, @libp2p/crypto@npm:^5.0.9": version: 5.0.9 resolution: "@libp2p/crypto@npm:5.0.9" @@ -6746,6 +7635,83 @@ __metadata: languageName: node linkType: hard +"@mdxeditor/editor@npm:^3.44.2": + version: 3.45.0 + resolution: "@mdxeditor/editor@npm:3.45.0" + dependencies: + "@codemirror/commands": "npm:^6.2.4" + "@codemirror/lang-markdown": "npm:^6.2.3" + "@codemirror/language-data": "npm:^6.5.1" + "@codemirror/merge": "npm:^6.4.0" + "@codemirror/state": "npm:^6.4.0" + "@codemirror/view": "npm:^6.23.0" + "@codesandbox/sandpack-react": "npm:^2.20.0" + "@lexical/clipboard": "npm:^0.35.0" + "@lexical/link": "npm:^0.35.0" + "@lexical/list": "npm:^0.35.0" + "@lexical/markdown": "npm:^0.35.0" + "@lexical/plain-text": "npm:^0.35.0" + "@lexical/react": "npm:^0.35.0" + "@lexical/rich-text": "npm:^0.35.0" + "@lexical/selection": "npm:^0.35.0" + "@lexical/utils": "npm:^0.35.0" + "@mdxeditor/gurx": "npm:^1.2.4" + "@radix-ui/colors": "npm:^3.0.0" + "@radix-ui/react-dialog": "npm:^1.1.11" + "@radix-ui/react-icons": "npm:^1.3.2" + "@radix-ui/react-popover": "npm:^1.1.11" + "@radix-ui/react-popper": "npm:^1.2.4" + "@radix-ui/react-select": "npm:^2.2.2" + "@radix-ui/react-toggle-group": "npm:^1.1.7" + "@radix-ui/react-toolbar": "npm:^1.1.7" + "@radix-ui/react-tooltip": "npm:^1.2.4" + classnames: "npm:^2.3.2" + cm6-theme-basic-light: "npm:^0.2.0" + codemirror: "npm:^6.0.1" + downshift: "npm:^7.6.0" + js-yaml: "npm:4.1.0" + lexical: "npm:^0.35.0" + mdast-util-directive: "npm:^3.0.0" + mdast-util-from-markdown: "npm:^2.0.0" + mdast-util-frontmatter: "npm:^2.0.1" + mdast-util-gfm-strikethrough: "npm:^2.0.0" + mdast-util-gfm-table: "npm:^2.0.0" + mdast-util-gfm-task-list-item: "npm:^2.0.0" + mdast-util-highlight-mark: "npm:^1.2.2" + mdast-util-mdx: "npm:^3.0.0" + mdast-util-mdx-jsx: "npm:^3.0.0" + mdast-util-to-markdown: "npm:^2.1.0" + micromark-extension-directive: "npm:^3.0.0" + micromark-extension-frontmatter: "npm:^2.0.0" + micromark-extension-gfm-strikethrough: "npm:^2.0.0" + micromark-extension-gfm-table: "npm:^2.0.0" + micromark-extension-gfm-task-list-item: "npm:^2.0.1" + micromark-extension-highlight-mark: "npm:^1.2.0" + micromark-extension-mdx-jsx: "npm:^3.0.0" + micromark-extension-mdx-md: "npm:^2.0.0" + micromark-extension-mdxjs: "npm:^3.0.0" + micromark-factory-space: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.1" + micromark-util-symbol: "npm:^2.0.0" + react-hook-form: "npm:^7.56.1" + unidiff: "npm:^1.0.2" + peerDependencies: + react: ">= 18 || >= 19" + react-dom: ">= 18 || >= 19" + checksum: 10/5d6a661721a1e5570480e8dc981758d5816e516deaa31aebf70d0a198a8bc0c4cdfa1fa843ce98786910f8c93ef818f963cd1857fe1e26332aeca1c2241fe7d1 + languageName: node + linkType: hard + +"@mdxeditor/gurx@npm:^1.2.4": + version: 1.2.4 + resolution: "@mdxeditor/gurx@npm:1.2.4" + peerDependencies: + react: ">= 18 || >= 19" + react-dom: ">= 18 || >= 19" + checksum: 10/b3c46bb20781cf20592f3ca830227d40290e5ecf2f972ceeae8fd136b868e7bff301ac52eb2757b009eefd7f9f11e4571a0d424c8a7ad414a95e914032ab8cfa + languageName: node + linkType: hard + "@metamask/eth-json-rpc-provider@npm:^1.0.0": version: 1.0.1 resolution: "@metamask/eth-json-rpc-provider@npm:1.0.1" @@ -7938,6 +8904,13 @@ __metadata: languageName: node linkType: hard +"@open-draft/deferred-promise@npm:^2.1.0": + version: 2.2.0 + resolution: "@open-draft/deferred-promise@npm:2.2.0" + checksum: 10/bc3bb1668a555bb87b33383cafcf207d9561e17d2ca0d9e61b7ce88e82b66e36a333d3676c1d39eb5848022c03c8145331fcdc828ba297f88cb1de9c5cef6c19 + languageName: node + linkType: hard + "@openzeppelin/contracts-upgradeable@npm:4.9.6": version: 4.9.6 resolution: "@openzeppelin/contracts-upgradeable@npm:4.9.6" @@ -8199,46 +9172,743 @@ __metadata: languageName: node linkType: hard -"@pnpm/network.ca-file@npm:^1.0.1": - version: 1.0.2 - resolution: "@pnpm/network.ca-file@npm:1.0.2" +"@pnpm/network.ca-file@npm:^1.0.1": + version: 1.0.2 + resolution: "@pnpm/network.ca-file@npm:1.0.2" + dependencies: + graceful-fs: "npm:4.2.10" + checksum: 10/d8d0884646500576bd5390464d13db1bb9a62e32a1069293e5bddb2ad8354b354b7e2d2a35e12850025651e795e6a80ce9e601c66312504667b7e3ee7b52becc + languageName: node + linkType: hard + +"@pnpm/npm-conf@npm:^2.1.0": + version: 2.3.1 + resolution: "@pnpm/npm-conf@npm:2.3.1" + dependencies: + "@pnpm/config.env-replace": "npm:^1.1.0" + "@pnpm/network.ca-file": "npm:^1.0.1" + config-chain: "npm:^1.1.11" + checksum: 10/44fbb0b166eee3e3631ef0e92b1bed6489aa6975e3e722c16577cc0181b81374f5ae90c6e4da183c8160f996e6b4863325525b00542f42d1b757b51ef62bc4e7 + languageName: node + linkType: hard + +"@polka/url@npm:^1.0.0-next.24": + version: 1.0.0-next.24 + resolution: "@polka/url@npm:1.0.0-next.24" + checksum: 10/00baec4458ac86ca27edf7ce807ccfad97cd1d4b67bdedaf3401a9e755757588f3331e891290d1deea52d88df2bf2387caf8d94a6835b614d5b37b638a688273 + languageName: node + linkType: hard + +"@popperjs/core@npm:^2.11.8": + version: 2.11.8 + resolution: "@popperjs/core@npm:2.11.8" + checksum: 10/ddd16090cde777aaf102940f05d0274602079a95ad9805bd20bc55dcc7c3a2ba1b99dd5c73e5cc2753c3d31250ca52a67d58059459d7d27debb983a9f552936c + languageName: node + linkType: hard + +"@prettier/sync@npm:^0.3.0": + version: 0.3.0 + resolution: "@prettier/sync@npm:0.3.0" + peerDependencies: + prettier: ^3.0.0 + checksum: 10/10520d2479830c18256bf2b18349a15a8964f968059f7ccaa1f6d455c133a26e6c96bd7aea7c64ef6701700e8007ad68619b16ec83391b356b5d4a741cbae504 + languageName: node + linkType: hard + +"@radix-ui/colors@npm:^3.0.0": + version: 3.0.0 + resolution: "@radix-ui/colors@npm:3.0.0" + checksum: 10/bc9ffb01b3964f16482dc278cf6d86d85b73eae7cb94a77018fbd53b103b3d5ec1ecf77882cfbf8892f28c2c6057db8e19bf4d66234ed330a430373b092c5cfe + languageName: node + linkType: hard + +"@radix-ui/number@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/number@npm:1.1.1" + checksum: 10/58717faf3f7aa180fdfcde7083cae0bc06677cbd08fd2bed5a3f8820deeb6f514f7d475f1fbb61e1f9a16cb2e7daf1000b2c614b0de3520fccfc04e3576e4566 + languageName: node + linkType: hard + +"@radix-ui/primitive@npm:1.1.3": + version: 1.1.3 + resolution: "@radix-ui/primitive@npm:1.1.3" + checksum: 10/ee27abbff0d6d305816e9314655eb35e72478ba47416bc9d5cb0581728be35e3408cfc0748313837561d635f0cb7dfaae26e61831f0e16c0fd7d669a612f2cb0 + languageName: node + linkType: hard + +"@radix-ui/react-arrow@npm:1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-arrow@npm:1.1.7" + dependencies: + "@radix-ui/react-primitive": "npm:2.1.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/6cdf74f06090f8994cdf6d3935a44ea3ac309163a4f59c476482c4907e8e0775f224045030abf10fa4f9e1cb7743db034429249b9e59354988e247eeb0f4fdcf + languageName: node + linkType: hard + +"@radix-ui/react-collection@npm:1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-collection@npm:1.1.7" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-slot": "npm:1.2.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/cd53e2a2be82be7bc4014164cac0b42948401a203e5d0294d3947a5193f1d56bd23eb60e878a98dba50d08283254e79c3b873de5f935276b849686a868d51dd5 + languageName: node + linkType: hard + +"@radix-ui/react-compose-refs@npm:1.1.2": + version: 1.1.2 + resolution: "@radix-ui/react-compose-refs@npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/9a91f0213014ffa40c5b8aae4debb993be5654217e504e35aa7422887eb2d114486d37e53c482d0fffb00cd44f51b5269fcdf397b280c71666fa11b7f32f165d + languageName: node + linkType: hard + +"@radix-ui/react-context@npm:1.1.2": + version: 1.1.2 + resolution: "@radix-ui/react-context@npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/156088367de42afa3c7e3acf5f0ba7cad6b359f3d17485585e80c2418434a6ed7cac2602eb73bca265d0091a1ad380f9405c069f103983e53497097ff35ba8f2 + languageName: node + linkType: hard + +"@radix-ui/react-dialog@npm:^1.1.11": + version: 1.1.15 + resolution: "@radix-ui/react-dialog@npm:1.1.15" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-dismissable-layer": "npm:1.1.11" + "@radix-ui/react-focus-guards": "npm:1.1.3" + "@radix-ui/react-focus-scope": "npm:1.1.7" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-portal": "npm:1.1.9" + "@radix-ui/react-presence": "npm:1.1.5" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-slot": "npm:1.2.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + aria-hidden: "npm:^1.2.4" + react-remove-scroll: "npm:^2.6.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/90ad9ea36d927a05bcc2701b471c2965f6d5d4f446511cd471e62235fc674186997dea081f52e18cb17a1e593828d94da3848e68864fa3acebe29df9b068b240 + languageName: node + linkType: hard + +"@radix-ui/react-direction@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-direction@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/8cc330285f1d06829568042ca9aabd3295be4690ae93683033fc8632b5c4dfc60f5c1312f6e2cae27c196189c719de3cfbcf792ff74800f9ccae0ab4abc1bc92 + languageName: node + linkType: hard + +"@radix-ui/react-dismissable-layer@npm:1.1.11": + version: 1.1.11 + resolution: "@radix-ui/react-dismissable-layer@npm:1.1.11" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + "@radix-ui/react-use-escape-keydown": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/c20772588423379dee47fbe1d45c238c45a3bbe612eaf64a86576bf81821975e256d92ac71f9151e91b94a73068656143a11da9a3e77de7564d2a9926468e37a + languageName: node + linkType: hard + +"@radix-ui/react-focus-guards@npm:1.1.3": + version: 1.1.3 + resolution: "@radix-ui/react-focus-guards@npm:1.1.3" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/b57878f6cf0ebc3e8d7c5c6bbaad44598daac19c921551ca541c104201048a9a902f3d69196e7a09995fd46e998c309aab64dc30fa184b3609d67d187a6a9c24 + languageName: node + linkType: hard + +"@radix-ui/react-focus-scope@npm:1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-focus-scope@npm:1.1.7" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/2a7cd00e39e01756999ebf0bdb3401d6a8efa489a7b19e6b629b40bad3022b7b1f616555ccb4b0505bc0ba53e13a1fb51be905db138b16ec39c4fe319fe701d3 + languageName: node + linkType: hard + +"@radix-ui/react-icons@npm:^1.3.2": + version: 1.3.2 + resolution: "@radix-ui/react-icons@npm:1.3.2" + peerDependencies: + react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc + checksum: 10/cf6c694a400677890d0d83cd30ac01fa638c04eefe6194cd4e3c9edff49269e97dccc01e7bb480e2dcc249b27ee4eafa5d82d72d15c5119d66f4c26db6128f36 + languageName: node + linkType: hard + +"@radix-ui/react-id@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-id@npm:1.1.1" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/8d68e200778eb3038906870fc869b3d881f4a46715fb20cddd9c76cba42fdaaa4810a3365b6ec2daf0f185b9201fc99d009167f59c7921bc3a139722c2e976db + languageName: node + linkType: hard + +"@radix-ui/react-popover@npm:^1.1.11": + version: 1.1.15 + resolution: "@radix-ui/react-popover@npm:1.1.15" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-dismissable-layer": "npm:1.1.11" + "@radix-ui/react-focus-guards": "npm:1.1.3" + "@radix-ui/react-focus-scope": "npm:1.1.7" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-popper": "npm:1.2.8" + "@radix-ui/react-portal": "npm:1.1.9" + "@radix-ui/react-presence": "npm:1.1.5" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-slot": "npm:1.2.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + aria-hidden: "npm:^1.2.4" + react-remove-scroll: "npm:^2.6.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/0ea7c8bb827e44d5c02b3f7193d9ac8085c71a01bf601b1afeb2bb0ec0124756e03db3471606e89e4d014e4de7c7066c8e2e9b81bb4b31ea321890ec33421f31 + languageName: node + linkType: hard + +"@radix-ui/react-popper@npm:1.2.8, @radix-ui/react-popper@npm:^1.2.4": + version: 1.2.8 + resolution: "@radix-ui/react-popper@npm:1.2.8" + dependencies: + "@floating-ui/react-dom": "npm:^2.0.0" + "@radix-ui/react-arrow": "npm:1.1.7" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + "@radix-ui/react-use-rect": "npm:1.1.1" + "@radix-ui/react-use-size": "npm:1.1.1" + "@radix-ui/rect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/01366054e1e63dd9394f77afb9da3367709478a5adf4436c080fc5bbe9456170192ff9d1425d9fae5b246e1ba95173848f84b6f2a06b21b47d966367ec7cb997 + languageName: node + linkType: hard + +"@radix-ui/react-portal@npm:1.1.9": + version: 1.1.9 + resolution: "@radix-ui/react-portal@npm:1.1.9" + dependencies: + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/bd6be39bf021d5c917e2474ecba411e2625171f7ef96862b9af04bbd68833bb3662a7f1fbdeb5a7a237111b10e811e76d2cd03e957dadd6e668ef16541bfbd68 + languageName: node + linkType: hard + +"@radix-ui/react-presence@npm:1.1.5": + version: 1.1.5 + resolution: "@radix-ui/react-presence@npm:1.1.5" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/4cdb05844c18877efb4b9739b46b7e5850b81d7ede994e75b5d62e8153a43c6e16b3ff9e55ff716e20b74b99b9415a94e97fd636bcb8698d5bbf7ab7b8663f9b + languageName: node + linkType: hard + +"@radix-ui/react-primitive@npm:2.1.3": + version: 2.1.3 + resolution: "@radix-ui/react-primitive@npm:2.1.3" + dependencies: + "@radix-ui/react-slot": "npm:1.2.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/1dbbf932a3527f4e62f210bb72944eff605c3e38c8d3275ed5a5c570c02820ab156169756a65ad9a638d2089a828a04a7903795377384e98c87d0ca456303253 + languageName: node + linkType: hard + +"@radix-ui/react-roving-focus@npm:1.1.11": + version: 1.1.11 + resolution: "@radix-ui/react-roving-focus@npm:1.1.11" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-collection": "npm:1.1.7" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-direction": "npm:1.1.1" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/0eddafa942332c95622ab8b53cce2fa25fd0dcaf4797218e9e6725da0734a81a438852cdcb3f588521018f68d38c6c5e50c64fda78c655f4e69dd45681ecc5e7 + languageName: node + linkType: hard + +"@radix-ui/react-select@npm:^2.2.2": + version: 2.2.6 + resolution: "@radix-ui/react-select@npm:2.2.6" + dependencies: + "@radix-ui/number": "npm:1.1.1" + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-collection": "npm:1.1.7" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-direction": "npm:1.1.1" + "@radix-ui/react-dismissable-layer": "npm:1.1.11" + "@radix-ui/react-focus-guards": "npm:1.1.3" + "@radix-ui/react-focus-scope": "npm:1.1.7" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-popper": "npm:1.2.8" + "@radix-ui/react-portal": "npm:1.1.9" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-slot": "npm:1.2.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + "@radix-ui/react-use-previous": "npm:1.1.1" + "@radix-ui/react-visually-hidden": "npm:1.2.3" + aria-hidden: "npm:^1.2.4" + react-remove-scroll: "npm:^2.6.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/ef6df1a6411a965d30f8e14387058ece020469897ad2089d1e1019d8e37487e6b3c0f9683d7c6ec217698fa85fedd419738cab089a5ebc49a04405e63aac0bf0 + languageName: node + linkType: hard + +"@radix-ui/react-separator@npm:1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-separator@npm:1.1.7" + dependencies: + "@radix-ui/react-primitive": "npm:2.1.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/c5c19b7991bf5395eb2b849145deeb9aa307d9fcf220380497992ff2a301753ab477d0329af51b6d500cd3c1d777edbd2504b544d9254542fb5f829ac5ddbcf3 + languageName: node + linkType: hard + +"@radix-ui/react-slot@npm:1.2.3": + version: 1.2.3 + resolution: "@radix-ui/react-slot@npm:1.2.3" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/fe484c2741e31d9c20a8fb53c5790a73c0664e2bea35e27f4d484a90c42135fcfffe11a08abfcacb7a8ee2faf013471f0e856818f3ddac8ac51ceb8869e0fd08 + languageName: node + linkType: hard + +"@radix-ui/react-toggle-group@npm:1.1.11, @radix-ui/react-toggle-group@npm:^1.1.7": + version: 1.1.11 + resolution: "@radix-ui/react-toggle-group@npm:1.1.11" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-direction": "npm:1.1.1" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-roving-focus": "npm:1.1.11" + "@radix-ui/react-toggle": "npm:1.1.10" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/b20e2aa2580624621b62e72d2e44585427807e6629186dc8a46909a3bd35d9122fb4837f8e8fa9856a24b54bb2a7aa8983007da8b459303495d0d55b14396b35 + languageName: node + linkType: hard + +"@radix-ui/react-toggle@npm:1.1.10": + version: 1.1.10 + resolution: "@radix-ui/react-toggle@npm:1.1.10" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/ece154bd7a0ca765040fafbe4131f753457a3d37f73dec3ae94f08f17f3889272d06f33f305ad34c986925ce8a40532ee43f6bdb7e8b99fd8bac299b01d69204 + languageName: node + linkType: hard + +"@radix-ui/react-toolbar@npm:^1.1.7": + version: 1.1.11 + resolution: "@radix-ui/react-toolbar@npm:1.1.11" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-direction": "npm:1.1.1" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-roving-focus": "npm:1.1.11" + "@radix-ui/react-separator": "npm:1.1.7" + "@radix-ui/react-toggle-group": "npm:1.1.11" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/da022ae96f0a02da2c5890af3350f622425c8bb8564b1cae51ca28cfeb5dc73a8bb597bb762dfef2f738d497d207792e22231aec050c8d05071518b9c58f1f8b + languageName: node + linkType: hard + +"@radix-ui/react-tooltip@npm:^1.2.4": + version: 1.2.8 + resolution: "@radix-ui/react-tooltip@npm:1.2.8" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-dismissable-layer": "npm:1.1.11" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-popper": "npm:1.2.8" + "@radix-ui/react-portal": "npm:1.1.9" + "@radix-ui/react-presence": "npm:1.1.5" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-slot": "npm:1.2.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + "@radix-ui/react-visually-hidden": "npm:1.2.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/e31857628d998b69616b8994f9627d387ed7bfa453b94e3b18ad2c04de83caf5fcca0ef2f304b1d343e00f183e937d883247d81e386dcc76c7c7c268484bc47c + languageName: node + linkType: hard + +"@radix-ui/react-use-callback-ref@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-callback-ref@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/cde8c40f1d4e79e6e71470218163a746858304bad03758ac84dc1f94247a046478e8e397518350c8d6609c84b7e78565441d7505bb3ed573afce82cfdcd19faf + languageName: node + linkType: hard + +"@radix-ui/react-use-controllable-state@npm:1.2.2": + version: 1.2.2 + resolution: "@radix-ui/react-use-controllable-state@npm:1.2.2" + dependencies: + "@radix-ui/react-use-effect-event": "npm:0.0.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/a100bff3ddecb753dab17444147273c9f70046c5949712c52174b259622eaef12acbf7ebcf289bae4e714eb84d0a7317c1aa44064cd997f327d77b62bc732a7c + languageName: node + linkType: hard + +"@radix-ui/react-use-effect-event@npm:0.0.2": + version: 0.0.2 + resolution: "@radix-ui/react-use-effect-event@npm:0.0.2" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/5a1950a30a399ea7e4b98154da9f536737a610de80189b7aacd4f064a89a3cd0d2a48571d527435227252e72e872bdb544ff6ffcfbdd02de2efd011be4aaa902 + languageName: node + linkType: hard + +"@radix-ui/react-use-escape-keydown@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-escape-keydown@npm:1.1.1" + dependencies: + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/0eb0756c2c55ddcde9ff01446ab01c085ab2bf799173e97db7ef5f85126f9e8600225570801a1f64740e6d14c39ffe8eed7c14d29737345a5797f4622ac96f6f + languageName: node + linkType: hard + +"@radix-ui/react-use-layout-effect@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-layout-effect@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/bad2ba4f206e6255263582bedfb7868773c400836f9a1b423c0b464ffe4a17e13d3f306d1ce19cf7a19a492e9d0e49747464f2656451bb7c6a99f5a57bd34de2 + languageName: node + linkType: hard + +"@radix-ui/react-use-previous@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-previous@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/ea6ea13523a0561dda9b14b9d44e299484816a6762d7fb50b91b27b6aec89f78c85245b69d5a904750d43919dbb7ef6ce6d3823639346675aa3a5cb9de32d984 + languageName: node + linkType: hard + +"@radix-ui/react-use-rect@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-rect@npm:1.1.1" + dependencies: + "@radix-ui/rect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/116461bebc49472f7497e66a9bd413541181b3d00c5e0aaeef45d790dc1fbd7c8dcea80b169ea273306228b9a3c2b70067e902d1fd5004b3057e3bbe35b9d55d + languageName: node + linkType: hard + +"@radix-ui/react-use-size@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-size@npm:1.1.1" dependencies: - graceful-fs: "npm:4.2.10" - checksum: 10/d8d0884646500576bd5390464d13db1bb9a62e32a1069293e5bddb2ad8354b354b7e2d2a35e12850025651e795e6a80ce9e601c66312504667b7e3ee7b52becc + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/64e61f65feb67ffc80e1fc4a8d5e32480fb6d68475e2640377e021178dead101568cba5f936c9c33e6c142c7cf2fb5d76ad7b23ef80e556ba142d56cf306147b languageName: node linkType: hard -"@pnpm/npm-conf@npm:^2.1.0": - version: 2.3.1 - resolution: "@pnpm/npm-conf@npm:2.3.1" +"@radix-ui/react-visually-hidden@npm:1.2.3": + version: 1.2.3 + resolution: "@radix-ui/react-visually-hidden@npm:1.2.3" dependencies: - "@pnpm/config.env-replace": "npm:^1.1.0" - "@pnpm/network.ca-file": "npm:^1.0.1" - config-chain: "npm:^1.1.11" - checksum: 10/44fbb0b166eee3e3631ef0e92b1bed6489aa6975e3e722c16577cc0181b81374f5ae90c6e4da183c8160f996e6b4863325525b00542f42d1b757b51ef62bc4e7 + "@radix-ui/react-primitive": "npm:2.1.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/42296bde1ddf4af4e7445e914c35d6bc8406d6ede49f0a959a553e75b3ed21da09fda80a81c48d8ec058ed8129ce7137499d02ee26f90f0d3eaa2417922d6509 languageName: node linkType: hard -"@polka/url@npm:^1.0.0-next.24": - version: 1.0.0-next.24 - resolution: "@polka/url@npm:1.0.0-next.24" - checksum: 10/00baec4458ac86ca27edf7ce807ccfad97cd1d4b67bdedaf3401a9e755757588f3331e891290d1deea52d88df2bf2387caf8d94a6835b614d5b37b638a688273 +"@radix-ui/rect@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/rect@npm:1.1.1" + checksum: 10/b6c5eb787640775b53dd52fa47218a089f0a0d8220d3ebff079c0b754e1fb82d89b6bdf08a82fd0d59549bdeb52678c0cca091c302da49dcf74c3c989cb55678 languageName: node linkType: hard -"@popperjs/core@npm:^2.11.8": - version: 2.11.8 - resolution: "@popperjs/core@npm:2.11.8" - checksum: 10/ddd16090cde777aaf102940f05d0274602079a95ad9805bd20bc55dcc7c3a2ba1b99dd5c73e5cc2753c3d31250ca52a67d58059459d7d27debb983a9f552936c +"@react-hook/intersection-observer@npm:^3.1.1": + version: 3.1.2 + resolution: "@react-hook/intersection-observer@npm:3.1.2" + dependencies: + "@react-hook/passive-layout-effect": "npm:^1.2.0" + intersection-observer: "npm:^0.10.0" + peerDependencies: + react: ">=16.8" + checksum: 10/fee587ca06bdfe02aa3a30b95bb9fb63cc745aafa74a34e68b2c1938b6b34e8807f02e8a9f3d656ab4b399f30cd6aaa88ef7b486ec1ee1f848e6e726d73f256d languageName: node linkType: hard -"@prettier/sync@npm:^0.3.0": - version: 0.3.0 - resolution: "@prettier/sync@npm:0.3.0" +"@react-hook/passive-layout-effect@npm:^1.2.0": + version: 1.2.1 + resolution: "@react-hook/passive-layout-effect@npm:1.2.1" peerDependencies: - prettier: ^3.0.0 - checksum: 10/10520d2479830c18256bf2b18349a15a8964f968059f7ccaa1f6d455c133a26e6c96bd7aea7c64ef6701700e8007ad68619b16ec83391b356b5d4a741cbae504 + react: ">=16.8" + checksum: 10/217cb8aa90fb8e677672319a9a466d7752890cf4357c76df000b207696e9cc717cf2ee88080671cc9dae238a82f92093ab4f61ab2f6032d2a8db958fc7d99b5d languageName: node linkType: hard @@ -9437,6 +11107,13 @@ __metadata: languageName: node linkType: hard +"@stitches/core@npm:^1.2.6": + version: 1.2.8 + resolution: "@stitches/core@npm:1.2.8" + checksum: 10/bdee1772f033b20bfb1081a3bb8c3e85f2a44f381379d4c2ae21408336025e2d2578f79eec74db26824b852ebcc72de3edfc8c51418608f189aa5ffc26df667a + languageName: node + linkType: hard + "@surma/rollup-plugin-off-main-thread@npm:^2.2.3": version: 2.2.3 resolution: "@surma/rollup-plugin-off-main-thread@npm:2.2.3" @@ -12063,7 +13740,7 @@ __metadata: languageName: node linkType: hard -"acorn-jsx@npm:^5.3.2": +"acorn-jsx@npm:^5.0.0, acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" peerDependencies: @@ -12095,6 +13772,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.0.0": + version: 8.15.0 + resolution: "acorn@npm:8.15.0" + bin: + acorn: bin/acorn + checksum: 10/77f2de5051a631cf1729c090e5759148459cdb76b5f5c70f890503d629cf5052357b0ce783c0f976dd8a93c5150f59f6d18df1def3f502396a20f81282482fa4 + languageName: node + linkType: hard + "acorn@npm:^8.1.0, acorn@npm:^8.10.0, acorn@npm:^8.14.0, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.7.1, acorn@npm:^8.8.0, acorn@npm:^8.8.1, acorn@npm:^8.8.2": version: 8.14.0 resolution: "acorn@npm:8.14.0" @@ -12322,6 +14008,13 @@ __metadata: languageName: node linkType: hard +"anser@npm:^2.1.1": + version: 2.3.2 + resolution: "anser@npm:2.3.2" + checksum: 10/2bfb5fc96533919060bd2f2c199d22011f58e3d0ca48156cec7508ca5f741ea08e38fe634ae3d6902ae44b445148438f2ebcaf09f08ff3b2be20687c19cf4419 + languageName: node + linkType: hard + "ansi-align@npm:^3.0.0": version: 3.0.1 resolution: "ansi-align@npm:3.0.1" @@ -12543,6 +14236,15 @@ __metadata: languageName: node linkType: hard +"aria-hidden@npm:^1.2.4": + version: 1.2.6 + resolution: "aria-hidden@npm:1.2.6" + dependencies: + tslib: "npm:^2.0.0" + checksum: 10/1914e5a36225dccdb29f0b88cc891eeca736cdc5b0c905ab1437b90b28b5286263ed3a221c75b7dc788f25b942367be0044b2ac8ccf073a72e07a50b1d964202 + languageName: node + linkType: hard + "aria-query@npm:^5.3.1, aria-query@npm:^5.3.2": version: 5.3.2 resolution: "aria-query@npm:5.3.2" @@ -14392,6 +16094,13 @@ __metadata: languageName: node linkType: hard +"classnames@npm:^2.3.2": + version: 2.5.1 + resolution: "classnames@npm:2.5.1" + checksum: 10/58eb394e8817021b153bb6e7d782cfb667e4ab390cb2e9dac2fc7c6b979d1cc2b2a733093955fc5c94aa79ef5c8c89f11ab77780894509be6afbb91dddd79d15 + languageName: node + linkType: hard + "clean-css@npm:^5.2.2": version: 5.3.2 resolution: "clean-css@npm:5.3.2" @@ -14401,6 +16110,13 @@ __metadata: languageName: node linkType: hard +"clean-set@npm:^1.1.2": + version: 1.1.2 + resolution: "clean-set@npm:1.1.2" + checksum: 10/b460b59c82a11945052b59efa1d51405c0ba11d227f2c2140e9f7803d702b4a36354bfee0077d46a758979891aa4322211ce392c86961f11bf57e2ff774d5506 + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -14596,6 +16312,18 @@ __metadata: languageName: node linkType: hard +"cm6-theme-basic-light@npm:^0.2.0": + version: 0.2.0 + resolution: "cm6-theme-basic-light@npm:0.2.0" + peerDependencies: + "@codemirror/language": ^6.0.0 + "@codemirror/state": ^6.0.0 + "@codemirror/view": ^6.0.0 + "@lezer/highlight": ^1.0.0 + checksum: 10/8eb28ac7d8d7abdd8e5e4589d6abe459f1fe841940e49ea6431135c446b93af67bccab3981627c8e6377d1199f64879691570d6d1d409f9df9627bf4edceb1fc + languageName: node + linkType: hard + "co@npm:^4.6.0": version: 4.6.0 resolution: "co@npm:4.6.0" @@ -14625,6 +16353,21 @@ __metadata: languageName: node linkType: hard +"codemirror@npm:^6.0.1": + version: 6.0.2 + resolution: "codemirror@npm:6.0.2" + dependencies: + "@codemirror/autocomplete": "npm:^6.0.0" + "@codemirror/commands": "npm:^6.0.0" + "@codemirror/language": "npm:^6.0.0" + "@codemirror/lint": "npm:^6.0.0" + "@codemirror/search": "npm:^6.0.0" + "@codemirror/state": "npm:^6.0.0" + "@codemirror/view": "npm:^6.0.0" + checksum: 10/bd73c9ebbd8cb709a697fa4e2484c188c44aafce4b4d2a342807a5648c6be5bd5876f0caac47db0c1181f1ec8d86e38bd2b6efe51b971bf240fd3382bef0b371 + languageName: node + linkType: hard + "collect-v8-coverage@npm:^1.0.0": version: 1.0.1 resolution: "collect-v8-coverage@npm:1.0.1" @@ -14859,6 +16602,13 @@ __metadata: languageName: node linkType: hard +"compute-scroll-into-view@npm:^2.0.4": + version: 2.0.4 + resolution: "compute-scroll-into-view@npm:2.0.4" + checksum: 10/a9015cbf464ed852d3c459c1777d5890e26925dd2e99ad438dc8cb6a0154f33f0ce6856f6c50de9dd176168d315e7223d08c4bae1e5dbe82b056dd5216c0bcc6 + languageName: node + linkType: hard + "computeds@npm:^0.0.1": version: 0.0.1 resolution: "computeds@npm:0.0.1" @@ -15383,7 +17133,7 @@ __metadata: languageName: node linkType: hard -"crelt@npm:^1.0.5": +"crelt@npm:^1.0.5, crelt@npm:^1.0.6": version: 1.0.6 resolution: "crelt@npm:1.0.6" checksum: 10/5ed326ca6bd243b1dba6b943f665b21c2c04be03271824bc48f20dba324b0f8233e221f8c67312526d24af2b1243c023dc05a41bd8bd05d1a479fd2c72fb39c3 @@ -15833,6 +17583,16 @@ __metadata: languageName: node linkType: hard +"d@npm:1, d@npm:^1.0.1, d@npm:^1.0.2": + version: 1.0.2 + resolution: "d@npm:1.0.2" + dependencies: + es5-ext: "npm:^0.10.64" + type: "npm:^2.7.2" + checksum: 10/a3f45ef964622f683f6a1cb9b8dcbd75ce490cd2f4ac9794099db3d8f0e2814d412d84cd3fe522e58feb1f273117bb480f29c5381f6225f0abca82517caaa77a + languageName: node + linkType: hard + "dag-jose@npm:^5.0.0": version: 5.1.1 resolution: "dag-jose@npm:5.1.1" @@ -16274,7 +18034,7 @@ __metadata: languageName: node linkType: hard -"dequal@npm:^2.0.0, dequal@npm:^2.0.3": +"dequal@npm:^2.0.0, dequal@npm:^2.0.2, dequal@npm:^2.0.3": version: 2.0.3 resolution: "dequal@npm:2.0.3" checksum: 10/6ff05a7561f33603df87c45e389c9ac0a95e3c056be3da1a0c4702149e3a7f6fe5ffbb294478687ba51a9e95f3a60e8b6b9005993acd79c292c7d15f71964b6b @@ -16358,6 +18118,13 @@ __metadata: languageName: node linkType: hard +"detect-node-es@npm:^1.1.0": + version: 1.1.0 + resolution: "detect-node-es@npm:1.1.0" + checksum: 10/e46307d7264644975b71c104b9f028ed1d3d34b83a15b8a22373640ce5ea630e5640b1078b8ea15f202b54641da71e4aa7597093bd4b91f113db520a26a37449 + languageName: node + linkType: hard + "detect-node@npm:^2.0.4": version: 2.1.0 resolution: "detect-node@npm:2.1.0" @@ -16415,7 +18182,7 @@ __metadata: languageName: node linkType: hard -"diff@npm:^5.0.0, diff@npm:^5.2.0": +"diff@npm:^5.0.0, diff@npm:^5.1.0, diff@npm:^5.2.0": version: 5.2.0 resolution: "diff@npm:5.2.0" checksum: 10/01b7b440f83a997350a988e9d2f558366c0f90f15be19f4aa7f1bb3109a4e153dfc3b9fbf78e14ea725717017407eeaa2271e3896374a0181e8f52445740846d @@ -16732,13 +18499,28 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:^16.6.1": +"dotenv@npm:^16.0.3, dotenv@npm:^16.6.1": version: 16.6.1 resolution: "dotenv@npm:16.6.1" checksum: 10/1d1897144344447ffe62aa1a6d664f4cd2e0784e0aff787eeeec1940ded32f8e4b5b506d665134fc87157baa086fce07ec6383970a2b6d2e7985beaed6a4cc14 languageName: node linkType: hard +"downshift@npm:^7.6.0": + version: 7.6.2 + resolution: "downshift@npm:7.6.2" + dependencies: + "@babel/runtime": "npm:^7.14.8" + compute-scroll-into-view: "npm:^2.0.4" + prop-types: "npm:^15.7.2" + react-is: "npm:^17.0.2" + tslib: "npm:^2.3.0" + peerDependencies: + react: ">=16.12.0" + checksum: 10/4ffca012d185a6eb57d5543650401323c932ae5f7227f92419aba4f04d5de2ca4f0270aa398caa289622f60ebb5f831fddf11e5d6d56981a89f7fbd7ed0a1f48 + languageName: node + linkType: hard + "dset@npm:^3.1.2": version: 3.1.2 resolution: "dset@npm:3.1.2" @@ -17197,6 +18979,29 @@ __metadata: languageName: node linkType: hard +"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.62, es5-ext@npm:^0.10.64, es5-ext@npm:~0.10.14": + version: 0.10.64 + resolution: "es5-ext@npm:0.10.64" + dependencies: + es6-iterator: "npm:^2.0.3" + es6-symbol: "npm:^3.1.3" + esniff: "npm:^2.0.1" + next-tick: "npm:^1.1.0" + checksum: 10/0c5d8657708b1695ddc4b06f4e0b9fbdda4d2fe46d037b6bedb49a7d1931e542ec9eecf4824d59e1d357e93229deab014bb4b86485db2d41b1d68e54439689ce + languageName: node + linkType: hard + +"es6-iterator@npm:^2.0.3": + version: 2.0.3 + resolution: "es6-iterator@npm:2.0.3" + dependencies: + d: "npm:1" + es5-ext: "npm:^0.10.35" + es6-symbol: "npm:^3.1.1" + checksum: 10/dbadecf3d0e467692815c2b438dfa99e5a97cbbecf4a58720adcb467a04220e0e36282399ba297911fd472c50ae4158fffba7ed0b7d4273fe322b69d03f9e3a5 + languageName: node + linkType: hard + "es6-promise@npm:^4.0.3": version: 4.2.8 resolution: "es6-promise@npm:4.2.8" @@ -17213,6 +19018,16 @@ __metadata: languageName: node linkType: hard +"es6-symbol@npm:^3, es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": + version: 3.1.4 + resolution: "es6-symbol@npm:3.1.4" + dependencies: + d: "npm:^1.0.2" + ext: "npm:^1.7.0" + checksum: 10/3743119fe61f89e2f049a6ce52bd82fab5f65d13e2faa72453b73f95c15292c3cb9bdf3747940d504517e675e45fd375554c6b5d35d2bcbefd35f5489ecba546 + languageName: node + linkType: hard + "esbuild@npm:^0.19.0": version: 0.19.12 resolution: "esbuild@npm:0.19.12" @@ -17476,6 +19291,13 @@ __metadata: languageName: node linkType: hard +"escape-carriage@npm:^1.3.1": + version: 1.3.1 + resolution: "escape-carriage@npm:1.3.1" + checksum: 10/6d7613a5875977b04eb4651f3fa14eb8f54c72aa198b603c823502fcfef9f5969afc4c76d27b2f2fc008d88764fbf4c3a6e04d549d6134e2ff7f705c99e3ddb9 + languageName: node + linkType: hard + "escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" @@ -17504,6 +19326,13 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 10/20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e + languageName: node + linkType: hard + "escodegen@npm:1.8.x": version: 1.8.1 resolution: "escodegen@npm:1.8.1" @@ -18056,6 +19885,18 @@ __metadata: languageName: node linkType: hard +"esniff@npm:^2.0.1": + version: 2.0.1 + resolution: "esniff@npm:2.0.1" + dependencies: + d: "npm:^1.0.1" + es5-ext: "npm:^0.10.62" + event-emitter: "npm:^0.3.5" + type: "npm:^2.7.2" + checksum: 10/f6a2abd2f8c5fe57c5fcf53e5407c278023313d0f6c3a92688e7122ab9ac233029fd424508a196ae5bc561aa1f67d23f4e2435b1a0d378030f476596129056ac + languageName: node + linkType: hard + "espree@npm:^10.0.1, espree@npm:^10.3.0": version: 10.3.0 resolution: "espree@npm:10.3.0" @@ -18153,6 +19994,16 @@ __metadata: languageName: node linkType: hard +"estree-util-visit@npm:^2.0.0": + version: 2.0.0 + resolution: "estree-util-visit@npm:2.0.0" + dependencies: + "@types/estree-jsx": "npm:^1.0.0" + "@types/unist": "npm:^3.0.0" + checksum: 10/e3c39d34c8b42fc2067dfa64d460f754b43cca4b573b031a5e5bb185e02c4efc753353197815bbb094b8149a781ab76f18116bec8056b5ff375162e68bffa0bd + languageName: node + linkType: hard + "estree-walker@npm:^1.0.1": version: 1.0.1 resolution: "estree-walker@npm:1.0.1" @@ -18440,6 +20291,16 @@ __metadata: languageName: node linkType: hard +"event-emitter@npm:^0.3.5": + version: 0.3.5 + resolution: "event-emitter@npm:0.3.5" + dependencies: + d: "npm:1" + es5-ext: "npm:~0.10.14" + checksum: 10/a7f5ea80029193f4869782d34ef7eb43baa49cd397013add1953491b24588468efbe7e3cc9eb87d53f33397e7aab690fd74c079ec440bf8b12856f6bdb6e9396 + languageName: node + linkType: hard + "event-target-shim@npm:^5.0.0": version: 5.0.1 resolution: "event-target-shim@npm:5.0.1" @@ -18618,6 +20479,15 @@ __metadata: languageName: node linkType: hard +"ext@npm:^1.7.0": + version: 1.7.0 + resolution: "ext@npm:1.7.0" + dependencies: + type: "npm:^2.7.2" + checksum: 10/666a135980b002df0e75c8ac6c389140cdc59ac953db62770479ee2856d58ce69d2f845e5f2586716350b725400f6945e51e9159573158c39f369984c72dcd84 + languageName: node + linkType: hard + "extend@npm:^3.0.0": version: 3.0.2 resolution: "extend@npm:3.0.2" @@ -18818,6 +20688,15 @@ __metadata: languageName: node linkType: hard +"fault@npm:^2.0.0": + version: 2.0.1 + resolution: "fault@npm:2.0.1" + dependencies: + format: "npm:^0.2.0" + checksum: 10/c9b30f47d95769177130a9409976a899ed31eb598450fbad5b0d39f2f5f56d5f4a9ff9257e0bee8407cb0fc3ce37165657888c6aa6d78472e403893104329b72 + languageName: node + linkType: hard + "faye-websocket@npm:^0.11.3": version: 0.11.4 resolution: "faye-websocket@npm:0.11.4" @@ -19211,6 +21090,13 @@ __metadata: languageName: node linkType: hard +"format@npm:^0.2.0": + version: 0.2.2 + resolution: "format@npm:0.2.2" + checksum: 10/5f878b8fc1a672c8cbefa4f293bdd977c822862577d70d53456a48b4169ec9b51677c0c995bf62c633b4e5cd673624b7c273f57923b28735a6c0c0a72c382a4a + languageName: node + linkType: hard + "forwarded@npm:0.2.0": version: 0.2.0 resolution: "forwarded@npm:0.2.0" @@ -19474,6 +21360,13 @@ __metadata: languageName: node linkType: hard +"get-nonce@npm:^1.0.0": + version: 1.0.1 + resolution: "get-nonce@npm:1.0.1" + checksum: 10/ad5104871d114a694ecc506a2d406e2331beccb961fe1e110dc25556b38bcdbf399a823a8a375976cd8889668156a9561e12ebe3fa6a4c6ba169c8466c2ff868 + languageName: node + linkType: hard + "get-own-enumerable-property-symbols@npm:^3.0.0": version: 3.0.2 resolution: "get-own-enumerable-property-symbols@npm:3.0.2" @@ -21197,6 +23090,13 @@ __metadata: languageName: node linkType: hard +"intersection-observer@npm:^0.10.0": + version: 0.10.0 + resolution: "intersection-observer@npm:0.10.0" + checksum: 10/d9ffce291459a2c4ada9e45f23ef805361691f93e9a41a2afe801d29e6c9b1d0054f7faddafd79ecc341d7008e1f921a2e67cadeae9692d9831af903f23fc644 + languageName: node + linkType: hard + "invariant@npm:^2.2.4": version: 2.2.4 resolution: "invariant@npm:2.2.4" @@ -23431,6 +25331,13 @@ __metadata: languageName: node linkType: hard +"lexical@npm:0.35.0, lexical@npm:^0.35.0": + version: 0.35.0 + resolution: "lexical@npm:0.35.0" + checksum: 10/31cb0b683c50826f70c6ef1ca1e3a5eb276a736c6e217789c1d38a12bfef93c9f9a16ed0b8747517742067e87145365589a6e133562619777aed58501a53d7b1 + languageName: node + linkType: hard + "lie@npm:3.1.1": version: 3.1.1 resolution: "lie@npm:3.1.1" @@ -24120,6 +26027,15 @@ __metadata: languageName: node linkType: hard +"lz-string@npm:^1.4.4": + version: 1.5.0 + resolution: "lz-string@npm:1.5.0" + bin: + lz-string: bin/bin.js + checksum: 10/e86f0280e99a8d8cd4eef24d8601ddae15ce54e43ac9990dfcb79e1e081c255ad24424a30d78d2ad8e51a8ce82a66a930047fed4b4aa38c6f0b392ff9300edfc + languageName: node + linkType: hard + "magic-string@npm:^0.25.0, magic-string@npm:^0.25.7": version: 0.25.9 resolution: "magic-string@npm:0.25.9" @@ -24239,6 +26155,13 @@ __metadata: languageName: node linkType: hard +"markdown-table@npm:^3.0.0": + version: 3.0.4 + resolution: "markdown-table@npm:3.0.4" + checksum: 10/bc699819e6a15607e5def0f21aa862aa061cf1f49877baa93b0185574f6ab143591afe0e18b94d9b15ea80c6a693894150dbccfacf4f6767160dc32ae393dfe0 + languageName: node + linkType: hard + "marked@npm:^4.1.1": version: 4.3.0 resolution: "marked@npm:4.3.0" @@ -24286,6 +26209,23 @@ __metadata: languageName: node linkType: hard +"mdast-util-directive@npm:^3.0.0": + version: 3.1.0 + resolution: "mdast-util-directive@npm:3.1.0" + dependencies: + "@types/mdast": "npm:^4.0.0" + "@types/unist": "npm:^3.0.0" + ccount: "npm:^2.0.0" + devlop: "npm:^1.0.0" + mdast-util-from-markdown: "npm:^2.0.0" + mdast-util-to-markdown: "npm:^2.0.0" + parse-entities: "npm:^4.0.0" + stringify-entities: "npm:^4.0.0" + unist-util-visit-parents: "npm:^6.0.0" + checksum: 10/5aabd777ae8752cb9d09c7827a6690887536da8a9f85e833d5399ab8f47e5aadaa3eea78985efd041f50c658bf91b4579800dae79b20549240f52bbc2bc26335 + languageName: node + linkType: hard + "mdast-util-from-markdown@npm:^1.0.0": version: 1.3.1 resolution: "mdast-util-from-markdown@npm:1.3.1" @@ -24326,6 +26266,65 @@ __metadata: languageName: node linkType: hard +"mdast-util-frontmatter@npm:^2.0.1": + version: 2.0.1 + resolution: "mdast-util-frontmatter@npm:2.0.1" + dependencies: + "@types/mdast": "npm:^4.0.0" + devlop: "npm:^1.0.0" + escape-string-regexp: "npm:^5.0.0" + mdast-util-from-markdown: "npm:^2.0.0" + mdast-util-to-markdown: "npm:^2.0.0" + micromark-extension-frontmatter: "npm:^2.0.0" + checksum: 10/afd9486af6ea74a94d84a225c367ab810ad4439683ecafc1ce9fc7bb0ecacaafac82e0af529974489c145824b242509f9387f833fc01a14a83a978049772ef80 + languageName: node + linkType: hard + +"mdast-util-gfm-strikethrough@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-gfm-strikethrough@npm:2.0.0" + dependencies: + "@types/mdast": "npm:^4.0.0" + mdast-util-from-markdown: "npm:^2.0.0" + mdast-util-to-markdown: "npm:^2.0.0" + checksum: 10/b1abc137d78270540585ad94a7a4ed1630683312690b902389dae0ede50a6832e26d1be053687f49728e14fa8a379da9384342725d3beb4480fc30b12866ab37 + languageName: node + linkType: hard + +"mdast-util-gfm-table@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-gfm-table@npm:2.0.0" + dependencies: + "@types/mdast": "npm:^4.0.0" + devlop: "npm:^1.0.0" + markdown-table: "npm:^3.0.0" + mdast-util-from-markdown: "npm:^2.0.0" + mdast-util-to-markdown: "npm:^2.0.0" + checksum: 10/a043d60d723a86f79c49cbdd1d98b80c89f4a8f9f5fa84b3880c53e132f40150972460aba9be1f44a612ef5abd6810d122c5e7e5d9c54f3ac7560cce8c305c75 + languageName: node + linkType: hard + +"mdast-util-gfm-task-list-item@npm:^2.0.0": + version: 2.0.0 + resolution: "mdast-util-gfm-task-list-item@npm:2.0.0" + dependencies: + "@types/mdast": "npm:^4.0.0" + devlop: "npm:^1.0.0" + mdast-util-from-markdown: "npm:^2.0.0" + mdast-util-to-markdown: "npm:^2.0.0" + checksum: 10/679a3ff09b52015c0088cd0616ccecc7cc9d250d56a8762aafdffc640f3f607bbd9fe047d3e7e7078e6a996e83f677be3bfcad7ac7260563825fa80a04f8e09d + languageName: node + linkType: hard + +"mdast-util-highlight-mark@npm:^1.2.2": + version: 1.2.2 + resolution: "mdast-util-highlight-mark@npm:1.2.2" + dependencies: + micromark-extension-highlight-mark: "npm:1.2.0" + checksum: 10/92f62acb2958e1f9e280350f707e0254f9f6363618fde528bc738c74143e5735f6393e0b0d08cce2e9f416c4f9e673d485e375bbcf1e861de055f3e50dab09b5 + languageName: node + linkType: hard + "mdast-util-mdx-expression@npm:^2.0.0": version: 2.0.1 resolution: "mdast-util-mdx-expression@npm:2.0.1" @@ -24352,11 +26351,24 @@ __metadata: devlop: "npm:^1.1.0" mdast-util-from-markdown: "npm:^2.0.0" mdast-util-to-markdown: "npm:^2.0.0" - parse-entities: "npm:^4.0.0" - stringify-entities: "npm:^4.0.0" - unist-util-stringify-position: "npm:^4.0.0" - vfile-message: "npm:^4.0.0" - checksum: 10/6c14f271f1380fd512038247f45887b7aa71bbf4acd8881651a317b61706b114f2582f62f7777d0eacd42c4a7b979802825c2a2fd8bb7c46a1ab931ccb1ddf3e + parse-entities: "npm:^4.0.0" + stringify-entities: "npm:^4.0.0" + unist-util-stringify-position: "npm:^4.0.0" + vfile-message: "npm:^4.0.0" + checksum: 10/6c14f271f1380fd512038247f45887b7aa71bbf4acd8881651a317b61706b114f2582f62f7777d0eacd42c4a7b979802825c2a2fd8bb7c46a1ab931ccb1ddf3e + languageName: node + linkType: hard + +"mdast-util-mdx@npm:^3.0.0": + version: 3.0.0 + resolution: "mdast-util-mdx@npm:3.0.0" + dependencies: + mdast-util-from-markdown: "npm:^2.0.0" + mdast-util-mdx-expression: "npm:^2.0.0" + mdast-util-mdx-jsx: "npm:^3.0.0" + mdast-util-mdxjs-esm: "npm:^2.0.0" + mdast-util-to-markdown: "npm:^2.0.0" + checksum: 10/547d928f0d1e60d9087cd8ad301cdf2e1d14b094d2662a00292874b923bcb59323bdad3a29804c7f323ad78f4d3954361bfdaf4a9be765c4e6fe47a815df50c2 languageName: node linkType: hard @@ -24417,7 +26429,7 @@ __metadata: languageName: node linkType: hard -"mdast-util-to-markdown@npm:^2.0.0": +"mdast-util-to-markdown@npm:^2.0.0, mdast-util-to-markdown@npm:^2.1.0": version: 2.1.2 resolution: "mdast-util-to-markdown@npm:2.1.2" dependencies: @@ -24681,6 +26693,163 @@ __metadata: languageName: node linkType: hard +"micromark-extension-directive@npm:^3.0.0": + version: 3.0.2 + resolution: "micromark-extension-directive@npm:3.0.2" + dependencies: + devlop: "npm:^1.0.0" + micromark-factory-space: "npm:^2.0.0" + micromark-factory-whitespace: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + parse-entities: "npm:^4.0.0" + checksum: 10/63dbaa209722c1a77ffea6c6d5ea0f873f5e795ef08a2039f3d795320c889e5ce10fe1162500b0ff3063f8ceb1f7d727ec1d29d2df6271cbe90ec0646e061c8d + languageName: node + linkType: hard + +"micromark-extension-frontmatter@npm:^2.0.0": + version: 2.0.0 + resolution: "micromark-extension-frontmatter@npm:2.0.0" + dependencies: + fault: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + checksum: 10/55873937494e9bfe1cc8cba3c8710e14e85ad0c9f3bb859d367268fc2204f3fe2eb70f9f83e496de0d3ea79c468fe6df879f9d475c716644c2daa90056cc8374 + languageName: node + linkType: hard + +"micromark-extension-gfm-strikethrough@npm:^2.0.0": + version: 2.1.0 + resolution: "micromark-extension-gfm-strikethrough@npm:2.1.0" + dependencies: + devlop: "npm:^1.0.0" + micromark-util-chunked: "npm:^2.0.0" + micromark-util-classify-character: "npm:^2.0.0" + micromark-util-resolve-all: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + checksum: 10/eaf2c7b1e3eb2a7d7f405e8abe561be083cc52b8e027225ed286490939f527d18c120df59c8d8e17fdcf284f8d014502bf3db45d8e36e3109457ece8fb1db29b + languageName: node + linkType: hard + +"micromark-extension-gfm-table@npm:^2.0.0": + version: 2.1.1 + resolution: "micromark-extension-gfm-table@npm:2.1.1" + dependencies: + devlop: "npm:^1.0.0" + micromark-factory-space: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + checksum: 10/0391ead408d79a183a9bba325b0e660b85aef2cd6e442a9214afc4e0bdc3105cd7dbf41fc75465acf152883a4050b6203107c2a80bcadb304235581a1340fd8c + languageName: node + linkType: hard + +"micromark-extension-gfm-task-list-item@npm:^2.0.1": + version: 2.1.0 + resolution: "micromark-extension-gfm-task-list-item@npm:2.1.0" + dependencies: + devlop: "npm:^1.0.0" + micromark-factory-space: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + checksum: 10/c5f72929f0dca77df01442b721356624de6657364e2264ef50fc7226305976f302a49b670836f9494ce70a9b0335d974b5ef8e6457553c4c200bfc06d6951964 + languageName: node + linkType: hard + +"micromark-extension-highlight-mark@npm:1.2.0, micromark-extension-highlight-mark@npm:^1.2.0": + version: 1.2.0 + resolution: "micromark-extension-highlight-mark@npm:1.2.0" + dependencies: + micromark-util-chunked: "npm:^2.0.0" + micromark-util-classify-character: "npm:^2.0.0" + micromark-util-resolve-all: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + uvu: "npm:^0.5.6" + checksum: 10/18474254eb7bf347ff68cc1953aa702527c8d710856d2b2252a3e59dda2fb3b7f34c0780ef18090f257270a00182380d731a7f705e5834e5795e8790aa3ea696 + languageName: node + linkType: hard + +"micromark-extension-mdx-expression@npm:^3.0.0": + version: 3.0.1 + resolution: "micromark-extension-mdx-expression@npm:3.0.1" + dependencies: + "@types/estree": "npm:^1.0.0" + devlop: "npm:^1.0.0" + micromark-factory-mdx-expression: "npm:^2.0.0" + micromark-factory-space: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-events-to-acorn: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + checksum: 10/a185e1787fe6d49d0e435690affd4b83ce319f88a08c57d2460d37d5c0a75ea64aa49a4a116b6d37f91389dc04351e1826aa834519a9f25fc31e1424962c6eb7 + languageName: node + linkType: hard + +"micromark-extension-mdx-jsx@npm:^3.0.0": + version: 3.0.2 + resolution: "micromark-extension-mdx-jsx@npm:3.0.2" + dependencies: + "@types/estree": "npm:^1.0.0" + devlop: "npm:^1.0.0" + estree-util-is-identifier-name: "npm:^3.0.0" + micromark-factory-mdx-expression: "npm:^2.0.0" + micromark-factory-space: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-events-to-acorn: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + vfile-message: "npm:^4.0.0" + checksum: 10/a85cdb7c972fbb2cc8f0a64adc808b2b62bc2d79dbdd31fcd3208ff15aafa0198b002022840b2c65b5bff6f2a8c2c4a59a32a89f3482e6e183114b476e98e25c + languageName: node + linkType: hard + +"micromark-extension-mdx-md@npm:^2.0.0": + version: 2.0.0 + resolution: "micromark-extension-mdx-md@npm:2.0.0" + dependencies: + micromark-util-types: "npm:^2.0.0" + checksum: 10/8b364a69b23196075258143c8c19fa58d7d5a91f6811ec0f881b75cf024a4869994be29f84f4d281147275c5a104af8b6a7fcd98abd8fde9f5b534a1acb254e8 + languageName: node + linkType: hard + +"micromark-extension-mdxjs-esm@npm:^3.0.0": + version: 3.0.0 + resolution: "micromark-extension-mdxjs-esm@npm:3.0.0" + dependencies: + "@types/estree": "npm:^1.0.0" + devlop: "npm:^1.0.0" + micromark-core-commonmark: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-events-to-acorn: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + unist-util-position-from-estree: "npm:^2.0.0" + vfile-message: "npm:^4.0.0" + checksum: 10/f2e0977f9a65284b0c765d1175d55ec5d1928dae3ae90f65cc36f293cda152a97fe2007977aaf5595b1bc02298b34c96e8ce8b647c9c647c75f1ea53e92d14d2 + languageName: node + linkType: hard + +"micromark-extension-mdxjs@npm:^3.0.0": + version: 3.0.0 + resolution: "micromark-extension-mdxjs@npm:3.0.0" + dependencies: + acorn: "npm:^8.0.0" + acorn-jsx: "npm:^5.0.0" + micromark-extension-mdx-expression: "npm:^3.0.0" + micromark-extension-mdx-jsx: "npm:^3.0.0" + micromark-extension-mdx-md: "npm:^2.0.0" + micromark-extension-mdxjs-esm: "npm:^3.0.0" + micromark-util-combine-extensions: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + checksum: 10/66e0df7b2db05b9c88796600e354e0753594f06760abfddcac706afcd5754586c9085adb89e15447ce1450e6a5f2fa66a75f6da394e0eceb919e9c364475593e + languageName: node + linkType: hard + "micromark-factory-destination@npm:^1.0.0": version: 1.1.0 resolution: "micromark-factory-destination@npm:1.1.0" @@ -24727,6 +26896,23 @@ __metadata: languageName: node linkType: hard +"micromark-factory-mdx-expression@npm:^2.0.0": + version: 2.0.3 + resolution: "micromark-factory-mdx-expression@npm:2.0.3" + dependencies: + "@types/estree": "npm:^1.0.0" + devlop: "npm:^1.0.0" + micromark-factory-space: "npm:^2.0.0" + micromark-util-character: "npm:^2.0.0" + micromark-util-events-to-acorn: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + unist-util-position-from-estree: "npm:^2.0.0" + vfile-message: "npm:^4.0.0" + checksum: 10/afadae88a18f31afa564747101e076011c56457454b30294ae55aeea7efee8626ddc3bad0f0f43649008f89b8784782b5adec143fdf477fb352354d76f08db55 + languageName: node + linkType: hard + "micromark-factory-space@npm:^1.0.0": version: 1.1.0 resolution: "micromark-factory-space@npm:1.1.0" @@ -24805,7 +26991,7 @@ __metadata: languageName: node linkType: hard -"micromark-util-character@npm:^2.0.0": +"micromark-util-character@npm:^2.0.0, micromark-util-character@npm:^2.0.1": version: 2.1.1 resolution: "micromark-util-character@npm:2.1.1" dependencies: @@ -24931,6 +27117,21 @@ __metadata: languageName: node linkType: hard +"micromark-util-events-to-acorn@npm:^2.0.0": + version: 2.0.3 + resolution: "micromark-util-events-to-acorn@npm:2.0.3" + dependencies: + "@types/estree": "npm:^1.0.0" + "@types/unist": "npm:^3.0.0" + devlop: "npm:^1.0.0" + estree-util-visit: "npm:^2.0.0" + micromark-util-symbol: "npm:^2.0.0" + micromark-util-types: "npm:^2.0.0" + vfile-message: "npm:^4.0.0" + checksum: 10/0d87e49b897636dc0e84b4bd06b6fa9e6abcd40ab90c9431e36737c85c444d3db1e4f9b8f51433422b1bedc46f086890ce96671b5a795230c6b7b09cb53d9aba + languageName: node + linkType: hard + "micromark-util-html-tag-name@npm:^1.0.0": version: 1.2.0 resolution: "micromark-util-html-tag-name@npm:1.2.0" @@ -25144,6 +27345,13 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:^1.52.0": + version: 1.54.0 + resolution: "mime-db@npm:1.54.0" + checksum: 10/9e7834be3d66ae7f10eaa69215732c6d389692b194f876198dca79b2b90cbf96688d9d5d05ef7987b20f749b769b11c01766564264ea5f919c88b32a29011311 + languageName: node + linkType: hard + "mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" @@ -25775,6 +27983,13 @@ __metadata: languageName: node linkType: hard +"next-tick@npm:^1.1.0": + version: 1.1.0 + resolution: "next-tick@npm:1.1.0" + checksum: 10/83b5cf36027a53ee6d8b7f9c0782f2ba87f4858d977342bfc3c20c21629290a2111f8374d13a81221179603ffc4364f38374b5655d17b6a8f8a8c77bdea4fe8b + languageName: node + linkType: hard + "next@npm:14.2.28": version: 14.2.28 resolution: "next@npm:14.2.28" @@ -26502,6 +28717,20 @@ __metadata: languageName: node linkType: hard +"outvariant@npm:1.4.0": + version: 1.4.0 + resolution: "outvariant@npm:1.4.0" + checksum: 10/07b9bcb9b3a2ff1b3db02af6b07d70e663082b30ddc08ff475d7c85fc623fdcc4433a4ab5b88f6902b62dbb284eef1be386aa537e14cef0519fad887ec483054 + languageName: node + linkType: hard + +"outvariant@npm:^1.3.0, outvariant@npm:^1.4.0": + version: 1.4.3 + resolution: "outvariant@npm:1.4.3" + checksum: 10/3a7582745850cb344d49641867a4c080858c54f4091afd91b9c0765ba6e471c2bc841348f0fff344845ddd0a4db42fd5d68c6f7ebaf32d4b676a3a9987b2488a + languageName: node + linkType: hard + "overlayscrollbars-react@npm:^0.5.6": version: 0.5.6 resolution: "overlayscrollbars-react@npm:0.5.6" @@ -28395,6 +30624,13 @@ __metadata: languageName: node linkType: hard +"prismjs@npm:^1.30.0": + version: 1.30.0 + resolution: "prismjs@npm:1.30.0" + checksum: 10/6b48a2439a82e5c6882f48ebc1564c3890e16463ba17ac10c3ad4f62d98dea5b5c915b172b63b83023a70ad4f5d7be3e8a60304420db34a161fae69dd4e3e2da + languageName: node + linkType: hard + "process-nextick-args@npm:~2.0.0": version: 2.0.1 resolution: "process-nextick-args@npm:2.0.1" @@ -28969,6 +31205,15 @@ __metadata: languageName: node linkType: hard +"react-devtools-inline@npm:4.4.0": + version: 4.4.0 + resolution: "react-devtools-inline@npm:4.4.0" + dependencies: + es6-symbol: "npm:^3" + checksum: 10/316a03bd21eb34f511e74e4e969e6a7d75d299800a4158ff59081457f024dc3aebc0c471938fd7e1c4676823fdcb546ca0d7c2d7ab74e34a9c1bdac31f2284b2 + languageName: node + linkType: hard + "react-dom@npm:^18.0.0, react-dom@npm:^18.3.1": version: 18.3.1 resolution: "react-dom@npm:18.3.1" @@ -28981,6 +31226,17 @@ __metadata: languageName: node linkType: hard +"react-error-boundary@npm:^3.1.4": + version: 3.1.4 + resolution: "react-error-boundary@npm:3.1.4" + dependencies: + "@babel/runtime": "npm:^7.12.5" + peerDependencies: + react: ">=16.13.1" + checksum: 10/7418637bf352b88f35ff3798e6faa094ee046df9d422fc08f54c017892c3c0738dac661ba3d64d97209464e7a60e7fbbeffdbeaee5edc38f3aaf5f1f4a8bf610 + languageName: node + linkType: hard + "react-error-boundary@npm:^4.1.2": version: 4.1.2 resolution: "react-error-boundary@npm:4.1.2" @@ -28999,6 +31255,15 @@ __metadata: languageName: node linkType: hard +"react-hook-form@npm:^7.56.1": + version: 7.62.0 + resolution: "react-hook-form@npm:7.62.0" + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + checksum: 10/092dcf0317ed3e314b124ed9df3f3494cf3447326078cd857f6fdc47aad0504e466ab2fb593bbb8e79c247b8772159f83aebe54a7e5799926b00d7e401d127a6 + languageName: node + linkType: hard + "react-i18next@npm:^15.4.1": version: 15.4.1 resolution: "react-i18next@npm:15.4.1" @@ -29047,7 +31312,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^17.0.1": +"react-is@npm:^17.0.1, react-is@npm:^17.0.2": version: 17.0.2 resolution: "react-is@npm:17.0.2" checksum: 10/73b36281e58eeb27c9cc6031301b6ae19ecdc9f18ae2d518bdb39b0ac564e65c5779405d623f1df9abf378a13858b79442480244bd579968afc1faf9a2ce5e05 @@ -29185,6 +31450,41 @@ __metadata: languageName: node linkType: hard +"react-remove-scroll-bar@npm:^2.3.7": + version: 2.3.8 + resolution: "react-remove-scroll-bar@npm:2.3.8" + dependencies: + react-style-singleton: "npm:^2.2.2" + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/6c0f8cff98b9f49a4ee2263f1eedf12926dced5ce220fbe83bd93544460e2a7ec8ec39b35d1b2a75d2fced0b2d64afeb8e66f830431ca896e05a20585f9fc350 + languageName: node + linkType: hard + +"react-remove-scroll@npm:^2.6.3": + version: 2.7.1 + resolution: "react-remove-scroll@npm:2.7.1" + dependencies: + react-remove-scroll-bar: "npm:^2.3.7" + react-style-singleton: "npm:^2.2.3" + tslib: "npm:^2.1.0" + use-callback-ref: "npm:^1.3.3" + use-sidecar: "npm:^1.1.3" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/5e571ba35ba527047c54c9c4a271363167770556fb85ee45ead8310673197719425cc8f7a2b7f672abf530294c41c8c34bdae325a571994cc1e694b664b52734 + languageName: node + linkType: hard + "react-router-dom@npm:^6.28.0": version: 6.28.0 resolution: "react-router-dom@npm:6.28.0" @@ -29316,6 +31616,22 @@ __metadata: languageName: node linkType: hard +"react-style-singleton@npm:^2.2.2, react-style-singleton@npm:^2.2.3": + version: 2.2.3 + resolution: "react-style-singleton@npm:2.2.3" + dependencies: + get-nonce: "npm:^1.0.0" + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/62498094ff3877a37f351b29e6cad9e38b2eb1ac3c0cb27ebf80aee96554f80b35e17bdb552bcd7ac8b7cb9904fea93ea5668f2057c73d38f90b5d46bb9b27ab + languageName: node + linkType: hard + "react-toastify@npm:^10.0.6": version: 10.0.6 resolution: "react-toastify@npm:10.0.6" @@ -31631,6 +33947,18 @@ __metadata: languageName: node linkType: hard +"static-browser-server@npm:1.0.3": + version: 1.0.3 + resolution: "static-browser-server@npm:1.0.3" + dependencies: + "@open-draft/deferred-promise": "npm:^2.1.0" + dotenv: "npm:^16.0.3" + mime-db: "npm:^1.52.0" + outvariant: "npm:^1.3.0" + checksum: 10/d047c6c8a667a054db23c3d9770cf5e9d558694f052be81886f606ccc1c6dab034eb1fc5b35d1e3bf23a8dc6ca6f9cd7e4349bfb7b5cad1c2af13058c32dea86 + languageName: node + linkType: hard + "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -31697,6 +34025,13 @@ __metadata: languageName: node linkType: hard +"strict-event-emitter@npm:^0.4.3": + version: 0.4.6 + resolution: "strict-event-emitter@npm:0.4.6" + checksum: 10/abdbf59b6c45b599cc2f227fa473765d1510d155ebd22533e8ecb06110dfacb2ff07aece7fd528dde2b4f9e379d60f2687eee8af3fa2877c3ed88ee5b7ed2707 + languageName: node + linkType: hard + "strict-uri-encode@npm:^2.0.0": version: 2.0.0 resolution: "strict-uri-encode@npm:2.0.0" @@ -32336,6 +34671,13 @@ __metadata: languageName: node linkType: hard +"tabbable@npm:^6.0.0": + version: 6.2.0 + resolution: "tabbable@npm:6.2.0" + checksum: 10/980fa73476026e99dcacfc0d6e000d41d42c8e670faf4682496d30c625495e412c4369694f2a15cf1e5252d22de3c396f2b62edbe8d60b5dadc40d09e3f2dde3 + languageName: node + linkType: hard + "table-layout@npm:^1.0.2": version: 1.0.2 resolution: "table-layout@npm:1.0.2" @@ -32962,7 +35304,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2, tslib@npm:^2.6.3, tslib@npm:^2.8.1": +"tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2, tslib@npm:^2.6.3, tslib@npm:^2.8.1": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10/3e2e043d5c2316461cb54e5c7fe02c30ef6dccb3384717ca22ae5c6b5bc95232a6241df19c622d9c73b809bea33b187f6dbc73030963e29950c2141bc32a79f7 @@ -33101,6 +35443,13 @@ __metadata: languageName: node linkType: hard +"type@npm:^2.7.2": + version: 2.7.3 + resolution: "type@npm:2.7.3" + checksum: 10/82e99e7795b3de3ecfe685680685e79a77aea515fad9f60b7c55fbf6d43a5c360b1e6e9443354ec8906b38cdf5325829c69f094cb7cd2a1238e85bef9026dc04 + languageName: node + linkType: hard + "typechain@npm:^8.3.2": version: 8.3.2 resolution: "typechain@npm:8.3.2" @@ -33445,6 +35794,15 @@ __metadata: languageName: node linkType: hard +"unidiff@npm:^1.0.2": + version: 1.0.4 + resolution: "unidiff@npm:1.0.4" + dependencies: + diff: "npm:^5.1.0" + checksum: 10/c0771d3107c79ef63446f34c9a3574df9889486fba4f9ce50c1beb51d441d1fbc42b84c9889af68a3806f60560633f1c26a81378b5469e00ec223c99fb238f27 + languageName: node + linkType: hard + "unified@npm:^10.0.0": version: 10.1.2 resolution: "unified@npm:10.1.2" @@ -33527,6 +35885,15 @@ __metadata: languageName: node linkType: hard +"unist-util-position-from-estree@npm:^2.0.0": + version: 2.0.0 + resolution: "unist-util-position-from-estree@npm:2.0.0" + dependencies: + "@types/unist": "npm:^3.0.0" + checksum: 10/d3b3048a5727c2367f64ef6dcc5b20c4717215ef8b1372ff9a7c426297c5d1e5776409938acd01531213e2cd2543218d16e73f9f862f318e9496e2c73bb18354 + languageName: node + linkType: hard + "unist-util-position@npm:^4.0.0": version: 4.0.4 resolution: "unist-util-position@npm:4.0.4" @@ -33801,6 +36168,37 @@ __metadata: languageName: node linkType: hard +"use-callback-ref@npm:^1.3.3": + version: 1.3.3 + resolution: "use-callback-ref@npm:1.3.3" + dependencies: + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/adf06a7b6a27d3651c325ac9b66d2b82ccacaed7450b85b211d123e91d9a23cb5a587fcc6db5b4fd07ac7233e5abf024d30cf02ddc2ec46bca712151c0836151 + languageName: node + linkType: hard + +"use-sidecar@npm:^1.1.3": + version: 1.1.3 + resolution: "use-sidecar@npm:1.1.3" + dependencies: + detect-node-es: "npm:^1.1.0" + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/2fec05eb851cdfc4a4657b1dfb434e686f346c3265ffc9db8a974bb58f8128bd4a708a3cc00e8f51655fccf81822ed4419ebed42f41610589e3aab0cf2492edb + languageName: node + linkType: hard + "use-sync-external-store@npm:1.2.0": version: 1.2.0 resolution: "use-sync-external-store@npm:1.2.0" @@ -33919,7 +36317,7 @@ __metadata: languageName: node linkType: hard -"uvu@npm:^0.5.0": +"uvu@npm:^0.5.0, uvu@npm:^0.5.6": version: 0.5.6 resolution: "uvu@npm:0.5.6" dependencies: From e7971b869e7f6d4d64d9549762e04cef72a42888 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Mon, 15 Sep 2025 19:28:49 +0900 Subject: [PATCH 02/13] fix: styling fixes, hack to make the text flicker appear --- web/package.json | 2 +- web/src/components/MarkdownEditor.tsx | 54 ++++++++++++++++++++------- yarn.lock | 4 +- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/web/package.json b/web/package.json index 35e5f6f29..67e989f72 100644 --- a/web/package.json +++ b/web/package.json @@ -91,7 +91,7 @@ "@kleros/ui-components-library": "^2.20.0", "@lifi/wallet-management": "^3.7.1", "@lifi/widget": "^3.18.1", - "@mdxeditor/editor": "^3.44.2", + "@mdxeditor/editor": "^3.45.0", "@reown/appkit": "^1.7.1", "@reown/appkit-adapter-wagmi": "^1.7.1", "@sentry/react": "^7.120.0", diff --git a/web/src/components/MarkdownEditor.tsx b/web/src/components/MarkdownEditor.tsx index 2a3fdb54e..3bc082c69 100644 --- a/web/src/components/MarkdownEditor.tsx +++ b/web/src/components/MarkdownEditor.tsx @@ -31,33 +31,47 @@ import InfoIcon from "svgs/icons/info-circle.svg"; const Container = styled.div<{ isEmpty: boolean }>` width: 100%; - [class*="mdxeditor"] { - background-color: ${({ theme }) => theme.whiteBackground} !important; + [class*="mdxeditor-toolbar"] { + background-color: ${({ theme }) => theme.lightGrey}; border: 1px solid ${({ theme }) => theme.stroke} !important; border-radius: 3px; font-family: "Open Sans", sans-serif; - } - [class*="toolbar"] { - background-color: ${({ theme }) => theme.lightGrey} !important; - border-bottom: none !important; + * svg { + color: ${({ theme }) => theme.primaryText} !important; + } - button { - color: ${({ theme }) => theme.whiteBackground} !important; + [class*="selectTrigger"] { + background-color: ${({ theme }) => theme.whiteBackground} !important; + color: ${({ theme }) => theme.primaryText} !important; + cursor: pointer !important; } - svg { - fill: ${({ theme }) => theme.whiteBackground} !important; + button:hover { + background-color: ${({ theme }) => theme.lightGrey}80 !important; + cursor: pointer; } - select { + button[data-state="on"], + button[aria-pressed="true"] { background-color: ${({ theme }) => theme.whiteBackground} !important; - color: ${({ theme }) => theme.primaryText} !important; + } + + button:disabled, + button[data-disabled="true"] { + opacity: 0.4 !important; + cursor: not-allowed !important; + + svg { + color: ${({ theme }) => theme.secondaryText} !important; + } } } [class*="contentEditable"] { background-color: ${({ theme }) => theme.whiteBackground} !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; + border-radius: 3px; color: ${({ theme }) => theme.primaryText} !important; min-height: 200px; padding: 16px; @@ -165,7 +179,19 @@ const MarkdownEditor: React.FC = ({ const editorRef = useRef(null); const handleChange = (markdown: string) => { - onChange(markdown); + const cleanedMarkdown = markdown === "\u200B" ? "" : markdown.replace(/^\u200B/, ""); + onChange(cleanedMarkdown); + }; + + const handleContainerClick = () => { + if (isEmpty && editorRef.current) { + editorRef.current.setMarkdown("\u200B"); + setTimeout(() => { + if (editorRef.current) { + editorRef.current.focus(); + } + }, 0); + } }; const isEmpty = !value || value.trim() === ""; @@ -204,7 +230,7 @@ const MarkdownEditor: React.FC = ({ }; return ( - + {showMessage && ( diff --git a/yarn.lock b/yarn.lock index ebb0d8076..216a85060 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6791,7 +6791,7 @@ __metadata: "@kleros/ui-components-library": "npm:^2.20.0" "@lifi/wallet-management": "npm:^3.7.1" "@lifi/widget": "npm:^3.18.1" - "@mdxeditor/editor": "npm:^3.44.2" + "@mdxeditor/editor": "npm:^3.45.0" "@reown/appkit": "npm:^1.7.1" "@reown/appkit-adapter-wagmi": "npm:^1.7.1" "@sentry/react": "npm:^7.120.0" @@ -7635,7 +7635,7 @@ __metadata: languageName: node linkType: hard -"@mdxeditor/editor@npm:^3.44.2": +"@mdxeditor/editor@npm:^3.45.0": version: 3.45.0 resolution: "@mdxeditor/editor@npm:3.45.0" dependencies: From d82188a59446ef23c03216238cb589f92fef63dc Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Tue, 16 Sep 2025 20:08:55 +0900 Subject: [PATCH 03/13] feat: style improvements --- web/src/components/MarkdownEditor.tsx | 138 +++----------- web/src/components/MarkdownRenderer.tsx | 160 +---------------- web/src/styles/mdxEditorTheme.ts | 230 ++++++++++++++++++++++++ web/src/utils/markdownSanitization.ts | 25 +++ web/src/utils/urlValidation.ts | 35 ++++ 5 files changed, 321 insertions(+), 267 deletions(-) create mode 100644 web/src/styles/mdxEditorTheme.ts create mode 100644 web/src/utils/markdownSanitization.ts create mode 100644 web/src/utils/urlValidation.ts diff --git a/web/src/components/MarkdownEditor.tsx b/web/src/components/MarkdownEditor.tsx index 3bc082c69..5080f69ba 100644 --- a/web/src/components/MarkdownEditor.tsx +++ b/web/src/components/MarkdownEditor.tsx @@ -24,113 +24,15 @@ import { Separator, } from "@mdxeditor/editor"; -import "@mdxeditor/editor/style.css"; - import InfoIcon from "svgs/icons/info-circle.svg"; -const Container = styled.div<{ isEmpty: boolean }>` - width: 100%; +import { sanitizeMarkdown } from "utils/markdownSanitization"; - [class*="mdxeditor-toolbar"] { - background-color: ${({ theme }) => theme.lightGrey}; - border: 1px solid ${({ theme }) => theme.stroke} !important; - border-radius: 3px; - font-family: "Open Sans", sans-serif; +import { MDXEditorContainer, MDXEditorGlobalStyles } from "styles/mdxEditorTheme"; - * svg { - color: ${({ theme }) => theme.primaryText} !important; - } - - [class*="selectTrigger"] { - background-color: ${({ theme }) => theme.whiteBackground} !important; - color: ${({ theme }) => theme.primaryText} !important; - cursor: pointer !important; - } - - button:hover { - background-color: ${({ theme }) => theme.lightGrey}80 !important; - cursor: pointer; - } - - button[data-state="on"], - button[aria-pressed="true"] { - background-color: ${({ theme }) => theme.whiteBackground} !important; - } - - button:disabled, - button[data-disabled="true"] { - opacity: 0.4 !important; - cursor: not-allowed !important; - - svg { - color: ${({ theme }) => theme.secondaryText} !important; - } - } - } - - [class*="contentEditable"] { - background-color: ${({ theme }) => theme.whiteBackground} !important; - border: 1px solid ${({ theme }) => theme.stroke} !important; - border-radius: 3px; - color: ${({ theme }) => theme.primaryText} !important; - min-height: 200px; - padding: 16px; - font-size: 16px; - line-height: 1.5; - - p { - color: ${({ theme, isEmpty }) => (isEmpty ? theme.secondaryText : theme.primaryText)} !important; - margin: 0 0 12px 0; - } - - p:empty::before { - color: ${({ theme }) => theme.secondaryText} !important; - opacity: 0.6 !important; - } - - h1, - h2, - h3, - h4, - h5, - h6 { - color: ${({ theme }) => theme.primaryText} !important; - font-weight: 600; - margin: 16px 0 8px 0; - } - - blockquote { - color: ${({ theme }) => theme.secondaryText} !important; - border-left: 3px solid ${({ theme }) => theme.mediumBlue} !important; - font-style: italic; - margin: 16px 0; - padding-left: 12px; - } - - code { - background-color: ${({ theme }) => theme.lightGrey} !important; - color: ${({ theme }) => theme.primaryText} !important; - } - - pre { - background-color: ${({ theme }) => theme.lightGrey} !important; - color: ${({ theme }) => theme.primaryText} !important; - } - - a { - color: ${({ theme }) => theme.primaryBlue} !important; - } - - th { - background-color: ${({ theme }) => theme.lightGrey} !important; - color: ${({ theme }) => theme.primaryText} !important; - } +import "@mdxeditor/editor/style.css"; - td { - color: ${({ theme }) => theme.primaryText} !important; - } - } -`; +const Container = styled(MDXEditorContainer)<{ isEmpty: boolean }>``; const MessageContainer = styled.div` display: flex; @@ -180,7 +82,8 @@ const MarkdownEditor: React.FC = ({ const handleChange = (markdown: string) => { const cleanedMarkdown = markdown === "\u200B" ? "" : markdown.replace(/^\u200B/, ""); - onChange(cleanedMarkdown); + const sanitizedMarkdown = sanitizeMarkdown(cleanedMarkdown); + onChange(sanitizedMarkdown); }; const handleContainerClick = () => { @@ -230,19 +133,22 @@ const MarkdownEditor: React.FC = ({ }; return ( - - - {showMessage && ( - - - - Please provide a comprehensive justification for your decision. Quality explanations are essential for the - parties involved and may be eligible for additional compensation in accordance with our justification - policy. - - - )} - + <> + + + + {showMessage && ( + + + + Please provide a comprehensive justification for your decision. Quality explanations are essential for the + parties involved and may be eligible for additional compensation in accordance with our justification + policy. + + + )} + + ); }; diff --git a/web/src/components/MarkdownRenderer.tsx b/web/src/components/MarkdownRenderer.tsx index 8df425279..1bfe2d0a4 100644 --- a/web/src/components/MarkdownRenderer.tsx +++ b/web/src/components/MarkdownRenderer.tsx @@ -1,5 +1,4 @@ import React from "react"; -import styled from "styled-components"; import { MDXEditor, @@ -13,154 +12,11 @@ import { tablePlugin, } from "@mdxeditor/editor"; -import "@mdxeditor/editor/style.css"; - -const Container = styled.div` - width: 100%; - - [class*="mdxeditor"] { - background: transparent !important; - border: none !important; - } - - [class*="toolbar"] { - display: none !important; - } - - [class*="contentEditable"] { - background: transparent !important; - border: none !important; - padding: 0 !important; - font-size: 16px; - line-height: 1.5; - - p { - margin: 0 0 12px 0; - color: ${({ theme }) => theme.primaryText} !important; - } - - p:last-child { - margin-bottom: 0; - } - - h1, - h2, - h3, - h4, - h5, - h6 { - margin: 16px 0 8px 0; - font-weight: 600; - color: ${({ theme }) => theme.primaryText} !important; - } - - h1 { - font-size: 24px; - } - h2 { - font-size: 20px; - } - h3 { - font-size: 18px; - } - h4 { - font-size: 16px; - } - h5 { - font-size: 14px; - } - h6 { - font-size: 12px; - } - - ul, - ol { - margin: 8px 0; - padding-left: 24px; - } - - li { - margin: 4px 0; - color: ${({ theme }) => theme.primaryText} !important; - } +import { sanitizeMarkdown } from "utils/markdownSanitization"; - blockquote { - border-left: 3px solid ${({ theme }) => theme.mediumBlue} !important; - padding-left: 12px; - margin: 16px 0; - color: ${({ theme }) => theme.secondaryText} !important; - font-style: italic; - } +import { MDXRendererContainer } from "styles/mdxEditorTheme"; - code { - background-color: ${({ theme }) => theme.lightGrey} !important; - color: ${({ theme }) => theme.primaryText} !important; - padding: 2px 4px; - border-radius: 3px; - font-family: "Monaco", "Consolas", monospace; - font-size: 14px; - } - - pre { - background-color: ${({ theme }) => theme.lightGrey} !important; - color: ${({ theme }) => theme.primaryText} !important; - padding: 12px; - border-radius: 3px; - overflow-x: auto; - margin: 16px 0; - } - - pre code { - background: transparent !important; - padding: 0; - } - - table { - border-collapse: collapse; - width: 100%; - margin: 16px 0; - } - - th, - td { - border: 1px solid ${({ theme }) => theme.stroke} !important; - padding: 8px 12px; - text-align: left; - color: ${({ theme }) => theme.primaryText} !important; - } - - th { - background-color: ${({ theme }) => theme.lightGrey} !important; - font-weight: 600; - } - - a { - color: ${({ theme }) => theme.primaryBlue} !important; - text-decoration: none; - } - - a:hover { - text-decoration: underline; - color: ${({ theme }) => theme.secondaryBlue} !important; - } - - hr { - border: none; - border-top: 1px solid ${({ theme }) => theme.stroke} !important; - margin: 24px 0; - } - - img { - max-width: 100%; - height: auto; - } - - * { - cursor: default !important; - user-select: text !important; - } - } -`; +import "@mdxeditor/editor/style.css"; interface IMarkdownRenderer { content: string; @@ -172,8 +28,10 @@ const MarkdownRenderer: React.FC = ({ content, className }) = return null; } + const sanitizedContent = sanitizeMarkdown(content); + const editorProps: MDXEditorProps = { - markdown: content, + markdown: sanitizedContent, readOnly: true, plugins: [ headingsPlugin(), @@ -187,9 +45,9 @@ const MarkdownRenderer: React.FC = ({ content, className }) = }; return ( - - - + + + ); }; diff --git a/web/src/styles/mdxEditorTheme.ts b/web/src/styles/mdxEditorTheme.ts new file mode 100644 index 000000000..16546c6a4 --- /dev/null +++ b/web/src/styles/mdxEditorTheme.ts @@ -0,0 +1,230 @@ +import styled, { createGlobalStyle, css } from "styled-components"; + +const sharedContentStyles = css` + .mdxeditor-root-contenteditable p { + color: ${({ theme }) => theme.primaryText} !important; + margin: 0 0 12px 0; + } + + .mdxeditor-root-contenteditable h1, + .mdxeditor-root-contenteditable h2, + .mdxeditor-root-contenteditable h3, + .mdxeditor-root-contenteditable h4, + .mdxeditor-root-contenteditable h5, + .mdxeditor-root-contenteditable h6 { + color: ${({ theme }) => theme.primaryText} !important; + font-weight: 600; + margin: 16px 0 8px 0; + } + + .mdxeditor-root-contenteditable blockquote { + color: ${({ theme }) => theme.primaryText} !important; + border-left: 3px solid ${({ theme }) => theme.mediumBlue} !important; + font-style: italic; + margin: 16px 0; + padding-left: 12px; + } + + .mdxeditor-root-contenteditable pre { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.primaryText} !important; + } + + .mdxeditor-root-contenteditable a { + color: ${({ theme }) => theme.primaryBlue} !important; + } + + .mdxeditor-root-contenteditable span[class*="_code_"] { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.secondaryText} !important; + padding: 2px 4px; + border-radius: 3px; + font-size: 0.9em; + } + + .mdxeditor-root-contenteditable th { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.primaryText} !important; + } + + .mdxeditor-root-contenteditable td { + color: ${({ theme }) => theme.primaryText} !important; + } +`; + +export const MDXEditorContainer = styled.div` + width: 100%; + + .mdxeditor-toolbar { + background-color: ${({ theme }) => theme.lightGrey} !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; + border-radius: 3px; + font-family: "Open Sans", sans-serif; + } + + .mdxeditor-toolbar button { + color: ${({ theme }) => theme.primaryText} !important; + } + + .mdxeditor-toolbar button:hover { + background-color: ${({ theme }) => theme.whiteBackground} !important; + cursor: pointer !important; + } + + .mdxeditor-toolbar button[data-state="on"], + .mdxeditor-toolbar button[aria-pressed="true"] { + background-color: ${({ theme }) => theme.whiteBackground} !important; + } + + .mdxeditor-toolbar button:disabled, + .mdxeditor-toolbar button[data-disabled="true"] { + opacity: 0.4 !important; + cursor: not-allowed !important; + } + + .mdxeditor-toolbar button svg { + color: ${({ theme }) => theme.primaryText} !important; + } + + .mdxeditor-toolbar button:disabled svg, + .mdxeditor-toolbar button[data-disabled="true"] svg { + color: ${({ theme }) => theme.secondaryText} !important; + } + + .mdxeditor-root-contenteditable { + background-color: ${({ theme }) => theme.whiteBackground} !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; + border-radius: 3px; + color: ${({ theme }) => theme.primaryText} !important; + height: 220px; + overflow-y: auto; + overflow-x: hidden; + padding: 16px; + font-size: 16px; + line-height: 1.5; + } + + [class*="placeholder"] { + color: ${({ theme }) => theme.secondaryText} !important; + opacity: 0.6 !important; + margin-top: 16px; + } + + ${sharedContentStyles} + + [class*="tableColumnEditorPopoverContent"], + [class*="addRowButton"], + [class*="addColumnButton"], + [class*="deleteRowButton"], + [class*="deleteColumnButton"], + [class*="tableEditor"], + [class*="tableToolbar"], + [class*="tablePopover"] { + background-color: ${({ theme }) => theme.whiteBackground} !important; + + svg, + path { + color: ${({ theme }) => theme.primaryText} !important; + } + } +`; + +export const MDXEditorGlobalStyles = createGlobalStyle` + /* Global styles for all MDXEditor popups and overlays */ + [class*="linkDialogPopoverContent"], + [class*="selectTrigger"], + [class*="selectContent"], + [class*="tableColumnEditorPopoverContent"], + [class*="tablePopover"], + [data-radix-popper-content-wrapper] [class*="linkDialog"], + [data-radix-popper-content-wrapper] [class*="select"], + [data-radix-popper-content-wrapper] [class*="table"], + [data-radix-portal] [class*="linkDialog"], + [data-radix-portal] [class*="select"], + [data-radix-portal] [class*="table"], + [data-radix-portal] div[class*="mdx"], + [data-radix-popper-content-wrapper] div[class*="mdx"] { + background-color: ${({ theme }) => theme.whiteBackground} !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; + color: ${({ theme }) => theme.primaryText} !important; + + input, + select { + background-color: ${({ theme }) => theme.whiteBackground} !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; + color: ${({ theme }) => theme.primaryText} !important; + + &:hover { + background-color: ${({ theme }) => theme.lightGrey} !important; + } + } + + button { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.primaryText} !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; + cursor: pointer !important; + transition: background-color 0.2s ease !important; + + &:hover { + background-color: ${({ theme }) => theme.lightBackground} !important; + } + + &:active { + background-color: ${({ theme }) => theme.stroke} !important; + } + } + + label, + span, + div { + color: ${({ theme }) => theme.primaryText} !important; + } + + svg, + path { + color: ${({ theme }) => theme.primaryText} !important; + } + } + + [class*="mdx"] button, + [class*="select"] button, + [class*="trigger"], + [role="button"], + [data-radix-portal] [role="button"], + [data-radix-popper-content-wrapper] [role="button"], + [data-radix-portal] [data-state], + [data-radix-popper-content-wrapper] [data-state] { + cursor: pointer !important; + transition: all 0.1s ease !important; + &:hover { + background-color: ${({ theme }) => theme.lightGrey} !important; + } + } +`; + +export const MDXRendererContainer = styled.div` + width: 100%; + + .mdxeditor-toolbar { + display: none !important; + } + + .mdxeditor-root-contenteditable { + background: transparent !important; + border: none !important; + padding: 0 !important; + font-size: 16px; + line-height: 1.5; + } + + .mdxeditor-root-contenteditable span[class*="_code_"] { + background-color: ${({ theme }) => theme.lightGrey} !important; + color: ${({ theme }) => theme.secondaryText} !important; + padding: 2px 4px; + border-radius: 3px; + font-size: 0.9em; + } + + ${sharedContentStyles} +`; diff --git a/web/src/utils/markdownSanitization.ts b/web/src/utils/markdownSanitization.ts new file mode 100644 index 000000000..39df8da58 --- /dev/null +++ b/web/src/utils/markdownSanitization.ts @@ -0,0 +1,25 @@ +import { sanitizeUrl } from "./urlValidation"; + +export const sanitizeMarkdown = (markdown: string): string => { + if (!markdown || typeof markdown !== "string") { + return ""; + } + + return markdown + .replace(/\[([^\]]*)\]\(([^)]+)\)/g, (match, text, url) => { + const sanitizedUrl = sanitizeUrl(url); + return `[${text}](${sanitizedUrl})`; + }) + .replace(/]*>([^<]*)<\/a>/gi, (match, url, text) => { + const sanitizedUrl = sanitizeUrl(url); + return `[${text}](${sanitizedUrl})`; + }) + .replace(/]*>.*?<\/script>/gis, "") + .replace(/]*>.*?<\/iframe>/gis, "") + .replace(/]*>.*?<\/object>/gis, "") + .replace(/]*\/?>/gi, "") + .replace(/javascript:/gi, "") + .replace(/vbscript:/gi, "") + .replace(/data:/gi, "") + .replace(/on\w+\s*=/gi, ""); +}; diff --git a/web/src/utils/urlValidation.ts b/web/src/utils/urlValidation.ts new file mode 100644 index 000000000..641490e82 --- /dev/null +++ b/web/src/utils/urlValidation.ts @@ -0,0 +1,35 @@ +const DANGEROUS_PROTOCOLS = ["javascript:", "data:", "vbscript:", "file:", "about:"]; + +const ALLOWED_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"]; + +export const isValidUrl = (url: string): boolean => { + if (!url || typeof url !== "string") { + return false; + } + + const trimmedUrl = url.trim().toLowerCase(); + + if (trimmedUrl.length === 0) { + return false; + } + + for (const protocol of DANGEROUS_PROTOCOLS) { + if (trimmedUrl.startsWith(protocol)) { + return false; + } + } + + try { + const urlObj = new URL(url); + return ALLOWED_PROTOCOLS.includes(urlObj.protocol); + } catch { + return false; + } +}; + +export const sanitizeUrl = (url: string): string => { + if (!isValidUrl(url)) { + return "#"; + } + return url; +}; From e1a3d053495048ca49c0a535c74a9d6c5f898bd2 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Wed, 17 Sep 2025 01:51:12 +0900 Subject: [PATCH 04/13] chore: comments from ai reviews --- .../FileViewer/Viewers/MarkdownViewer.tsx | 23 ++----- web/src/components/MarkdownEditor.tsx | 6 +- web/src/components/MarkdownRenderer.tsx | 8 ++- web/src/utils/markdownSanitization.ts | 66 ++++++++++++++----- web/src/utils/urlValidation.ts | 20 +++++- 5 files changed, 87 insertions(+), 36 deletions(-) diff --git a/web/src/components/FileViewer/Viewers/MarkdownViewer.tsx b/web/src/components/FileViewer/Viewers/MarkdownViewer.tsx index 0ee77ac37..e7cc14079 100644 --- a/web/src/components/FileViewer/Viewers/MarkdownViewer.tsx +++ b/web/src/components/FileViewer/Viewers/MarkdownViewer.tsx @@ -2,23 +2,14 @@ import React from "react"; import styled from "styled-components"; import { type DocRenderer } from "@cyntler/react-doc-viewer"; -import ReactMarkdown from "react-markdown"; + +import MarkdownRenderer from "../../MarkdownRenderer"; const Container = styled.div` padding: 16px; `; -const StyledMarkdown = styled(ReactMarkdown)` - background-color: ${({ theme }) => theme.whiteBackground}; - a { - font-size: 16px; - } - code { - color: ${({ theme }) => theme.secondaryText}; - } -`; - -const MarkdownRenderer: DocRenderer = ({ mainState: { currentDocument } }) => { +const MarkdownDocRenderer: DocRenderer = ({ mainState: { currentDocument } }) => { if (!currentDocument) return null; const base64String = (currentDocument.fileData as string).split(",")[1]; @@ -27,12 +18,12 @@ const MarkdownRenderer: DocRenderer = ({ mainState: { currentDocument } }) => { return ( - {decodedData} + ); }; -MarkdownRenderer.fileTypes = ["md", "text/plain"]; -MarkdownRenderer.weight = 1; +MarkdownDocRenderer.fileTypes = ["md", "text/plain"]; +MarkdownDocRenderer.weight = 1; -export default MarkdownRenderer; +export default MarkdownDocRenderer; diff --git a/web/src/components/MarkdownEditor.tsx b/web/src/components/MarkdownEditor.tsx index 5080f69ba..002dd0aa2 100644 --- a/web/src/components/MarkdownEditor.tsx +++ b/web/src/components/MarkdownEditor.tsx @@ -27,6 +27,7 @@ import { import InfoIcon from "svgs/icons/info-circle.svg"; import { sanitizeMarkdown } from "utils/markdownSanitization"; +import { isValidUrl } from "utils/urlValidation"; import { MDXEditorContainer, MDXEditorGlobalStyles } from "styles/mdxEditorTheme"; @@ -103,13 +104,16 @@ const MarkdownEditor: React.FC = ({ markdown: value, onChange: handleChange, placeholder, + suppressHtmlProcessing: true, plugins: [ headingsPlugin(), listsPlugin(), quotePlugin(), thematicBreakPlugin(), markdownShortcutPlugin(), - linkPlugin(), + linkPlugin({ + validateUrl: (url) => isValidUrl(url), + }), linkDialogPlugin(), tablePlugin(), toolbarPlugin({ diff --git a/web/src/components/MarkdownRenderer.tsx b/web/src/components/MarkdownRenderer.tsx index 1bfe2d0a4..6ddcbe97e 100644 --- a/web/src/components/MarkdownRenderer.tsx +++ b/web/src/components/MarkdownRenderer.tsx @@ -10,9 +10,11 @@ import { markdownShortcutPlugin, linkPlugin, tablePlugin, + codeBlockPlugin, } from "@mdxeditor/editor"; import { sanitizeMarkdown } from "utils/markdownSanitization"; +import { isValidUrl } from "utils/urlValidation"; import { MDXRendererContainer } from "styles/mdxEditorTheme"; @@ -33,14 +35,18 @@ const MarkdownRenderer: React.FC = ({ content, className }) = const editorProps: MDXEditorProps = { markdown: sanitizedContent, readOnly: true, + suppressHtmlProcessing: true, plugins: [ headingsPlugin(), listsPlugin(), quotePlugin(), thematicBreakPlugin(), markdownShortcutPlugin(), - linkPlugin(), + linkPlugin({ + validateUrl: (url) => isValidUrl(url), + }), tablePlugin(), + codeBlockPlugin({ defaultCodeBlockLanguage: "text" }), ], }; diff --git a/web/src/utils/markdownSanitization.ts b/web/src/utils/markdownSanitization.ts index 39df8da58..36178a2d7 100644 --- a/web/src/utils/markdownSanitization.ts +++ b/web/src/utils/markdownSanitization.ts @@ -1,25 +1,57 @@ import { sanitizeUrl } from "./urlValidation"; +const sanitizeRepeated = (text: string, pattern: RegExp, replacement: string): string => { + let result = text; + let previousResult; + do { + previousResult = result; + result = result.replace(pattern, replacement); + } while (result !== previousResult); + return result; +}; + export const sanitizeMarkdown = (markdown: string): string => { if (!markdown || typeof markdown !== "string") { return ""; } - return markdown - .replace(/\[([^\]]*)\]\(([^)]+)\)/g, (match, text, url) => { - const sanitizedUrl = sanitizeUrl(url); - return `[${text}](${sanitizedUrl})`; - }) - .replace(/]*>([^<]*)<\/a>/gi, (match, url, text) => { - const sanitizedUrl = sanitizeUrl(url); - return `[${text}](${sanitizedUrl})`; - }) - .replace(/]*>.*?<\/script>/gis, "") - .replace(/]*>.*?<\/iframe>/gis, "") - .replace(/]*>.*?<\/object>/gis, "") - .replace(/]*\/?>/gi, "") - .replace(/javascript:/gi, "") - .replace(/vbscript:/gi, "") - .replace(/data:/gi, "") - .replace(/on\w+\s*=/gi, ""); + let sanitized = markdown; + + sanitized = sanitized.replace(/\[([^\]]*)\]\(([^)]+)\)/g, (match, text, url) => { + const sanitizedUrl = sanitizeUrl(url); + return `[${text}](${sanitizedUrl})`; + }); + + sanitized = sanitized.replace(/]*>([^<]*)<\/a>/gi, (match, url, text) => { + const sanitizedUrl = sanitizeUrl(url); + return `[${text}](${sanitizedUrl})`; + }); + + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/script>/gis, ""); + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/iframe>/gis, ""); + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/object>/gis, ""); + sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/form>/gis, ""); + sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/button>/gis, ""); + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/applet>/gis, ""); + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/audio>/gis, ""); + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/video>/gis, ""); + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/svg>/gis, ""); + sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/canvas>/gis, ""); + + sanitized = sanitizeRepeated(sanitized, /javascript:/gi, ""); + sanitized = sanitizeRepeated(sanitized, /vbscript:/gi, ""); + + sanitized = sanitizeRepeated(sanitized, /on\w+\s*=/gi, ""); + sanitized = sanitizeRepeated(sanitized, /style\s*=/gi, ""); + + sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); + sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); + sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); + + sanitized = sanitized.replace(/&#x[0-9a-f]+;/gi, ""); + sanitized = sanitized.replace(/&#[0-9]+;/gi, ""); + + return sanitized; }; diff --git a/web/src/utils/urlValidation.ts b/web/src/utils/urlValidation.ts index 641490e82..115f5bef8 100644 --- a/web/src/utils/urlValidation.ts +++ b/web/src/utils/urlValidation.ts @@ -1,7 +1,21 @@ -const DANGEROUS_PROTOCOLS = ["javascript:", "data:", "vbscript:", "file:", "about:"]; +const DANGEROUS_PROTOCOLS = ["javascript:", "vbscript:", "file:", "about:", "blob:", "filesystem:"]; const ALLOWED_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"]; +const ALLOWED_DATA_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"]; + +const isValidDataUri = (url: string): boolean => { + const dataUriRegex = /^data:([^;,]+)(;base64)?,/i; + const match = url.match(dataUriRegex); + + if (!match) { + return false; + } + + const mimeType = match[1].toLowerCase(); + return ALLOWED_DATA_TYPES.includes(mimeType); +}; + export const isValidUrl = (url: string): boolean => { if (!url || typeof url !== "string") { return false; @@ -13,6 +27,10 @@ export const isValidUrl = (url: string): boolean => { return false; } + if (trimmedUrl.startsWith("data:")) { + return isValidDataUri(trimmedUrl); + } + for (const protocol of DANGEROUS_PROTOCOLS) { if (trimmedUrl.startsWith(protocol)) { return false; From 9d4b2868dd2bf13338efa0b1f013268f8cca7186 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Wed, 17 Sep 2025 03:06:19 +0900 Subject: [PATCH 05/13] feat: link popup warning, clean up codes --- web/src/components/ExternalLinkWarning.tsx | 168 +++++++++++++++++++++ web/src/components/MarkdownRenderer.tsx | 93 +++++++++++- web/src/utils/linkUtils.ts | 28 ++++ 3 files changed, 281 insertions(+), 8 deletions(-) create mode 100644 web/src/components/ExternalLinkWarning.tsx create mode 100644 web/src/utils/linkUtils.ts diff --git a/web/src/components/ExternalLinkWarning.tsx b/web/src/components/ExternalLinkWarning.tsx new file mode 100644 index 000000000..96efe70c6 --- /dev/null +++ b/web/src/components/ExternalLinkWarning.tsx @@ -0,0 +1,168 @@ +import React from "react"; +import styled, { css } from "styled-components"; + +import Modal from "react-modal"; + +import { Button } from "@kleros/ui-components-library"; + +import WarningIcon from "svgs/icons/warning-outline.svg"; + +import { landscapeStyle } from "styles/landscapeStyle"; + +const StyledModal = styled(Modal)` + position: absolute; + top: 50%; + left: 50%; + right: auto; + bottom: auto; + margin-right: -50%; + transform: translate(-50%, -50%); + height: auto; + width: min(90%, 480px); + border: 1px solid ${({ theme }) => theme.stroke}; + border-radius: 8px; + background-color: ${({ theme }) => theme.whiteBackground}; + padding: 32px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); + z-index: 10002; +`; + +const Overlay = styled.div` + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + z-index: 10001; +`; + +const Header = styled.div` + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 16px; +`; + +const StyledWarningIcon = styled(WarningIcon)` + width: 24px; + height: 24px; + fill: ${({ theme }) => theme.warning}; +`; + +const Title = styled.h3` + color: ${({ theme }) => theme.primaryText}; + font-size: 18px; + font-weight: 600; + margin: 0; +`; + +const Message = styled.p` + color: ${({ theme }) => theme.primaryText}; + font-size: 14px; + line-height: 1.5; + margin: 0 0 16px 0; +`; + +const UrlContainer = styled.div` + background-color: ${({ theme }) => theme.lightGrey}; + border: 1px solid ${({ theme }) => theme.stroke}; + border-radius: 4px; + padding: 12px; + margin: 16px 0; + word-break: break-all; +`; + +const Url = styled.code` + color: ${({ theme }) => theme.secondaryText}; + font-size: 13px; + font-family: monospace; +`; + +const ButtonContainer = styled.div` + display: flex; + gap: 12px; + justify-content: center; + flex-wrap: wrap; + margin-top: 24px; + + ${landscapeStyle( + () => css` + justify-content: flex-end; + ` + )} +`; + +const CancelButton = styled(Button)` + background-color: ${({ theme }) => theme.whiteBackground}; + border: 1px solid ${({ theme }) => theme.stroke}; + + p { + color: ${({ theme }) => theme.primaryText} !important; + } + + &:hover { + background-color: ${({ theme }) => theme.mediumBlue}; + } +`; + +const ConfirmButton = styled(Button)` + background-color: ${({ theme }) => theme.warning}; + color: ${({ theme }) => theme.whiteBackground}; + border: 1px solid ${({ theme }) => theme.warning}; + + &:hover { + background-color: ${({ theme }) => theme.warning}BB; + } +`; + +interface IExternalLinkWarning { + isOpen: boolean; + url: string; + onConfirm: () => void; + onCancel: () => void; +} + +const ExternalLinkWarning: React.FC = ({ isOpen, url, onConfirm, onCancel }) => { + return ( + {contentElement}} + ariaHideApp={false} + role="dialog" + aria-labelledby="external-link-title" + aria-describedby="external-link-description" + > +
+ + External Link Warning +
+ + + You are about to navigate to an external website. Please verify the URL before proceeding to ensure it's + safe and legitimate. + + + + {url} + + + + Safety Tips: +
+ • Verify the domain name is correct +
+ • Check for suspicious characters or typos +
• Only proceed if you trust this destination +
+ + + + + +
+ ); +}; + +export default ExternalLinkWarning; diff --git a/web/src/components/MarkdownRenderer.tsx b/web/src/components/MarkdownRenderer.tsx index 6ddcbe97e..b885acce5 100644 --- a/web/src/components/MarkdownRenderer.tsx +++ b/web/src/components/MarkdownRenderer.tsx @@ -1,4 +1,5 @@ -import React from "react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; +import styled from "styled-components"; import { MDXEditor, @@ -13,11 +14,33 @@ import { codeBlockPlugin, } from "@mdxeditor/editor"; +import { isExternalLink } from "utils/linkUtils"; import { sanitizeMarkdown } from "utils/markdownSanitization"; import { isValidUrl } from "utils/urlValidation"; import { MDXRendererContainer } from "styles/mdxEditorTheme"; +import ExternalLinkWarning from "components/ExternalLinkWarning"; + +const LinkInterceptorContainer = styled(MDXRendererContainer)` + a { + pointer-events: none; + cursor: pointer; + position: relative; + + &::after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: auto; + cursor: pointer; + } + } +`; + import "@mdxeditor/editor/style.css"; interface IMarkdownRenderer { @@ -26,6 +49,54 @@ interface IMarkdownRenderer { } const MarkdownRenderer: React.FC = ({ content, className }) => { + const [isWarningOpen, setIsWarningOpen] = useState(false); + const [pendingUrl, setPendingUrl] = useState(""); + const containerRef = useRef(null); + + const handleExternalLink = useCallback((url: string) => { + setPendingUrl(url); + setIsWarningOpen(true); + }, []); + + const handleConfirmNavigation = useCallback(() => { + if (pendingUrl) { + window.open(pendingUrl, "_blank", "noopener,noreferrer"); + } + setIsWarningOpen(false); + setPendingUrl(""); + }, [pendingUrl]); + + const handleCancelNavigation = useCallback(() => { + setIsWarningOpen(false); + setPendingUrl(""); + }, []); + + useEffect(() => { + const container = containerRef.current; + if (!container) return; + + const handleClick = (event: Event) => { + const linkElement = (event.target as HTMLElement).closest("a") as HTMLAnchorElement | null; + + if (linkElement) { + const href = linkElement.getAttribute("href") || linkElement.href; + if (href && isValidUrl(href) && isExternalLink(href)) { + event.preventDefault(); + event.stopImmediatePropagation(); + handleExternalLink(href); + } + } + }; + + container.addEventListener("click", handleClick, true); + document.addEventListener("click", handleClick, true); + + return () => { + container.removeEventListener("click", handleClick, true); + document.removeEventListener("click", handleClick, true); + }; + }, [handleExternalLink]); + if (!content || content.trim() === "") { return null; } @@ -35,25 +106,31 @@ const MarkdownRenderer: React.FC = ({ content, className }) = const editorProps: MDXEditorProps = { markdown: sanitizedContent, readOnly: true, - suppressHtmlProcessing: true, + suppressHtmlProcessing: false, plugins: [ headingsPlugin(), listsPlugin(), quotePlugin(), thematicBreakPlugin(), markdownShortcutPlugin(), - linkPlugin({ - validateUrl: (url) => isValidUrl(url), - }), + linkPlugin({ validateUrl: isValidUrl }), tablePlugin(), codeBlockPlugin({ defaultCodeBlockLanguage: "text" }), ], }; return ( - - - + <> + + + + + ); }; diff --git a/web/src/utils/linkUtils.ts b/web/src/utils/linkUtils.ts new file mode 100644 index 000000000..e926d70f0 --- /dev/null +++ b/web/src/utils/linkUtils.ts @@ -0,0 +1,28 @@ +export const isExternalLink = (url: string): boolean => { + if (!url || typeof url !== "string") { + return false; + } + + const trimmedUrl = url.trim(); + + if (trimmedUrl.startsWith("/") || trimmedUrl.startsWith("./") || trimmedUrl.startsWith("../")) { + return false; + } + + if (trimmedUrl.startsWith("#")) { + return false; + } + + if (trimmedUrl.startsWith("mailto:") || trimmedUrl.startsWith("tel:")) { + return true; + } + + try { + const currentOrigin = window.location.origin; + const linkUrl = new URL(trimmedUrl, currentOrigin); + + return linkUrl.origin !== currentOrigin; + } catch { + return true; + } +}; From e3dc195c367f64c3680383ce6a8d31dbbdeaa1da Mon Sep 17 00:00:00 2001 From: Marino <102478601+kemuru@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:28:42 +0900 Subject: [PATCH 06/13] Potential fix for code scanning alert no. 96: Bad HTML filtering regexp Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- web/package.json | 4 ++- web/src/utils/markdownSanitization.ts | 41 +++++++++++++-------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/web/package.json b/web/package.json index 67e989f72..51a386fd2 100644 --- a/web/package.json +++ b/web/package.json @@ -131,6 +131,8 @@ "styled-components": "^5.3.3", "subgraph-status": "^1.2.4", "viem": "^2.24.1", - "wagmi": "^2.14.15" + "wagmi": "^2.14.15", + "dompurify": "^3.2.6", + "@types/dompurify": "^3.2.0" } } diff --git a/web/src/utils/markdownSanitization.ts b/web/src/utils/markdownSanitization.ts index 36178a2d7..d8e5d1cd0 100644 --- a/web/src/utils/markdownSanitization.ts +++ b/web/src/utils/markdownSanitization.ts @@ -1,4 +1,5 @@ import { sanitizeUrl } from "./urlValidation"; +import DOMPurify from "dompurify"; const sanitizeRepeated = (text: string, pattern: RegExp, replacement: string): string => { let result = text; @@ -27,29 +28,25 @@ export const sanitizeMarkdown = (markdown: string): string => { return `[${text}](${sanitizedUrl})`; }); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/script>/gis, ""); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/iframe>/gis, ""); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/object>/gis, ""); - sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/form>/gis, ""); - sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/button>/gis, ""); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/applet>/gis, ""); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/audio>/gis, ""); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/video>/gis, ""); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/svg>/gis, ""); - sanitized = sanitizeRepeated(sanitized, /]*>.*?<\/canvas>/gis, ""); - - sanitized = sanitizeRepeated(sanitized, /javascript:/gi, ""); - sanitized = sanitizeRepeated(sanitized, /vbscript:/gi, ""); - - sanitized = sanitizeRepeated(sanitized, /on\w+\s*=/gi, ""); - sanitized = sanitizeRepeated(sanitized, /style\s*=/gi, ""); - - sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); - sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); - sanitized = sanitizeRepeated(sanitized, /]*\/?>/gi, ""); + // Use DOMPurify to sanitize dangerous HTML tags and attributes + sanitized = DOMPurify.sanitize(sanitized, { + ALLOWED_TAGS: [ + // Allow only safe tags that are valid in Markdown output; + // Configure to disallow script, iframe, object, embed, form, input, button, applet, audio, video, svg, canvas, meta, link, base + "b", "i", "em", "strong", "a", "p", "ul", "ol", "li", "blockquote", "code", "pre", "span", "br", "hr", "img" + ], + ALLOWED_ATTR: ["href", "src", "alt", "title"], // No style, no event handlers + FORBID_TAGS: [ + "script", "iframe", "object", "embed", "form", "input", "button", "applet", "audio", "video", "svg", "canvas", "meta", "link", "base" + ], + FORBID_ATTR: [ + "onerror", "onload", "onclick", "style" + ] + }); + // Optional: Remove encoded protocols/entities as before + sanitized = sanitized.replace(/javascript:/gi, ""); + sanitized = sanitized.replace(/vbscript:/gi, ""); sanitized = sanitized.replace(/&#x[0-9a-f]+;/gi, ""); sanitized = sanitized.replace(/&#[0-9]+;/gi, ""); From 942fa9e0e08c62674246cea64fbc1f36e004d52a Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:05:06 +0900 Subject: [PATCH 07/13] chore: dompurify in packagejson --- web/package.json | 6 +++--- yarn.lock | 25 ++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/web/package.json b/web/package.json index 51a386fd2..7dc2aeb14 100644 --- a/web/package.json +++ b/web/package.json @@ -100,6 +100,7 @@ "@solana/wallet-adapter-react": "^0.15.36", "@solana/web3.js": "^1.98.0", "@tanstack/react-query": "^5.69.0", + "@types/dompurify": "^3.2.0", "@types/react-modal": "^3.16.3", "@wagmi/connectors": "^5.7.11", "@wagmi/core": "^2.16.7", @@ -108,6 +109,7 @@ "chartjs-adapter-moment": "^1.0.1", "chartjs-plugin-datalabels": "^2.2.0", "core-js": "^3.39.0", + "dompurify": "^3.2.6", "ethers": "^5.8.0", "graphql": "^16.9.0", "graphql-request": "^7.1.2", @@ -131,8 +133,6 @@ "styled-components": "^5.3.3", "subgraph-status": "^1.2.4", "viem": "^2.24.1", - "wagmi": "^2.14.15", - "dompurify": "^3.2.6", - "@types/dompurify": "^3.2.0" + "wagmi": "^2.14.15" } } diff --git a/yarn.lock b/yarn.lock index 216a85060..9d8559478 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6801,6 +6801,7 @@ __metadata: "@solana/web3.js": "npm:^1.98.0" "@tanstack/react-query": "npm:^5.69.0" "@types/busboy": "npm:^1.5.4" + "@types/dompurify": "npm:^3.2.0" "@types/react": "npm:^18.3.12" "@types/react-dom": "npm:^18.3.1" "@types/react-modal": "npm:^3.16.3" @@ -6816,6 +6817,7 @@ __metadata: chartjs-adapter-moment: "npm:^1.0.1" chartjs-plugin-datalabels: "npm:^2.2.0" core-js: "npm:^3.39.0" + dompurify: "npm:^3.2.6" eslint: "npm:^9.15.0" eslint-config-prettier: "npm:^9.1.0" eslint-import-resolver-typescript: "npm:^3.6.3" @@ -11750,6 +11752,15 @@ __metadata: languageName: node linkType: hard +"@types/dompurify@npm:^3.2.0": + version: 3.2.0 + resolution: "@types/dompurify@npm:3.2.0" + dependencies: + dompurify: "npm:*" + checksum: 10/0194dd9024e76e856f3373e8b080c7a5ac9910543ac1ee85db45277efbbea820b2f27fe22c8a6f02bb51833e0a8540d732be0d11d156efd16cb0b97f88e41ebf + languageName: node + linkType: hard + "@types/eslint-scope@npm:^3.7.3": version: 3.7.4 resolution: "@types/eslint-scope@npm:3.7.4" @@ -12291,7 +12302,7 @@ __metadata: languageName: node linkType: hard -"@types/trusted-types@npm:*, @types/trusted-types@npm:^2.0.2": +"@types/trusted-types@npm:*, @types/trusted-types@npm:^2.0.2, @types/trusted-types@npm:^2.0.7": version: 2.0.7 resolution: "@types/trusted-types@npm:2.0.7" checksum: 10/8e4202766a65877efcf5d5a41b7dd458480b36195e580a3b1085ad21e948bc417d55d6f8af1fd2a7ad008015d4117d5fdfe432731157da3c68678487174e4ba3 @@ -18413,6 +18424,18 @@ __metadata: languageName: node linkType: hard +"dompurify@npm:*, dompurify@npm:^3.2.6": + version: 3.2.6 + resolution: "dompurify@npm:3.2.6" + dependencies: + "@types/trusted-types": "npm:^2.0.7" + dependenciesMeta: + "@types/trusted-types": + optional: true + checksum: 10/b91631ed0e4d17fae950ef53613cc009ed7e73adc43ac94a41dd52f35483f7538d13caebdafa7626e0da145fc8184e7ac7935f14f25b7e841b32fda777e40447 + languageName: node + linkType: hard + "dompurify@npm:2.5.7": version: 2.5.7 resolution: "dompurify@npm:2.5.7" From 20ae3a4188784edd4b3cc9aaed1887b040b241a7 Mon Sep 17 00:00:00 2001 From: Marino <102478601+kemuru@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:06:24 +0900 Subject: [PATCH 08/13] Potential fix for code scanning alert no. 97: Incomplete URL scheme check Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- web/src/utils/markdownSanitization.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/utils/markdownSanitization.ts b/web/src/utils/markdownSanitization.ts index d8e5d1cd0..6e21f8eda 100644 --- a/web/src/utils/markdownSanitization.ts +++ b/web/src/utils/markdownSanitization.ts @@ -47,6 +47,7 @@ export const sanitizeMarkdown = (markdown: string): string => { // Optional: Remove encoded protocols/entities as before sanitized = sanitized.replace(/javascript:/gi, ""); sanitized = sanitized.replace(/vbscript:/gi, ""); + sanitized = sanitized.replace(/data:/gi, ""); sanitized = sanitized.replace(/&#x[0-9a-f]+;/gi, ""); sanitized = sanitized.replace(/&#[0-9]+;/gi, ""); From e2d7c8157b4a4d1858cbdc4102f8c1599cbb0e24 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Wed, 17 Sep 2025 15:21:19 +0900 Subject: [PATCH 09/13] feat: max height and scrollable on mobile --- web/src/components/ExternalLinkWarning.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/src/components/ExternalLinkWarning.tsx b/web/src/components/ExternalLinkWarning.tsx index 96efe70c6..ce2373dab 100644 --- a/web/src/components/ExternalLinkWarning.tsx +++ b/web/src/components/ExternalLinkWarning.tsx @@ -18,6 +18,7 @@ const StyledModal = styled(Modal)` margin-right: -50%; transform: translate(-50%, -50%); height: auto; + max-height: 90vh; width: min(90%, 480px); border: 1px solid ${({ theme }) => theme.stroke}; border-radius: 8px; @@ -25,6 +26,7 @@ const StyledModal = styled(Modal)` padding: 32px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); z-index: 10002; + overflow-y: auto; `; const Overlay = styled.div` From 859834bc091787764d46c396e1ea33f2e563442c Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:12:07 +0900 Subject: [PATCH 10/13] feat: switch to reactmarkdown, remark gfm, rehype raw and rehype sanitize --- web/package.json | 5 +- .../DisputePreview/DisputeContext.tsx | 17 +- web/src/components/MarkdownEditor.tsx | 23 +- web/src/components/MarkdownRenderer.tsx | 351 ++++++++++++-- web/src/components/ReactMarkdown.tsx | 16 - .../CaseDetails/Voting/Classic/Reveal.tsx | 10 +- .../CaseDetails/Voting/OptionsContainer.tsx | 4 +- .../CaseDetails/Voting/VotingHistory.tsx | 14 +- .../pages/Courts/CourtDetails/Description.tsx | 7 +- .../pages/Resolver/Briefing/Description.tsx | 25 +- web/src/styles/mdxEditorTheme.ts | 86 ++-- web/src/utils/markdownSanitization.ts | 55 --- web/src/utils/urlValidation.ts | 7 - yarn.lock | 448 ++++++++++++++++-- 14 files changed, 826 insertions(+), 242 deletions(-) delete mode 100644 web/src/components/ReactMarkdown.tsx delete mode 100644 web/src/utils/markdownSanitization.ts diff --git a/web/package.json b/web/package.json index 7dc2aeb14..d17e27f70 100644 --- a/web/package.json +++ b/web/package.json @@ -100,7 +100,6 @@ "@solana/wallet-adapter-react": "^0.15.36", "@solana/web3.js": "^1.98.0", "@tanstack/react-query": "^5.69.0", - "@types/dompurify": "^3.2.0", "@types/react-modal": "^3.16.3", "@wagmi/connectors": "^5.7.11", "@wagmi/core": "^2.16.7", @@ -109,7 +108,6 @@ "chartjs-adapter-moment": "^1.0.1", "chartjs-plugin-datalabels": "^2.2.0", "core-js": "^3.39.0", - "dompurify": "^3.2.6", "ethers": "^5.8.0", "graphql": "^16.9.0", "graphql-request": "^7.1.2", @@ -130,6 +128,9 @@ "react-scripts": "^5.0.1", "react-toastify": "^9.1.3", "react-use": "^17.5.1", + "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", + "remark-gfm": "^3.0.1", "styled-components": "^5.3.3", "subgraph-status": "^1.2.4", "viem": "^2.24.1", diff --git a/web/src/components/DisputePreview/DisputeContext.tsx b/web/src/components/DisputePreview/DisputeContext.tsx index 435bc47a8..70111de69 100644 --- a/web/src/components/DisputePreview/DisputeContext.tsx +++ b/web/src/components/DisputePreview/DisputeContext.tsx @@ -1,26 +1,27 @@ import React, { useMemo } from "react"; import styled from "styled-components"; -import { DisputeDetails } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsTypes"; import { useAccount } from "wagmi"; +import { DisputeDetails } from "@kleros/kleros-sdk/src/dataMappings/utils/disputeDetailsTypes"; + import { INVALID_DISPUTE_DATA_ERROR, RPC_ERROR } from "consts/index"; import { Answer as IAnswer } from "context/NewDisputeContext"; import { isUndefined } from "utils/index"; -import { responsiveSize } from "styles/responsiveSize"; - import { DisputeDetailsQuery, VotingHistoryQuery } from "src/graphql/graphql"; -import ReactMarkdown from "components/ReactMarkdown"; +import { responsiveSize } from "styles/responsiveSize"; + +import MarkdownRenderer from "components/MarkdownRenderer"; import { StyledSkeleton } from "components/StyledSkeleton"; +import CardLabel from "../DisputeView/CardLabels"; import { Divider } from "../Divider"; import { ExternalLink } from "../ExternalLink"; +import RulingAndRewardsIndicators from "../Verdict/RulingAndRewardsIndicators"; import AliasDisplay from "./Alias"; -import RulingAndRewardsIndicators from "../Verdict/RulingAndRewardsIndicators"; -import CardLabel from "../DisputeView/CardLabels"; const StyledH1 = styled.h1` margin: 0; @@ -134,12 +135,12 @@ export const DisputeContext: React.FC = ({
{disputeDetails?.question?.trim() ? ( - {disputeDetails.question} + ) : null} {disputeDetails?.description?.trim() ? ( - {disputeDetails.description} + ) : null}
diff --git a/web/src/components/MarkdownEditor.tsx b/web/src/components/MarkdownEditor.tsx index 002dd0aa2..e49c4ffa2 100644 --- a/web/src/components/MarkdownEditor.tsx +++ b/web/src/components/MarkdownEditor.tsx @@ -13,20 +13,21 @@ import { linkPlugin, linkDialogPlugin, tablePlugin, + codeBlockPlugin, + codeMirrorPlugin, toolbarPlugin, UndoRedo, BoldItalicUnderlineToggles, - CodeToggle, ListsToggle, CreateLink, InsertTable, + InsertCodeBlock, BlockTypeSelect, Separator, } from "@mdxeditor/editor"; import InfoIcon from "svgs/icons/info-circle.svg"; -import { sanitizeMarkdown } from "utils/markdownSanitization"; import { isValidUrl } from "utils/urlValidation"; import { MDXEditorContainer, MDXEditorGlobalStyles } from "styles/mdxEditorTheme"; @@ -82,9 +83,13 @@ const MarkdownEditor: React.FC = ({ const editorRef = useRef(null); const handleChange = (markdown: string) => { - const cleanedMarkdown = markdown === "\u200B" ? "" : markdown.replace(/^\u200B/, ""); - const sanitizedMarkdown = sanitizeMarkdown(cleanedMarkdown); - onChange(sanitizedMarkdown); + let cleanedMarkdown = markdown === "\u200B" ? "" : markdown.replace(/^\u200B/, ""); + // Remove ALL escape characters - no exceptions + cleanedMarkdown = cleanedMarkdown.replace(/\\([`[]*_#|>-+=~^{}()!&<$%\\])/g, "$1"); + // Also handle multiple consecutive backslashes that might accumulate + cleanedMarkdown = cleanedMarkdown.replace(/\\+/g, ""); + + onChange(cleanedMarkdown); }; const handleContainerClick = () => { @@ -116,13 +121,19 @@ const MarkdownEditor: React.FC = ({ }), linkDialogPlugin(), tablePlugin(), + codeBlockPlugin({ defaultCodeBlockLanguage: "text" }), + codeMirrorPlugin({ + codeBlockLanguages: { + text: "Code", + }, + }), toolbarPlugin({ toolbarContents: () => ( <> - + diff --git a/web/src/components/MarkdownRenderer.tsx b/web/src/components/MarkdownRenderer.tsx index b885acce5..4c6c47acf 100644 --- a/web/src/components/MarkdownRenderer.tsx +++ b/web/src/components/MarkdownRenderer.tsx @@ -1,28 +1,25 @@ import React, { useCallback, useEffect, useRef, useState } from "react"; import styled from "styled-components"; -import { - MDXEditor, - type MDXEditorProps, - headingsPlugin, - listsPlugin, - quotePlugin, - thematicBreakPlugin, - markdownShortcutPlugin, - linkPlugin, - tablePlugin, - codeBlockPlugin, -} from "@mdxeditor/editor"; +import ReactMarkdown from "react-markdown"; +import rehypeRaw from "rehype-raw"; +import rehypeSanitize from "rehype-sanitize"; +import remarkGfm from "remark-gfm"; import { isExternalLink } from "utils/linkUtils"; -import { sanitizeMarkdown } from "utils/markdownSanitization"; import { isValidUrl } from "utils/urlValidation"; -import { MDXRendererContainer } from "styles/mdxEditorTheme"; - import ExternalLinkWarning from "components/ExternalLinkWarning"; -const LinkInterceptorContainer = styled(MDXRendererContainer)` +const MarkdownContainer = styled.div` + font-size: 16px; + line-height: 1.6; + + *, + ** { + font-size: 16px; + } + a { pointer-events: none; cursor: pointer; @@ -39,9 +36,203 @@ const LinkInterceptorContainer = styled(MDXRendererContainer)` cursor: pointer; } } -`; -import "@mdxeditor/editor/style.css"; + pre { + background-color: ${({ theme }) => theme.lightBackground}; + border-radius: 8px; + padding: 16px; + overflow-x: auto; + } + + code { + background-color: ${({ theme }) => theme.lightBackground}; + padding: 2px 4px; + border-radius: 4px; + font-family: "Fira Code", monospace; + } + + pre code { + background-color: transparent; + padding: 0; + } + + blockquote { + border-left: 4px solid ${({ theme }) => theme.primaryBlue}; + margin: 16px 0; + padding-left: 16px; + color: ${({ theme }) => theme.secondaryText}; + } + + ul, + ol { + padding-left: 20px; + } + + input[type="checkbox"] { + margin-right: 8px; + margin-top: 4px; + accent-color: ${({ theme }) => theme.primaryBlue}; + cursor: default; + vertical-align: top; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + color: ${({ theme }) => theme.primaryText}; + margin: 16px 0 8px 0; + line-height: 1.3; + } + + h1 { + font-size: 2em; + font-weight: 700; + } + + h2 { + font-size: 1.5em; + font-weight: 600; + } + + h3 { + font-size: 1.25em; + font-weight: 600; + } + + h4 { + font-size: 1.125em; + font-weight: 600; + } + + h5 { + font-size: 1em; + font-weight: 600; + } + + h6 { + font-size: 0.875em; + font-weight: 600; + } + + pre { + color: ${({ theme }) => theme.primaryText}; + } + + pre code { + color: inherit; + } + + code { + color: ${({ theme }) => theme.primaryText}; + } + + table { + border-collapse: collapse; + width: 100%; + margin: 16px 0; + border: 1px solid ${({ theme }) => theme.stroke}; + } + + th, + td { + border: 1px solid ${({ theme }) => theme.stroke}; + padding: 8px 12px; + text-align: left; + } + + th { + background-color: ${({ theme }) => theme.lightBackground}; + color: ${({ theme }) => theme.primaryText}; + font-weight: 600; + } + + td { + color: ${({ theme }) => theme.primaryText}; + } + + tbody tr:nth-child(even) { + background-color: ${({ theme }) => theme.lightGrey}; + } + + details { + border: 1px solid ${({ theme }) => theme.stroke}; + border-radius: 8px; + padding: 8px 12px; + margin: 16px 0; + background-color: ${({ theme }) => theme.lightBackground}; + } + + summary { + font-weight: 600; + cursor: pointer; + color: ${({ theme }) => theme.primaryText}; + padding: 4px 0; + outline: none; + } + + summary:hover { + color: ${({ theme }) => theme.primaryBlue}; + } + + details[open] summary { + margin-bottom: 8px; + border-bottom: 1px solid ${({ theme }) => theme.stroke}; + padding-bottom: 8px; + } + + u { + text-decoration: underline; + text-decoration-color: ${({ theme }) => theme.primaryText}; + } + + del, + s { + text-decoration: line-through; + text-decoration-color: ${({ theme }) => theme.secondaryText}; + } + + mark { + background-color: ${({ theme }) => theme.warning}; + color: ${({ theme }) => theme.primaryText}; + padding: 2px 4px; + border-radius: 2px; + } + + sub, + sup { + font-size: 0.75em; + line-height: 0; + position: relative; + vertical-align: baseline; + } + + sup { + top: -0.5em; + } + + sub { + bottom: -0.25em; + } + + kbd { + background-color: ${({ theme }) => theme.lightBackground}; + border: 1px solid ${({ theme }) => theme.stroke}; + border-radius: 4px; + box-shadow: 0 1px 1px ${({ theme }) => theme.stroke}; + color: ${({ theme }) => theme.primaryText}; + font-family: "Fira Code", monospace; + font-size: 0.875em; + padding: 2px 6px; + } + + abbr { + text-decoration: underline dotted; + cursor: help; + } +`; interface IMarkdownRenderer { content: string; @@ -76,7 +267,13 @@ const MarkdownRenderer: React.FC = ({ content, className }) = if (!container) return; const handleClick = (event: Event) => { - const linkElement = (event.target as HTMLElement).closest("a") as HTMLAnchorElement | null; + const target = event.target as HTMLElement; + + if (!container.contains(target)) { + return; + } + + const linkElement = target.closest("a") as HTMLAnchorElement | null; if (linkElement) { const href = linkElement.getAttribute("href") || linkElement.href; @@ -89,11 +286,9 @@ const MarkdownRenderer: React.FC = ({ content, className }) = }; container.addEventListener("click", handleClick, true); - document.addEventListener("click", handleClick, true); return () => { container.removeEventListener("click", handleClick, true); - document.removeEventListener("click", handleClick, true); }; }, [handleExternalLink]); @@ -101,29 +296,101 @@ const MarkdownRenderer: React.FC = ({ content, className }) = return null; } - const sanitizedContent = sanitizeMarkdown(content); - - const editorProps: MDXEditorProps = { - markdown: sanitizedContent, - readOnly: true, - suppressHtmlProcessing: false, - plugins: [ - headingsPlugin(), - listsPlugin(), - quotePlugin(), - thematicBreakPlugin(), - markdownShortcutPlugin(), - linkPlugin({ validateUrl: isValidUrl }), - tablePlugin(), - codeBlockPlugin({ defaultCodeBlockLanguage: "text" }), - ], - }; - return ( <> - - - + + { + return ( + + {children} + + ); + }, + }} + > + {content} + + = ({ children }) => {children}; - -export default ReactMarkdown; diff --git a/web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx b/web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx index e95ee1bd3..f4ce45368 100644 --- a/web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx +++ b/web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx @@ -1,7 +1,6 @@ import React, { useCallback, useMemo, useState } from "react"; import styled from "styled-components"; -import ReactMarkdown from "react-markdown"; import { useParams } from "react-router-dom"; import { useLocalStorage } from "react-use"; import { encodePacked, keccak256, PrivateKeyAccount } from "viem"; @@ -21,6 +20,7 @@ import { useDisputeDetailsQuery } from "queries/useDisputeDetailsQuery"; import { EnsureChain } from "components/EnsureChain"; import InfoCard from "components/InfoCard"; import MarkdownEditor from "components/MarkdownEditor"; +import MarkdownRenderer from "components/MarkdownRenderer"; const Container = styled.div` width: 100%; @@ -39,7 +39,7 @@ const StyledEnsureChain = styled(EnsureChain)` margin: 8px auto; `; -const ReactMarkdownWrapper = styled.div``; +const MarkdownWrapper = styled.div``; interface IReveal { arbitrable?: `0x${string}`; voteIDs: string[]; @@ -110,9 +110,9 @@ const Reveal: React.FC = ({ arbitrable, voteIDs, setIsOpen, commit, isR ) : isRevealPeriod ? ( <> - - {disputeDetails?.question ?? ""} - + + + = ({ arbitrable, handleSelection, justificatio return id ? ( <> - {disputeDetails?.question ?? ""} + {!isUndefined(justification) && !isUndefined(setJustification) ? ( ) : null} diff --git a/web/src/pages/Cases/CaseDetails/Voting/VotingHistory.tsx b/web/src/pages/Cases/CaseDetails/Voting/VotingHistory.tsx index da02108bf..e6421b1c4 100644 --- a/web/src/pages/Cases/CaseDetails/Voting/VotingHistory.tsx +++ b/web/src/pages/Cases/CaseDetails/Voting/VotingHistory.tsx @@ -2,7 +2,6 @@ import React, { useEffect, useMemo, useState } from "react"; import styled from "styled-components"; import Skeleton from "react-loading-skeleton"; -import ReactMarkdown from "react-markdown"; import { useParams } from "react-router-dom"; import { useToggle } from "react-use"; @@ -19,6 +18,7 @@ import { useVotingHistory } from "queries/useVotingHistory"; import { responsiveSize } from "styles/responsiveSize"; import HowItWorks from "components/HowItWorks"; +import MarkdownRenderer from "components/MarkdownRenderer"; import BinaryVoting from "components/Popup/MiniGuides/BinaryVoting"; import PendingVotesBox from "./PendingVotesBox"; @@ -47,8 +47,8 @@ const StyledTitle = styled.h1` margin-bottom: 0; font-size: ${responsiveSize(18, 24)}; `; -const ReactMarkdownWrapper = styled.div``; -const StyledReactMarkDown = styled(ReactMarkdown)` +const MarkdownWrapper = styled.div``; +const StyledMarkdownRenderer = styled(MarkdownRenderer)` max-width: inherit; word-wrap: break-word; p { @@ -95,11 +95,11 @@ const VotingHistory: React.FC<{ arbitrable?: `0x${string}`; isQuestion: boolean {isQuestion && ( <> {disputeDetails.question ? ( - - {disputeDetails.question} - + + + ) : ( - {isError ? RPC_ERROR : INVALID_DISPUTE_DATA_ERROR} + )} )} diff --git a/web/src/pages/Courts/CourtDetails/Description.tsx b/web/src/pages/Courts/CourtDetails/Description.tsx index b8ff78dbb..c860cdd0e 100644 --- a/web/src/pages/Courts/CourtDetails/Description.tsx +++ b/web/src/pages/Courts/CourtDetails/Description.tsx @@ -1,12 +1,13 @@ import React, { useEffect } from "react"; import styled from "styled-components"; -import ReactMarkdown from "react-markdown"; import { Routes, Route, Navigate, useParams, useNavigate, useLocation, useSearchParams } from "react-router-dom"; + import { Tabs } from "@kleros/ui-components-library"; import { useCourtPolicy } from "queries/useCourtPolicy"; +import MarkdownRenderer from "components/MarkdownRenderer"; import { StyledSkeleton } from "components/StyledSkeleton"; const Container = styled.div` @@ -18,7 +19,7 @@ const TextContainer = styled.div` padding: 12px 0; `; -const StyledReactMarkdown = styled(ReactMarkdown)` +const StyledMarkdownRenderer = styled(MarkdownRenderer)` p { word-break: break-word; } @@ -127,6 +128,6 @@ const Description: React.FC = () => { }; const formatMarkdown = (markdown?: string) => - markdown ? {markdown.replace(/\n/g, " \n")} : ; + markdown ? : ; export default Description; diff --git a/web/src/pages/Resolver/Briefing/Description.tsx b/web/src/pages/Resolver/Briefing/Description.tsx index 91efc9415..4a9318f98 100644 --- a/web/src/pages/Resolver/Briefing/Description.tsx +++ b/web/src/pages/Resolver/Briefing/Description.tsx @@ -1,13 +1,12 @@ import React, { useRef, useEffect } from "react"; import styled, { css } from "styled-components"; -import { Textarea } from "@kleros/ui-components-library"; - import { useNewDisputeContext } from "context/NewDisputeContext"; import { landscapeStyle } from "styles/landscapeStyle"; import { responsiveSize } from "styles/responsiveSize"; +import MarkdownEditor from "components/MarkdownEditor"; import Header from "pages/Resolver/Header"; import NavigationButtons from "../NavigationButtons"; @@ -18,9 +17,8 @@ const Container = styled.div` align-items: center; `; -const StyledTextArea = styled(Textarea)` +const StyledMarkdownEditor = styled(MarkdownEditor)` width: 84vw; - height: 300px; ${landscapeStyle( () => css` width: ${responsiveSize(442, 700, 900)}; @@ -32,15 +30,18 @@ const Description: React.FC = () => { const { disputeData, setDisputeData } = useNewDisputeContext(); const containerRef = useRef(null); - const handleWrite = (event: React.ChangeEvent) => { - setDisputeData({ ...disputeData, description: event.target.value }); + const handleWrite = (value: string) => { + setDisputeData({ ...disputeData, description: value }); }; useEffect(() => { if (containerRef.current) { - const textareaElement = containerRef.current.querySelector("textarea"); - if (textareaElement) { - textareaElement.focus(); + const editorElement = containerRef.current.querySelector('[role="region"]'); + if (editorElement) { + const contentEditable = editorElement.querySelector('[contenteditable="true"]'); + if (contentEditable) { + (contentEditable as HTMLElement).focus(); + } } } }, []); @@ -48,11 +49,11 @@ const Description: React.FC = () => { return (
- diff --git a/web/src/styles/mdxEditorTheme.ts b/web/src/styles/mdxEditorTheme.ts index 16546c6a4..315aaaeca 100644 --- a/web/src/styles/mdxEditorTheme.ts +++ b/web/src/styles/mdxEditorTheme.ts @@ -1,6 +1,10 @@ import styled, { createGlobalStyle, css } from "styled-components"; const sharedContentStyles = css` + .mdxeditor-root-contenteditable div { + padding: 0; + } + .mdxeditor-root-contenteditable p { color: ${({ theme }) => theme.primaryText} !important; margin: 0 0 12px 0; @@ -26,20 +30,29 @@ const sharedContentStyles = css` } .mdxeditor-root-contenteditable pre { - background-color: ${({ theme }) => theme.lightGrey} !important; + background-color: ${({ theme }) => theme.lightBackground} !important; color: ${({ theme }) => theme.primaryText} !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; + border-radius: 6px !important; + padding: 12px !important; + margin: 12px 0 !important; + font-family: "Fira Code", monospace !important; + font-size: 14px !important; } .mdxeditor-root-contenteditable a { color: ${({ theme }) => theme.primaryBlue} !important; } - .mdxeditor-root-contenteditable span[class*="_code_"] { - background-color: ${({ theme }) => theme.lightGrey} !important; - color: ${({ theme }) => theme.secondaryText} !important; - padding: 2px 4px; - border-radius: 3px; - font-size: 0.9em; + .mdxeditor-root-contenteditable span[class*="_code_"], + .mdxeditor-root-contenteditable code { + background-color: ${({ theme }) => theme.lightBackground} !important; + color: ${({ theme }) => theme.primaryText} !important; + padding: 2px 6px !important; + border-radius: 4px !important; + font-size: 14px !important; + font-family: "Fira Code", monospace !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; } .mdxeditor-root-contenteditable th { @@ -130,6 +143,39 @@ export const MDXEditorContainer = styled.div` `; export const MDXEditorGlobalStyles = createGlobalStyle` + .cm-editor { + background-color: ${({ theme }) => theme.lightBackground} !important; + border: 1px solid ${({ theme }) => theme.stroke} !important; + border-radius: 6px !important; + } + + .cm-content { + color: ${({ theme }) => theme.primaryText} !important; + font-family: "Fira Code", monospace !important; + font-size: 14px !important; + padding: 12px !important; + } + + .cm-focused { + outline: none !important; + } + + [class*="codeMirrorToolbar"] { + background-color: transparent !important; + } + + [class*="cm-gutterElement"] { + color: ${({ theme }) => theme.secondaryText} !important; + } + + [class*="codeMirrorWrapper"] { + border: 1px solid ${({ theme }) => theme.stroke} !important; + } + + [class*="activeLineGutter"] { + background-color: transparent !important; + } + /* Global styles for all MDXEditor popups and overlays */ [class*="linkDialogPopoverContent"], [class*="selectTrigger"], @@ -202,29 +248,3 @@ export const MDXEditorGlobalStyles = createGlobalStyle` } } `; - -export const MDXRendererContainer = styled.div` - width: 100%; - - .mdxeditor-toolbar { - display: none !important; - } - - .mdxeditor-root-contenteditable { - background: transparent !important; - border: none !important; - padding: 0 !important; - font-size: 16px; - line-height: 1.5; - } - - .mdxeditor-root-contenteditable span[class*="_code_"] { - background-color: ${({ theme }) => theme.lightGrey} !important; - color: ${({ theme }) => theme.secondaryText} !important; - padding: 2px 4px; - border-radius: 3px; - font-size: 0.9em; - } - - ${sharedContentStyles} -`; diff --git a/web/src/utils/markdownSanitization.ts b/web/src/utils/markdownSanitization.ts deleted file mode 100644 index 6e21f8eda..000000000 --- a/web/src/utils/markdownSanitization.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { sanitizeUrl } from "./urlValidation"; -import DOMPurify from "dompurify"; - -const sanitizeRepeated = (text: string, pattern: RegExp, replacement: string): string => { - let result = text; - let previousResult; - do { - previousResult = result; - result = result.replace(pattern, replacement); - } while (result !== previousResult); - return result; -}; - -export const sanitizeMarkdown = (markdown: string): string => { - if (!markdown || typeof markdown !== "string") { - return ""; - } - - let sanitized = markdown; - - sanitized = sanitized.replace(/\[([^\]]*)\]\(([^)]+)\)/g, (match, text, url) => { - const sanitizedUrl = sanitizeUrl(url); - return `[${text}](${sanitizedUrl})`; - }); - - sanitized = sanitized.replace(/]*>([^<]*)<\/a>/gi, (match, url, text) => { - const sanitizedUrl = sanitizeUrl(url); - return `[${text}](${sanitizedUrl})`; - }); - - // Use DOMPurify to sanitize dangerous HTML tags and attributes - sanitized = DOMPurify.sanitize(sanitized, { - ALLOWED_TAGS: [ - // Allow only safe tags that are valid in Markdown output; - // Configure to disallow script, iframe, object, embed, form, input, button, applet, audio, video, svg, canvas, meta, link, base - "b", "i", "em", "strong", "a", "p", "ul", "ol", "li", "blockquote", "code", "pre", "span", "br", "hr", "img" - ], - ALLOWED_ATTR: ["href", "src", "alt", "title"], // No style, no event handlers - FORBID_TAGS: [ - "script", "iframe", "object", "embed", "form", "input", "button", "applet", "audio", "video", "svg", "canvas", "meta", "link", "base" - ], - FORBID_ATTR: [ - "onerror", "onload", "onclick", "style" - ] - }); - - // Optional: Remove encoded protocols/entities as before - sanitized = sanitized.replace(/javascript:/gi, ""); - sanitized = sanitized.replace(/vbscript:/gi, ""); - sanitized = sanitized.replace(/data:/gi, ""); - sanitized = sanitized.replace(/&#x[0-9a-f]+;/gi, ""); - sanitized = sanitized.replace(/&#[0-9]+;/gi, ""); - - return sanitized; -}; diff --git a/web/src/utils/urlValidation.ts b/web/src/utils/urlValidation.ts index 115f5bef8..ba4cc7b36 100644 --- a/web/src/utils/urlValidation.ts +++ b/web/src/utils/urlValidation.ts @@ -44,10 +44,3 @@ export const isValidUrl = (url: string): boolean => { return false; } }; - -export const sanitizeUrl = (url: string): string => { - if (!isValidUrl(url)) { - return "#"; - } - return url; -}; diff --git a/yarn.lock b/yarn.lock index 9d8559478..0c287d75a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2520,8 +2520,8 @@ __metadata: linkType: hard "@codemirror/lang-sql@npm:^6.0.0": - version: 6.9.1 - resolution: "@codemirror/lang-sql@npm:6.9.1" + version: 6.10.0 + resolution: "@codemirror/lang-sql@npm:6.10.0" dependencies: "@codemirror/autocomplete": "npm:^6.0.0" "@codemirror/language": "npm:^6.0.0" @@ -2529,7 +2529,7 @@ __metadata: "@lezer/common": "npm:^1.2.0" "@lezer/highlight": "npm:^1.0.0" "@lezer/lr": "npm:^1.0.0" - checksum: 10/2fa0f61d8253f9dd28c255fa13ac27181fd42782160aeadfb72fdded426820c2ca49cf5057cfa92fc1016318bdf1008d0c33e23522f555ed802694ae73f3a137 + checksum: 10/23b9f4f1283bf63a41e7e8455f33fb528769bcc277ab0981b1bf7b8a589041883f9e2dcb0d64e0de0964577a7a6a30921ed3109c7fa0d85405716236ddc97d45 languageName: node linkType: hard @@ -2758,14 +2758,14 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.7.1": - version: 6.38.2 - resolution: "@codemirror/view@npm:6.38.2" + version: 6.38.3 + resolution: "@codemirror/view@npm:6.38.3" dependencies: "@codemirror/state": "npm:^6.5.0" crelt: "npm:^1.0.6" style-mod: "npm:^4.1.0" w3c-keyname: "npm:^2.2.4" - checksum: 10/300608850a29215d7b47fe8ade183fc2241457a924335bd127e29e1af11da9314369c65ec0da968177086f3529abbcd71a609c1af673ea8951c32a523cab358c + checksum: 10/2df41450399cbac0eaf06dba822418dd6926e48344b9255902248075ef040c957dfe97fe842a755e284a2fd4a66dc17b9638385f46ad74e926baac2e797335a2 languageName: node linkType: hard @@ -6801,7 +6801,6 @@ __metadata: "@solana/web3.js": "npm:^1.98.0" "@tanstack/react-query": "npm:^5.69.0" "@types/busboy": "npm:^1.5.4" - "@types/dompurify": "npm:^3.2.0" "@types/react": "npm:^18.3.12" "@types/react-dom": "npm:^18.3.1" "@types/react-modal": "npm:^3.16.3" @@ -6817,7 +6816,6 @@ __metadata: chartjs-adapter-moment: "npm:^1.0.1" chartjs-plugin-datalabels: "npm:^2.2.0" core-js: "npm:^3.39.0" - dompurify: "npm:^3.2.6" eslint: "npm:^9.15.0" eslint-config-prettier: "npm:^9.1.0" eslint-import-resolver-typescript: "npm:^3.6.3" @@ -6846,6 +6844,9 @@ __metadata: react-scripts: "npm:^5.0.1" react-toastify: "npm:^9.1.3" react-use: "npm:^17.5.1" + rehype-raw: "npm:^7.0.0" + rehype-sanitize: "npm:^6.0.0" + remark-gfm: "npm:^3.0.1" rimraf: "npm:^6.0.1" styled-components: "npm:^5.3.3" subgraph-status: "npm:^1.2.4" @@ -7237,13 +7238,13 @@ __metadata: linkType: hard "@lezer/javascript@npm:^1.0.0": - version: 1.5.3 - resolution: "@lezer/javascript@npm:1.5.3" + version: 1.5.4 + resolution: "@lezer/javascript@npm:1.5.4" dependencies: "@lezer/common": "npm:^1.2.0" "@lezer/highlight": "npm:^1.1.3" "@lezer/lr": "npm:^1.3.0" - checksum: 10/1cc3a719b7edda14bd816b9e4efab51fcf7392b7800ccdc0f135fb9652349b93c8f3bec50b82a200ac037ee8b9387efbe2d00c9870f7e0cb62ae8036635d6115 + checksum: 10/e3cf0b57b131e163aa6ce8a66469e5c39da4db6e83cbefa3bc864575f999229ad02d5d69af56d8aa05b21db22de284c13cfbc9b8b5bb7a628b5599330cf1ef39 languageName: node linkType: hard @@ -7638,8 +7639,8 @@ __metadata: linkType: hard "@mdxeditor/editor@npm:^3.45.0": - version: 3.45.0 - resolution: "@mdxeditor/editor@npm:3.45.0" + version: 3.46.0 + resolution: "@mdxeditor/editor@npm:3.46.0" dependencies: "@codemirror/commands": "npm:^6.2.4" "@codemirror/lang-markdown": "npm:^6.2.3" @@ -7700,7 +7701,7 @@ __metadata: peerDependencies: react: ">= 18 || >= 19" react-dom: ">= 18 || >= 19" - checksum: 10/5d6a661721a1e5570480e8dc981758d5816e516deaa31aebf70d0a198a8bc0c4cdfa1fa843ce98786910f8c93ef818f963cd1857fe1e26332aeca1c2241fe7d1 + checksum: 10/6b6b61e4e1b373ae1a0d14de392ee0cf5e017fa5e71d7d4d574e9bb5ca27a89f006b2cfd9761041c130a0b1ce01b43c8b4e46efafe8a500aab1f6b75e7af63c0 languageName: node linkType: hard @@ -11752,15 +11753,6 @@ __metadata: languageName: node linkType: hard -"@types/dompurify@npm:^3.2.0": - version: 3.2.0 - resolution: "@types/dompurify@npm:3.2.0" - dependencies: - dompurify: "npm:*" - checksum: 10/0194dd9024e76e856f3373e8b080c7a5ac9910543ac1ee85db45277efbbea820b2f27fe22c8a6f02bb51833e0a8540d732be0d11d156efd16cb0b97f88e41ebf - languageName: node - linkType: hard - "@types/eslint-scope@npm:^3.7.3": version: 3.7.4 resolution: "@types/eslint-scope@npm:3.7.4" @@ -12103,13 +12095,20 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0": +"@types/prop-types@npm:*": version: 15.7.12 resolution: "@types/prop-types@npm:15.7.12" checksum: 10/ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe languageName: node linkType: hard +"@types/prop-types@npm:^15.0.0": + version: 15.7.15 + resolution: "@types/prop-types@npm:15.7.15" + checksum: 10/31aa2f59b28f24da6fb4f1d70807dae2aedfce090ec63eaf9ea01727a9533ef6eaf017de5bff99fbccad7d1c9e644f52c6c2ba30869465dd22b1a7221c29f356 + languageName: node + linkType: hard + "@types/prop-types@npm:^15.7.14": version: 15.7.14 resolution: "@types/prop-types@npm:15.7.14" @@ -12302,7 +12301,7 @@ __metadata: languageName: node linkType: hard -"@types/trusted-types@npm:*, @types/trusted-types@npm:^2.0.2, @types/trusted-types@npm:^2.0.7": +"@types/trusted-types@npm:*, @types/trusted-types@npm:^2.0.2": version: 2.0.7 resolution: "@types/trusted-types@npm:2.0.7" checksum: 10/8e4202766a65877efcf5d5a41b7dd458480b36195e580a3b1085ad21e948bc417d55d6f8af1fd2a7ad008015d4117d5fdfe432731157da3c68678487174e4ba3 @@ -12316,7 +12315,14 @@ __metadata: languageName: node linkType: hard -"@types/unist@npm:^2, @types/unist@npm:^2.0.0": +"@types/unist@npm:^2": + version: 2.0.11 + resolution: "@types/unist@npm:2.0.11" + checksum: 10/6d436e832bc35c6dde9f056ac515ebf2b3384a1d7f63679d12358766f9b313368077402e9c1126a14d827f10370a5485e628bf61aa91117cf4fc882423191a4e + languageName: node + linkType: hard + +"@types/unist@npm:^2.0.0": version: 2.0.10 resolution: "@types/unist@npm:2.0.10" checksum: 10/e2924e18dedf45f68a5c6ccd6015cd62f1643b1b43baac1854efa21ae9e70505db94290434a23da1137d9e31eb58e54ca175982005698ac37300a1c889f6c4aa @@ -18424,18 +18430,6 @@ __metadata: languageName: node linkType: hard -"dompurify@npm:*, dompurify@npm:^3.2.6": - version: 3.2.6 - resolution: "dompurify@npm:3.2.6" - dependencies: - "@types/trusted-types": "npm:^2.0.7" - dependenciesMeta: - "@types/trusted-types": - optional: true - checksum: 10/b91631ed0e4d17fae950ef53613cc009ed7e73adc43ac94a41dd52f35483f7538d13caebdafa7626e0da145fc8184e7ac7935f14f25b7e841b32fda777e40447 - languageName: node - linkType: hard - "dompurify@npm:2.5.7": version: 2.5.7 resolution: "dompurify@npm:2.5.7" @@ -18804,6 +18798,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:^6.0.0": + version: 6.0.1 + resolution: "entities@npm:6.0.1" + checksum: 10/62af1307202884349d2867f0aac5c60d8b57102ea0b0e768b16246099512c28e239254ad772d6834e7e14cb1b6f153fc3d0c031934e3183b086c86d3838d874a + languageName: node + linkType: hard + "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -22353,6 +22354,63 @@ __metadata: languageName: node linkType: hard +"hast-util-from-parse5@npm:^8.0.0": + version: 8.0.3 + resolution: "hast-util-from-parse5@npm:8.0.3" + dependencies: + "@types/hast": "npm:^3.0.0" + "@types/unist": "npm:^3.0.0" + devlop: "npm:^1.0.0" + hastscript: "npm:^9.0.0" + property-information: "npm:^7.0.0" + vfile: "npm:^6.0.0" + vfile-location: "npm:^5.0.0" + web-namespaces: "npm:^2.0.0" + checksum: 10/539c945c550cfef394a89dcff6e4de26768a748a7288ddce6f59554dd271b663b8398d58ace434264e965aaf3828fdbff86f9109d7fa639b3fe34dedcad4a5df + languageName: node + linkType: hard + +"hast-util-parse-selector@npm:^4.0.0": + version: 4.0.0 + resolution: "hast-util-parse-selector@npm:4.0.0" + dependencies: + "@types/hast": "npm:^3.0.0" + checksum: 10/76087670d3b0b50b23a6cb70bca53a6176d6608307ccdbb3ed18b650b82e7c3513bfc40348f1389dc0c5ae872b9a768851f4335f44654abd7deafd6974c52402 + languageName: node + linkType: hard + +"hast-util-raw@npm:^9.0.0": + version: 9.1.0 + resolution: "hast-util-raw@npm:9.1.0" + dependencies: + "@types/hast": "npm:^3.0.0" + "@types/unist": "npm:^3.0.0" + "@ungap/structured-clone": "npm:^1.0.0" + hast-util-from-parse5: "npm:^8.0.0" + hast-util-to-parse5: "npm:^8.0.0" + html-void-elements: "npm:^3.0.0" + mdast-util-to-hast: "npm:^13.0.0" + parse5: "npm:^7.0.0" + unist-util-position: "npm:^5.0.0" + unist-util-visit: "npm:^5.0.0" + vfile: "npm:^6.0.0" + web-namespaces: "npm:^2.0.0" + zwitch: "npm:^2.0.0" + checksum: 10/fa304d08a9fce0f54b2baa18d15c45cb5cac695cbee3567b8ccbd9a57fa295c0fb23d238daca1cf0135ad8d538bb341dcd7d9da03f8b7d12e6980a9f8c4340ae + languageName: node + linkType: hard + +"hast-util-sanitize@npm:^5.0.0": + version: 5.0.2 + resolution: "hast-util-sanitize@npm:5.0.2" + dependencies: + "@types/hast": "npm:^3.0.0" + "@ungap/structured-clone": "npm:^1.0.0" + unist-util-position: "npm:^5.0.0" + checksum: 10/920d4d78c8f73962e2440e626c02f65e832de3be5c49ddd101eee2269982489efa5aac7780e487bdebfcc407b1cb20ceea21fb48b690dd686d9a18273bffb817 + languageName: node + linkType: hard + "hast-util-to-jsx-runtime@npm:^2.0.0": version: 2.3.2 resolution: "hast-util-to-jsx-runtime@npm:2.3.2" @@ -22376,6 +22434,21 @@ __metadata: languageName: node linkType: hard +"hast-util-to-parse5@npm:^8.0.0": + version: 8.0.0 + resolution: "hast-util-to-parse5@npm:8.0.0" + dependencies: + "@types/hast": "npm:^3.0.0" + comma-separated-tokens: "npm:^2.0.0" + devlop: "npm:^1.0.0" + property-information: "npm:^6.0.0" + space-separated-tokens: "npm:^2.0.0" + web-namespaces: "npm:^2.0.0" + zwitch: "npm:^2.0.0" + checksum: 10/ba59d0913ba7e914d8b0a50955c06806a6868445c56796ac9129d58185e86d7ff24037246767aba2ea904d9dee8c09b8ff303630bcd854431fdc1bbee2164c36 + languageName: node + linkType: hard + "hast-util-whitespace@npm:^2.0.0": version: 2.0.1 resolution: "hast-util-whitespace@npm:2.0.1" @@ -22392,6 +22465,19 @@ __metadata: languageName: node linkType: hard +"hastscript@npm:^9.0.0": + version: 9.0.1 + resolution: "hastscript@npm:9.0.1" + dependencies: + "@types/hast": "npm:^3.0.0" + comma-separated-tokens: "npm:^2.0.0" + hast-util-parse-selector: "npm:^4.0.0" + property-information: "npm:^7.0.0" + space-separated-tokens: "npm:^2.0.0" + checksum: 10/9aa8135faf0307807cca4075bef4e3403ae1ce959ad4b9e6720892ba957d58ff98b2f60b5eb3ac67d88ae897dc918997299cd4249d7ac602a0066dd46442c5d4 + languageName: node + linkType: hard + "he@npm:^1.2.0": version: 1.2.0 resolution: "he@npm:1.2.0" @@ -22577,6 +22663,13 @@ __metadata: languageName: node linkType: hard +"html-void-elements@npm:^3.0.0": + version: 3.0.0 + resolution: "html-void-elements@npm:3.0.0" + checksum: 10/59be397525465a7489028afa064c55763d9cccd1d7d9f630cca47137317f0e897a9ca26cef7e745e7cff1abc44260cfa407742b243a54261dfacd42230e94fce + languageName: node + linkType: hard + "html-webpack-plugin@npm:^5.5.0": version: 5.5.3 resolution: "html-webpack-plugin@npm:5.5.3" @@ -26249,6 +26342,18 @@ __metadata: languageName: node linkType: hard +"mdast-util-find-and-replace@npm:^2.0.0": + version: 2.2.2 + resolution: "mdast-util-find-and-replace@npm:2.2.2" + dependencies: + "@types/mdast": "npm:^3.0.0" + escape-string-regexp: "npm:^5.0.0" + unist-util-is: "npm:^5.0.0" + unist-util-visit-parents: "npm:^5.0.0" + checksum: 10/59e11e853b74d8f6083950327df39e27287b383930ff836298a5100aeda5568282bb45046c27886d2156ea101580bb0689b890c29623cefa5adc74e95d9ca9ff + languageName: node + linkType: hard + "mdast-util-from-markdown@npm:^1.0.0": version: 1.3.1 resolution: "mdast-util-from-markdown@npm:1.3.1" @@ -26303,6 +26408,39 @@ __metadata: languageName: node linkType: hard +"mdast-util-gfm-autolink-literal@npm:^1.0.0": + version: 1.0.3 + resolution: "mdast-util-gfm-autolink-literal@npm:1.0.3" + dependencies: + "@types/mdast": "npm:^3.0.0" + ccount: "npm:^2.0.0" + mdast-util-find-and-replace: "npm:^2.0.0" + micromark-util-character: "npm:^1.0.0" + checksum: 10/272d075cdc7937bec0179af4052bd9032a6fbb05608b387b1b075b0491c73ce012f3ff1c718cdb5fb0ed1032c1fa7570d955b59c0ab3c3c72609928754774529 + languageName: node + linkType: hard + +"mdast-util-gfm-footnote@npm:^1.0.0": + version: 1.0.2 + resolution: "mdast-util-gfm-footnote@npm:1.0.2" + dependencies: + "@types/mdast": "npm:^3.0.0" + mdast-util-to-markdown: "npm:^1.3.0" + micromark-util-normalize-identifier: "npm:^1.0.0" + checksum: 10/825f207afc98fd1daa0acc8adcb5754d1f0d577ccb1749245289bee7c892557668d8ee3a5ab618f42e710646cf018dcda84f3c0c608ae11718e9014e5bf4f9dc + languageName: node + linkType: hard + +"mdast-util-gfm-strikethrough@npm:^1.0.0": + version: 1.0.3 + resolution: "mdast-util-gfm-strikethrough@npm:1.0.3" + dependencies: + "@types/mdast": "npm:^3.0.0" + mdast-util-to-markdown: "npm:^1.3.0" + checksum: 10/a9c2dc3ef46be7952d13b7063a16171bba8aa266bffe6b1e7267df02a60b4fa3734115cca311e9127db8cfcbbcd68fdd92aa26152bcd0c14372c79b254e4df2f + languageName: node + linkType: hard + "mdast-util-gfm-strikethrough@npm:^2.0.0": version: 2.0.0 resolution: "mdast-util-gfm-strikethrough@npm:2.0.0" @@ -26314,6 +26452,18 @@ __metadata: languageName: node linkType: hard +"mdast-util-gfm-table@npm:^1.0.0": + version: 1.0.7 + resolution: "mdast-util-gfm-table@npm:1.0.7" + dependencies: + "@types/mdast": "npm:^3.0.0" + markdown-table: "npm:^3.0.0" + mdast-util-from-markdown: "npm:^1.0.0" + mdast-util-to-markdown: "npm:^1.3.0" + checksum: 10/167f7f7a9dc17ce852f4f9bd155d7be179588e2ccf4ce3c4f23b12c1c9db5de904cdacc6f41b2d635cb84eb09a7ff5a33497585f2664a7f1e6bd6f7ab7e1197a + languageName: node + linkType: hard + "mdast-util-gfm-table@npm:^2.0.0": version: 2.0.0 resolution: "mdast-util-gfm-table@npm:2.0.0" @@ -26327,6 +26477,16 @@ __metadata: languageName: node linkType: hard +"mdast-util-gfm-task-list-item@npm:^1.0.0": + version: 1.0.2 + resolution: "mdast-util-gfm-task-list-item@npm:1.0.2" + dependencies: + "@types/mdast": "npm:^3.0.0" + mdast-util-to-markdown: "npm:^1.3.0" + checksum: 10/958417a7d7690728b44d65127ab9189c7feaa17aea924dd56a888c781ab3abaa4eb0c209f05c4dbf203da3d0c4df8fdace4c9471b644268bfc7fc792a018a171 + languageName: node + linkType: hard + "mdast-util-gfm-task-list-item@npm:^2.0.0": version: 2.0.0 resolution: "mdast-util-gfm-task-list-item@npm:2.0.0" @@ -26339,6 +26499,21 @@ __metadata: languageName: node linkType: hard +"mdast-util-gfm@npm:^2.0.0": + version: 2.0.2 + resolution: "mdast-util-gfm@npm:2.0.2" + dependencies: + mdast-util-from-markdown: "npm:^1.0.0" + mdast-util-gfm-autolink-literal: "npm:^1.0.0" + mdast-util-gfm-footnote: "npm:^1.0.0" + mdast-util-gfm-strikethrough: "npm:^1.0.0" + mdast-util-gfm-table: "npm:^1.0.0" + mdast-util-gfm-task-list-item: "npm:^1.0.0" + mdast-util-to-markdown: "npm:^1.0.0" + checksum: 10/70e6cd32af94181d409f171f984f83fc18b3efe316844c62f31816f5c1612a92517b8ed766340f23e0a6d6cb0f27a8b07d288bab6619cbdbb0c5341006bcdc4d + languageName: node + linkType: hard + "mdast-util-highlight-mark@npm:^1.2.2": version: 1.2.2 resolution: "mdast-util-highlight-mark@npm:1.2.2" @@ -26409,6 +26584,16 @@ __metadata: languageName: node linkType: hard +"mdast-util-phrasing@npm:^3.0.0": + version: 3.0.1 + resolution: "mdast-util-phrasing@npm:3.0.1" + dependencies: + "@types/mdast": "npm:^3.0.0" + unist-util-is: "npm:^5.0.0" + checksum: 10/c5b616d9b1eb76a6b351d195d94318494722525a12a89d9c8a3b091af7db3dd1fc55d294f9d29266d8159a8267b0df4a7a133bda8a3909d5331c383e1e1ff328 + languageName: node + linkType: hard + "mdast-util-phrasing@npm:^4.0.0": version: 4.1.0 resolution: "mdast-util-phrasing@npm:4.1.0" @@ -26452,6 +26637,22 @@ __metadata: languageName: node linkType: hard +"mdast-util-to-markdown@npm:^1.0.0, mdast-util-to-markdown@npm:^1.3.0": + version: 1.5.0 + resolution: "mdast-util-to-markdown@npm:1.5.0" + dependencies: + "@types/mdast": "npm:^3.0.0" + "@types/unist": "npm:^2.0.0" + longest-streak: "npm:^3.0.0" + mdast-util-phrasing: "npm:^3.0.0" + mdast-util-to-string: "npm:^3.0.0" + micromark-util-decode-string: "npm:^1.0.0" + unist-util-visit: "npm:^4.0.0" + zwitch: "npm:^2.0.0" + checksum: 10/713f674588a01969a2ce524a69985bd57e507377eea2c4ba69800fb305414468b30144ae9b837fbdde8c609877673140e4f56f6cabe9e0e2bc1487291e3c5144 + languageName: node + linkType: hard + "mdast-util-to-markdown@npm:^2.0.0, mdast-util-to-markdown@npm:^2.1.0": version: 2.1.2 resolution: "mdast-util-to-markdown@npm:2.1.2" @@ -26469,7 +26670,7 @@ __metadata: languageName: node linkType: hard -"mdast-util-to-string@npm:^3.1.0": +"mdast-util-to-string@npm:^3.0.0, mdast-util-to-string@npm:^3.1.0": version: 3.2.0 resolution: "mdast-util-to-string@npm:3.2.0" dependencies: @@ -26668,7 +26869,7 @@ __metadata: languageName: node linkType: hard -"micromark-core-commonmark@npm:^1.0.1": +"micromark-core-commonmark@npm:^1.0.0, micromark-core-commonmark@npm:^1.0.1": version: 1.1.0 resolution: "micromark-core-commonmark@npm:1.1.0" dependencies: @@ -26743,6 +26944,48 @@ __metadata: languageName: node linkType: hard +"micromark-extension-gfm-autolink-literal@npm:^1.0.0": + version: 1.0.5 + resolution: "micromark-extension-gfm-autolink-literal@npm:1.0.5" + dependencies: + micromark-util-character: "npm:^1.0.0" + micromark-util-sanitize-uri: "npm:^1.0.0" + micromark-util-symbol: "npm:^1.0.0" + micromark-util-types: "npm:^1.0.0" + checksum: 10/1e0ccc758baef3cd0478ba84ff86fa1ec2b389042421c7cade9485b775456c1a9c3bd797393002b2c6f6abd9bdf829cb114874557bbcb8e43d16d06a464811c0 + languageName: node + linkType: hard + +"micromark-extension-gfm-footnote@npm:^1.0.0": + version: 1.1.2 + resolution: "micromark-extension-gfm-footnote@npm:1.1.2" + dependencies: + micromark-core-commonmark: "npm:^1.0.0" + micromark-factory-space: "npm:^1.0.0" + micromark-util-character: "npm:^1.0.0" + micromark-util-normalize-identifier: "npm:^1.0.0" + micromark-util-sanitize-uri: "npm:^1.0.0" + micromark-util-symbol: "npm:^1.0.0" + micromark-util-types: "npm:^1.0.0" + uvu: "npm:^0.5.0" + checksum: 10/8777073fb76d2fd01f6b2405106af6c349c1e25660c4d37cadcc61c187d71c8444870f73cefaaa67f12884d5e45c78ee3c5583561a0b330bd91c6d997113584a + languageName: node + linkType: hard + +"micromark-extension-gfm-strikethrough@npm:^1.0.0": + version: 1.0.7 + resolution: "micromark-extension-gfm-strikethrough@npm:1.0.7" + dependencies: + micromark-util-chunked: "npm:^1.0.0" + micromark-util-classify-character: "npm:^1.0.0" + micromark-util-resolve-all: "npm:^1.0.0" + micromark-util-symbol: "npm:^1.0.0" + micromark-util-types: "npm:^1.0.0" + uvu: "npm:^0.5.0" + checksum: 10/8411ef1aa5dc83f662e8b45b085f70ddff29deb3c4259269e8a1ff656397abb755d8ea841a14be23e8585a31d3c0a5de1bd2c05f3453b66670e499d4a0004f5e + languageName: node + linkType: hard + "micromark-extension-gfm-strikethrough@npm:^2.0.0": version: 2.1.0 resolution: "micromark-extension-gfm-strikethrough@npm:2.1.0" @@ -26757,6 +27000,19 @@ __metadata: languageName: node linkType: hard +"micromark-extension-gfm-table@npm:^1.0.0": + version: 1.0.7 + resolution: "micromark-extension-gfm-table@npm:1.0.7" + dependencies: + micromark-factory-space: "npm:^1.0.0" + micromark-util-character: "npm:^1.0.0" + micromark-util-symbol: "npm:^1.0.0" + micromark-util-types: "npm:^1.0.0" + uvu: "npm:^0.5.0" + checksum: 10/f05d86a099c941a2a309d60bf4839d16a00a93cb880cda4ab8faeb831647763fff6e03197ec15b80e1f195002afcca6afe2b95c3622b049b82d7ff8ef1c1c776 + languageName: node + linkType: hard + "micromark-extension-gfm-table@npm:^2.0.0": version: 2.1.1 resolution: "micromark-extension-gfm-table@npm:2.1.1" @@ -26770,6 +27026,28 @@ __metadata: languageName: node linkType: hard +"micromark-extension-gfm-tagfilter@npm:^1.0.0": + version: 1.0.2 + resolution: "micromark-extension-gfm-tagfilter@npm:1.0.2" + dependencies: + micromark-util-types: "npm:^1.0.0" + checksum: 10/55c7d9019d6a39efaaed2c2e40b0aaa137d2c4f9c94cac82e93f509a806c3a775e4c815b5d8e986617450b68861a19776e4b886307e83db452b393f15a837b39 + languageName: node + linkType: hard + +"micromark-extension-gfm-task-list-item@npm:^1.0.0": + version: 1.0.5 + resolution: "micromark-extension-gfm-task-list-item@npm:1.0.5" + dependencies: + micromark-factory-space: "npm:^1.0.0" + micromark-util-character: "npm:^1.0.0" + micromark-util-symbol: "npm:^1.0.0" + micromark-util-types: "npm:^1.0.0" + uvu: "npm:^0.5.0" + checksum: 10/46bb1baa10bfb785a2e3e2f975e5509260b9995d5c3aeddf77051957d218ce1af4ea737bcb6a56a930e62d42b05307b20632a400eff25cdb290789ff3170cad5 + languageName: node + linkType: hard + "micromark-extension-gfm-task-list-item@npm:^2.0.1": version: 2.1.0 resolution: "micromark-extension-gfm-task-list-item@npm:2.1.0" @@ -26783,6 +27061,22 @@ __metadata: languageName: node linkType: hard +"micromark-extension-gfm@npm:^2.0.0": + version: 2.0.3 + resolution: "micromark-extension-gfm@npm:2.0.3" + dependencies: + micromark-extension-gfm-autolink-literal: "npm:^1.0.0" + micromark-extension-gfm-footnote: "npm:^1.0.0" + micromark-extension-gfm-strikethrough: "npm:^1.0.0" + micromark-extension-gfm-table: "npm:^1.0.0" + micromark-extension-gfm-tagfilter: "npm:^1.0.0" + micromark-extension-gfm-task-list-item: "npm:^1.0.0" + micromark-util-combine-extensions: "npm:^1.0.0" + micromark-util-types: "npm:^1.0.0" + checksum: 10/3ffd06ced4314abd0f0c72ec227f034f38dd47facbb62439ef3216d42f32433f3901d14675cf806e8d73689802a11849958b330bb5b55dd4fd5cdc64ebaf345c + languageName: node + linkType: hard + "micromark-extension-highlight-mark@npm:1.2.0, micromark-extension-highlight-mark@npm:^1.2.0": version: 1.2.0 resolution: "micromark-extension-highlight-mark@npm:1.2.0" @@ -29171,6 +29465,15 @@ __metadata: languageName: node linkType: hard +"parse5@npm:^7.0.0": + version: 7.3.0 + resolution: "parse5@npm:7.3.0" + dependencies: + entities: "npm:^6.0.0" + checksum: 10/b0e48be20b820c655b138b86fa6fb3a790de6c891aa2aba536524f8027b4dca4fe538f11a0e5cf2f6f847d120dbb9e4822dcaeb933ff1e10850a2ef0154d1d88 + languageName: node + linkType: hard + "parse5@npm:^7.1.1": version: 7.1.2 resolution: "parse5@npm:7.1.2" @@ -30763,6 +31066,13 @@ __metadata: languageName: node linkType: hard +"property-information@npm:^7.0.0": + version: 7.1.0 + resolution: "property-information@npm:7.1.0" + checksum: 10/896d38a52ad7170de73f832d277c69e76a9605d941ebb3f0d6e56271414a7fdf95ff6d2819e68036b8a0c7d2d4d88bf1d4a5765c032cb19c2343567ee3a14b15 + languageName: node + linkType: hard + "proto-list@npm:~1.2.1": version: 1.2.4 resolution: "proto-list@npm:1.2.4" @@ -31279,11 +31589,11 @@ __metadata: linkType: hard "react-hook-form@npm:^7.56.1": - version: 7.62.0 - resolution: "react-hook-form@npm:7.62.0" + version: 7.63.0 + resolution: "react-hook-form@npm:7.63.0" peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 - checksum: 10/092dcf0317ed3e314b124ed9df3f3494cf3447326078cd857f6fdc47aad0504e466ab2fb593bbb8e79c247b8772159f83aebe54a7e5799926b00d7e401d127a6 + checksum: 10/df07de6fce42bbcd65ed100aaea7d0e907c555c2635c253517225c84f06eab0ebd278578ada4f479ad582c18a52898c4f1cabca327a12a74b8b7e6e54718edbe languageName: node linkType: hard @@ -32063,6 +32373,27 @@ __metadata: languageName: node linkType: hard +"rehype-raw@npm:^7.0.0": + version: 7.0.0 + resolution: "rehype-raw@npm:7.0.0" + dependencies: + "@types/hast": "npm:^3.0.0" + hast-util-raw: "npm:^9.0.0" + vfile: "npm:^6.0.0" + checksum: 10/65dd5809f95410ca5056efe50f5b16cb08a69c0785c6d4ec80c9280487efbaec81d342084f6cfdca5624134c1c4018705d97c37b5c0a21d9625ed8a3c88700f1 + languageName: node + linkType: hard + +"rehype-sanitize@npm:^6.0.0": + version: 6.0.0 + resolution: "rehype-sanitize@npm:6.0.0" + dependencies: + "@types/hast": "npm:^3.0.0" + hast-util-sanitize: "npm:^5.0.0" + checksum: 10/976e928b4f9da6c515e4fde7e4ae873f815c50ab1a268a3c442468eaa981d117492f991926858d69467f7b131358e441ca6d0be0f60a0034b72b3ce6dc69a387 + languageName: node + linkType: hard + "relateurl@npm:^0.2.7": version: 0.2.7 resolution: "relateurl@npm:0.2.7" @@ -32081,6 +32412,18 @@ __metadata: languageName: node linkType: hard +"remark-gfm@npm:^3.0.1": + version: 3.0.1 + resolution: "remark-gfm@npm:3.0.1" + dependencies: + "@types/mdast": "npm:^3.0.0" + mdast-util-gfm: "npm:^2.0.0" + micromark-extension-gfm: "npm:^2.0.0" + unified: "npm:^10.0.0" + checksum: 10/8ec301f5fb1f52c548b5a6d7ca6a3422d55db73cd703f147c979d16dca003f065181f55404d6f3f49d33f1faca3fe56ae731ed7fe0acc00cd945a8e605f155f2 + languageName: node + linkType: hard + "remark-parse@npm:^10.0.0": version: 10.0.2 resolution: "remark-parse@npm:10.0.2" @@ -35953,7 +36296,7 @@ __metadata: languageName: node linkType: hard -"unist-util-visit-parents@npm:^5.1.1": +"unist-util-visit-parents@npm:^5.0.0, unist-util-visit-parents@npm:^5.1.1": version: 5.1.3 resolution: "unist-util-visit-parents@npm:5.1.3" dependencies: @@ -36497,6 +36840,16 @@ __metadata: languageName: node linkType: hard +"vfile-location@npm:^5.0.0": + version: 5.0.3 + resolution: "vfile-location@npm:5.0.3" + dependencies: + "@types/unist": "npm:^3.0.0" + vfile: "npm:^6.0.0" + checksum: 10/f481d592fd507fe242da9a00d7400ded3c91587931f24e64c54f24752d7b30321721a1c99c0d949be1f6ed5fa7f8b169054fd07c744705b65dbdd10a9e4ebfe0 + languageName: node + linkType: hard + "vfile-message@npm:^3.0.0": version: 3.1.4 resolution: "vfile-message@npm:3.1.4" @@ -37072,6 +37425,13 @@ __metadata: languageName: node linkType: hard +"web-namespaces@npm:^2.0.0": + version: 2.0.1 + resolution: "web-namespaces@npm:2.0.1" + checksum: 10/b6d9f02f1a43d0ef0848a812d89c83801d5bbad57d8bb61f02eb6d7eb794c3736f6cc2e1191664bb26136594c8218ac609f4069722c6f56d9fc2d808fa9271c6 + languageName: node + linkType: hard + "web3-errors@npm:^1.2.0, web3-errors@npm:^1.3.0": version: 1.3.0 resolution: "web3-errors@npm:1.3.0" From 56aaca87b3c278cecf73894829b1f4520f8d6dfa Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:49:54 +0900 Subject: [PATCH 11/13] chore: style impros resolver description --- web/src/pages/Resolver/Briefing/Description.tsx | 17 +++++++++-------- web/src/styles/mdxEditorTheme.ts | 2 ++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/web/src/pages/Resolver/Briefing/Description.tsx b/web/src/pages/Resolver/Briefing/Description.tsx index 4a9318f98..55a924621 100644 --- a/web/src/pages/Resolver/Briefing/Description.tsx +++ b/web/src/pages/Resolver/Briefing/Description.tsx @@ -17,8 +17,7 @@ const Container = styled.div` align-items: center; `; -const StyledMarkdownEditor = styled(MarkdownEditor)` - width: 84vw; +const MarkdownEditorContainer = styled.div` ${landscapeStyle( () => css` width: ${responsiveSize(442, 700, 900)}; @@ -49,12 +48,14 @@ const Description: React.FC = () => { return (
- + + + ); diff --git a/web/src/styles/mdxEditorTheme.ts b/web/src/styles/mdxEditorTheme.ts index 315aaaeca..dede51b07 100644 --- a/web/src/styles/mdxEditorTheme.ts +++ b/web/src/styles/mdxEditorTheme.ts @@ -69,6 +69,8 @@ export const MDXEditorContainer = styled.div` width: 100%; .mdxeditor-toolbar { + display: flex; + flex-wrap: wrap; background-color: ${({ theme }) => theme.lightGrey} !important; border: 1px solid ${({ theme }) => theme.stroke} !important; border-radius: 3px; From 94e47834f9df7a388ba59a837f702d1f46114228 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Mon, 22 Sep 2025 18:02:35 +0900 Subject: [PATCH 12/13] chore: slight transition and coloring --- web/src/styles/mdxEditorTheme.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/web/src/styles/mdxEditorTheme.ts b/web/src/styles/mdxEditorTheme.ts index dede51b07..7bbfe2687 100644 --- a/web/src/styles/mdxEditorTheme.ts +++ b/web/src/styles/mdxEditorTheme.ts @@ -1,8 +1,11 @@ import styled, { createGlobalStyle, css } from "styled-components"; const sharedContentStyles = css` - .mdxeditor-root-contenteditable div { - padding: 0; + .mdxeditor-root-contenteditable { + transition: background-color 0.1s ease !important; + :hover { + background-color: ${({ theme }) => theme.lightGrey}60 !important; + } } .mdxeditor-root-contenteditable p { From a8d32b8977adb5ce1974593ea54a77cfc0b59a0e Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Mon, 22 Sep 2025 18:23:36 +0900 Subject: [PATCH 13/13] chore: small styling issue --- web/src/styles/mdxEditorTheme.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/styles/mdxEditorTheme.ts b/web/src/styles/mdxEditorTheme.ts index 7bbfe2687..0ef1d8b21 100644 --- a/web/src/styles/mdxEditorTheme.ts +++ b/web/src/styles/mdxEditorTheme.ts @@ -175,6 +175,7 @@ export const MDXEditorGlobalStyles = createGlobalStyle` [class*="codeMirrorWrapper"] { border: 1px solid ${({ theme }) => theme.stroke} !important; + padding: 0 !important; } [class*="activeLineGutter"] {