@agentscope-ai/chat 1.1.40 → 1.1.41-beta.1764749089549
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ImageGenerator/index.tsx +1 -1
- package/components/Markdown/Markdown.tsx +105 -0
- package/components/Markdown/{Markdown/defaultComponents → core/components}/CodeBlock.tsx +1 -1
- package/components/Markdown/core/components/Null.tsx +1 -0
- package/components/Markdown/core/components/Raw.tsx +18 -0
- package/components/Markdown/{Markdown → core}/hooks/useCitationsData.tsx +3 -7
- package/components/Markdown/core/hooks/useCursorContent.tsx +15 -0
- package/components/Markdown/{Markdown/hooks/useTyping.ts → core/hooks/useTyping.tsx} +4 -1
- package/components/Markdown/core/index.tsx +18 -0
- package/components/Markdown/{plugins → core/plugins}/citations/CitationComponent.tsx +5 -3
- package/components/Markdown/{plugins → core/plugins}/citations/index.tsx +3 -4
- package/components/Markdown/{plugins → core/plugins}/cursor/Underline.tsx +1 -1
- package/components/Markdown/{plugins → core/plugins}/cursor/index.tsx +8 -8
- package/components/Markdown/demo/cursor.tsx +2 -3
- package/components/Markdown/index.en-US.md +1 -2
- package/components/Markdown/index.tsx +6 -0
- package/components/Markdown/index.zh-CN.md +1 -2
- package/components/Markdown/{Markdown/style.ts → styles.ts} +12 -21
- package/components/Markdown/types.tsx +94 -0
- package/components/index.ts +1 -3
- package/lib/ImageGenerator/index.js +1 -1
- package/lib/Markdown/Markdown.d.ts +4 -0
- package/lib/Markdown/Markdown.js +110 -0
- package/lib/Markdown/core/components/Null.d.ts +2 -0
- package/lib/Markdown/core/components/Null.js +3 -0
- package/lib/Markdown/core/components/Raw.d.ts +8 -0
- package/lib/Markdown/core/components/Raw.js +13 -0
- package/lib/Markdown/core/hooks/useCitationsData.d.ts +6 -0
- package/lib/Markdown/{Markdown → core}/hooks/useCitationsData.js +1 -1
- package/lib/Markdown/core/hooks/useCursorContent.d.ts +4 -0
- package/lib/Markdown/core/hooks/useCursorContent.js +14 -0
- package/lib/Markdown/core/hooks/useTyping.d.ts +5 -0
- package/lib/Markdown/{Markdown → core}/hooks/useTyping.js +3 -2
- package/lib/Markdown/core/index.d.ts +2 -0
- package/lib/Markdown/{Markdown/hooks/useAnimation.js → core/index.js} +23 -23
- package/lib/Markdown/{plugins → core/plugins}/citations/CitationComponent.js +5 -5
- package/lib/Markdown/{plugins → core/plugins}/citations/index.d.ts +1 -2
- package/lib/Markdown/{plugins → core/plugins}/citations/index.js +1 -1
- package/lib/Markdown/{plugins → core/plugins}/cursor/Dot.js +1 -1
- package/lib/Markdown/{plugins → core/plugins}/cursor/Underline.js +1 -1
- package/lib/Markdown/{plugins → core/plugins}/cursor/index.js +4 -4
- package/lib/Markdown/index.d.ts +2 -1
- package/lib/Markdown/styles.js +32 -0
- package/lib/Markdown/types.d.ts +78 -0
- package/lib/index.d.ts +0 -2
- package/lib/index.js +0 -2
- package/package.json +7 -31
- package/components/AGUI/components/HelpModal/icons.tsx +0 -68
- package/components/AGUI/components/HelpModal/index.tsx +0 -1
- package/components/AGUI/components/HelpModal/modal.tsx +0 -101
- package/components/AGUI/components/chat/Button.tsx +0 -18
- package/components/AGUI/components/chat/Chat.tsx +0 -780
- package/components/AGUI/components/chat/ChatContext.tsx +0 -248
- package/components/AGUI/components/chat/CodeBlock.tsx +0 -406
- package/components/AGUI/components/chat/Header.tsx +0 -22
- package/components/AGUI/components/chat/Icons.tsx +0 -237
- package/components/AGUI/components/chat/ImageUploadQueue.tsx +0 -77
- package/components/AGUI/components/chat/Input.tsx +0 -24
- package/components/AGUI/components/chat/Markdown.tsx +0 -134
- package/components/AGUI/components/chat/Messages.tsx +0 -259
- package/components/AGUI/components/chat/Modal.tsx +0 -133
- package/components/AGUI/components/chat/Popup.tsx +0 -57
- package/components/AGUI/components/chat/PoweredByTag.tsx +0 -29
- package/components/AGUI/components/chat/Sidebar.tsx +0 -74
- package/components/AGUI/components/chat/Suggestion.tsx +0 -132
- package/components/AGUI/components/chat/Suggestions.tsx +0 -20
- package/components/AGUI/components/chat/Textarea.tsx +0 -61
- package/components/AGUI/components/chat/Window.tsx +0 -152
- package/components/AGUI/components/chat/index.tsx +0 -11
- package/components/AGUI/components/chat/messages/AssistantMessage.tsx +0 -69
- package/components/AGUI/components/chat/messages/RenderActionExecutionMessage.tsx +0 -129
- package/components/AGUI/components/chat/messages/RenderAgentStateMessage.tsx +0 -116
- package/components/AGUI/components/chat/messages/RenderImageMessage.tsx +0 -64
- package/components/AGUI/components/chat/messages/RenderResultMessage.tsx +0 -26
- package/components/AGUI/components/chat/messages/RenderTextMessage.tsx +0 -51
- package/components/AGUI/components/chat/messages/UserMessage.tsx +0 -10
- package/components/AGUI/components/chat/props.ts +0 -186
- package/components/AGUI/components/index.ts +0 -1
- package/components/AGUI/context/index.ts +0 -1
- package/components/AGUI/hooks/index.ts +0 -1
- package/components/AGUI/hooks/use-copilot-chat-suggestions.tsx +0 -122
- package/components/AGUI/hooks/use-copy-to-clipboard.tsx +0 -29
- package/components/AGUI/hooks/use-dark-mode.ts +0 -10
- package/components/AGUI/hooks/use-push-to-talk.tsx +0 -166
- package/components/AGUI/index.tsx +0 -4
- package/components/AGUI/lib/utils.test.ts +0 -7
- package/components/AGUI/lib/utils.ts +0 -27
- package/components/AGUI/styles.css +0 -0
- package/components/AGUI/types/css.ts +0 -0
- package/components/AGUI/types/index.ts +0 -1
- package/components/AGUI/types/suggestions.ts +0 -6
- package/components/Markdown/Markdown/AnimationNode.tsx +0 -89
- package/components/Markdown/Markdown/Markdown.tsx +0 -61
- package/components/Markdown/Markdown/core/Parser.ts +0 -52
- package/components/Markdown/Markdown/core/Renderer.ts +0 -121
- package/components/Markdown/Markdown/core/index.ts +0 -4
- package/components/Markdown/Markdown/hooks/index.ts +0 -4
- package/components/Markdown/Markdown/hooks/useAnimation.tsx +0 -27
- package/components/Markdown/Markdown/hooks/useStreaming.ts +0 -503
- package/components/Markdown/Markdown/index.tsx +0 -198
- package/components/Markdown/Markdown/interface.ts +0 -217
- package/components/Markdown/demo/typing.tsx +0 -82
- package/components/Markdown/index.ts +0 -1
- package/components/Markdown/plugins/latex/index.ts +0 -109
- package/components/Markdown/plugins/type.ts +0 -71
- package/lib/AGUI/components/HelpModal/icons.d.ts +0 -5
- package/lib/AGUI/components/HelpModal/icons.js +0 -84
- package/lib/AGUI/components/HelpModal/index.d.ts +0 -1
- package/lib/AGUI/components/HelpModal/index.js +0 -1
- package/lib/AGUI/components/HelpModal/modal.d.ts +0 -1
- package/lib/AGUI/components/HelpModal/modal.js +0 -104
- package/lib/AGUI/components/chat/Button.d.ts +0 -2
- package/lib/AGUI/components/chat/Button.js +0 -27
- package/lib/AGUI/components/chat/Chat.d.ts +0 -242
- package/lib/AGUI/components/chat/Chat.js +0 -634
- package/lib/AGUI/components/chat/ChatContext.d.ts +0 -142
- package/lib/AGUI/components/chat/ChatContext.js +0 -75
- package/lib/AGUI/components/chat/CodeBlock.d.ts +0 -12
- package/lib/AGUI/components/chat/CodeBlock.js +0 -398
- package/lib/AGUI/components/chat/Header.d.ts +0 -2
- package/lib/AGUI/components/chat/Header.js +0 -28
- package/lib/AGUI/components/chat/Icons.d.ts +0 -16
- package/lib/AGUI/components/chat/Icons.js +0 -247
- package/lib/AGUI/components/chat/ImageUploadQueue.d.ts +0 -11
- package/lib/AGUI/components/chat/ImageUploadQueue.js +0 -65
- package/lib/AGUI/components/chat/Input.d.ts +0 -2
- package/lib/AGUI/components/chat/Input.js +0 -30
- package/lib/AGUI/components/chat/Markdown.d.ts +0 -7
- package/lib/AGUI/components/chat/Markdown.js +0 -187
- package/lib/AGUI/components/chat/Messages.d.ts +0 -7
- package/lib/AGUI/components/chat/Messages.js +0 -242
- package/lib/AGUI/components/chat/Modal.d.ts +0 -43
- package/lib/AGUI/components/chat/Modal.js +0 -113
- package/lib/AGUI/components/chat/Popup.d.ts +0 -49
- package/lib/AGUI/components/chat/Popup.js +0 -64
- package/lib/AGUI/components/chat/PoweredByTag.d.ts +0 -3
- package/lib/AGUI/components/chat/PoweredByTag.js +0 -27
- package/lib/AGUI/components/chat/Sidebar.d.ts +0 -2
- package/lib/AGUI/components/chat/Sidebar.js +0 -85
- package/lib/AGUI/components/chat/Suggestion.d.ts +0 -16
- package/lib/AGUI/components/chat/Suggestion.js +0 -146
- package/lib/AGUI/components/chat/Suggestions.d.ts +0 -2
- package/lib/AGUI/components/chat/Suggestions.js +0 -21
- package/lib/AGUI/components/chat/Textarea.d.ts +0 -11
- package/lib/AGUI/components/chat/Textarea.js +0 -60
- package/lib/AGUI/components/chat/Window.d.ts +0 -2
- package/lib/AGUI/components/chat/Window.js +0 -115
- package/lib/AGUI/components/chat/index.d.ts +0 -11
- package/lib/AGUI/components/chat/index.js +0 -11
- package/lib/AGUI/components/chat/messages/AssistantMessage.d.ts +0 -2
- package/lib/AGUI/components/chat/messages/AssistantMessage.js +0 -56
- package/lib/AGUI/components/chat/messages/RenderActionExecutionMessage.d.ts +0 -2
- package/lib/AGUI/components/chat/messages/RenderActionExecutionMessage.js +0 -114
- package/lib/AGUI/components/chat/messages/RenderAgentStateMessage.d.ts +0 -2
- package/lib/AGUI/components/chat/messages/RenderAgentStateMessage.js +0 -97
- package/lib/AGUI/components/chat/messages/RenderImageMessage.d.ts +0 -2
- package/lib/AGUI/components/chat/messages/RenderImageMessage.js +0 -61
- package/lib/AGUI/components/chat/messages/RenderResultMessage.d.ts +0 -2
- package/lib/AGUI/components/chat/messages/RenderResultMessage.js +0 -27
- package/lib/AGUI/components/chat/messages/RenderTextMessage.d.ts +0 -2
- package/lib/AGUI/components/chat/messages/RenderTextMessage.js +0 -47
- package/lib/AGUI/components/chat/messages/UserMessage.d.ts +0 -2
- package/lib/AGUI/components/chat/messages/UserMessage.js +0 -9
- package/lib/AGUI/components/chat/props.d.ts +0 -157
- package/lib/AGUI/components/index.d.ts +0 -1
- package/lib/AGUI/components/index.js +0 -1
- package/lib/AGUI/context/index.d.ts +0 -1
- package/lib/AGUI/context/index.js +0 -1
- package/lib/AGUI/hooks/index.d.ts +0 -1
- package/lib/AGUI/hooks/index.js +0 -1
- package/lib/AGUI/hooks/use-copilot-chat-suggestions.d.ts +0 -87
- package/lib/AGUI/hooks/use-copilot-chat-suggestions.js +0 -95
- package/lib/AGUI/hooks/use-copy-to-clipboard.d.ts +0 -7
- package/lib/AGUI/hooks/use-copy-to-clipboard.js +0 -34
- package/lib/AGUI/hooks/use-dark-mode.d.ts +0 -1
- package/lib/AGUI/hooks/use-dark-mode.js +0 -4
- package/lib/AGUI/hooks/use-push-to-talk.d.ts +0 -16
- package/lib/AGUI/hooks/use-push-to-talk.js +0 -260
- package/lib/AGUI/index.d.ts +0 -4
- package/lib/AGUI/index.js +0 -4
- package/lib/AGUI/lib/utils.d.ts +0 -2
- package/lib/AGUI/lib/utils.js +0 -52
- package/lib/AGUI/styles.css +0 -0
- package/lib/AGUI/types/css.d.ts +0 -0
- package/lib/AGUI/types/css.js +0 -0
- package/lib/AGUI/types/index.d.ts +0 -1
- package/lib/AGUI/types/index.js +0 -1
- package/lib/AGUI/types/suggestions.d.ts +0 -6
- package/lib/AGUI/types/suggestions.js +0 -1
- package/lib/Markdown/Markdown/AnimationNode.d.ts +0 -20
- package/lib/Markdown/Markdown/AnimationNode.js +0 -84
- package/lib/Markdown/Markdown/Markdown.d.ts +0 -4
- package/lib/Markdown/Markdown/Markdown.js +0 -58
- package/lib/Markdown/Markdown/core/Parser.d.ts +0 -16
- package/lib/Markdown/Markdown/core/Parser.js +0 -65
- package/lib/Markdown/Markdown/core/Renderer.d.ts +0 -24
- package/lib/Markdown/Markdown/core/Renderer.js +0 -137
- package/lib/Markdown/Markdown/core/index.d.ts +0 -3
- package/lib/Markdown/Markdown/core/index.js +0 -3
- package/lib/Markdown/Markdown/hooks/index.d.ts +0 -3
- package/lib/Markdown/Markdown/hooks/index.js +0 -3
- package/lib/Markdown/Markdown/hooks/useAnimation.d.ts +0 -4
- package/lib/Markdown/Markdown/hooks/useCitationsData.d.ts +0 -7
- package/lib/Markdown/Markdown/hooks/useStreaming.d.ts +0 -3
- package/lib/Markdown/Markdown/hooks/useStreaming.js +0 -521
- package/lib/Markdown/Markdown/hooks/useTyping.d.ts +0 -4
- package/lib/Markdown/Markdown/index.d.ts +0 -84
- package/lib/Markdown/Markdown/index.js +0 -161
- package/lib/Markdown/Markdown/interface.d.ts +0 -203
- package/lib/Markdown/Markdown/interface.js +0 -1
- package/lib/Markdown/Markdown/style.js +0 -32
- package/lib/Markdown/plugins/latex/index.d.ts +0 -9
- package/lib/Markdown/plugins/latex/index.js +0 -97
- package/lib/Markdown/plugins/type.d.ts +0 -60
- package/lib/Markdown/plugins/type.js +0 -1
- /package/components/Markdown/{Markdown/defaultComponents/DisabledImage.tsx → core/components/DisableImage.tsx} +0 -0
- /package/components/Markdown/{Markdown/defaultComponents → core/components}/Media.tsx +0 -0
- /package/components/Markdown/{plugins → core/plugins}/cursor/Dot.tsx +0 -0
- /package/lib/Markdown/{Markdown/defaultComponents → core/components}/CodeBlock.d.ts +0 -0
- /package/lib/Markdown/{Markdown/defaultComponents → core/components}/CodeBlock.js +0 -0
- /package/lib/Markdown/{Markdown/defaultComponents/DisabledImage.d.ts → core/components/DisableImage.d.ts} +0 -0
- /package/lib/Markdown/{Markdown/defaultComponents/DisabledImage.js → core/components/DisableImage.js} +0 -0
- /package/lib/Markdown/{Markdown/defaultComponents → core/components}/Media.d.ts +0 -0
- /package/lib/Markdown/{Markdown/defaultComponents → core/components}/Media.js +0 -0
- /package/lib/Markdown/{plugins → core/plugins}/citations/CitationComponent.d.ts +0 -0
- /package/lib/Markdown/{plugins → core/plugins}/cursor/Dot.d.ts +0 -0
- /package/lib/Markdown/{plugins → core/plugins}/cursor/Underline.d.ts +0 -0
- /package/lib/Markdown/{plugins → core/plugins}/cursor/index.d.ts +0 -0
- /package/lib/Markdown/{Markdown/style.d.ts → styles.d.ts} +0 -0
- /package/lib/{AGUI/components/chat/props.js → Markdown/types.js} +0 -0
|
@@ -4,7 +4,7 @@ import { useProviderContext } from '../Provider';
|
|
|
4
4
|
import { ConfigProvider, Image } from 'antd';
|
|
5
5
|
import { Locale } from 'antd/es/locale';
|
|
6
6
|
import { SparkCheckCircleFill } from '@agentscope-ai/icons';
|
|
7
|
-
import Dot from '../Markdown/plugins/cursor/Dot';
|
|
7
|
+
import Dot from '../Markdown/core/plugins/cursor/Dot';
|
|
8
8
|
|
|
9
9
|
export interface IImageGeneratorProps {
|
|
10
10
|
/**
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { memo, useMemo } from 'react';
|
|
2
|
+
import MarkdownX from './core';
|
|
3
|
+
import type { MarkdownProps } from './types';
|
|
4
|
+
import useTyping from './core/hooks/useTyping';
|
|
5
|
+
import { useProviderContext } from '@agentscope-ai/chat';
|
|
6
|
+
import classNames from 'classnames';
|
|
7
|
+
import Null from './core/components/Null';
|
|
8
|
+
import CodeBlock from './core/components/CodeBlock';
|
|
9
|
+
import DisabledImage from './core/components/DisableImage';
|
|
10
|
+
import Media from './core/components/Media';
|
|
11
|
+
import Raw from './core/components/Raw';
|
|
12
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
13
|
+
import useCitationsData from './core/hooks/useCitationsData';
|
|
14
|
+
import Latex from '@ant-design/x-markdown/plugins/Latex';
|
|
15
|
+
import { citationsExtension } from './core/plugins/citations';
|
|
16
|
+
import { CursorComponent, cursorExtension } from './core/plugins/cursor';
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
// 缓存不变的 dompurify 配置
|
|
20
|
+
const EMPTY_DOMPURIFY_CONFIG = {
|
|
21
|
+
ALLOWED_TAGS: [],
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 检测浏览器是否支持正则表达式的 lookbehind assertions
|
|
26
|
+
* iOS Safari < 16.4 不支持此特性
|
|
27
|
+
*/
|
|
28
|
+
function supportsLookbehindAssertions(): boolean {
|
|
29
|
+
try {
|
|
30
|
+
// 尝试创建包含正向后行断言的正则表达式
|
|
31
|
+
new RegExp('(?<=a)b');
|
|
32
|
+
return true;
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const isSupportsLookbehindAssertions = supportsLookbehindAssertions();
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
export default memo(function (props: MarkdownProps) {
|
|
42
|
+
const baseFontSize = props.baseFontSize || 14;
|
|
43
|
+
const baseLineHeight = props.baseLineHeight || 1.7;
|
|
44
|
+
const content = useTyping({ content: props.content, typing: props.typing });
|
|
45
|
+
const prefixCls = useProviderContext().getPrefixCls('markdown');
|
|
46
|
+
const {
|
|
47
|
+
raw = false,
|
|
48
|
+
allowHtml = true,
|
|
49
|
+
} = props;
|
|
50
|
+
|
|
51
|
+
const {
|
|
52
|
+
citationsData,
|
|
53
|
+
citationsDataCount,
|
|
54
|
+
CitationComponent
|
|
55
|
+
} = useCitationsData({ citations: props.citations, citationsMap: props.citationsMap });
|
|
56
|
+
|
|
57
|
+
const components = useMemo(() => ({
|
|
58
|
+
pre: CodeBlock,
|
|
59
|
+
style: Null,
|
|
60
|
+
script: Null,
|
|
61
|
+
img: props.disableImage ? DisabledImage : Media,
|
|
62
|
+
citation: CitationComponent,
|
|
63
|
+
'custom-cursor': CursorComponent,
|
|
64
|
+
}), [props.disableImage, CitationComponent]);
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
const dompurifyConfig = useMemo(() =>
|
|
68
|
+
allowHtml ? {
|
|
69
|
+
ADD_TAGS: ['custom-cursor', 'citation']
|
|
70
|
+
} : EMPTY_DOMPURIFY_CONFIG
|
|
71
|
+
, [allowHtml]);
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
// 使用 useMemo 缓存 extensions 配置
|
|
75
|
+
const extensions = useMemo(() => {
|
|
76
|
+
const exts = Latex()
|
|
77
|
+
exts.push(cursorExtension());
|
|
78
|
+
if (citationsDataCount > 0) exts.push(citationsExtension(citationsData));
|
|
79
|
+
return exts;
|
|
80
|
+
}, [citationsDataCount, citationsData]);
|
|
81
|
+
|
|
82
|
+
// // 使用 useMemo 缓存 config 对象
|
|
83
|
+
const config = useMemo(() => ({
|
|
84
|
+
extensions,
|
|
85
|
+
}), [extensions]);
|
|
86
|
+
|
|
87
|
+
const fallback = <Raw content={content} baseFontSize={baseFontSize} baseLineHeight={baseLineHeight} />;
|
|
88
|
+
|
|
89
|
+
if (raw || !isSupportsLookbehindAssertions) return fallback;
|
|
90
|
+
|
|
91
|
+
return <ErrorBoundary fallback={fallback}>
|
|
92
|
+
<MarkdownX
|
|
93
|
+
dompurifyConfig={dompurifyConfig}
|
|
94
|
+
cursor={props.cursor}
|
|
95
|
+
// @ts-ignore
|
|
96
|
+
components={components}
|
|
97
|
+
style={{ fontSize: baseFontSize, lineHeight: baseLineHeight }}
|
|
98
|
+
openLinksInNewTab={true}
|
|
99
|
+
className={classNames(prefixCls, props.className)}
|
|
100
|
+
content={content}
|
|
101
|
+
config={config}
|
|
102
|
+
/>
|
|
103
|
+
</ErrorBoundary>
|
|
104
|
+
|
|
105
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default () => null;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MarkdownProps } from '../../types'
|
|
2
|
+
import { useProviderContext } from '@agentscope-ai/chat';
|
|
3
|
+
|
|
4
|
+
interface RawProps {
|
|
5
|
+
content: MarkdownProps['content'];
|
|
6
|
+
baseFontSize?: number;
|
|
7
|
+
baseLineHeight?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default function Raw(props: RawProps) {
|
|
11
|
+
const prefixCls = useProviderContext().getPrefixCls('markdown');
|
|
12
|
+
|
|
13
|
+
return <div
|
|
14
|
+
className={prefixCls}
|
|
15
|
+
style={{ fontSize: props.baseFontSize, lineHeight: props.baseLineHeight }}>
|
|
16
|
+
{props.content}
|
|
17
|
+
</div>
|
|
18
|
+
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import
|
|
3
|
-
import InnerCitationComponent, { CitationComponentProps } from '../../plugins/citations/CitationComponent';
|
|
2
|
+
import InnerCitationComponent, { CitationComponentProps } from '../plugins/citations/CitationComponent';
|
|
4
3
|
|
|
5
4
|
const emptyArray = [];
|
|
6
5
|
const emptyMap = {};
|
|
7
6
|
|
|
8
7
|
export default function useCitationsData(
|
|
9
|
-
props
|
|
8
|
+
props,
|
|
10
9
|
) {
|
|
11
10
|
const { citations = emptyArray, citationsMap = emptyMap } = props;
|
|
12
11
|
|
|
@@ -18,9 +17,6 @@ export default function useCitationsData(
|
|
|
18
17
|
map[key] = item;
|
|
19
18
|
});
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
20
|
return [map, (function citationComponentWrapper() {
|
|
25
21
|
return function (props: CitationComponentProps) {
|
|
26
22
|
return <InnerCitationComponent {...props} citationsData={map} />;
|
|
@@ -33,4 +29,4 @@ export default function useCitationsData(
|
|
|
33
29
|
citationsData,
|
|
34
30
|
citationsDataCount: Object.keys(citationsData).length,
|
|
35
31
|
};
|
|
36
|
-
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
export default function useCursorContent({ cursor, content }: { cursor: boolean | 'dot' | 'underline', content: string }) {
|
|
4
|
+
const cursorContent = useMemo(() => {
|
|
5
|
+
if (cursor) {
|
|
6
|
+
if (cursor === 'dot') return ' :dot:';
|
|
7
|
+
if (cursor === 'underline') return ' :underline:';
|
|
8
|
+
return ' :dot:';
|
|
9
|
+
}
|
|
10
|
+
return '';
|
|
11
|
+
}, [cursor, content]);
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
return content + cursorContent;
|
|
15
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const useTyping = ({ content, typing }) => {
|
|
4
4
|
const [index, setIndex] = useState(0);
|
|
5
5
|
const timer = useRef<NodeJS.Timeout>();
|
|
6
6
|
|
|
@@ -20,3 +20,6 @@ export const useTyping = ({ content, typing }) => {
|
|
|
20
20
|
|
|
21
21
|
return content.slice(0, index);
|
|
22
22
|
};
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export default useTyping;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import XMarkdown from '@ant-design/x-markdown';
|
|
2
|
+
import { InnerMarkdownXProps } from '../types';
|
|
3
|
+
import Styles from '../styles';
|
|
4
|
+
import useCursorContent from './hooks/useCursorContent';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export default function (props: InnerMarkdownXProps) {
|
|
8
|
+
const { content: originalContent, cursor, ...rest } = props;
|
|
9
|
+
const content = useCursorContent({
|
|
10
|
+
cursor: cursor,
|
|
11
|
+
content: originalContent
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
return <>
|
|
15
|
+
<Styles />
|
|
16
|
+
<XMarkdown {...rest} content={content} />
|
|
17
|
+
</>;
|
|
18
|
+
};
|
|
@@ -44,7 +44,10 @@ export interface CitationComponentProps extends DefaultRenderProps {
|
|
|
44
44
|
function DefaultRender(props: DefaultRenderProps) {
|
|
45
45
|
const { getPrefixCls } = useProviderContext();
|
|
46
46
|
const prefixCls = getPrefixCls('markdown-citation');
|
|
47
|
-
const
|
|
47
|
+
const text = props['data-text'];
|
|
48
|
+
const url = props['data-url'];
|
|
49
|
+
const title = props['data-title'];
|
|
50
|
+
const content = props['data-content'];
|
|
48
51
|
|
|
49
52
|
const isTooltip = content || title;
|
|
50
53
|
|
|
@@ -67,6 +70,5 @@ function DefaultRender(props: DefaultRenderProps) {
|
|
|
67
70
|
|
|
68
71
|
export default function CitationComponent(props: DefaultRenderProps & { citationsData: Record<string, any> }) {
|
|
69
72
|
const Render = props.citationsData[props.text]?.render || DefaultRender;
|
|
70
|
-
|
|
71
73
|
return <Render {...props} />
|
|
72
|
-
}
|
|
74
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { MarkdownProps } from "../../Markdown/interface";
|
|
2
1
|
export { default as CitationComponent } from './CitationComponent';
|
|
3
2
|
|
|
4
|
-
export function citationsExtension(citationsData
|
|
3
|
+
export function citationsExtension(citationsData) {
|
|
5
4
|
|
|
6
5
|
return {
|
|
7
6
|
name: 'citation',
|
|
@@ -29,8 +28,8 @@ export function citationsExtension(citationsData: MarkdownProps['citationsMap'])
|
|
|
29
28
|
const citation = citationsData?.[text];
|
|
30
29
|
|
|
31
30
|
if (!citation) return token.raw;
|
|
32
|
-
|
|
33
|
-
return `<citation text="${text}" url="${citation.url}" title="${citation.title}" content="${citation.content}"></citation>`;
|
|
31
|
+
|
|
32
|
+
return `<citation data-text="${text}" data-url="${citation.url}" data-title="${citation.title}" data-content="${citation.content}"></citation>`;
|
|
34
33
|
|
|
35
34
|
},
|
|
36
35
|
};
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import Underline from './Underline';
|
|
3
2
|
import Dot from './Dot';
|
|
4
3
|
|
|
5
|
-
export const CursorComponent = function(props) {
|
|
6
|
-
|
|
7
|
-
if (
|
|
4
|
+
export const CursorComponent = function (props) {
|
|
5
|
+
const type = props['data-type'];
|
|
6
|
+
if (type === 'dot') {
|
|
8
7
|
return <Dot />
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
if (
|
|
10
|
+
if (type === 'underline') {
|
|
12
11
|
return <Underline />
|
|
13
12
|
}
|
|
14
13
|
|
|
@@ -43,7 +42,7 @@ export function cursorExtension() {
|
|
|
43
42
|
if (!cursor) {
|
|
44
43
|
return;
|
|
45
44
|
}
|
|
46
|
-
|
|
45
|
+
|
|
47
46
|
return {
|
|
48
47
|
type: 'cursor',
|
|
49
48
|
raw: match[0],
|
|
@@ -52,8 +51,9 @@ export function cursorExtension() {
|
|
|
52
51
|
};
|
|
53
52
|
},
|
|
54
53
|
renderer(token) {
|
|
55
|
-
const content = `<cursor type="${token.name}"></cursor>`;
|
|
54
|
+
const content = `<custom-cursor data-type="${token.name}"></custom-cursor>`;
|
|
55
|
+
|
|
56
56
|
return content;
|
|
57
57
|
},
|
|
58
58
|
};
|
|
59
|
-
}
|
|
59
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Markdown } from '@agentscope-ai/chat';
|
|
2
|
-
import { Space } from 'antd';
|
|
3
2
|
|
|
4
|
-
const text = `Hello, world!`
|
|
5
3
|
|
|
4
|
+
const content = `Hello, world!`;
|
|
6
5
|
|
|
7
6
|
export default function () {
|
|
8
|
-
return <
|
|
7
|
+
return <Markdown content={content} cursor="underline" />;
|
|
9
8
|
}
|
|
@@ -19,9 +19,8 @@ import { Markdown } from '@agentscope-ai/chat';
|
|
|
19
19
|
<code src="./demo/latex.tsx" height="600">Latex</code>
|
|
20
20
|
<code src="./demo/citations.tsx" height="auto">Citations</code>
|
|
21
21
|
<code src="./demo/cursor.tsx" height="auto">Cursor</code>
|
|
22
|
-
<code src="./demo/typing.tsx" height="300">Typing</code>
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
#### API
|
|
26
25
|
|
|
27
|
-
<ApiParser source="./
|
|
26
|
+
<ApiParser source="./types.tsx" id="MarkdownProps"></ApiParser>
|
|
@@ -20,9 +20,8 @@ import { Markdown } from '@agentscope-ai/chat';
|
|
|
20
20
|
<code src="./demo/latex.tsx" height="600">Latex</code>
|
|
21
21
|
<code src="./demo/citations.tsx" height="auto">引用</code>
|
|
22
22
|
<code src="./demo/cursor.tsx" height="auto">光标</code>
|
|
23
|
-
<code src="./demo/typing.tsx" height="300">打字效果</code>
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
#### API
|
|
27
26
|
|
|
28
|
-
<ApiParser source="./
|
|
27
|
+
<ApiParser source="./types.tsx" id="MarkdownProps"></ApiParser>
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import { createGlobalStyle } from 'antd-style';
|
|
2
2
|
|
|
3
3
|
export default createGlobalStyle`
|
|
4
|
-
.${(p) => p.theme.prefixCls}-markdown
|
|
4
|
+
.${(p) => p.theme.prefixCls}-markdown {
|
|
5
5
|
color: inherit;
|
|
6
6
|
max-width: 100%;
|
|
7
7
|
|
|
8
|
-
ol, ul {
|
|
9
|
-
padding-left: 30px;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
8
|
blockquote {
|
|
13
9
|
padding-inline: 0.6em 0;
|
|
14
10
|
padding-block: 0;
|
|
@@ -35,6 +31,14 @@ export default createGlobalStyle`
|
|
|
35
31
|
|
|
36
32
|
pre code {
|
|
37
33
|
font-size: 0.8571428571428571em;
|
|
34
|
+
background-color: transparent;
|
|
35
|
+
border: none;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
pre {
|
|
39
|
+
background-color: ${(p) => p.theme.colorFillQuaternary};
|
|
40
|
+
padding: 4px 10px;
|
|
41
|
+
border: 1px solid ${(p) => p.theme.colorBorderSecondary};
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
h1,
|
|
@@ -51,7 +55,6 @@ export default createGlobalStyle`
|
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
p {
|
|
54
|
-
margin-top: 0.5714285714285714em;
|
|
55
58
|
margin-bottom: 0.5714285714285714em;
|
|
56
59
|
}
|
|
57
60
|
|
|
@@ -130,23 +133,11 @@ export default createGlobalStyle`
|
|
|
130
133
|
font-size: 30px;
|
|
131
134
|
}
|
|
132
135
|
}
|
|
133
|
-
|
|
134
136
|
}
|
|
135
137
|
|
|
136
|
-
.${(p) => p.theme.prefixCls}-markdown
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
.${(p) => p.theme.prefixCls}-markdown > *:first-child {
|
|
141
|
-
margin-top: 0 !important;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
@keyframes ${(p) => p.theme.prefixCls}-markdown-fadeIn {
|
|
145
|
-
from {
|
|
146
|
-
opacity: 0;
|
|
147
|
-
}
|
|
148
|
-
to {
|
|
149
|
-
opacity: 1;
|
|
138
|
+
.${(p) => p.theme.prefixCls}-markdown.x-markdown {
|
|
139
|
+
img {
|
|
140
|
+
margin: 0;
|
|
150
141
|
}
|
|
151
142
|
}
|
|
152
143
|
`;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { XMarkdownProps } from '@ant-design/x-markdown';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export interface MarkdownProps {
|
|
5
|
+
/**
|
|
6
|
+
* @description 需要渲染的 Markdown 内容
|
|
7
|
+
* @descriptionEn Markdown content to be rendered
|
|
8
|
+
*/
|
|
9
|
+
content?: string;
|
|
10
|
+
/**
|
|
11
|
+
* @description 光标样式类型,支持点状、下划线或布尔值控制
|
|
12
|
+
* @descriptionEn Cursor style type, supports dot, underline, or boolean control
|
|
13
|
+
*/
|
|
14
|
+
cursor?: boolean | 'dot' | 'underline';
|
|
15
|
+
/**
|
|
16
|
+
* @description 基础字体大小,影响整个Markdown内容的字体大小
|
|
17
|
+
* @descriptionEn Base font size that affects the font size of the entire Markdown content
|
|
18
|
+
*/
|
|
19
|
+
baseFontSize?: number;
|
|
20
|
+
/**
|
|
21
|
+
* @description 基础行高,影响文本的行间距
|
|
22
|
+
* @descriptionEn Base line height that affects text line spacing
|
|
23
|
+
*/
|
|
24
|
+
baseLineHeight?: number;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @description 是否允许渲染HTML标签,影响安全性
|
|
28
|
+
* @descriptionEn Whether to allow rendering HTML tags, affects security
|
|
29
|
+
*/
|
|
30
|
+
allowHtml?: boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @description 是否禁用图片渲染
|
|
34
|
+
* @descriptionEn Whether to disable image rendering
|
|
35
|
+
*/
|
|
36
|
+
disableImage?: boolean;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @description 是否以原始文本形式显示,跳过Markdown解析
|
|
40
|
+
* @descriptionEn Whether to display as raw text, skipping Markdown parsing
|
|
41
|
+
*/
|
|
42
|
+
raw?: boolean;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @description 是否启用打字机效果,逐字显示内容
|
|
46
|
+
* @descriptionEn Whether to enable typewriter effect for character-by-character display
|
|
47
|
+
*/
|
|
48
|
+
typing?: boolean | number;
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @description 组件的CSS类名
|
|
53
|
+
* @descriptionEn CSS class name for the component
|
|
54
|
+
*/
|
|
55
|
+
className?: string;
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
citations?: {
|
|
61
|
+
title?: string;
|
|
62
|
+
url?: string;
|
|
63
|
+
content?: string;
|
|
64
|
+
render?: (props: {
|
|
65
|
+
text: string;
|
|
66
|
+
url: string;
|
|
67
|
+
title: string;
|
|
68
|
+
content: string;
|
|
69
|
+
}) => React.ReactNode;
|
|
70
|
+
}[];
|
|
71
|
+
citationsMap?: Record<
|
|
72
|
+
string,
|
|
73
|
+
{
|
|
74
|
+
title?: string;
|
|
75
|
+
url?: string;
|
|
76
|
+
content?: string;
|
|
77
|
+
render?: (props: {
|
|
78
|
+
text: string;
|
|
79
|
+
url: string;
|
|
80
|
+
title: string;
|
|
81
|
+
content: string;
|
|
82
|
+
}) => React.ReactNode;
|
|
83
|
+
}
|
|
84
|
+
>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
export interface InnerMarkdownXProps extends XMarkdownProps {
|
|
89
|
+
/**
|
|
90
|
+
* @description 光标样式类型,支持点状、下划线或布尔值控制
|
|
91
|
+
* @descriptionEn Cursor style type, supports dot, underline, or boolean control
|
|
92
|
+
*/
|
|
93
|
+
cursor?: MarkdownProps['cursor'];
|
|
94
|
+
}
|
package/components/index.ts
CHANGED
|
@@ -2,8 +2,6 @@ export { ConfigProvider } from 'antd';
|
|
|
2
2
|
|
|
3
3
|
export { default as version } from './Version';
|
|
4
4
|
|
|
5
|
-
export * from '@copilotkit/react-core';
|
|
6
|
-
export * from './AGUI';
|
|
7
5
|
|
|
8
6
|
export {
|
|
9
7
|
CustomCardsContext,
|
|
@@ -85,4 +83,4 @@ export {
|
|
|
85
83
|
default as Markdown,
|
|
86
84
|
type MarkdownProps as IMarkdownProps,
|
|
87
85
|
type MarkdownProps,
|
|
88
|
-
} from './Markdown';
|
|
86
|
+
} from './Markdown';
|
|
@@ -3,7 +3,7 @@ import Style from "./style";
|
|
|
3
3
|
import { useProviderContext } from "../Provider";
|
|
4
4
|
import { ConfigProvider, Image } from 'antd';
|
|
5
5
|
import { SparkCheckCircleFill } from '@agentscope-ai/icons';
|
|
6
|
-
import Dot from "../Markdown/plugins/cursor/Dot";
|
|
6
|
+
import Dot from "../Markdown/core/plugins/cursor/Dot";
|
|
7
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
8
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { memo, useMemo } from 'react';
|
|
2
|
+
import MarkdownX from "./core";
|
|
3
|
+
import useTyping from "./core/hooks/useTyping";
|
|
4
|
+
import { useProviderContext } from "./..";
|
|
5
|
+
import classNames from 'classnames';
|
|
6
|
+
import Null from "./core/components/Null";
|
|
7
|
+
import CodeBlock from "./core/components/CodeBlock";
|
|
8
|
+
import DisabledImage from "./core/components/DisableImage";
|
|
9
|
+
import Media from "./core/components/Media";
|
|
10
|
+
import Raw from "./core/components/Raw";
|
|
11
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
12
|
+
import useCitationsData from "./core/hooks/useCitationsData";
|
|
13
|
+
import Latex from '@ant-design/x-markdown/plugins/Latex';
|
|
14
|
+
import { citationsExtension } from "./core/plugins/citations";
|
|
15
|
+
import { CursorComponent, cursorExtension } from "./core/plugins/cursor";
|
|
16
|
+
|
|
17
|
+
// 缓存不变的 dompurify 配置
|
|
18
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
19
|
+
var EMPTY_DOMPURIFY_CONFIG = {
|
|
20
|
+
ALLOWED_TAGS: []
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 检测浏览器是否支持正则表达式的 lookbehind assertions
|
|
25
|
+
* iOS Safari < 16.4 不支持此特性
|
|
26
|
+
*/
|
|
27
|
+
function supportsLookbehindAssertions() {
|
|
28
|
+
try {
|
|
29
|
+
// 尝试创建包含正向后行断言的正则表达式
|
|
30
|
+
new RegExp('(?<=a)b');
|
|
31
|
+
return true;
|
|
32
|
+
} catch (e) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
var isSupportsLookbehindAssertions = supportsLookbehindAssertions();
|
|
37
|
+
export default /*#__PURE__*/memo(function (props) {
|
|
38
|
+
var baseFontSize = props.baseFontSize || 14;
|
|
39
|
+
var baseLineHeight = props.baseLineHeight || 1.7;
|
|
40
|
+
var content = useTyping({
|
|
41
|
+
content: props.content,
|
|
42
|
+
typing: props.typing
|
|
43
|
+
});
|
|
44
|
+
var prefixCls = useProviderContext().getPrefixCls('markdown');
|
|
45
|
+
var _props$raw = props.raw,
|
|
46
|
+
raw = _props$raw === void 0 ? false : _props$raw,
|
|
47
|
+
_props$allowHtml = props.allowHtml,
|
|
48
|
+
allowHtml = _props$allowHtml === void 0 ? true : _props$allowHtml;
|
|
49
|
+
var _useCitationsData = useCitationsData({
|
|
50
|
+
citations: props.citations,
|
|
51
|
+
citationsMap: props.citationsMap
|
|
52
|
+
}),
|
|
53
|
+
citationsData = _useCitationsData.citationsData,
|
|
54
|
+
citationsDataCount = _useCitationsData.citationsDataCount,
|
|
55
|
+
CitationComponent = _useCitationsData.CitationComponent;
|
|
56
|
+
var components = useMemo(function () {
|
|
57
|
+
return {
|
|
58
|
+
pre: CodeBlock,
|
|
59
|
+
style: Null,
|
|
60
|
+
script: Null,
|
|
61
|
+
img: props.disableImage ? DisabledImage : Media,
|
|
62
|
+
citation: CitationComponent,
|
|
63
|
+
'custom-cursor': CursorComponent
|
|
64
|
+
};
|
|
65
|
+
}, [props.disableImage, CitationComponent]);
|
|
66
|
+
var dompurifyConfig = useMemo(function () {
|
|
67
|
+
return allowHtml ? {
|
|
68
|
+
ADD_TAGS: ['custom-cursor', 'citation']
|
|
69
|
+
} : EMPTY_DOMPURIFY_CONFIG;
|
|
70
|
+
}, [allowHtml]);
|
|
71
|
+
|
|
72
|
+
// 使用 useMemo 缓存 extensions 配置
|
|
73
|
+
var extensions = useMemo(function () {
|
|
74
|
+
var exts = Latex();
|
|
75
|
+
exts.push(cursorExtension());
|
|
76
|
+
if (citationsDataCount > 0) exts.push(citationsExtension(citationsData));
|
|
77
|
+
return exts;
|
|
78
|
+
}, [citationsDataCount, citationsData]);
|
|
79
|
+
|
|
80
|
+
// // 使用 useMemo 缓存 config 对象
|
|
81
|
+
var config = useMemo(function () {
|
|
82
|
+
return {
|
|
83
|
+
extensions: extensions
|
|
84
|
+
};
|
|
85
|
+
}, [extensions]);
|
|
86
|
+
var fallback = /*#__PURE__*/_jsx(Raw, {
|
|
87
|
+
content: content,
|
|
88
|
+
baseFontSize: baseFontSize,
|
|
89
|
+
baseLineHeight: baseLineHeight
|
|
90
|
+
});
|
|
91
|
+
if (raw || !isSupportsLookbehindAssertions) return fallback;
|
|
92
|
+
return /*#__PURE__*/_jsx(ErrorBoundary, {
|
|
93
|
+
fallback: fallback,
|
|
94
|
+
children: /*#__PURE__*/_jsx(MarkdownX, {
|
|
95
|
+
dompurifyConfig: dompurifyConfig,
|
|
96
|
+
cursor: props.cursor
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
,
|
|
99
|
+
components: components,
|
|
100
|
+
style: {
|
|
101
|
+
fontSize: baseFontSize,
|
|
102
|
+
lineHeight: baseLineHeight
|
|
103
|
+
},
|
|
104
|
+
openLinksInNewTab: true,
|
|
105
|
+
className: classNames(prefixCls, props.className),
|
|
106
|
+
content: content,
|
|
107
|
+
config: config
|
|
108
|
+
})
|
|
109
|
+
});
|
|
110
|
+
});
|