From 508065107ae74739063a3115df597ea16b271941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8C=97=E6=9E=B3?= <7854742+wang_rumeng@user.noreply.gitee.com> Date: Sun, 3 Aug 2025 18:34:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=A7=E6=9C=AC=E4=BF=AE=E6=94=B9=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=8A=A0=E6=9A=82=E5=81=9C/=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/pages/create-to-video2.tsx | 2 +- components/pages/style/work-flow.css | 18 +- components/pages/work-flow.tsx | 21 +- components/pages/work-flow/media-viewer.tsx | 15 + .../pages/work-flow/use-workflow-data.tsx | 9 +- components/script-edit-dialog.tsx | 2 +- components/script-renderer/ScriptRenderer.tsx | 191 ++++++++++ components/script-renderer/mock.ts | 76 ++++ components/script-renderer/types.ts | 26 ++ package-lock.json | 332 ++++++++++++++++++ package.json | 2 + 11 files changed, 677 insertions(+), 17 deletions(-) create mode 100644 components/script-renderer/ScriptRenderer.tsx create mode 100644 components/script-renderer/mock.ts create mode 100644 components/script-renderer/types.ts diff --git a/components/pages/create-to-video2.tsx b/components/pages/create-to-video2.tsx index 2574c99..8f2338a 100644 --- a/components/pages/create-to-video2.tsx +++ b/components/pages/create-to-video2.tsx @@ -613,7 +613,7 @@ export function CreateToVideo2() { {script}
Describe the content you want to action. Get an (null); @@ -39,6 +40,8 @@ export default function WorkFlow() { dataLoadError, setCurrentSketchIndex, retryLoadData, + isPauseWorkFlow, + setIsPauseWorkFlow, } = useWorkflowData(); const { @@ -108,7 +111,7 @@ export default function WorkFlow() { return (
-
+
@@ -124,10 +127,10 @@ export default function WorkFlow() {
-
+
{dataLoadError ? ( @@ -208,6 +211,16 @@ export default function WorkFlow() {
+ {/* 暂停/播放按钮 */} +
+ setIsPauseWorkFlow(!isPauseWorkFlow)} + /> +
+ {/* AI 建议栏 */} { + return ( +
+ +
+ ); + }; + // 根据当前步骤渲染对应内容 if (Number(currentStep) === 6 || Number(currentStep) === 5.5) { return renderFinalVideo(currentStep); @@ -804,5 +815,9 @@ export function MediaViewer({ return renderVideoContent(); } + if (Number(currentStep) === 0) { + return renderScriptContent(); + } + return renderSketchContent(); } \ No newline at end of file diff --git a/components/pages/work-flow/use-workflow-data.tsx b/components/pages/work-flow/use-workflow-data.tsx index 5f258cf..f3b1629 100644 --- a/components/pages/work-flow/use-workflow-data.tsx +++ b/components/pages/work-flow/use-workflow-data.tsx @@ -73,6 +73,7 @@ export function useWorkflowData() { const [final, setFinal] = useState(null); const [dataLoadError, setDataLoadError] = useState(null); const [needStreamData, setNeedStreamData] = useState(false); + const [isPauseWorkFlow, setIsPauseWorkFlow] = useState(false); const dispatch = useAppDispatch(); const { sketchCount, videoCount } = useAppSelector((state) => state.workflow); @@ -154,7 +155,7 @@ export function useWorkflowData() { } let loadingText: any = LOADING_TEXT_MAP.initializing; - let finalStep = '1', sketchCount = 0, isChange = false; + let finalStep = '0', sketchCount = 0, isChange = false; const all_task_data = response.data; // all_task_data 下标0 和 下标1 换位置 const temp = all_task_data[0]; @@ -166,6 +167,7 @@ export function useWorkflowData() { // 如果有已完成的数据,同步到状态 if (task.task_name === 'generate_sketch' && task.task_result) { + finalStep = '1'; const realSketchResultData = task.task_result.data.filter((item: any) => item.image_path); if (realSketchResultData.length >= 0) { // 正在生成草图中 替换 sketch 数据 @@ -383,9 +385,10 @@ export function useWorkflowData() { } // 如果有已完成的数据,同步到状态 - let finalStep = '1'; + let finalStep = '0'; if (data) { if (data.sketch && data.sketch.data) { + finalStep = '1'; const realSketchResultData = data.sketch.data.filter((item: any) => item.image_path); const sketchList = []; for (const sketch of realSketchResultData) { @@ -570,5 +573,7 @@ export function useWorkflowData() { setCurrentSketchIndex, retryLoadData, handleManualPlay, + isPauseWorkFlow, + setIsPauseWorkFlow, }; } \ No newline at end of file diff --git a/components/script-edit-dialog.tsx b/components/script-edit-dialog.tsx index a17e625..fcf4c3a 100644 --- a/components/script-edit-dialog.tsx +++ b/components/script-edit-dialog.tsx @@ -2,7 +2,7 @@ import { motion, AnimatePresence } from 'framer-motion'; import { X } from 'lucide-react'; -import { useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Button } from './ui/button'; import { Input } from './ui/input'; diff --git a/components/script-renderer/ScriptRenderer.tsx b/components/script-renderer/ScriptRenderer.tsx new file mode 100644 index 0000000..3125294 --- /dev/null +++ b/components/script-renderer/ScriptRenderer.tsx @@ -0,0 +1,191 @@ +import React, { useRef, useState } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; +import { SquarePen, Lightbulb, Navigation, Globe, Copy, SendHorizontal } from 'lucide-react'; +import { ScriptData, ScriptBlock, ScriptContent } from './types'; +import ContentEditable, { ContentEditableEvent } from 'react-contenteditable'; +import { toast } from 'sonner'; + + +interface ScriptRendererProps { + data: ScriptData; +} + +export const ScriptRenderer: React.FC = ({ data }) => { + const [activeBlockId, setActiveBlockId] = useState(null); + const [hoveredBlockId, setHoveredBlockId] = useState(null); + const contentRefs = useRef<{ [key: string]: HTMLDivElement | null }>({}); + const [editBlockId, setEditBlockId] = useState(null); + const contentEditableRef = useRef(null); + + const scrollToBlock = (blockId: string) => { + const element = contentRefs.current[blockId]; + if (element) { + element.scrollIntoView({ behavior: 'smooth' }); + setActiveBlockId(blockId); + } + }; + + // 用于渲染展示的 JSX + const renderContent = (content: ScriptContent) => { + switch (content.type) { + case 'heading': + return

{content.text}

; + case 'bold': + return {content.text}; + case 'italic': + return {content.text}; + default: + return

{content.text}

; + } + }; + + // 用于生成编辑时的 HTML 字符串 + const contentToHtml = (content: ScriptContent): string => { + switch (content.type) { + case 'heading': + return `

${content.text}

`; + case 'bold': + return `${content.text}`; + case 'italic': + return `${content.text}`; + default: + return `

${content.text}

`; + } + }; + + // 格式化文本为 HTML + const formatTextToHtml = (text: string) => { + return text + .split('\n') + .map(line => line || '
') + .join('
'); + }; + + const handleBlockTextChange = (block: ScriptBlock) => (e: ContentEditableEvent) => { + console.log(e.target.value); + }; + + const renderEditBlock = (block: ScriptBlock) => { + let blockHtmlText = ''; + block.content.forEach(item => { + blockHtmlText += contentToHtml(item); + }); + + return ( + + ); + }; + + const renderBlock = (block: ScriptBlock) => { + const isHovered = hoveredBlockId === block.id; + const isActive = activeBlockId === block.id; + const isEditing = editBlockId === block.id; + + return ( + (contentRefs.current[block.id] = el)} + onMouseEnter={() => setHoveredBlockId(block.id)} + onMouseLeave={() => setHoveredBlockId(null)} + initial={{ opacity: 0 }} + animate={{ opacity: 1 }} + transition={{ duration: 0.3 }} + > +

{block.title}

+ + {(isHovered || isActive) && ( + + { + setEditBlockId(block.id); + setActiveBlockId(block.id); + }} + /> + { + navigator.clipboard.writeText(block.content.map(item => item.text).join('\n')); + toast.success('Copied!'); + }} + /> + + )} + +
+ {isEditing ? ( + renderEditBlock(block) + ) : ( + block.content.map((item, index) => ( +
{renderContent(item)}
+ )) + )} +
+
+ ); + }; + + return ( +
+
+ {data.blocks.map(renderBlock)} +
+
+ {/* 翻译功能 待开发 */} + {/*
+

+ + 翻译 +

+
+ +
+ + +
+
+
*/} +
+

+ + 导航 +

+ {data.blocks.map((block) => ( + scrollToBlock(block.id)} + whileHover={{ scale: 1.02 }} + whileTap={{ scale: 0.98 }} + > + {block.title} + + ))} +
+
+
+ ); +}; \ No newline at end of file diff --git a/components/script-renderer/mock.ts b/components/script-renderer/mock.ts new file mode 100644 index 0000000..6c295dc --- /dev/null +++ b/components/script-renderer/mock.ts @@ -0,0 +1,76 @@ +import { ScriptData } from './types'; + +export const mockScriptData: ScriptData = { + blocks: [ + { + id: 'core', + title: "SCENE'S CORE CONFLICT", + type: 'core', + content: [ + { + type: 'paragraph', + text: 'The desperate, on-stage improvisation of a failing comedian triggers a physical and professional collapse, forcing him and his partner to confront the absurd meaninglessness of their ambitions. This scene serves as the inciting incident and rising action, where the internal conflict of artistic decay manifests as a literal, catastrophic failure, propelling them from a state of professional anxiety into a fight for survival.' + }, + { + type: 'bold', + text: 'GENRE: Satire | Absurdist Comedy | Disaster' + } + ] + }, + { + id: 'scene1', + title: 'SCENE 1', + type: 'scene', + sceneNumber: 1, + content: [ + { + type: 'heading', + text: 'INT. GRAND VICTORIA THEATER - NIGHT' + }, + { + type: 'paragraph', + text: "Scene Transition: An establishing shot of the theater's exterior: a once-magnificent building, now looking tired. A few neon characters in its name are flickering or dead. We are introduced to the world of fading glory before we even meet the characters inside." + }, + { + type: 'heading', + text: 'ACTION LINE' + }, + { + type: 'paragraph', + text: "The air is thick with the ghosts of applause. The GRAND VICTORIA THEATER is a cavern of faded grandeur. Ornate gold leaf peels from the balconies, and the deep red velvet seats are pocked with empty spaces. Maybe fifty people are scattered throughout an auditorium built for a thousand." + }, + { + type: 'paragraph', + text: "On stage, under a single, harsh SPOTLIGHT that illuminates a universe of dancing dust motes, are two men in traditional 'changshan' robes. This is a Xiangsheng (crosstalk) performance." + }, + { + type: 'paragraph', + text: "LIU WEI (40s), the 'Dougen' (the funny one), is sweating. His smile is a painful rictus. Beside a traditional wooden table, his partner ZHANG HAO (40s), the 'Penggen' (the straight man), stands ramrod straight, his face a mask of placid professionalism." + }, + { + type: 'paragraph', + text: "The audience is a mix of tourists and locals, many of whom are looking at their phones. The stage is a stage, but it's not a stage. It's a place where the audience can see the actors, but the actors can't see the audience." + }, + { + type: 'italic', + text: '(小明缓缓起身)' + } + ] + }, + { + id: 'summary', + title: '总结', + type: 'summary', + content: [ + { + type: 'paragraph', + text: '故事通过展现...' + } + ] + } + ], + translation: { + language: 'English', + content: 'This is a story about growth...' + } +} \ No newline at end of file diff --git a/components/script-renderer/types.ts b/components/script-renderer/types.ts new file mode 100644 index 0000000..440c9d7 --- /dev/null +++ b/components/script-renderer/types.ts @@ -0,0 +1,26 @@ +export interface ScriptBlock { + id: string; + title: string; + content: ScriptContent[]; + type: 'core' | 'scene' | 'summary'; + sceneNumber?: number; +} + +export interface ScriptContent { + type: 'paragraph' | 'bold' | 'italic' | 'heading'; + text: string; +} + +export interface ScriptData { + blocks: ScriptBlock[]; + translation?: { + language: string; + content: string; + }; +} + +export interface NavigationItem { + id: string; + title: string; + type: 'core' | 'scene' | 'summary'; +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c4ca8f5..299b95f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -90,12 +90,14 @@ "react-hook-form": "^7.53.0", "react-intersection-observer": "^9.16.0", "react-joyride": "^2.9.3", + "react-markdown": "^10.1.0", "react-redux": "^9.2.0", "react-resizable": "^3.0.5", "react-resizable-panels": "^2.1.3", "react-rough-notation": "^1.0.5", "react-textarea-autosize": "^8.5.9", "recharts": "^2.15.4", + "remark-gfm": "^4.0.1", "sonner": "^1.5.0", "styled-components": "^6.1.19", "swiper": "^11.2.8", @@ -12645,6 +12647,16 @@ "dev": true, "license": "MIT" }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -14600,6 +14612,16 @@ "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -14609,6 +14631,34 @@ "node": ">= 0.4" } }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/mdast-util-from-markdown": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", @@ -14633,6 +14683,107 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-mdx": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", @@ -14879,6 +15030,127 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-extension-mdx-expression": { "version": "3.0.1", "resolved": "https://registry.npmmirror.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", @@ -17603,6 +17875,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/react-markdown": { + "version": "10.1.0", + "resolved": "https://registry.npmmirror.com/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, "node_modules/react-redux": { "version": "9.2.0", "resolved": "https://registry.npmmirror.com/react-redux/-/react-redux-9.2.0.tgz", @@ -17989,6 +18288,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-mdx": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/remark-mdx/-/remark-mdx-3.1.0.tgz", @@ -18036,6 +18353,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmmirror.com/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz", diff --git a/package.json b/package.json index eab97b4..9880999 100644 --- a/package.json +++ b/package.json @@ -93,12 +93,14 @@ "react-hook-form": "^7.53.0", "react-intersection-observer": "^9.16.0", "react-joyride": "^2.9.3", + "react-markdown": "^10.1.0", "react-redux": "^9.2.0", "react-resizable": "^3.0.5", "react-resizable-panels": "^2.1.3", "react-rough-notation": "^1.0.5", "react-textarea-autosize": "^8.5.9", "recharts": "^2.15.4", + "remark-gfm": "^4.0.1", "sonner": "^1.5.0", "styled-components": "^6.1.19", "swiper": "^11.2.8",