mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-17 16:45:02 +00:00
feat: add new Markdown components and enhance i18n support (#5622)
* feat: add new Markdown components and enhance i18n support (cherry picked from commit b0b6cc7ad49ac35f070389744a764928d7103074) * feat: support structured data render --------- Co-authored-by: FinleyGe <m13203533462@163.com>
This commit is contained in:
@@ -372,6 +372,8 @@
|
|||||||
"core.chat.feedback.Feedback Close": "Close Feedback",
|
"core.chat.feedback.Feedback Close": "Close Feedback",
|
||||||
"core.chat.feedback.No Content": "User Did Not Provide Specific Feedback Content",
|
"core.chat.feedback.No Content": "User Did Not Provide Specific Feedback Content",
|
||||||
"core.chat.feedback.Read User dislike": "User Disagrees\nClick to View Content",
|
"core.chat.feedback.Read User dislike": "User Disagrees\nClick to View Content",
|
||||||
|
"core.chat.indicator.no_data": "There is no data yet",
|
||||||
|
"core.chat.table.per_page": "{{num}} per page",
|
||||||
"core.chat.logs.api": "API Call",
|
"core.chat.logs.api": "API Call",
|
||||||
"core.chat.logs.feishu": "Feishu",
|
"core.chat.logs.feishu": "Feishu",
|
||||||
"core.chat.logs.free_login": "No login link",
|
"core.chat.logs.free_login": "No login link",
|
||||||
@@ -392,6 +394,7 @@
|
|||||||
"core.chat.quote.beforeUpdate": "Before update",
|
"core.chat.quote.beforeUpdate": "Before update",
|
||||||
"core.chat.response.Complete Response": "Complete Response",
|
"core.chat.response.Complete Response": "Complete Response",
|
||||||
"core.chat.response.Extension model": "Question Optimization Model",
|
"core.chat.response.Extension model": "Question Optimization Model",
|
||||||
|
"core.chat.response.Fold response": "Fold",
|
||||||
"core.chat.response.Read complete response": "View Details",
|
"core.chat.response.Read complete response": "View Details",
|
||||||
"core.chat.response.Read complete response tips": "Click to View Detailed Process",
|
"core.chat.response.Read complete response tips": "Click to View Detailed Process",
|
||||||
"core.chat.response.Tool call input tokens": "Tool Call Input Tokens Consumption",
|
"core.chat.response.Tool call input tokens": "Tool Call Input Tokens Consumption",
|
||||||
|
@@ -372,6 +372,8 @@
|
|||||||
"core.chat.feedback.Feedback Close": "关闭反馈",
|
"core.chat.feedback.Feedback Close": "关闭反馈",
|
||||||
"core.chat.feedback.No Content": "用户没有填写具体反馈内容",
|
"core.chat.feedback.No Content": "用户没有填写具体反馈内容",
|
||||||
"core.chat.feedback.Read User dislike": "用户表示反对\n点击查看内容",
|
"core.chat.feedback.Read User dislike": "用户表示反对\n点击查看内容",
|
||||||
|
"core.chat.indicator.no_data": "暂时没有该数据",
|
||||||
|
"core.chat.table.per_page": "{{num}} 条/页",
|
||||||
"core.chat.logs.api": "API 调用",
|
"core.chat.logs.api": "API 调用",
|
||||||
"core.chat.logs.feishu": "飞书",
|
"core.chat.logs.feishu": "飞书",
|
||||||
"core.chat.logs.free_login": "免登录链接",
|
"core.chat.logs.free_login": "免登录链接",
|
||||||
@@ -392,6 +394,7 @@
|
|||||||
"core.chat.quote.beforeUpdate": "更新前",
|
"core.chat.quote.beforeUpdate": "更新前",
|
||||||
"core.chat.response.Complete Response": "完整响应",
|
"core.chat.response.Complete Response": "完整响应",
|
||||||
"core.chat.response.Extension model": "问题优化模型",
|
"core.chat.response.Extension model": "问题优化模型",
|
||||||
|
"core.chat.response.Fold response": "收起",
|
||||||
"core.chat.response.Read complete response": "查看详情",
|
"core.chat.response.Read complete response": "查看详情",
|
||||||
"core.chat.response.Read complete response tips": "点击查看详细流程",
|
"core.chat.response.Read complete response tips": "点击查看详细流程",
|
||||||
"core.chat.response.Tool call input tokens": "工具调用输入 Tokens",
|
"core.chat.response.Tool call input tokens": "工具调用输入 Tokens",
|
||||||
|
@@ -372,6 +372,8 @@
|
|||||||
"core.chat.feedback.Feedback Close": "關閉回饋",
|
"core.chat.feedback.Feedback Close": "關閉回饋",
|
||||||
"core.chat.feedback.No Content": "使用者未提供具體回饋內容",
|
"core.chat.feedback.No Content": "使用者未提供具體回饋內容",
|
||||||
"core.chat.feedback.Read User dislike": "使用者表示反對\n點選檢視內容",
|
"core.chat.feedback.Read User dislike": "使用者表示反對\n點選檢視內容",
|
||||||
|
"core.chat.indicator.no_data": "暫時沒有該數據",
|
||||||
|
"core.chat.table.per_page": "{{num}} 筆/頁",
|
||||||
"core.chat.logs.api": "API 呼叫",
|
"core.chat.logs.api": "API 呼叫",
|
||||||
"core.chat.logs.feishu": "飛書",
|
"core.chat.logs.feishu": "飛書",
|
||||||
"core.chat.logs.free_login": "免登入連結",
|
"core.chat.logs.free_login": "免登入連結",
|
||||||
@@ -392,6 +394,7 @@
|
|||||||
"core.chat.quote.beforeUpdate": "更新前",
|
"core.chat.quote.beforeUpdate": "更新前",
|
||||||
"core.chat.response.Complete Response": "完整回應",
|
"core.chat.response.Complete Response": "完整回應",
|
||||||
"core.chat.response.Extension model": "問題最佳化模型",
|
"core.chat.response.Extension model": "問題最佳化模型",
|
||||||
|
"core.chat.response.Fold response": "收起",
|
||||||
"core.chat.response.Read complete response": "檢視詳細資料",
|
"core.chat.response.Read complete response": "檢視詳細資料",
|
||||||
"core.chat.response.Read complete response tips": "點選檢視詳細流程",
|
"core.chat.response.Read complete response tips": "點選檢視詳細流程",
|
||||||
"core.chat.response.Tool call input tokens": "工具呼叫輸入 Token 消耗",
|
"core.chat.response.Tool call input tokens": "工具呼叫輸入 Token 消耗",
|
||||||
|
105
pnpm-lock.yaml
generated
105
pnpm-lock.yaml
generated
@@ -46,7 +46,7 @@ importers:
|
|||||||
version: 10.1.4(socks@2.8.4)
|
version: 10.1.4(socks@2.8.4)
|
||||||
next-i18next:
|
next-i18next:
|
||||||
specifier: 15.4.2
|
specifier: 15.4.2
|
||||||
version: 15.4.2(i18next@23.16.8)(next@14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 15.4.2(i18next@23.16.8)(next@14.2.32(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
prettier:
|
prettier:
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4
|
version: 3.2.4
|
||||||
@@ -318,7 +318,7 @@ importers:
|
|||||||
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
'@chakra-ui/next-js':
|
'@chakra-ui/next-js':
|
||||||
specifier: 2.4.2
|
specifier: 2.4.2
|
||||||
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
|
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.32(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
|
||||||
'@chakra-ui/react':
|
'@chakra-ui/react':
|
||||||
specifier: 2.10.7
|
specifier: 2.10.7
|
||||||
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@@ -396,7 +396,7 @@ importers:
|
|||||||
version: 14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
|
version: 14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
|
||||||
next-i18next:
|
next-i18next:
|
||||||
specifier: 15.4.2
|
specifier: 15.4.2
|
||||||
version: 15.4.2(i18next@23.16.8)(next@14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 15.4.2(i18next@23.16.8)(next@14.2.32(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
papaparse:
|
papaparse:
|
||||||
specifier: ^5.4.1
|
specifier: ^5.4.1
|
||||||
version: 5.4.1
|
version: 5.4.1
|
||||||
@@ -460,7 +460,7 @@ importers:
|
|||||||
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
'@chakra-ui/next-js':
|
'@chakra-ui/next-js':
|
||||||
specifier: 2.4.2
|
specifier: 2.4.2
|
||||||
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
|
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.32(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
|
||||||
'@chakra-ui/react':
|
'@chakra-ui/react':
|
||||||
specifier: 2.10.7
|
specifier: 2.10.7
|
||||||
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@@ -512,6 +512,9 @@ importers:
|
|||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.7
|
specifier: ^1.11.7
|
||||||
version: 1.11.13
|
version: 1.11.13
|
||||||
|
dompurify:
|
||||||
|
specifier: ^3.2.7
|
||||||
|
version: 3.2.7
|
||||||
echarts:
|
echarts:
|
||||||
specifier: 5.4.1
|
specifier: 5.4.1
|
||||||
version: 5.4.1
|
version: 5.4.1
|
||||||
@@ -556,7 +559,7 @@ importers:
|
|||||||
version: 14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
|
version: 14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
|
||||||
next-i18next:
|
next-i18next:
|
||||||
specifier: 15.4.2
|
specifier: 15.4.2
|
||||||
version: 15.4.2(i18next@23.16.8)(next@14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 15.4.2(i18next@23.16.8)(next@14.2.32(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
nprogress:
|
nprogress:
|
||||||
specifier: ^0.2.0
|
specifier: ^0.2.0
|
||||||
version: 0.2.0
|
version: 0.2.0
|
||||||
@@ -599,6 +602,9 @@ importers:
|
|||||||
rehype-katex:
|
rehype-katex:
|
||||||
specifier: ^7.0.0
|
specifier: ^7.0.0
|
||||||
version: 7.0.1
|
version: 7.0.1
|
||||||
|
rehype-raw:
|
||||||
|
specifier: ^7.0.0
|
||||||
|
version: 7.0.0
|
||||||
remark-breaks:
|
remark-breaks:
|
||||||
specifier: ^4.0.0
|
specifier: ^4.0.0
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
@@ -624,6 +630,9 @@ importers:
|
|||||||
'@svgr/webpack':
|
'@svgr/webpack':
|
||||||
specifier: ^6.5.1
|
specifier: ^6.5.1
|
||||||
version: 6.5.1
|
version: 6.5.1
|
||||||
|
'@types/dompurify':
|
||||||
|
specifier: ^3.2.0
|
||||||
|
version: 3.2.0
|
||||||
'@types/js-yaml':
|
'@types/js-yaml':
|
||||||
specifier: ^4.0.9
|
specifier: ^4.0.9
|
||||||
version: 4.0.9
|
version: 4.0.9
|
||||||
@@ -3421,6 +3430,10 @@ packages:
|
|||||||
'@types/decompress@4.2.7':
|
'@types/decompress@4.2.7':
|
||||||
resolution: {integrity: sha512-9z+8yjKr5Wn73Pt17/ldnmQToaFHZxK0N1GHysuk/JIPT8RIdQeoInM01wWPgypRcvb6VH1drjuFpQ4zmY437g==}
|
resolution: {integrity: sha512-9z+8yjKr5Wn73Pt17/ldnmQToaFHZxK0N1GHysuk/JIPT8RIdQeoInM01wWPgypRcvb6VH1drjuFpQ4zmY437g==}
|
||||||
|
|
||||||
|
'@types/dompurify@3.2.0':
|
||||||
|
resolution: {integrity: sha512-Fgg31wv9QbLDA0SpTOXO3MaxySc4DKGLi8sna4/Utjo4r3ZRPdCt4UQee8BWr+Q5z21yifghREPJGYaEOEIACg==}
|
||||||
|
deprecated: This is a stub types definition. dompurify provides its own type definitions, so you do not need this installed.
|
||||||
|
|
||||||
'@types/eslint-scope@3.7.7':
|
'@types/eslint-scope@3.7.7':
|
||||||
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
|
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
|
||||||
|
|
||||||
@@ -3601,6 +3614,9 @@ packages:
|
|||||||
'@types/triple-beam@1.3.5':
|
'@types/triple-beam@1.3.5':
|
||||||
resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==}
|
resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==}
|
||||||
|
|
||||||
|
'@types/trusted-types@2.0.7':
|
||||||
|
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||||
|
|
||||||
'@types/tunnel@0.0.4':
|
'@types/tunnel@0.0.4':
|
||||||
resolution: {integrity: sha512-bQgDBL5XiqrrPUaZd9bZ2esOXcU4GTmgg0n6LHDqoMJezO3VFRZsW8qN6Gp64/LAmjtzNU3iAHBfV3Z2ht5DSg==}
|
resolution: {integrity: sha512-bQgDBL5XiqrrPUaZd9bZ2esOXcU4GTmgg0n6LHDqoMJezO3VFRZsW8qN6Gp64/LAmjtzNU3iAHBfV3Z2ht5DSg==}
|
||||||
|
|
||||||
@@ -5097,6 +5113,9 @@ packages:
|
|||||||
dompurify@3.1.6:
|
dompurify@3.1.6:
|
||||||
resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==}
|
resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==}
|
||||||
|
|
||||||
|
dompurify@3.2.7:
|
||||||
|
resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==}
|
||||||
|
|
||||||
domutils@2.8.0:
|
domutils@2.8.0:
|
||||||
resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
|
resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
|
||||||
|
|
||||||
@@ -5921,9 +5940,15 @@ packages:
|
|||||||
hast-util-parse-selector@4.0.0:
|
hast-util-parse-selector@4.0.0:
|
||||||
resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
|
resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
|
||||||
|
|
||||||
|
hast-util-raw@9.1.0:
|
||||||
|
resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
|
||||||
|
|
||||||
hast-util-to-jsx-runtime@2.3.6:
|
hast-util-to-jsx-runtime@2.3.6:
|
||||||
resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
|
resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
|
||||||
|
|
||||||
|
hast-util-to-parse5@8.0.0:
|
||||||
|
resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==}
|
||||||
|
|
||||||
hast-util-to-text@4.0.2:
|
hast-util-to-text@4.0.2:
|
||||||
resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
|
resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
|
||||||
|
|
||||||
@@ -5958,6 +5983,9 @@ packages:
|
|||||||
html-url-attributes@3.0.1:
|
html-url-attributes@3.0.1:
|
||||||
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
|
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
|
||||||
|
|
||||||
|
html-void-elements@3.0.0:
|
||||||
|
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
|
||||||
|
|
||||||
htmlparser2@8.0.2:
|
htmlparser2@8.0.2:
|
||||||
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
||||||
|
|
||||||
@@ -8019,6 +8047,9 @@ packages:
|
|||||||
property-information@5.6.0:
|
property-information@5.6.0:
|
||||||
resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==}
|
resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==}
|
||||||
|
|
||||||
|
property-information@6.5.0:
|
||||||
|
resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
|
||||||
|
|
||||||
property-information@7.0.0:
|
property-information@7.0.0:
|
||||||
resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
|
resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
|
||||||
|
|
||||||
@@ -8343,6 +8374,9 @@ packages:
|
|||||||
rehype-katex@7.0.1:
|
rehype-katex@7.0.1:
|
||||||
resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==}
|
resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==}
|
||||||
|
|
||||||
|
rehype-raw@7.0.0:
|
||||||
|
resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
|
||||||
|
|
||||||
remark-breaks@4.0.0:
|
remark-breaks@4.0.0:
|
||||||
resolution: {integrity: sha512-IjEjJOkH4FuJvHZVIW0QCDWxcG96kCq7An/KVH2NfJe6rKZU2AsHeB3OEjPNRxi4QC34Xdx7I2KGYn6IpT7gxQ==}
|
resolution: {integrity: sha512-IjEjJOkH4FuJvHZVIW0QCDWxcG96kCq7An/KVH2NfJe6rKZU2AsHeB3OEjPNRxi4QC34Xdx7I2KGYn6IpT7gxQ==}
|
||||||
|
|
||||||
@@ -8900,7 +8934,7 @@ packages:
|
|||||||
superagent@8.1.2:
|
superagent@8.1.2:
|
||||||
resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==}
|
resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==}
|
||||||
engines: {node: '>=6.4.0 <13 || >=14'}
|
engines: {node: '>=6.4.0 <13 || >=14'}
|
||||||
deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net
|
deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net
|
||||||
|
|
||||||
supertest@6.3.4:
|
supertest@6.3.4:
|
||||||
resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==}
|
resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==}
|
||||||
@@ -10795,7 +10829,7 @@ snapshots:
|
|||||||
'@chakra-ui/system': 2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1)
|
'@chakra-ui/system': 2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1)
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|
||||||
'@chakra-ui/next-js@2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)':
|
'@chakra-ui/next-js@2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.32(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@chakra-ui/react': 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
'@chakra-ui/react': 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
'@emotion/cache': 11.14.0
|
'@emotion/cache': 11.14.0
|
||||||
@@ -12785,6 +12819,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.17.24
|
'@types/node': 20.17.24
|
||||||
|
|
||||||
|
'@types/dompurify@3.2.0':
|
||||||
|
dependencies:
|
||||||
|
dompurify: 3.2.7
|
||||||
|
|
||||||
'@types/eslint-scope@3.7.7':
|
'@types/eslint-scope@3.7.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/eslint': 9.6.1
|
'@types/eslint': 9.6.1
|
||||||
@@ -13004,6 +13042,9 @@ snapshots:
|
|||||||
|
|
||||||
'@types/triple-beam@1.3.5': {}
|
'@types/triple-beam@1.3.5': {}
|
||||||
|
|
||||||
|
'@types/trusted-types@2.0.7':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@types/tunnel@0.0.4':
|
'@types/tunnel@0.0.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.17.24
|
'@types/node': 20.17.24
|
||||||
@@ -14798,6 +14839,10 @@ snapshots:
|
|||||||
|
|
||||||
dompurify@3.1.6: {}
|
dompurify@3.1.6: {}
|
||||||
|
|
||||||
|
dompurify@3.2.7:
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/trusted-types': 2.0.7
|
||||||
|
|
||||||
domutils@2.8.0:
|
domutils@2.8.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
dom-serializer: 1.4.1
|
dom-serializer: 1.4.1
|
||||||
@@ -15140,7 +15185,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.0(eslint-plugin-import@2.31.0)(eslint@8.56.0))(eslint@8.56.0):
|
eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.0)(eslint@8.56.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@@ -15151,7 +15196,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.0(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
|
eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.0)(eslint@8.57.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@@ -15173,7 +15218,7 @@ snapshots:
|
|||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 8.56.0
|
eslint: 8.56.0
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.0(eslint-plugin-import@2.31.0)(eslint@8.56.0))(eslint@8.56.0)
|
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.0)(eslint@8.56.0)
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
is-core-module: 2.16.1
|
is-core-module: 2.16.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@@ -15202,7 +15247,7 @@ snapshots:
|
|||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.0(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
|
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.9.0)(eslint@8.57.1)
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
is-core-module: 2.16.1
|
is-core-module: 2.16.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@@ -16105,6 +16150,22 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/hast': 3.0.4
|
'@types/hast': 3.0.4
|
||||||
|
|
||||||
|
hast-util-raw@9.1.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 3.0.4
|
||||||
|
'@types/unist': 3.0.3
|
||||||
|
'@ungap/structured-clone': 1.3.0
|
||||||
|
hast-util-from-parse5: 8.0.3
|
||||||
|
hast-util-to-parse5: 8.0.0
|
||||||
|
html-void-elements: 3.0.0
|
||||||
|
mdast-util-to-hast: 13.2.0
|
||||||
|
parse5: 7.2.1
|
||||||
|
unist-util-position: 5.0.0
|
||||||
|
unist-util-visit: 5.0.0
|
||||||
|
vfile: 6.0.3
|
||||||
|
web-namespaces: 2.0.1
|
||||||
|
zwitch: 2.0.4
|
||||||
|
|
||||||
hast-util-to-jsx-runtime@2.3.6:
|
hast-util-to-jsx-runtime@2.3.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': 1.0.6
|
'@types/estree': 1.0.6
|
||||||
@@ -16125,6 +16186,16 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
hast-util-to-parse5@8.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 3.0.4
|
||||||
|
comma-separated-tokens: 2.0.3
|
||||||
|
devlop: 1.1.0
|
||||||
|
property-information: 6.5.0
|
||||||
|
space-separated-tokens: 2.0.2
|
||||||
|
web-namespaces: 2.0.1
|
||||||
|
zwitch: 2.0.4
|
||||||
|
|
||||||
hast-util-to-text@4.0.2:
|
hast-util-to-text@4.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/hast': 3.0.4
|
'@types/hast': 3.0.4
|
||||||
@@ -16170,6 +16241,8 @@ snapshots:
|
|||||||
|
|
||||||
html-url-attributes@3.0.1: {}
|
html-url-attributes@3.0.1: {}
|
||||||
|
|
||||||
|
html-void-elements@3.0.0: {}
|
||||||
|
|
||||||
htmlparser2@8.0.2:
|
htmlparser2@8.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype: 2.3.0
|
domelementtype: 2.3.0
|
||||||
@@ -18193,7 +18266,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
next-i18next@15.4.2(i18next@23.16.8)(next@14.2.32(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
|
next-i18next@15.4.2(i18next@23.16.8)(next@14.2.32(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.26.10
|
'@babel/runtime': 7.26.10
|
||||||
'@types/hoist-non-react-statics': 3.3.6
|
'@types/hoist-non-react-statics': 3.3.6
|
||||||
@@ -18826,6 +18899,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
xtend: 4.0.2
|
xtend: 4.0.2
|
||||||
|
|
||||||
|
property-information@6.5.0: {}
|
||||||
|
|
||||||
property-information@7.0.0: {}
|
property-information@7.0.0: {}
|
||||||
|
|
||||||
proto-list@1.2.4: {}
|
proto-list@1.2.4: {}
|
||||||
@@ -19231,6 +19306,12 @@ snapshots:
|
|||||||
unist-util-visit-parents: 6.0.1
|
unist-util-visit-parents: 6.0.1
|
||||||
vfile: 6.0.3
|
vfile: 6.0.3
|
||||||
|
|
||||||
|
rehype-raw@7.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 3.0.4
|
||||||
|
hast-util-raw: 9.1.0
|
||||||
|
vfile: 6.0.3
|
||||||
|
|
||||||
remark-breaks@4.0.0:
|
remark-breaks@4.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/mdast': 4.0.4
|
'@types/mdast': 4.0.4
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
"axios": "^1.12.1",
|
"axios": "^1.12.1",
|
||||||
"date-fns": "2.30.0",
|
"date-fns": "2.30.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
|
"dompurify": "^3.2.7",
|
||||||
"echarts": "5.4.1",
|
"echarts": "5.4.1",
|
||||||
"echarts-gl": "2.0.9",
|
"echarts-gl": "2.0.9",
|
||||||
"framer-motion": "9.1.7",
|
"framer-motion": "9.1.7",
|
||||||
@@ -58,6 +59,7 @@
|
|||||||
"recharts": "^2.15.0",
|
"recharts": "^2.15.0",
|
||||||
"rehype-external-links": "^3.0.0",
|
"rehype-external-links": "^3.0.0",
|
||||||
"rehype-katex": "^7.0.0",
|
"rehype-katex": "^7.0.0",
|
||||||
|
"rehype-raw": "^7.0.0",
|
||||||
"remark-breaks": "^4.0.0",
|
"remark-breaks": "^4.0.0",
|
||||||
"remark-gfm": "^4.0.0",
|
"remark-gfm": "^4.0.0",
|
||||||
"remark-math": "^6.0.0",
|
"remark-math": "^6.0.0",
|
||||||
@@ -68,6 +70,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@svgr/webpack": "^6.5.1",
|
"@svgr/webpack": "^6.5.1",
|
||||||
|
"@types/dompurify": "^3.2.0",
|
||||||
"@types/js-yaml": "^4.0.9",
|
"@types/js-yaml": "^4.0.9",
|
||||||
"@types/jsonwebtoken": "^9.0.3",
|
"@types/jsonwebtoken": "^9.0.3",
|
||||||
"@types/lodash": "^4.14.191",
|
"@types/lodash": "^4.14.191",
|
||||||
|
@@ -23,7 +23,6 @@ import Markdown from '.';
|
|||||||
import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils';
|
import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils';
|
||||||
import { Types } from 'mongoose';
|
import { Types } from 'mongoose';
|
||||||
import type { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
|
import type { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
|
||||||
import { useCreation } from 'ahooks';
|
|
||||||
|
|
||||||
export type AProps = {
|
export type AProps = {
|
||||||
chatAuthData?: {
|
chatAuthData?: {
|
||||||
|
@@ -0,0 +1,8 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
const Divider: React.FC = () => {
|
||||||
|
return <Box width="100%" height="1px" bg="gray.200" my={4} mx="auto" />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Divider;
|
@@ -0,0 +1,65 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Box, Text, VStack, Flex } from '@chakra-ui/react';
|
||||||
|
import { useSafeTranslation } from '@fastgpt/web/hooks/useSafeTranslation';
|
||||||
|
|
||||||
|
type IndicatorCardProps = {
|
||||||
|
dataList: {
|
||||||
|
name: string;
|
||||||
|
value: string | number;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const IndicatorCard: React.FC<IndicatorCardProps> = ({ dataList }) => {
|
||||||
|
const { t } = useSafeTranslation();
|
||||||
|
if (!dataList || !Array.isArray(dataList) || dataList.length === 0) {
|
||||||
|
return <Box>No indicator data available</Box>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<VStack align="stretch">
|
||||||
|
{dataList.map((indicator, index) => (
|
||||||
|
<Flex align="stretch" w="250px" key={index} gap={1} mt={1}>
|
||||||
|
<Flex w="5px" bg="blue.500"></Flex>
|
||||||
|
<Flex
|
||||||
|
flex="1"
|
||||||
|
borderRadius="md"
|
||||||
|
bg="gray.100"
|
||||||
|
display="flex"
|
||||||
|
flexDirection="column"
|
||||||
|
overflow="hidden"
|
||||||
|
>
|
||||||
|
{/* indicator name */}
|
||||||
|
<Flex w="full">
|
||||||
|
<Text
|
||||||
|
color="gray.800"
|
||||||
|
fontSize="sm"
|
||||||
|
fontWeight="normal"
|
||||||
|
textAlign="right"
|
||||||
|
flex="1"
|
||||||
|
noOfLines={1}
|
||||||
|
>
|
||||||
|
{indicator.name}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
{/* indicator value and unit */}
|
||||||
|
<Flex w="full">
|
||||||
|
<Text
|
||||||
|
color="blue.500"
|
||||||
|
fontSize="lg"
|
||||||
|
fontWeight="bold"
|
||||||
|
textAlign="right"
|
||||||
|
flex="1"
|
||||||
|
noOfLines={1}
|
||||||
|
>
|
||||||
|
{indicator.value || t('common:core.chat.indicator.no_data')}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
))}
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default IndicatorCard;
|
31
projects/app/src/components/Markdown/codeBlock/Link.tsx
Normal file
31
projects/app/src/components/Markdown/codeBlock/Link.tsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Box, Text, Link, Flex } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
const LinkBlock: React.FC<{ data: { text: string; url: string } }> = ({ data }) => {
|
||||||
|
const handleClick = () => {
|
||||||
|
window.open(data.url, '_blank', 'noopener,noreferrer');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box my={4}>
|
||||||
|
<Link
|
||||||
|
onClick={handleClick}
|
||||||
|
cursor="pointer"
|
||||||
|
textDecoration="none"
|
||||||
|
_hover={{ textDecoration: 'none' }}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
fontWeight="medium"
|
||||||
|
color="blue.600"
|
||||||
|
_hover={{ color: 'blue.700' }}
|
||||||
|
noOfLines={1}
|
||||||
|
flex="1"
|
||||||
|
>
|
||||||
|
{data.text}
|
||||||
|
</Text>
|
||||||
|
</Link>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LinkBlock;
|
142
projects/app/src/components/Markdown/codeBlock/Table.tsx
Normal file
142
projects/app/src/components/Markdown/codeBlock/Table.tsx
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import React, { useState, useMemo } from 'react';
|
||||||
|
import { Box, Flex, Text, Grid } from '@chakra-ui/react';
|
||||||
|
import Icon from '@fastgpt/web/components/common/Icon';
|
||||||
|
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||||
|
import { useSafeTranslation } from '@fastgpt/web/hooks/useSafeTranslation';
|
||||||
|
|
||||||
|
const TableBlock: React.FC<{ code: string }> = ({ code }) => {
|
||||||
|
const { t } = useSafeTranslation();
|
||||||
|
const tableData = JSON.parse(code);
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [perPage, setPerPage] = useState(10);
|
||||||
|
|
||||||
|
const headers = Object.keys(tableData[0]);
|
||||||
|
|
||||||
|
// calculate paginated data
|
||||||
|
const { paginatedData, totalPages } = useMemo(() => {
|
||||||
|
const total = Math.ceil(tableData.length / perPage);
|
||||||
|
const startIndex = (currentPage - 1) * perPage;
|
||||||
|
const endIndex = startIndex + perPage;
|
||||||
|
const paginated = tableData.slice(startIndex, endIndex);
|
||||||
|
|
||||||
|
return {
|
||||||
|
paginatedData: paginated,
|
||||||
|
totalPages: total
|
||||||
|
};
|
||||||
|
}, [tableData, currentPage, perPage]);
|
||||||
|
|
||||||
|
const handlePrevPage = () => {
|
||||||
|
setCurrentPage((prev) => Math.max(prev - 1, 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNextPage = () => {
|
||||||
|
setCurrentPage((prev) => Math.min(prev + 1, totalPages));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePerPageChange = (value: string) => {
|
||||||
|
setPerPage(Number(value));
|
||||||
|
setCurrentPage(1); // reset to first page
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box my={4}>
|
||||||
|
<Flex overflowX="auto">
|
||||||
|
<table style={{ width: '100%', borderCollapse: 'collapse', border: '1px solid #e2e8f0' }}>
|
||||||
|
<thead>
|
||||||
|
<tr style={{ backgroundColor: '#f7fafc' }}>
|
||||||
|
{headers.map((header, index) => (
|
||||||
|
<th
|
||||||
|
key={index}
|
||||||
|
style={{
|
||||||
|
padding: '12px',
|
||||||
|
border: '1px solid #e2e8f0',
|
||||||
|
textAlign: 'left',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{header}
|
||||||
|
</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{paginatedData.map((row: any, rowIndex: number) => (
|
||||||
|
<tr
|
||||||
|
key={rowIndex}
|
||||||
|
style={{ backgroundColor: rowIndex % 2 === 0 ? '#ffffff' : '#f9f9f9' }}
|
||||||
|
>
|
||||||
|
{headers.map((header, colIndex) => (
|
||||||
|
<td
|
||||||
|
key={colIndex}
|
||||||
|
style={{
|
||||||
|
padding: '12px',
|
||||||
|
border: '1px solid #e2e8f0',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{row[header] || ''}
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Grid width="full" gridTemplateColumns="1fr auto 1fr" alignItems="center" gap={4}>
|
||||||
|
<Flex gap={1} align="center" gridColumn="2">
|
||||||
|
<Icon
|
||||||
|
name="core/chat/chevronLeft"
|
||||||
|
w="16px"
|
||||||
|
height="16px"
|
||||||
|
cursor={currentPage === 1 ? 'not-allowed' : 'pointer'}
|
||||||
|
opacity={currentPage === 1 ? 0.5 : 1}
|
||||||
|
onClick={currentPage === 1 ? undefined : handlePrevPage}
|
||||||
|
/>
|
||||||
|
<Text>
|
||||||
|
{currentPage} / {totalPages}
|
||||||
|
</Text>
|
||||||
|
<Icon
|
||||||
|
name="core/chat/chevronRight"
|
||||||
|
w="16px"
|
||||||
|
height="16px"
|
||||||
|
cursor={currentPage === totalPages ? 'not-allowed' : 'pointer'}
|
||||||
|
opacity={currentPage === totalPages ? 0.5 : 1}
|
||||||
|
onClick={currentPage === totalPages ? undefined : handleNextPage}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
{totalPages > 1 && (
|
||||||
|
<Flex gridColumn="3">
|
||||||
|
<MySelect
|
||||||
|
value={perPage.toString()}
|
||||||
|
onChange={handlePerPageChange}
|
||||||
|
list={[
|
||||||
|
{ label: t('common:core.chat.table.per_page', { num: 5 }), value: '5' },
|
||||||
|
{
|
||||||
|
label: t('common:core.chat.table.per_page', { num: 10 }),
|
||||||
|
value: '10'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('common:core.chat.table.per_page', { num: 20 }),
|
||||||
|
value: '20'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('common:core.chat.table.per_page', { num: 50 }),
|
||||||
|
value: '50'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('common:core.chat.table.per_page', { num: 100 }),
|
||||||
|
value: '100'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TableBlock;
|
88
projects/app/src/components/Markdown/codeBlock/TextBlock.tsx
Normal file
88
projects/app/src/components/Markdown/codeBlock/TextBlock.tsx
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import React, { useState, useMemo } from 'react';
|
||||||
|
import { Box, Button, Collapse, Flex } from '@chakra-ui/react';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
import RemarkMath from 'remark-math';
|
||||||
|
import RemarkBreaks from 'remark-breaks';
|
||||||
|
import RehypeKatex from 'rehype-katex';
|
||||||
|
import RemarkGfm from 'remark-gfm';
|
||||||
|
import RehypeExternalLinks from 'rehype-external-links';
|
||||||
|
import { useSafeTranslation } from '@fastgpt/web/hooks/useSafeTranslation';
|
||||||
|
|
||||||
|
const TextBlock: React.FC<{ content: string }> = ({ content }) => {
|
||||||
|
const { t } = useSafeTranslation();
|
||||||
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
|
|
||||||
|
const { preview, detail, hasNewlines } = useMemo(() => {
|
||||||
|
const hasNewlines = content.includes('\n');
|
||||||
|
|
||||||
|
if (!hasNewlines) {
|
||||||
|
return { preview: content, detail: '', hasNewlines: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
const lines = content.split('\n');
|
||||||
|
return {
|
||||||
|
preview: lines[0],
|
||||||
|
detail: lines.slice(1).join('\n'),
|
||||||
|
hasNewlines: true
|
||||||
|
};
|
||||||
|
}, [content]);
|
||||||
|
|
||||||
|
const buttonProps = {
|
||||||
|
size: 'xs' as const,
|
||||||
|
variant: 'ghost' as const,
|
||||||
|
colorScheme: 'blue' as const,
|
||||||
|
_hover: { bg: 'blue.50' }
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
w="90%"
|
||||||
|
mx="auto"
|
||||||
|
mt={2}
|
||||||
|
p={4}
|
||||||
|
bg="gray.200"
|
||||||
|
border="1px solid"
|
||||||
|
borderColor="gray.200"
|
||||||
|
borderRadius="md"
|
||||||
|
fontSize="sm"
|
||||||
|
lineHeight="1.6"
|
||||||
|
>
|
||||||
|
<ReactMarkdown
|
||||||
|
remarkPlugins={[RemarkMath, [RemarkGfm, { singleTilde: false }], RemarkBreaks]}
|
||||||
|
rehypePlugins={[RehypeKatex, [RehypeExternalLinks, { target: '_blank' }]]}
|
||||||
|
>
|
||||||
|
{preview}
|
||||||
|
</ReactMarkdown>
|
||||||
|
|
||||||
|
{hasNewlines && (
|
||||||
|
<>
|
||||||
|
{!isExpanded && (
|
||||||
|
<Flex justify="flex-end">
|
||||||
|
<Button {...buttonProps} onClick={() => setIsExpanded(true)}>
|
||||||
|
{t('common:core.chat.response.Read complete response')}
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Collapse in={isExpanded} animateOpacity>
|
||||||
|
<Box borderTop="1px solid" borderColor="gray.200">
|
||||||
|
<ReactMarkdown
|
||||||
|
remarkPlugins={[RemarkMath, [RemarkGfm, { singleTilde: false }], RemarkBreaks]}
|
||||||
|
rehypePlugins={[RehypeKatex, [RehypeExternalLinks, { target: '_blank' }]]}
|
||||||
|
>
|
||||||
|
{detail}
|
||||||
|
</ReactMarkdown>
|
||||||
|
<Flex justify="flex-end">
|
||||||
|
<Button {...buttonProps} onClick={() => setIsExpanded(false)}>
|
||||||
|
{t('common:core.chat.response.Fold response')}
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Box>
|
||||||
|
</Collapse>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TextBlock;
|
36
projects/app/src/components/Markdown/codeBlock/Tips.tsx
Normal file
36
projects/app/src/components/Markdown/codeBlock/Tips.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Text, Flex } from '@chakra-ui/react';
|
||||||
|
import Icon from '@fastgpt/web/components/common/Icon';
|
||||||
|
|
||||||
|
interface TipsProps {
|
||||||
|
content: string;
|
||||||
|
type?: 'error' | 'warning';
|
||||||
|
}
|
||||||
|
|
||||||
|
const Tips: React.FC<TipsProps> = ({ content, type = 'error' }) => {
|
||||||
|
const isError = type === 'error';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
align="center"
|
||||||
|
p={4}
|
||||||
|
bg={isError ? 'red.50' : 'yellow.50'}
|
||||||
|
border="1px solid"
|
||||||
|
borderColor={isError ? 'red.200' : 'yellow.200'}
|
||||||
|
borderRadius="md"
|
||||||
|
gap={3}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
name={isError ? 'common/errorFill' : 'common/errorFill'}
|
||||||
|
w="20px"
|
||||||
|
h="20px"
|
||||||
|
color={isError ? 'red.500' : 'yellow.500'}
|
||||||
|
/>
|
||||||
|
<Text color={isError ? 'red.700' : 'yellow.700'} fontSize="sm" fontWeight="medium">
|
||||||
|
{content}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Tips;
|
@@ -7,12 +7,42 @@ import { useMount } from 'ahooks';
|
|||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
import { useScreen } from '@fastgpt/web/hooks/useScreen';
|
import { useScreen } from '@fastgpt/web/hooks/useScreen';
|
||||||
|
|
||||||
|
type EChartsGrid = {
|
||||||
|
top: string;
|
||||||
|
left: string;
|
||||||
|
bottom: string;
|
||||||
|
right: string;
|
||||||
|
containLabel: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type EChartsSeries = {
|
||||||
|
data: number[];
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type EChartsConfig = {
|
||||||
|
xAxis: { data: string[]; type: string }[];
|
||||||
|
yAxis: { type: string }[];
|
||||||
|
grid: EChartsGrid;
|
||||||
|
legend: { show: boolean };
|
||||||
|
series: EChartsSeries[];
|
||||||
|
tooltip: { trigger: string };
|
||||||
|
dataZoom: unknown[];
|
||||||
|
};
|
||||||
|
|
||||||
const EChartsCodeBlock = ({ code }: { code: string }) => {
|
const EChartsCodeBlock = ({ code }: { code: string }) => {
|
||||||
const chartRef = useRef<HTMLDivElement>(null);
|
const chartRef = useRef<HTMLDivElement>(null);
|
||||||
const eChart = useRef<ECharts>();
|
const eChart = useRef<ECharts>();
|
||||||
const { isPc } = useSystem();
|
const { isPc } = useSystem();
|
||||||
const [option, setOption] = useState<any>();
|
const [option, setOption] = useState<EChartsConfig>();
|
||||||
const [width, setWidth] = useState(400);
|
const [width, setWidth] = useState(400);
|
||||||
|
const [dataRange, setDataRange] = useState({ start: 0, end: 100 });
|
||||||
|
const [totalDataLength, setTotalDataLength] = useState(0);
|
||||||
|
const [originalXData, setOriginalXData] = useState<string[]>([]);
|
||||||
|
const [originalYData, setOriginalYData] = useState<number[]>([]);
|
||||||
|
const dragStartTime = useRef<number>(0);
|
||||||
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
|
|
||||||
const findMarkdownDom = useCallback(() => {
|
const findMarkdownDom = useCallback(() => {
|
||||||
if (!chartRef.current) return;
|
if (!chartRef.current) return;
|
||||||
@@ -29,39 +59,176 @@ const EChartsCodeBlock = ({ code }: { code: string }) => {
|
|||||||
return parent?.parentElement;
|
return parent?.parentElement;
|
||||||
}, [isPc]);
|
}, [isPc]);
|
||||||
|
|
||||||
|
// filter data
|
||||||
|
const filterDataByRange = useCallback(
|
||||||
|
(originalXData: string[], originalYData: number[], range: { start: number; end: number }) => {
|
||||||
|
if (!originalXData.length || !originalYData.length) return { xData: [], yData: [] };
|
||||||
|
|
||||||
|
const totalLength = Math.min(originalXData.length, originalYData.length);
|
||||||
|
|
||||||
|
const startIndex = Math.floor((range.start / 100) * totalLength);
|
||||||
|
const endIndex = Math.min(totalLength, Math.ceil((range.end / 100) * totalLength));
|
||||||
|
|
||||||
|
const actualEndIndex = Math.max(startIndex + 1, endIndex);
|
||||||
|
|
||||||
|
// slice data
|
||||||
|
const filteredXData = originalXData.slice(startIndex, actualEndIndex);
|
||||||
|
const filteredYData = originalYData.slice(startIndex, actualEndIndex);
|
||||||
|
|
||||||
|
return { xData: filteredXData, yData: filteredYData };
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
// x and y data extraction
|
||||||
|
const extractXYData = useCallback((echartsConfig: EChartsConfig) => {
|
||||||
|
const emptyResult = {
|
||||||
|
xData: [] as string[],
|
||||||
|
yData: [] as number[],
|
||||||
|
chartContent: null as EChartsConfig | null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (echartsConfig?.series?.length > 0 && echartsConfig?.xAxis?.length > 0) {
|
||||||
|
const series = echartsConfig.series[0];
|
||||||
|
const xAxis = echartsConfig.xAxis[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
xData: xAxis.data || [],
|
||||||
|
yData: series.data || [],
|
||||||
|
chartContent: echartsConfig
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return emptyResult;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// abstract chart render function
|
||||||
|
const createChartOption = useCallback(
|
||||||
|
(xData: string[], yData: number[], chartContent?: EChartsConfig | null) => {
|
||||||
|
if (chartContent) {
|
||||||
|
return {
|
||||||
|
...chartContent,
|
||||||
|
xAxis: chartContent.xAxis.map((axis) => ({
|
||||||
|
...axis,
|
||||||
|
data: xData
|
||||||
|
})),
|
||||||
|
series: chartContent.series.map((series) => ({
|
||||||
|
...series,
|
||||||
|
data: yData
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to default config
|
||||||
|
return {
|
||||||
|
grid: {
|
||||||
|
bottom: '15%',
|
||||||
|
left: '5%',
|
||||||
|
right: '5%',
|
||||||
|
top: '10%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: xData,
|
||||||
|
boundaryGap: true,
|
||||||
|
axisTick: {
|
||||||
|
alignWithLabel: true,
|
||||||
|
interval: 0
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
interval: (() => {
|
||||||
|
const dataLength = xData.length;
|
||||||
|
if (dataLength <= 10) return 0;
|
||||||
|
if (dataLength <= 20) return 1;
|
||||||
|
if (dataLength <= 50) return Math.floor(dataLength / 10);
|
||||||
|
return Math.floor(dataLength / 15);
|
||||||
|
})(),
|
||||||
|
rotate: 45,
|
||||||
|
fontSize: 10,
|
||||||
|
formatter: (value: string) => {
|
||||||
|
return value && value.length > 20 ? `${value.substring(0, 20)}...` : value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
scale: true
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'bar',
|
||||||
|
data: yData,
|
||||||
|
barCategoryGap: '20%',
|
||||||
|
itemStyle: {
|
||||||
|
borderRadius: [4, 4, 0, 0]
|
||||||
|
},
|
||||||
|
name: 'Data'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
formatter: function (params: Array<{ name: string; seriesName: string; value: number }>) {
|
||||||
|
if (Array.isArray(params) && params.length > 0) {
|
||||||
|
const param = params[0];
|
||||||
|
return `${param.name}<br/>${param.seriesName}: ${param.value}`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
useMount(() => {
|
useMount(() => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import('echarts-gl');
|
import('echarts-gl');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// generate and update chart option
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const option = (() => {
|
try {
|
||||||
try {
|
const rawConfig: EChartsConfig = json5.parse(code.trim());
|
||||||
const parse = {
|
|
||||||
...json5.parse(code.trim()),
|
|
||||||
toolbox: {
|
|
||||||
// show: true,
|
|
||||||
feature: {
|
|
||||||
saveAsImage: {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return parse;
|
const { xData, yData, chartContent } = extractXYData(rawConfig);
|
||||||
} catch (error) {}
|
|
||||||
})();
|
|
||||||
|
|
||||||
setOption(option ?? {});
|
if (xData.length === 0 || yData.length === 0) {
|
||||||
|
return;
|
||||||
if (!option) return;
|
|
||||||
|
|
||||||
if (chartRef.current) {
|
|
||||||
try {
|
|
||||||
eChart.current = echarts.init(chartRef.current);
|
|
||||||
eChart.current.setOption(option);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('ECharts render failed:', error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setOriginalXData(xData);
|
||||||
|
setOriginalYData(yData);
|
||||||
|
setTotalDataLength(Math.min(xData.length, yData.length));
|
||||||
|
|
||||||
|
const { xData: filteredXData, yData: filteredYData } = filterDataByRange(
|
||||||
|
xData,
|
||||||
|
yData,
|
||||||
|
dataRange
|
||||||
|
);
|
||||||
|
|
||||||
|
const chartOption = createChartOption(filteredXData, filteredYData, chartContent);
|
||||||
|
|
||||||
|
// Add toolbox for image saving
|
||||||
|
const RenderOption = {
|
||||||
|
...chartOption,
|
||||||
|
toolbox: {
|
||||||
|
feature: {
|
||||||
|
saveAsImage: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setOption(RenderOption as EChartsConfig);
|
||||||
|
|
||||||
|
if (chartRef.current) {
|
||||||
|
if (!eChart.current) {
|
||||||
|
eChart.current = echarts.init(chartRef.current);
|
||||||
|
}
|
||||||
|
eChart.current.setOption(RenderOption);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('ECharts render failed:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
findMarkdownDom();
|
findMarkdownDom();
|
||||||
@@ -69,25 +236,159 @@ const EChartsCodeBlock = ({ code }: { code: string }) => {
|
|||||||
return () => {
|
return () => {
|
||||||
if (eChart.current) {
|
if (eChart.current) {
|
||||||
eChart.current.dispose();
|
eChart.current.dispose();
|
||||||
|
eChart.current = undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [code, findMarkdownDom]);
|
}, [code, findMarkdownDom, filterDataByRange, dataRange, createChartOption, extractXYData]);
|
||||||
|
|
||||||
const { screenWidth } = useScreen();
|
const { screenWidth } = useScreen();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
findMarkdownDom();
|
findMarkdownDom();
|
||||||
}, [screenWidth]);
|
}, [screenWidth, findMarkdownDom]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
eChart.current?.resize();
|
eChart.current?.resize();
|
||||||
}, [width]);
|
}, [width]);
|
||||||
|
|
||||||
|
// slider control
|
||||||
|
const handleRangeChange = useCallback((newRange: { start: number; end: number }) => {
|
||||||
|
setDataRange(newRange);
|
||||||
|
}, []);
|
||||||
|
// handle drag
|
||||||
|
const handleDrag = useCallback(
|
||||||
|
(type: 'left' | 'right' | 'range', e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
setIsDragging(false);
|
||||||
|
dragStartTime.current = Date.now();
|
||||||
|
const startX = e.clientX;
|
||||||
|
const { start: startValue, end: endValue } = dataRange;
|
||||||
|
const rangeWidth = endValue - startValue;
|
||||||
|
|
||||||
|
const handleMouseMove = (moveEvent: MouseEvent) => {
|
||||||
|
const deltaX = Math.abs(moveEvent.clientX - startX);
|
||||||
|
const timeDelta = Date.now() - dragStartTime.current;
|
||||||
|
|
||||||
|
if (deltaX > 5 || timeDelta > 100) {
|
||||||
|
setIsDragging(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const deltaPercent = ((moveEvent.clientX - startX) / Math.max(width, 400)) * 100;
|
||||||
|
|
||||||
|
// drag handle
|
||||||
|
if (type === 'left') {
|
||||||
|
const newStart = Math.max(0, Math.min(startValue + deltaPercent, endValue));
|
||||||
|
handleRangeChange({ start: newStart, end: endValue });
|
||||||
|
} else if (type === 'right') {
|
||||||
|
const newEnd = Math.min(100, Math.max(endValue + deltaPercent, startValue));
|
||||||
|
handleRangeChange({ start: startValue, end: newEnd });
|
||||||
|
} else if (type === 'range') {
|
||||||
|
const newStart = Math.max(0, Math.min(startValue + deltaPercent, 100 - rangeWidth));
|
||||||
|
handleRangeChange({ start: newStart, end: newStart + rangeWidth });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseUp = () => {
|
||||||
|
document.removeEventListener('mousemove', handleMouseMove);
|
||||||
|
document.removeEventListener('mouseup', handleMouseUp);
|
||||||
|
setTimeout(() => setIsDragging(false), 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', handleMouseMove);
|
||||||
|
document.addEventListener('mouseup', handleMouseUp);
|
||||||
|
},
|
||||||
|
[dataRange, width, handleRangeChange]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box overflowX={'auto'} bg={'white'} borderRadius={'md'}>
|
<Box overflowX={'auto'} bg={'white'} borderRadius={'md'}>
|
||||||
<Box h={'400px'} w={`${width}px`} ref={chartRef} />
|
<Box h={'400px'} w={`${width}px`} ref={chartRef} />
|
||||||
{!option && (
|
{!option && (
|
||||||
<Skeleton isLoaded={true} fadeDuration={2} h={'400px'} w={`${width}px`}></Skeleton>
|
<Skeleton isLoaded={true} fadeDuration={2} h={'400px'} w={`${width}px`}></Skeleton>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* data range slider */}
|
||||||
|
{option && totalDataLength > 1 && (
|
||||||
|
<Box borderTop="1px solid #e2e8f0">
|
||||||
|
<Box
|
||||||
|
position="relative"
|
||||||
|
h="40px"
|
||||||
|
w={`${width}px`}
|
||||||
|
minW="400px"
|
||||||
|
bg="gray.50"
|
||||||
|
borderRadius="md"
|
||||||
|
overflow="hidden"
|
||||||
|
cursor="pointer"
|
||||||
|
onClick={(e) => {
|
||||||
|
if (!isDragging) {
|
||||||
|
const rect = e.currentTarget.getBoundingClientRect();
|
||||||
|
const percentage = ((e.clientX - rect.left) / rect.width) * 100;
|
||||||
|
const halfWidth = 10;
|
||||||
|
|
||||||
|
const newStart = Math.max(0, Math.min(percentage - halfWidth, 80));
|
||||||
|
const newEnd = Math.min(100, Math.max(percentage + halfWidth, 20));
|
||||||
|
handleRangeChange({ start: newStart, end: newEnd });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* data thumbnail */}
|
||||||
|
{originalYData.length > 0 && (
|
||||||
|
<svg width="100%" height="100%" style={{ position: 'absolute' }}>
|
||||||
|
<polyline
|
||||||
|
points={(() => {
|
||||||
|
const maxVal = Math.max(...originalYData);
|
||||||
|
const minVal = Math.min(...originalYData);
|
||||||
|
const range = maxVal - minVal || 1;
|
||||||
|
|
||||||
|
return originalYData
|
||||||
|
.map((value, index) => {
|
||||||
|
const x = (index / (originalYData.length - 1)) * (width - 8) + 4;
|
||||||
|
const y = 36 - ((value - minVal) / range) * 32;
|
||||||
|
return `${x},${y}`;
|
||||||
|
})
|
||||||
|
.join(' ');
|
||||||
|
})()}
|
||||||
|
fill="none"
|
||||||
|
stroke="#93c5fd"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
opacity="0.7"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* select area */}
|
||||||
|
<Box
|
||||||
|
position="absolute"
|
||||||
|
left={`${dataRange.start}%`}
|
||||||
|
width={`${dataRange.end - dataRange.start}%`}
|
||||||
|
h="100%"
|
||||||
|
bg="rgba(59, 130, 246, 0.2)"
|
||||||
|
cursor="ew-resize"
|
||||||
|
onMouseDown={(e) => handleDrag('range', e)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* left and right drag handle */}
|
||||||
|
<Box
|
||||||
|
position="absolute"
|
||||||
|
left={`${dataRange.start}%`}
|
||||||
|
w="8px"
|
||||||
|
h="100%"
|
||||||
|
cursor="ew-resize"
|
||||||
|
transform="translateX(-50%)"
|
||||||
|
onMouseDown={(e) => handleDrag('left', e)}
|
||||||
|
/>
|
||||||
|
<Box
|
||||||
|
position="absolute"
|
||||||
|
left={`${dataRange.end}%`}
|
||||||
|
w="8px"
|
||||||
|
h="100%"
|
||||||
|
cursor="ew-resize"
|
||||||
|
transform="translateX(-50%)"
|
||||||
|
onMouseDown={(e) => handleDrag('right', e)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -1,19 +1,22 @@
|
|||||||
|
import 'katex/dist/katex.min.css';
|
||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import 'katex/dist/katex.min.css';
|
|
||||||
import RemarkMath from 'remark-math'; // Math syntax
|
|
||||||
import RemarkBreaks from 'remark-breaks'; // Line break
|
|
||||||
import RehypeKatex from 'rehype-katex'; // Math render
|
|
||||||
import RemarkGfm from 'remark-gfm'; // Special markdown syntax
|
|
||||||
import RehypeExternalLinks from 'rehype-external-links';
|
import RehypeExternalLinks from 'rehype-external-links';
|
||||||
|
import RehypeKatex from 'rehype-katex'; // Math render
|
||||||
|
import RehypeRaw from 'rehype-raw';
|
||||||
|
import RemarkBreaks from 'remark-breaks'; // Line break
|
||||||
|
import RemarkGfm from 'remark-gfm'; // Special markdown syntax
|
||||||
|
import RemarkMath from 'remark-math'; // Math syntax
|
||||||
|
|
||||||
import styles from './index.module.scss';
|
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
|
import styles from './index.module.scss';
|
||||||
|
|
||||||
import { Box } from '@chakra-ui/react';
|
import { Box } from '@chakra-ui/react';
|
||||||
import { CodeClassNameEnum, mdTextFormat } from './utils';
|
|
||||||
import { useCreation } from 'ahooks';
|
import { useCreation } from 'ahooks';
|
||||||
import type { AProps } from './A';
|
import type { AProps } from './A';
|
||||||
|
import { CodeClassNameEnum } from './utils';
|
||||||
|
|
||||||
|
import DomPurify from 'dompurify';
|
||||||
|
|
||||||
const CodeLight = dynamic(() => import('./codeBlock/CodeLight'), { ssr: false });
|
const CodeLight = dynamic(() => import('./codeBlock/CodeLight'), { ssr: false });
|
||||||
const MermaidCodeBlock = dynamic(() => import('./img/MermaidCodeBlock'), { ssr: false });
|
const MermaidCodeBlock = dynamic(() => import('./img/MermaidCodeBlock'), { ssr: false });
|
||||||
@@ -23,11 +26,19 @@ const IframeCodeBlock = dynamic(() => import('./codeBlock/Iframe'), { ssr: false
|
|||||||
const IframeHtmlCodeBlock = dynamic(() => import('./codeBlock/iframe-html'), { ssr: false });
|
const IframeHtmlCodeBlock = dynamic(() => import('./codeBlock/iframe-html'), { ssr: false });
|
||||||
const VideoBlock = dynamic(() => import('./codeBlock/Video'), { ssr: false });
|
const VideoBlock = dynamic(() => import('./codeBlock/Video'), { ssr: false });
|
||||||
const AudioBlock = dynamic(() => import('./codeBlock/Audio'), { ssr: false });
|
const AudioBlock = dynamic(() => import('./codeBlock/Audio'), { ssr: false });
|
||||||
|
const TableBlock = dynamic(() => import('./codeBlock/Table'), { ssr: false });
|
||||||
|
const IndicatorCard = dynamic(() => import('./codeBlock/IndicatorCard'), { ssr: false });
|
||||||
|
const LinkBlock = dynamic(() => import('./codeBlock/Link'), { ssr: false });
|
||||||
|
const Tips = dynamic(() => import('./codeBlock/Tips'), { ssr: false });
|
||||||
|
const Divider = dynamic(() => import('./codeBlock/Divider'), { ssr: false });
|
||||||
|
const TextBlock = dynamic(() => import('./codeBlock/TextBlock'), { ssr: false });
|
||||||
|
|
||||||
const ChatGuide = dynamic(() => import('./chat/Guide'), { ssr: false });
|
const ChatGuide = dynamic(() => import('./chat/Guide'), { ssr: false });
|
||||||
const QuestionGuide = dynamic(() => import('./chat/QuestionGuide'), { ssr: false });
|
const QuestionGuide = dynamic(() => import('./chat/QuestionGuide'), { ssr: false });
|
||||||
const A = dynamic(() => import('./A'), { ssr: false });
|
const A = dynamic(() => import('./A'), { ssr: false });
|
||||||
|
|
||||||
|
const formatCodeBlock = (lang: string, content: string) => `\`\`\`${lang}\n${content}\n\`\`\``;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
source?: string;
|
source?: string;
|
||||||
showAnimation?: boolean;
|
showAnimation?: boolean;
|
||||||
@@ -68,10 +79,79 @@ const MarkdownRender = ({
|
|||||||
};
|
};
|
||||||
}, [chatAuthData, onOpenCiteModal, showAnimation]);
|
}, [chatAuthData, onOpenCiteModal, showAnimation]);
|
||||||
|
|
||||||
|
// convert single item to Markdown
|
||||||
|
const convertRenderBlockToMarkdown = useCallback((jsonContent: string): string => {
|
||||||
|
const converItem = (type: string, content: any) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'TEXT':
|
||||||
|
return (typeof content === 'string' ? content : JSON.stringify(content)) + '\n\n';
|
||||||
|
|
||||||
|
case 'CHART':
|
||||||
|
return content?.hasChart && content?.echartsData
|
||||||
|
? `\`\`\`echarts\n${JSON.stringify(content.echartsData, null, 2)}\n\`\`\`\n\n`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
case 'TABLE':
|
||||||
|
return content?.data
|
||||||
|
? `\`\`\`table\n${JSON.stringify(content.data, null, 2)}\n\`\`\`\n\n`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
case 'INDICATOR':
|
||||||
|
return content?.dataList
|
||||||
|
? `\`\`\`indicator\n${JSON.stringify(content.dataList, null, 2)}\n\`\`\`\n\n`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
case 'LINK':
|
||||||
|
return content?.text && content?.url
|
||||||
|
? `\`\`\`link\n${JSON.stringify(content, null, 2)}\n\`\`\`\n\n`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
case 'ERROR_TIPS':
|
||||||
|
return content ? `\`\`\`error_tips\n${content}\n\`\`\`\n\n` : '';
|
||||||
|
|
||||||
|
case 'WARNING_TIPS':
|
||||||
|
return content ? `\`\`\`warning_tips\n${content}\n\`\`\`\n\n` : '';
|
||||||
|
|
||||||
|
case 'DIVIDER':
|
||||||
|
return `\`\`\`divider\n\n\`\`\`\n\n`;
|
||||||
|
|
||||||
|
case 'TEXTBLOCK':
|
||||||
|
return content ? `\`\`\`textblock\n${content}\n\`\`\`\n\n` : '';
|
||||||
|
|
||||||
|
default:
|
||||||
|
return formatCodeBlock('json', jsonContent);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const jsonObj = JSON.parse(jsonContent);
|
||||||
|
if (Array.isArray(jsonObj)) {
|
||||||
|
return jsonObj.map((item) => converItem(item.type, item.content)).join(`\n\n`);
|
||||||
|
} else {
|
||||||
|
return converItem(jsonObj.type, jsonObj.content);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return formatCodeBlock('json', jsonContent);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const formatSource = useMemo(() => {
|
const formatSource = useMemo(() => {
|
||||||
if (showAnimation || forbidZhFormat) return source;
|
if (showAnimation || forbidZhFormat) return source;
|
||||||
return mdTextFormat(source);
|
|
||||||
}, [forbidZhFormat, showAnimation, source]);
|
const result = source.replace(/```RENDER([\s\S]*?)```/g, (match, p1) => {
|
||||||
|
// p1: the content inside ```RENDER ... ```
|
||||||
|
const cleanedContent = p1
|
||||||
|
.replace(/^```[\s\S]*?(\n)?/, '')
|
||||||
|
.replace(/```$/, '')
|
||||||
|
.trim();
|
||||||
|
return convertRenderBlockToMarkdown(cleanedContent);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}, [convertRenderBlockToMarkdown, forbidZhFormat, showAnimation, source]);
|
||||||
|
|
||||||
|
const sanitizedSource = useMemo(() => {
|
||||||
|
return DomPurify.sanitize(formatSource);
|
||||||
|
}, [formatSource]);
|
||||||
|
|
||||||
const urlTransform = useCallback((val: string) => {
|
const urlTransform = useCallback((val: string) => {
|
||||||
return val;
|
return val;
|
||||||
@@ -81,14 +161,38 @@ const MarkdownRender = ({
|
|||||||
<Box position={'relative'}>
|
<Box position={'relative'}>
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
className={`markdown ${styles.markdown}
|
className={`markdown ${styles.markdown}
|
||||||
${showAnimation ? `${formatSource ? styles.waitingAnimation : styles.animation}` : ''}
|
${showAnimation ? `${sanitizedSource ? styles.waitingAnimation : styles.animation}` : ''}
|
||||||
`}
|
`}
|
||||||
remarkPlugins={[RemarkMath, [RemarkGfm, { singleTilde: false }], RemarkBreaks]}
|
remarkPlugins={[RemarkMath, [RemarkGfm, { singleTilde: false }], RemarkBreaks]}
|
||||||
rehypePlugins={[RehypeKatex, [RehypeExternalLinks, { target: '_blank' }]]}
|
rehypePlugins={[
|
||||||
|
RehypeKatex,
|
||||||
|
[RehypeExternalLinks, { target: '_blank' }],
|
||||||
|
[
|
||||||
|
RehypeRaw,
|
||||||
|
{
|
||||||
|
tagfilter: [
|
||||||
|
'script',
|
||||||
|
'style',
|
||||||
|
'iframe',
|
||||||
|
'frame',
|
||||||
|
'frameset',
|
||||||
|
'object',
|
||||||
|
'embed',
|
||||||
|
'link',
|
||||||
|
'meta',
|
||||||
|
'base',
|
||||||
|
'form',
|
||||||
|
'input',
|
||||||
|
'button',
|
||||||
|
'img'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]}
|
||||||
components={components}
|
components={components}
|
||||||
urlTransform={urlTransform}
|
urlTransform={urlTransform}
|
||||||
>
|
>
|
||||||
{formatSource}
|
{sanitizedSource}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
{isDisabled && <Box position={'absolute'} top={0} right={0} left={0} bottom={0} />}
|
{isDisabled && <Box position={'absolute'} top={0} right={0} left={0} bottom={0} />}
|
||||||
</Box>
|
</Box>
|
||||||
@@ -134,6 +238,27 @@ function Code(e: any) {
|
|||||||
if (codeType === CodeClassNameEnum.audio) {
|
if (codeType === CodeClassNameEnum.audio) {
|
||||||
return <AudioBlock code={strChildren} />;
|
return <AudioBlock code={strChildren} />;
|
||||||
}
|
}
|
||||||
|
if (codeType === CodeClassNameEnum.table) {
|
||||||
|
return <TableBlock code={strChildren} />;
|
||||||
|
}
|
||||||
|
if (codeType === CodeClassNameEnum.indicator) {
|
||||||
|
return <IndicatorCard dataList={JSON.parse(strChildren)} />;
|
||||||
|
}
|
||||||
|
if (codeType === CodeClassNameEnum.link) {
|
||||||
|
return <LinkBlock data={JSON.parse(strChildren)} />;
|
||||||
|
}
|
||||||
|
if (codeType === CodeClassNameEnum.error_tips) {
|
||||||
|
return <Tips content={strChildren} type="error" />;
|
||||||
|
}
|
||||||
|
if (codeType === CodeClassNameEnum.warning_tips) {
|
||||||
|
return <Tips content={strChildren} type="warning" />;
|
||||||
|
}
|
||||||
|
if (codeType === CodeClassNameEnum.divider) {
|
||||||
|
return <Divider />;
|
||||||
|
}
|
||||||
|
if (codeType === CodeClassNameEnum.textblock) {
|
||||||
|
return <TextBlock content={strChildren} />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CodeLight className={className} codeBlock={codeBlock} match={match}>
|
<CodeLight className={className} codeBlock={codeBlock} match={match}>
|
||||||
|
@@ -10,7 +10,14 @@ export enum CodeClassNameEnum {
|
|||||||
html = 'html',
|
html = 'html',
|
||||||
svg = 'svg',
|
svg = 'svg',
|
||||||
video = 'video',
|
video = 'video',
|
||||||
audio = 'audio'
|
audio = 'audio',
|
||||||
|
table = 'table',
|
||||||
|
indicator = 'indicator',
|
||||||
|
link = 'link',
|
||||||
|
error_tips = 'error_tips',
|
||||||
|
warning_tips = 'warning_tips',
|
||||||
|
divider = 'divider',
|
||||||
|
textblock = 'textblock'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mdTextFormat = (text: string) => {
|
export const mdTextFormat = (text: string) => {
|
||||||
|
Reference in New Issue
Block a user