ds-markdown 0.1.2-beta.3 → 0.1.3-beta.0
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/README.en.md +292 -4
- package/README.ja.md +240 -0
- package/README.ko.md +196 -0
- package/README.md +71 -4
- package/dist/cjs/hooks/useTypingTask.js +4 -2
- package/dist/cjs/hooks/useTypingTask.js.map +1 -1
- package/dist/esm/hooks/useTypingTask.js +4 -2
- package/dist/esm/hooks/useTypingTask.js.map +1 -1
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -18,6 +18,57 @@ A React component designed specifically for modern AI applications, providing sm
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
## 📋 Table of Contents
|
|
22
|
+
|
|
23
|
+
- [✨ Core Features](#-core-features)
|
|
24
|
+
- [📦 Quick Installation](#-quick-installation)
|
|
25
|
+
- [🚀 5-Minute Quick Start](#-5-minute-quick-start)
|
|
26
|
+
- [Basic Usage](#basic-usage)
|
|
27
|
+
- [Disable Typing Animation](#disable-typing-animation)
|
|
28
|
+
- [Mathematical Formula Support](#mathematical-formula-support)
|
|
29
|
+
- [AI Conversation Scenario](#ai-conversation-scenario)
|
|
30
|
+
- [🎯 Advanced Callback Control](#-advanced-callback-control)
|
|
31
|
+
- [🔄 Restart Animation Demo](#-restart-animation-demo)
|
|
32
|
+
- [▶️ Manual Start Animation Demo](#️-manual-start-animation-demo)
|
|
33
|
+
- [📚 Complete API Documentation](#-complete-api-documentation)
|
|
34
|
+
- [🧮 Mathematical Formula Usage Guide](#-mathematical-formula-usage-guide)
|
|
35
|
+
- [🔌 Plugin System](#-plugin-system)
|
|
36
|
+
- [🎛️ Timer Mode Details](#️-timer-mode-details)
|
|
37
|
+
- [💡 Practical Examples](#-practical-examples)
|
|
38
|
+
- [🔧 Best Practices](#-best-practices)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## ❓ Why use ds-markdown?
|
|
43
|
+
|
|
44
|
+
- **Ultimate AI Chat Experience**
|
|
45
|
+
Faithfully recreates the typing animation and streaming response of leading AI chat interfaces (like DeepSeek), delivering a truly immersive "AI is thinking/answering" experience.
|
|
46
|
+
|
|
47
|
+
- **Perfect for Streaming Backend Data**
|
|
48
|
+
Many AI/LLM backends (OpenAI, DeepSeek, etc.) send data chunks containing multiple characters at once.
|
|
49
|
+
**ds-markdown automatically splits each chunk into single characters and animates them one by one, ensuring smooth typing even if the backend sends several characters at a time.**
|
|
50
|
+
|
|
51
|
+
- **Full Markdown & Math Formula Support**
|
|
52
|
+
Built-in KaTeX, supports all major Markdown syntax and math formulas—ideal for technical Q&A, education, and knowledge bases.
|
|
53
|
+
|
|
54
|
+
- **Excellent Developer Experience**
|
|
55
|
+
Rich imperative API, supports streaming data, async callbacks, and plugin extensions for flexible animation and content control.
|
|
56
|
+
|
|
57
|
+
- **Lightweight & High Performance**
|
|
58
|
+
Small bundle size, fast, mobile and desktop ready. The only core dependency is [react-markdown](https://github.com/remarkjs/react-markdown) (a widely used, mature Markdown renderer). No other heavy dependencies—works out of the box.
|
|
59
|
+
|
|
60
|
+
- **Multi-theme & Plugin Architecture**
|
|
61
|
+
Light/dark theme switching, remark/rehype plugin compatibility, and advanced extensibility.
|
|
62
|
+
|
|
63
|
+
- **Wide Range of Use Cases**
|
|
64
|
+
- AI chatbots/assistants
|
|
65
|
+
- Real-time Q&A/knowledge bases
|
|
66
|
+
- Education/math/programming content
|
|
67
|
+
- Product demos, interactive docs
|
|
68
|
+
- Any scenario needing "typewriter" animation and streaming Markdown rendering
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
21
72
|
## ✨ Core Features
|
|
22
73
|
|
|
23
74
|
### 🤖 **AI Conversation Scenarios**
|
|
@@ -184,6 +235,227 @@ Let's explore these new features together!`);
|
|
|
184
235
|
}
|
|
185
236
|
```
|
|
186
237
|
|
|
238
|
+
### 🎯 Advanced Callback Control
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
import { useRef, useState } from 'react';
|
|
242
|
+
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
243
|
+
|
|
244
|
+
function AdvancedCallbackDemo() {
|
|
245
|
+
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
246
|
+
const [typingStats, setTypingStats] = useState({ progress: 0, currentChar: '', totalChars: 0 });
|
|
247
|
+
|
|
248
|
+
const handleBeforeTypedChar = async (data) => {
|
|
249
|
+
// Perform async operations before character typing
|
|
250
|
+
console.log('About to type:', data.currentChar);
|
|
251
|
+
|
|
252
|
+
// Can perform network requests, data validation, etc.
|
|
253
|
+
if (data.currentChar === '!') {
|
|
254
|
+
await new Promise((resolve) => setTimeout(resolve, 500)); // Simulate delay
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const handleTypedChar = (data) => {
|
|
259
|
+
// Update typing statistics
|
|
260
|
+
setTypingStats({
|
|
261
|
+
progress: Math.round(data.percent),
|
|
262
|
+
currentChar: data.currentChar,
|
|
263
|
+
totalChars: data.currentIndex + 1,
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Can add sound effects, animations, etc.
|
|
267
|
+
if (data.currentChar === '.') {
|
|
268
|
+
// Play period sound effect
|
|
269
|
+
console.log('Play period sound effect');
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
const handleStart = (data) => {
|
|
274
|
+
console.log('Start typing:', data.currentChar);
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const handleEnd = (data) => {
|
|
278
|
+
console.log('Typing complete:', data.str);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const startDemo = () => {
|
|
282
|
+
markdownRef.current?.clear();
|
|
283
|
+
markdownRef.current?.push(
|
|
284
|
+
'# Advanced Callback Demo\n\n' +
|
|
285
|
+
'This example shows how to use `onBeforeTypedChar` and `onTypedChar` callbacks:\n\n' +
|
|
286
|
+
'- 🎯 **Pre-typing callback**: Can perform async operations before character display\n' +
|
|
287
|
+
'- 📊 **Post-typing callback**: Can update progress in real-time and add effects\n' +
|
|
288
|
+
'- ⚡ **Performance optimization**: Supports async operations without affecting typing smoothness\n\n' +
|
|
289
|
+
'Current progress: ' +
|
|
290
|
+
typingStats.progress +
|
|
291
|
+
'%\n' +
|
|
292
|
+
'Characters typed: ' +
|
|
293
|
+
typingStats.totalChars +
|
|
294
|
+
'\n\n' +
|
|
295
|
+
'This is a very powerful feature!',
|
|
296
|
+
'answer',
|
|
297
|
+
);
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
return (
|
|
301
|
+
<div>
|
|
302
|
+
<button onClick={startDemo}>🚀 Start Advanced Demo</button>
|
|
303
|
+
|
|
304
|
+
<div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
|
|
305
|
+
<strong>Typing Stats:</strong> Progress {typingStats.progress}% | Current char: "{typingStats.currentChar}" | Total chars: {typingStats.totalChars}
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<MarkdownCMD ref={markdownRef} interval={30} onBeforeTypedChar={handleBeforeTypedChar} onTypedChar={handleTypedChar} onStart={handleStart} onEnd={handleEnd} />
|
|
309
|
+
</div>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 🔄 Restart Animation Demo
|
|
315
|
+
|
|
316
|
+
```tsx
|
|
317
|
+
import { useRef, useState } from 'react';
|
|
318
|
+
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
319
|
+
|
|
320
|
+
function RestartDemo() {
|
|
321
|
+
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
322
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
323
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
324
|
+
|
|
325
|
+
const startContent = () => {
|
|
326
|
+
markdownRef.current?.clear();
|
|
327
|
+
markdownRef.current?.push(
|
|
328
|
+
'# Restart Animation Demo\n\n' +
|
|
329
|
+
'This example shows how to use the `restart()` method:\n\n' +
|
|
330
|
+
'- 🔄 **Restart**: Play current content from the beginning\n' +
|
|
331
|
+
'- ⏸️ **Pause/Resume**: Can pause and resume at any time\n' +
|
|
332
|
+
'- 🎯 **Precise Control**: Complete control over animation playback state\n\n' +
|
|
333
|
+
'Current state: ' +
|
|
334
|
+
(isPlaying ? 'Playing' : 'Paused') +
|
|
335
|
+
'\n\n' +
|
|
336
|
+
'This is a very practical feature!',
|
|
337
|
+
'answer',
|
|
338
|
+
);
|
|
339
|
+
setIsPlaying(true);
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const handleStart = () => {
|
|
343
|
+
if (hasStarted) {
|
|
344
|
+
// If already started, restart
|
|
345
|
+
markdownRef.current?.restart();
|
|
346
|
+
} else {
|
|
347
|
+
// First time start
|
|
348
|
+
markdownRef.current?.start();
|
|
349
|
+
setHasStarted(true);
|
|
350
|
+
}
|
|
351
|
+
setIsPlaying(true);
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
const handleStop = () => {
|
|
355
|
+
markdownRef.current?.stop();
|
|
356
|
+
setIsPlaying(false);
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const handleResume = () => {
|
|
360
|
+
markdownRef.current?.resume();
|
|
361
|
+
setIsPlaying(true);
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
const handleRestart = () => {
|
|
365
|
+
markdownRef.current?.restart();
|
|
366
|
+
setIsPlaying(true);
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const handleEnd = () => {
|
|
370
|
+
setIsPlaying(false);
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
return (
|
|
374
|
+
<div>
|
|
375
|
+
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
376
|
+
<button onClick={startContent}>🚀 Start Content</button>
|
|
377
|
+
<button onClick={handleStart} disabled={isPlaying}>
|
|
378
|
+
{hasStarted ? '🔄 Restart' : '▶️ Start'}
|
|
379
|
+
</button>
|
|
380
|
+
<button onClick={handleStop} disabled={!isPlaying}>
|
|
381
|
+
⏸️ Pause
|
|
382
|
+
</button>
|
|
383
|
+
<button onClick={handleResume} disabled={isPlaying}>
|
|
384
|
+
▶️ Resume
|
|
385
|
+
</button>
|
|
386
|
+
<button onClick={handleRestart}>🔄 Restart</button>
|
|
387
|
+
</div>
|
|
388
|
+
|
|
389
|
+
<div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
|
|
390
|
+
<strong>Animation State:</strong> {isPlaying ? '🟢 Playing' : '🔴 Paused'}
|
|
391
|
+
</div>
|
|
392
|
+
|
|
393
|
+
<MarkdownCMD ref={markdownRef} interval={25} onEnd={handleEnd} />
|
|
394
|
+
</div>
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### ▶️ Manual Start Animation Demo
|
|
400
|
+
|
|
401
|
+
```tsx
|
|
402
|
+
import { useRef, useState } from 'react';
|
|
403
|
+
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
404
|
+
|
|
405
|
+
function StartDemo() {
|
|
406
|
+
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
407
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
408
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
409
|
+
|
|
410
|
+
const loadContent = () => {
|
|
411
|
+
markdownRef.current?.clear();
|
|
412
|
+
markdownRef.current?.push(
|
|
413
|
+
'# Manual Start Animation Demo\n\n' +
|
|
414
|
+
'This example shows how to use the `start()` method:\n\n' +
|
|
415
|
+
'- 🎯 **Manual Control**: When `autoStartTyping=false`, need to manually call `start()`\n' +
|
|
416
|
+
'- ⏱️ **Delayed Start**: Can start animation after user interaction\n' +
|
|
417
|
+
'- 🎮 **Gamification**: Suitable for scenarios requiring user initiative\n\n' +
|
|
418
|
+
'Click the "Start Animation" button to manually trigger the typing effect!',
|
|
419
|
+
'answer',
|
|
420
|
+
);
|
|
421
|
+
setIsPlaying(false);
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
const handleStart = () => {
|
|
425
|
+
if (hasStarted) {
|
|
426
|
+
// If already started, restart
|
|
427
|
+
markdownRef.current?.restart();
|
|
428
|
+
} else {
|
|
429
|
+
// First time start
|
|
430
|
+
markdownRef.current?.start();
|
|
431
|
+
setHasStarted(true);
|
|
432
|
+
}
|
|
433
|
+
setIsPlaying(true);
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
const handleEnd = () => {
|
|
437
|
+
setIsPlaying(false);
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
return (
|
|
441
|
+
<div>
|
|
442
|
+
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
443
|
+
<button onClick={loadContent}>📝 Load Content</button>
|
|
444
|
+
<button onClick={handleStart} disabled={isPlaying}>
|
|
445
|
+
{hasStarted ? '🔄 Restart' : '▶️ Start Animation'}
|
|
446
|
+
</button>
|
|
447
|
+
</div>
|
|
448
|
+
|
|
449
|
+
<div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
|
|
450
|
+
<strong>State:</strong> {isPlaying ? '🟢 Animation Playing' : '🔴 Waiting to Start'}
|
|
451
|
+
</div>
|
|
452
|
+
|
|
453
|
+
<MarkdownCMD ref={markdownRef} interval={30} autoStartTyping={false} onEnd={handleEnd} />
|
|
454
|
+
</div>
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
```
|
|
458
|
+
|
|
187
459
|
---
|
|
188
460
|
|
|
189
461
|
## 📚 Complete API Documentation
|
|
@@ -639,6 +911,7 @@ import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
|
639
911
|
function RestartDemo() {
|
|
640
912
|
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
641
913
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
914
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
642
915
|
|
|
643
916
|
const startContent = () => {
|
|
644
917
|
markdownRef.current?.clear();
|
|
@@ -658,7 +931,14 @@ function RestartDemo() {
|
|
|
658
931
|
};
|
|
659
932
|
|
|
660
933
|
const handleStart = () => {
|
|
661
|
-
|
|
934
|
+
if (hasStarted) {
|
|
935
|
+
// If already started, restart
|
|
936
|
+
markdownRef.current?.restart();
|
|
937
|
+
} else {
|
|
938
|
+
// First time start
|
|
939
|
+
markdownRef.current?.start();
|
|
940
|
+
setHasStarted(true);
|
|
941
|
+
}
|
|
662
942
|
setIsPlaying(true);
|
|
663
943
|
};
|
|
664
944
|
|
|
@@ -686,7 +966,7 @@ function RestartDemo() {
|
|
|
686
966
|
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
687
967
|
<button onClick={startContent}>🚀 Start Content</button>
|
|
688
968
|
<button onClick={handleStart} disabled={isPlaying}>
|
|
689
|
-
▶️ Start
|
|
969
|
+
{hasStarted ? '🔄 Restart' : '▶️ Start'}
|
|
690
970
|
</button>
|
|
691
971
|
<button onClick={handleStop} disabled={!isPlaying}>
|
|
692
972
|
⏸️ Pause
|
|
@@ -716,6 +996,7 @@ import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
|
716
996
|
function StartDemo() {
|
|
717
997
|
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
718
998
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
999
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
719
1000
|
|
|
720
1001
|
const loadContent = () => {
|
|
721
1002
|
markdownRef.current?.clear();
|
|
@@ -732,7 +1013,14 @@ function StartDemo() {
|
|
|
732
1013
|
};
|
|
733
1014
|
|
|
734
1015
|
const handleStart = () => {
|
|
735
|
-
|
|
1016
|
+
if (hasStarted) {
|
|
1017
|
+
// If already started, restart
|
|
1018
|
+
markdownRef.current?.restart();
|
|
1019
|
+
} else {
|
|
1020
|
+
// First time start
|
|
1021
|
+
markdownRef.current?.start();
|
|
1022
|
+
setHasStarted(true);
|
|
1023
|
+
}
|
|
736
1024
|
setIsPlaying(true);
|
|
737
1025
|
};
|
|
738
1026
|
|
|
@@ -745,7 +1033,7 @@ function StartDemo() {
|
|
|
745
1033
|
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
746
1034
|
<button onClick={loadContent}>📝 Load Content</button>
|
|
747
1035
|
<button onClick={handleStart} disabled={isPlaying}>
|
|
748
|
-
▶️ Start Animation
|
|
1036
|
+
{hasStarted ? '🔄 Restart' : '▶️ Start Animation'}
|
|
749
1037
|
</button>
|
|
750
1038
|
</div>
|
|
751
1039
|
|
package/README.ja.md
CHANGED
|
@@ -18,6 +18,57 @@
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
## 📋 目次
|
|
22
|
+
|
|
23
|
+
- [✨ コア機能](#-コア機能)
|
|
24
|
+
- [📦 クイックインストール](#-クイックインストール)
|
|
25
|
+
- [🚀 5分クイックスタート](#-5分クイックスタート)
|
|
26
|
+
- [基本的な使用法](#基本的な使用法)
|
|
27
|
+
- [タイピングアニメーションの無効化](#タイピングアニメーションの無効化)
|
|
28
|
+
- [数式サポート](#数式サポート)
|
|
29
|
+
- [AI 会話シナリオ](#ai-会話シナリオ)
|
|
30
|
+
- [🎯 高度なコールバック制御](#-高度なコールバック制御)
|
|
31
|
+
- [🔄 アニメーション再開デモ](#-アニメーション再開デモ)
|
|
32
|
+
- [▶️ 手動開始アニメーションデモ](#️-手動開始アニメーションデモ)
|
|
33
|
+
- [📚 完全 API ドキュメント](#-完全-api-ドキュメント)
|
|
34
|
+
- [🧮 数式使用ガイド](#-数式使用ガイド)
|
|
35
|
+
- [🔌 プラグインシステム](#-プラグインシステム)
|
|
36
|
+
- [🎛️ タイマーモード詳細](#️-タイマーモード詳細)
|
|
37
|
+
- [💡 実戦例](#-実戦例)
|
|
38
|
+
- [🔧 ベストプラクティス](#-ベストプラクティス)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## ❓ なぜ ds-markdown を使うのか?
|
|
43
|
+
|
|
44
|
+
- **AI チャット体験を完全再現**
|
|
45
|
+
DeepSeek などの主要な AI チャット UI のタイピングアニメーションとストリーミング応答を1:1で再現し、「AI が考え中/回答中」のリアルな体験を提供します。
|
|
46
|
+
|
|
47
|
+
- **バックエンドのストリーミングデータに完全対応**
|
|
48
|
+
多くの AI/LLM バックエンド(OpenAI、DeepSeek など)は、一度に複数文字を含む chunk を送信します。
|
|
49
|
+
**ds-markdown は各 chunk を自動的に1文字ずつ分割し、どんなにまとめて送られても滑らかに1文字ずつアニメーション表示します。**
|
|
50
|
+
|
|
51
|
+
- **Markdown & 数式完全対応**
|
|
52
|
+
KaTeX 内蔵、主要な Markdown 構文と数式をすべてサポート。技術 Q&A、教育、ナレッジベースに最適。
|
|
53
|
+
|
|
54
|
+
- **優れた開発体験**
|
|
55
|
+
豊富な命令型 API、ストリーミングデータ・非同期コールバック・プラグイン拡張に対応し、柔軟な制御が可能。
|
|
56
|
+
|
|
57
|
+
- **軽量・高性能**
|
|
58
|
+
小さなバンドルサイズ、高速、モバイル・デスクトップ両対応。コア依存は [react-markdown](https://github.com/remarkjs/react-markdown)(業界標準の成熟した Markdown レンダラー)のみで、他に重い依存はありません。すぐに使えます。
|
|
59
|
+
|
|
60
|
+
- **多テーマ・プラグインアーキテクチャ**
|
|
61
|
+
ライト/ダークテーマ切替、remark/rehype プラグイン互換、拡張性抜群。
|
|
62
|
+
|
|
63
|
+
- **幅広い用途**
|
|
64
|
+
- AI チャットボット/アシスタント
|
|
65
|
+
- リアルタイム Q&A/ナレッジベース
|
|
66
|
+
- 教育/数学/プログラミングコンテンツ
|
|
67
|
+
- プロダクトデモ、インタラクティブドキュメント
|
|
68
|
+
- 「タイプライター」アニメーションやストリーミング Markdown が必要なあらゆる場面
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
21
72
|
## ✨ コア機能
|
|
22
73
|
|
|
23
74
|
### 🤖 **AI 会話シナリオ**
|
|
@@ -179,6 +230,195 @@ React 19 は多くのエキサイティングな新機能をもたらします
|
|
|
179
230
|
}
|
|
180
231
|
```
|
|
181
232
|
|
|
233
|
+
### 🎯 高度なコールバック制御
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
import { useRef } from 'react';
|
|
237
|
+
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
238
|
+
|
|
239
|
+
function AdvancedCallbackDemo() {
|
|
240
|
+
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
241
|
+
|
|
242
|
+
const handleStart = () => {
|
|
243
|
+
markdownRef.current?.start();
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const handleStop = () => {
|
|
247
|
+
markdownRef.current?.stop();
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const handleResume = () => {
|
|
251
|
+
markdownRef.current?.resume();
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const handleRestart = () => {
|
|
255
|
+
markdownRef.current?.restart();
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const handleEnd = (data: EndData) => {
|
|
259
|
+
console.log('セクション完了:', data);
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
return (
|
|
263
|
+
<div>
|
|
264
|
+
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
265
|
+
<button onClick={handleStart}>🚀 コンテンツ開始</button>
|
|
266
|
+
<button onClick={handleStop}>⏸️ 一時停止</button>
|
|
267
|
+
<button onClick={handleResume}>▶️ 再開</button>
|
|
268
|
+
<button onClick={handleRestart}>🔄 再開</button>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
<MarkdownCMD ref={markdownRef} interval={20} onEnd={handleEnd} />
|
|
272
|
+
</div>
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 🔄 アニメーション再開デモ
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import { useRef, useState } from 'react';
|
|
281
|
+
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
282
|
+
|
|
283
|
+
function RestartDemo() {
|
|
284
|
+
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
285
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
286
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
287
|
+
|
|
288
|
+
const startContent = () => {
|
|
289
|
+
markdownRef.current?.clear();
|
|
290
|
+
markdownRef.current?.push(
|
|
291
|
+
'# アニメーション再開デモ\n\n' +
|
|
292
|
+
'この例は `restart()` メソッドの使用方法を示しています:\n\n' +
|
|
293
|
+
'- 🔄 **再開**:現在のコンテンツを最初から再生\n' +
|
|
294
|
+
'- ⏸️ **一時停止/再開**:いつでも一時停止と再開が可能\n' +
|
|
295
|
+
'- 🎯 **精密制御**:アニメーション再生状態の完全制御\n\n' +
|
|
296
|
+
'現在の状態:' +
|
|
297
|
+
(isPlaying ? '再生中' : '一時停止') +
|
|
298
|
+
'\n\n' +
|
|
299
|
+
'これは非常に実用的な機能です!',
|
|
300
|
+
'answer',
|
|
301
|
+
);
|
|
302
|
+
setIsPlaying(true);
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const handleStart = () => {
|
|
306
|
+
if (hasStarted) {
|
|
307
|
+
// 既に開始されている場合は再開
|
|
308
|
+
markdownRef.current?.restart();
|
|
309
|
+
} else {
|
|
310
|
+
// 初回開始
|
|
311
|
+
markdownRef.current?.start();
|
|
312
|
+
setHasStarted(true);
|
|
313
|
+
}
|
|
314
|
+
setIsPlaying(true);
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
const handleStop = () => {
|
|
318
|
+
markdownRef.current?.stop();
|
|
319
|
+
setIsPlaying(false);
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
const handleResume = () => {
|
|
323
|
+
markdownRef.current?.resume();
|
|
324
|
+
setIsPlaying(true);
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
const handleRestart = () => {
|
|
328
|
+
markdownRef.current?.restart();
|
|
329
|
+
setIsPlaying(true);
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const handleEnd = () => {
|
|
333
|
+
setIsPlaying(false);
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
return (
|
|
337
|
+
<div>
|
|
338
|
+
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
339
|
+
<button onClick={startContent}>🚀 コンテンツ開始</button>
|
|
340
|
+
<button onClick={handleStart} disabled={isPlaying}>
|
|
341
|
+
{hasStarted ? '🔄 再開' : '▶️ 開始'}
|
|
342
|
+
</button>
|
|
343
|
+
<button onClick={handleStop} disabled={!isPlaying}>
|
|
344
|
+
⏸️ 一時停止
|
|
345
|
+
</button>
|
|
346
|
+
<button onClick={handleResume} disabled={isPlaying}>
|
|
347
|
+
▶️ 再開
|
|
348
|
+
</button>
|
|
349
|
+
<button onClick={handleRestart}>🔄 再開</button>
|
|
350
|
+
</div>
|
|
351
|
+
|
|
352
|
+
<div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
|
|
353
|
+
<strong>アニメーション状態:</strong> {isPlaying ? '🟢 再生中' : '🔴 一時停止'}
|
|
354
|
+
</div>
|
|
355
|
+
|
|
356
|
+
<MarkdownCMD ref={markdownRef} interval={25} onEnd={handleEnd} />
|
|
357
|
+
</div>
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### ▶️ 手動開始アニメーションデモ
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
import { useRef, useState } from 'react';
|
|
366
|
+
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
367
|
+
|
|
368
|
+
function StartDemo() {
|
|
369
|
+
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
370
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
371
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
372
|
+
|
|
373
|
+
const loadContent = () => {
|
|
374
|
+
markdownRef.current?.clear();
|
|
375
|
+
markdownRef.current?.push(
|
|
376
|
+
'# 手動開始アニメーションデモ\n\n' +
|
|
377
|
+
'この例は `start()` メソッドの使用方法を示しています:\n\n' +
|
|
378
|
+
'- 🎯 **手動制御**:`autoStartTyping=false` の場合、手動で `start()` を呼び出す必要があります\n' +
|
|
379
|
+
'- ⏱️ **遅延開始**:ユーザーインタラクション後にアニメーションを開始できます\n' +
|
|
380
|
+
'- 🎮 **ゲーミフィケーション**:ユーザーの積極性を必要とするシナリオに適しています\n\n' +
|
|
381
|
+
'"アニメーション開始"ボタンをクリックしてタイピング効果を手動でトリガーしてください!',
|
|
382
|
+
'answer',
|
|
383
|
+
);
|
|
384
|
+
setIsPlaying(false);
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const handleStart = () => {
|
|
388
|
+
if (hasStarted) {
|
|
389
|
+
// 既に開始されている場合は再開
|
|
390
|
+
markdownRef.current?.restart();
|
|
391
|
+
} else {
|
|
392
|
+
// 初回開始
|
|
393
|
+
markdownRef.current?.start();
|
|
394
|
+
setHasStarted(true);
|
|
395
|
+
}
|
|
396
|
+
setIsPlaying(true);
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const handleEnd = () => {
|
|
400
|
+
setIsPlaying(false);
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
return (
|
|
404
|
+
<div>
|
|
405
|
+
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
406
|
+
<button onClick={loadContent}>📝 コンテンツ読み込み</button>
|
|
407
|
+
<button onClick={handleStart} disabled={isPlaying}>
|
|
408
|
+
{hasStarted ? '🔄 再開' : '▶️ アニメーション開始'}
|
|
409
|
+
</button>
|
|
410
|
+
</div>
|
|
411
|
+
|
|
412
|
+
<div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
|
|
413
|
+
<strong>状態:</strong> {isPlaying ? '🟢 アニメーション再生中' : '🔴 開始待機中'}
|
|
414
|
+
</div>
|
|
415
|
+
|
|
416
|
+
<MarkdownCMD ref={markdownRef} interval={30} autoStartTyping={false} onEnd={handleEnd} />
|
|
417
|
+
</div>
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
182
422
|
---
|
|
183
423
|
|
|
184
424
|
## 📚 完全 API ドキュメント
|
package/README.ko.md
CHANGED
|
@@ -18,6 +18,57 @@
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
## 📋 목차
|
|
22
|
+
|
|
23
|
+
- [✨ 핵심 기능](#-핵심-기능)
|
|
24
|
+
- [📦 빠른 설치](#-빠른-설치)
|
|
25
|
+
- [🚀 5분 빠른 시작](#-5분-빠른-시작)
|
|
26
|
+
- [기본 사용법](#기본-사용법)
|
|
27
|
+
- [타이핑 애니메이션 비활성화](#타이핑-애니메이션-비활성화)
|
|
28
|
+
- [수학 공식 지원](#수학-공식-지원)
|
|
29
|
+
- [AI 대화 시나리오](#ai-대화-시나리오)
|
|
30
|
+
- [🎯 고급 콜백 제어](#-고급-콜백-제어)
|
|
31
|
+
- [🔄 애니메이션 재시작 데모](#-애니메이션-재시작-데모)
|
|
32
|
+
- [▶️ 수동 시작 애니메이션 데모](#️-수동-시작-애니메이션-데모)
|
|
33
|
+
- [📚 완전 API 문서](#-완전-api-문서)
|
|
34
|
+
- [🧮 수학 공식 사용 가이드](#-수학-공식-사용-가이드)
|
|
35
|
+
- [🔌 플러그인 시스템](#-플러그인-시스템)
|
|
36
|
+
- [🎛️ 타이머 모드 상세](#️-타이머-모드-상세)
|
|
37
|
+
- [💡 실전 예제](#-실전-예제)
|
|
38
|
+
- [🔧 모범 사례](#-모범-사례)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## ❓ 왜 ds-markdown을 써야 하나요?
|
|
43
|
+
|
|
44
|
+
- **AI 채팅 경험 완벽 재현**
|
|
45
|
+
DeepSeek 등 주요 AI 채팅 UI의 타이핑 애니메이션과 스트리밍 응답을 1:1로 재현, "AI가 생각/답변 중"인 진짜 같은 경험을 제공합니다.
|
|
46
|
+
|
|
47
|
+
- **백엔드 스트리밍 데이터 완벽 대응**
|
|
48
|
+
많은 AI/LLM 백엔드(OpenAI, DeepSeek 등)는 한 번에 여러 글자가 포함된 chunk를 보냅니다.
|
|
49
|
+
**ds-markdown은 각 chunk를 자동으로 한 글자씩 분리해, 백엔드가 여러 글자를 한 번에 보내도 항상 부드럽게 한 글자씩 타이핑 애니메이션을 보여줍니다.**
|
|
50
|
+
|
|
51
|
+
- **완벽한 Markdown & 수식 지원**
|
|
52
|
+
KaTeX 내장, 모든 주요 Markdown 구문과 수식 지원—기술 Q&A, 교육, 지식베이스에 최적.
|
|
53
|
+
|
|
54
|
+
- **최고의 개발 경험**
|
|
55
|
+
풍부한 명령형 API, 스트리밍 데이터, 비동기 콜백, 플러그인 확장 등으로 유연한 제어 가능.
|
|
56
|
+
|
|
57
|
+
- **가볍고 고성능**
|
|
58
|
+
작은 용량, 빠른 속도, 모바일/데스크탑 모두 지원. 핵심 의존성은 [react-markdown](https://github.com/remarkjs/react-markdown) (업계 표준의 성숙한 Markdown 렌더러) 하나뿐이며, 그 외 무거운 의존성은 없습니다. 바로 사용 가능합니다.
|
|
59
|
+
|
|
60
|
+
- **다중 테마 및 플러그인 아키텍처**
|
|
61
|
+
라이트/다크 테마 전환, remark/rehype 플러그인 호환, 고급 확장성.
|
|
62
|
+
|
|
63
|
+
- **다양한 활용 사례**
|
|
64
|
+
- AI 챗봇/어시스턴트
|
|
65
|
+
- 실시간 Q&A/지식베이스
|
|
66
|
+
- 교육/수학/프로그래밍 콘텐츠
|
|
67
|
+
- 제품 데모, 인터랙티브 문서
|
|
68
|
+
- "타자기" 애니메이션과 스트리밍 Markdown이 필요한 모든 상황
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
21
72
|
## ✨ 핵심 기능
|
|
22
73
|
|
|
23
74
|
### 🤖 **AI 대화 시나리오**
|
|
@@ -607,3 +658,148 @@ import { MarkdownCMDRef } from 'ds-markdown';
|
|
|
607
658
|
const ref = useRef<MarkdownCMDRef>(null);
|
|
608
659
|
// 완전한 TypeScript 타입 힌트
|
|
609
660
|
```
|
|
661
|
+
|
|
662
|
+
### 🔄 애니메이션 재시작 데모
|
|
663
|
+
|
|
664
|
+
```tsx
|
|
665
|
+
import { useRef, useState } from 'react';
|
|
666
|
+
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
667
|
+
|
|
668
|
+
function RestartDemo() {
|
|
669
|
+
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
670
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
671
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
672
|
+
|
|
673
|
+
const startContent = () => {
|
|
674
|
+
markdownRef.current?.clear();
|
|
675
|
+
markdownRef.current?.push(
|
|
676
|
+
'# 애니메이션 재시작 데모\n\n' +
|
|
677
|
+
'이 예제는 `restart()` 메서드의 사용법을 보여줍니다:\n\n' +
|
|
678
|
+
'- 🔄 **재시작**: 현재 콘텐츠를 처음부터 재생\n' +
|
|
679
|
+
'- ⏸️ **일시정지/재개**: 언제든지 일시정지와 재개 가능\n' +
|
|
680
|
+
'- 🎯 **정밀 제어**: 애니메이션 재생 상태의 완전한 제어\n\n' +
|
|
681
|
+
'현재 상태: ' +
|
|
682
|
+
(isPlaying ? '재생 중' : '일시정지') +
|
|
683
|
+
'\n\n' +
|
|
684
|
+
'이는 매우 실용적인 기능입니다!',
|
|
685
|
+
'answer',
|
|
686
|
+
);
|
|
687
|
+
setIsPlaying(true);
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
const handleStart = () => {
|
|
691
|
+
if (hasStarted) {
|
|
692
|
+
// 이미 시작된 경우 재시작
|
|
693
|
+
markdownRef.current?.restart();
|
|
694
|
+
} else {
|
|
695
|
+
// 첫 번째 시작
|
|
696
|
+
markdownRef.current?.start();
|
|
697
|
+
setHasStarted(true);
|
|
698
|
+
}
|
|
699
|
+
setIsPlaying(true);
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
const handleStop = () => {
|
|
703
|
+
markdownRef.current?.stop();
|
|
704
|
+
setIsPlaying(false);
|
|
705
|
+
};
|
|
706
|
+
|
|
707
|
+
const handleResume = () => {
|
|
708
|
+
markdownRef.current?.resume();
|
|
709
|
+
setIsPlaying(true);
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
const handleRestart = () => {
|
|
713
|
+
markdownRef.current?.restart();
|
|
714
|
+
setIsPlaying(true);
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
const handleEnd = () => {
|
|
718
|
+
setIsPlaying(false);
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
return (
|
|
722
|
+
<div>
|
|
723
|
+
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
724
|
+
<button onClick={startContent}>🚀 콘텐츠 시작</button>
|
|
725
|
+
<button onClick={handleStart} disabled={isPlaying}>
|
|
726
|
+
{hasStarted ? '🔄 재시작' : '▶️ 시작'}
|
|
727
|
+
</button>
|
|
728
|
+
<button onClick={handleStop} disabled={!isPlaying}>
|
|
729
|
+
⏸️ 일시정지
|
|
730
|
+
</button>
|
|
731
|
+
<button onClick={handleResume} disabled={isPlaying}>
|
|
732
|
+
▶️ 재개
|
|
733
|
+
</button>
|
|
734
|
+
<button onClick={handleRestart}>🔄 재시작</button>
|
|
735
|
+
</div>
|
|
736
|
+
|
|
737
|
+
<div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
|
|
738
|
+
<strong>애니메이션 상태:</strong> {isPlaying ? '🟢 재생 중' : '🔴 일시정지'}
|
|
739
|
+
</div>
|
|
740
|
+
|
|
741
|
+
<MarkdownCMD ref={markdownRef} interval={25} onEnd={handleEnd} />
|
|
742
|
+
</div>
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
### ▶️ 수동 시작 애니메이션 데모
|
|
748
|
+
|
|
749
|
+
```tsx
|
|
750
|
+
import { useRef, useState } from 'react';
|
|
751
|
+
import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
752
|
+
|
|
753
|
+
function StartDemo() {
|
|
754
|
+
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
755
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
756
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
757
|
+
|
|
758
|
+
const loadContent = () => {
|
|
759
|
+
markdownRef.current?.clear();
|
|
760
|
+
markdownRef.current?.push(
|
|
761
|
+
'# 수동 시작 애니메이션 데모\n\n' +
|
|
762
|
+
'이 예제는 `start()` 메서드의 사용법을 보여줍니다:\n\n' +
|
|
763
|
+
'- 🎯 **수동 제어**: `autoStartTyping=false`일 때 수동으로 `start()`를 호출해야 합니다\n' +
|
|
764
|
+
'- ⏱️ **지연 시작**: 사용자 상호작용 후 애니메이션을 시작할 수 있습니다\n' +
|
|
765
|
+
'- 🎮 **게임화**: 사용자의 적극성이 필요한 시나리오에 적합합니다\n\n' +
|
|
766
|
+
'"애니메이션 시작" 버튼을 클릭하여 타이핑 효과를 수동으로 트리거하세요!',
|
|
767
|
+
'answer',
|
|
768
|
+
);
|
|
769
|
+
setIsPlaying(false);
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
const handleStart = () => {
|
|
773
|
+
if (hasStarted) {
|
|
774
|
+
// 이미 시작된 경우 재시작
|
|
775
|
+
markdownRef.current?.restart();
|
|
776
|
+
} else {
|
|
777
|
+
// 첫 번째 시작
|
|
778
|
+
markdownRef.current?.start();
|
|
779
|
+
setHasStarted(true);
|
|
780
|
+
}
|
|
781
|
+
setIsPlaying(true);
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
const handleEnd = () => {
|
|
785
|
+
setIsPlaying(false);
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
return (
|
|
789
|
+
<div>
|
|
790
|
+
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
791
|
+
<button onClick={loadContent}>📝 콘텐츠 로드</button>
|
|
792
|
+
<button onClick={handleStart} disabled={isPlaying}>
|
|
793
|
+
{hasStarted ? '🔄 재시작' : '▶️ 애니메이션 시작'}
|
|
794
|
+
</button>
|
|
795
|
+
</div>
|
|
796
|
+
|
|
797
|
+
<div style={{ margin: '10px 0', padding: '10px', background: '#f5f5f5', borderRadius: '4px' }}>
|
|
798
|
+
<strong>상태:</strong> {isPlaying ? '🟢 애니메이션 재생 중' : '🔴 시작 대기 중'}
|
|
799
|
+
</div>
|
|
800
|
+
|
|
801
|
+
<MarkdownCMD ref={markdownRef} interval={30} autoStartTyping={false} onEnd={handleEnd} />
|
|
802
|
+
</div>
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
```
|
package/README.md
CHANGED
|
@@ -18,6 +18,57 @@
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
## ❓ 为什么要用 ds-markdown?
|
|
22
|
+
|
|
23
|
+
- **AI 聊天体验极致还原**
|
|
24
|
+
1:1 复刻 DeepSeek 等主流 AI 聊天界面的打字动画和流式响应,带来真实的"AI 正在思考/回答"体验,极大提升用户沉浸感。
|
|
25
|
+
|
|
26
|
+
- **后端流式数据完美适配**
|
|
27
|
+
很多 AI/LLM 后端接口(如 OpenAI、DeepSeek 等)推送的数据 chunk 往往一次包含多个字符,普通打字机实现会出现卡顿、跳字等问题。
|
|
28
|
+
**ds-markdown 会自动将每个 chunk 拆分为单个字符,逐字流畅渲染动画,无论后端一次推送多少字,都能保证每个字都流畅打字。**
|
|
29
|
+
|
|
30
|
+
- **完整 Markdown & 数学公式支持**
|
|
31
|
+
内置 KaTeX,支持所有主流 Markdown 语法和数学公式,适合技术问答、教育、知识库等内容丰富的应用。
|
|
32
|
+
|
|
33
|
+
- **极致开发体验**
|
|
34
|
+
丰富的命令式 API,支持流式数据、异步回调、插件扩展,开发者可灵活控制动画和内容。
|
|
35
|
+
|
|
36
|
+
- **轻量高性能**
|
|
37
|
+
体积小、性能优,适配移动端和桌面端。核心依赖 [react-markdown](https://github.com/remarkjs/react-markdown)(业界主流、成熟的 Markdown 渲染库),无其它重量级依赖,开箱即用。
|
|
38
|
+
|
|
39
|
+
- **多主题与插件化架构**
|
|
40
|
+
支持亮/暗主题切换,兼容 remark/rehype 插件,满足个性化和高级扩展需求。
|
|
41
|
+
|
|
42
|
+
- **适用场景广泛**
|
|
43
|
+
- AI 聊天机器人/助手
|
|
44
|
+
- 实时问答/知识库
|
|
45
|
+
- 教育/数学/编程内容展示
|
|
46
|
+
- 产品演示、交互式文档
|
|
47
|
+
- 任何需要"打字机"动画和流式 Markdown 渲染的场景
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 📋 目录
|
|
52
|
+
|
|
53
|
+
- [✨ 核心特性](#-核心特性)
|
|
54
|
+
- [📦 快速安装](#-快速安装)
|
|
55
|
+
- [🚀 5分钟上手](#-5分钟上手)
|
|
56
|
+
- [基础用法](#基础用法)
|
|
57
|
+
- [禁用打字动画](#禁用打字动画)
|
|
58
|
+
- [数学公式支持](#数学公式支持)
|
|
59
|
+
- [AI 对话场景](#ai-对话场景)
|
|
60
|
+
- [🎯 高级回调控制](#-高级回调控制)
|
|
61
|
+
- [🔄 重新开始动画演示](#-重新开始动画演示)
|
|
62
|
+
- [▶️ 手动开始动画演示](#️-手动开始动画演示)
|
|
63
|
+
- [📚 完整 API 文档](#-完整-api-文档)
|
|
64
|
+
- [🧮 数学公式使用指南](#-数学公式使用指南)
|
|
65
|
+
- [🔌 插件系统](#-插件系统)
|
|
66
|
+
- [🎛️ 定时器模式详解](#️-定时器模式详解)
|
|
67
|
+
- [💡 实战示例](#-实战示例)
|
|
68
|
+
- [🔧 最佳实践](#-最佳实践)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
21
72
|
## ✨ 核心特性
|
|
22
73
|
|
|
23
74
|
### 🤖 **AI 对话场景**
|
|
@@ -267,6 +318,7 @@ import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
|
267
318
|
function RestartDemo() {
|
|
268
319
|
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
269
320
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
321
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
270
322
|
|
|
271
323
|
const startContent = () => {
|
|
272
324
|
markdownRef.current?.clear();
|
|
@@ -286,7 +338,14 @@ function RestartDemo() {
|
|
|
286
338
|
};
|
|
287
339
|
|
|
288
340
|
const handleStart = () => {
|
|
289
|
-
|
|
341
|
+
if (hasStarted) {
|
|
342
|
+
// 如果已经开始过,则重新开始
|
|
343
|
+
markdownRef.current?.restart();
|
|
344
|
+
} else {
|
|
345
|
+
// 第一次开始
|
|
346
|
+
markdownRef.current?.start();
|
|
347
|
+
setHasStarted(true);
|
|
348
|
+
}
|
|
290
349
|
setIsPlaying(true);
|
|
291
350
|
};
|
|
292
351
|
|
|
@@ -314,7 +373,7 @@ function RestartDemo() {
|
|
|
314
373
|
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
315
374
|
<button onClick={startContent}>🚀 开始内容</button>
|
|
316
375
|
<button onClick={handleStart} disabled={isPlaying}>
|
|
317
|
-
▶️ 开始
|
|
376
|
+
{hasStarted ? '🔄 重新开始' : '▶️ 开始'}
|
|
318
377
|
</button>
|
|
319
378
|
<button onClick={handleStop} disabled={!isPlaying}>
|
|
320
379
|
⏸️ 暂停
|
|
@@ -344,6 +403,7 @@ import { MarkdownCMD, MarkdownCMDRef } from 'ds-markdown';
|
|
|
344
403
|
function StartDemo() {
|
|
345
404
|
const markdownRef = useRef<MarkdownCMDRef>(null);
|
|
346
405
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
406
|
+
const [hasStarted, setHasStarted] = useState(false);
|
|
347
407
|
|
|
348
408
|
const loadContent = () => {
|
|
349
409
|
markdownRef.current?.clear();
|
|
@@ -360,7 +420,14 @@ function StartDemo() {
|
|
|
360
420
|
};
|
|
361
421
|
|
|
362
422
|
const handleStart = () => {
|
|
363
|
-
|
|
423
|
+
if (hasStarted) {
|
|
424
|
+
// 如果已经开始过,则重新开始
|
|
425
|
+
markdownRef.current?.restart();
|
|
426
|
+
} else {
|
|
427
|
+
// 第一次开始
|
|
428
|
+
markdownRef.current?.start();
|
|
429
|
+
setHasStarted(true);
|
|
430
|
+
}
|
|
364
431
|
setIsPlaying(true);
|
|
365
432
|
};
|
|
366
433
|
|
|
@@ -373,7 +440,7 @@ function StartDemo() {
|
|
|
373
440
|
<div style={{ marginBottom: '10px', display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
374
441
|
<button onClick={loadContent}>📝 加载内容</button>
|
|
375
442
|
<button onClick={handleStart} disabled={isPlaying}>
|
|
376
|
-
▶️ 开始动画
|
|
443
|
+
{hasStarted ? '🔄 重新开始' : '▶️ 开始动画'}
|
|
377
444
|
</button>
|
|
378
445
|
</div>
|
|
379
446
|
|
|
@@ -18,6 +18,8 @@ const useTypingTask = (options) => {
|
|
|
18
18
|
const typedIsManualStopRef = (0, react_1.useRef)(false);
|
|
19
19
|
const disableTypingRef = (0, react_1.useRef)(disableTyping);
|
|
20
20
|
disableTypingRef.current = disableTyping;
|
|
21
|
+
const intervalRef = (0, react_1.useRef)(interval);
|
|
22
|
+
intervalRef.current = interval;
|
|
21
23
|
const getChars = () => {
|
|
22
24
|
return charsRef.current;
|
|
23
25
|
};
|
|
@@ -185,7 +187,7 @@ const useTypingTask = (options) => {
|
|
|
185
187
|
lastFrameTime = currentTime;
|
|
186
188
|
}
|
|
187
189
|
const deltaTime = currentTime - lastFrameTime;
|
|
188
|
-
const charsToType = Math.max(1, Math.floor(deltaTime /
|
|
190
|
+
const charsToType = Math.max(1, Math.floor(deltaTime / intervalRef.current));
|
|
189
191
|
const actualCharsToType = Math.min(charsToType, chars.length);
|
|
190
192
|
// 处理字符
|
|
191
193
|
for (let i = 0; i < actualCharsToType; i++) {
|
|
@@ -233,7 +235,7 @@ const useTypingTask = (options) => {
|
|
|
233
235
|
stopTimeout();
|
|
234
236
|
return;
|
|
235
237
|
}
|
|
236
|
-
timerRef.current = setTimeout(startTyped,
|
|
238
|
+
timerRef.current = setTimeout(startTyped, intervalRef.current);
|
|
237
239
|
};
|
|
238
240
|
const startTyped = async (isStartPoint = false) => {
|
|
239
241
|
// 如果关闭打字机效果,则打完所有字符
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTypingTask.js","sourceRoot":"","sources":["../../../src/hooks/useTypingTask.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"useTypingTask.js","sourceRoot":"","sources":["../../../src/hooks/useTypingTask.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,8 @@ export const useTypingTask = (options) => {
|
|
|
15
15
|
const typedIsManualStopRef = useRef(false);
|
|
16
16
|
const disableTypingRef = useRef(disableTyping);
|
|
17
17
|
disableTypingRef.current = disableTyping;
|
|
18
|
+
const intervalRef = useRef(interval);
|
|
19
|
+
intervalRef.current = interval;
|
|
18
20
|
const getChars = () => {
|
|
19
21
|
return charsRef.current;
|
|
20
22
|
};
|
|
@@ -182,7 +184,7 @@ export const useTypingTask = (options) => {
|
|
|
182
184
|
lastFrameTime = currentTime;
|
|
183
185
|
}
|
|
184
186
|
const deltaTime = currentTime - lastFrameTime;
|
|
185
|
-
const charsToType = Math.max(1, Math.floor(deltaTime /
|
|
187
|
+
const charsToType = Math.max(1, Math.floor(deltaTime / intervalRef.current));
|
|
186
188
|
const actualCharsToType = Math.min(charsToType, chars.length);
|
|
187
189
|
// 处理字符
|
|
188
190
|
for (let i = 0; i < actualCharsToType; i++) {
|
|
@@ -230,7 +232,7 @@ export const useTypingTask = (options) => {
|
|
|
230
232
|
stopTimeout();
|
|
231
233
|
return;
|
|
232
234
|
}
|
|
233
|
-
timerRef.current = setTimeout(startTyped,
|
|
235
|
+
timerRef.current = setTimeout(startTyped, intervalRef.current);
|
|
234
236
|
};
|
|
235
237
|
const startTyped = async (isStartPoint = false) => {
|
|
236
238
|
// 如果关闭打字机效果,则打完所有字符
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTypingTask.js","sourceRoot":"","sources":["../../../src/hooks/useTypingTask.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"useTypingTask.js","sourceRoot":"","sources":["../../../src/hooks/useTypingTask.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AA6B1C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAA6B,EAAwB,EAAE;IACnF,MAAM,EACJ,SAAS,GAAG,YAAY,EACxB,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,OAAO,EACP,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,aAAa,EACb,iBAAiB,GAClB,GAAG,OAAO,CAAC;IACZ,WAAW;IACX,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACnC,aAAa;IACb,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,YAAY;IACZ,MAAM,iBAAiB,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;IACtD,kBAAkB;IAClB,MAAM,QAAQ,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACrD,WAAW;IACX,MAAM,aAAa,GAAG,MAAM,CAAgF,SAAS,CAAC,CAAC;IACvH,iBAAiB;IACjB,MAAM,oBAAoB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE3C,MAAM,gBAAgB,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IAC/C,gBAAgB,CAAC,OAAO,GAAG,aAAa,CAAC;IAEzC,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IAE/B,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,OAAO,QAAQ,CAAC,OAAO,CAAC;IAC1B,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC;QAE7B,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;QAC9B,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP;;;OAGG;IACH,MAAM,cAAc,GAAG,CAAC,IAAW,EAAE,EAAE;QACrC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC;QACjE,OAAO,CAAC;YACN,YAAY,EAAE,OAAO,CAAC,MAAM;YAC5B,WAAW,EAAE,IAAI,CAAC,OAAO;YACzB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;IAEF;;OAEG;IACH,MAAM,YAAY,GAAG,CAAC,IAA2B,EAAE,EAAE;QACnD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QAED,KAAK,CAAC;YACJ,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO;YAC3C,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO;YACjD,WAAW,EAAE,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO;YACrD,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK;SAC9B,CAAC,CAAC;IACL,CAAC,CAAC;IAEF;;;OAGG;IACH,MAAM,wBAAwB,GAAG,KAAK,EAAE,IAAW,EAAE,EAAE;QACrD,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAE5C,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC;QAEpD,aAAa;QACb,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC;QAE/C,MAAM,iBAAiB,CAAC;YACtB,YAAY,EAAE,KAAK;YACnB,WAAW,EAAE,OAAO;YACpB,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO;YACpD,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,aAAa;IACb,MAAM,kBAAkB,GAAG,KAAK,EAAE,IAAW,EAAE,EAAE;QAC/C,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAC5C,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC;QACpD,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC;QAErD,WAAW,CAAC;YACV,YAAY,EAAE,KAAK;YACnB,WAAW,EAAE,OAAO;YACpB,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;YACpE,UAAU,EAAE,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO;YACvD,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,YAAY;IACZ,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,2BAA2B;QAC3B,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC9B,oBAAoB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAChD,iBAAiB,CAAC,OAAO,GAAG,IAAI,CAAC;QACnC,CAAC;QAED,qCAAqC;QACrC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC/B,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;QAC1B,CAAC;QAED,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;QAC5B,aAAa,CAAC,OAAO,GAAG,SAAS,CAAC;IACpC,CAAC,CAAC;IAEF,aAAa;IACb,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,8BAA8B;QAC9B,IAAI,oBAAoB,CAAC,OAAO,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QAED,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,SAAS,KAAK,uBAAuB,EAAE,CAAC;YAC1C,uBAAuB,EAAE,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,gBAAgB,EAAE,CAAC;QACrB,CAAC;IACH,CAAC,CAAC;IAEF,gBAAgB;IAChB,KAAK,UAAU,eAAe;QAC5B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;QACzB,MAAM,gBAAgB,GAAG,KAAK;aAC3B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,UAAU,CAAC;aAChD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;aAC3B,IAAI,CAAC,EAAE,CAAC,CAAC;QACZ,MAAM,cAAc,GAAG,KAAK;aACzB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC;aAC9C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;aAC3B,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,iBAAiB,EAAE,CAAC;gBACxB,YAAY,EAAE,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBACrD,WAAW,EAAE,gBAAgB;gBAC7B,UAAU,EAAE,UAAU;gBACtB,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBACjD,OAAO,EAAE,GAAG;aACb,CAAC,CAAC;QACL,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,iBAAiB,EAAE,CAAC;gBACxB,YAAY,EAAE,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM;gBACnD,WAAW,EAAE,cAAc;gBAC3B,UAAU,EAAE,QAAQ;gBACpB,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO;gBAC/C,OAAO,EAAE,GAAG;aACb,CAAC,CAAC;QACL,CAAC;QAED,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,IAAI,gBAAgB,CAAC;QAC7D,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC;QACnE,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,cAAc,CAAC;QACzD,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC;QAC/D,eAAe,CAAC,OAAO,CAAC,SAAS,IAAI,gBAAgB,CAAC,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC;QACrF,QAAQ,CAAC,OAAO,GAAG,EAAE,CAAC;QACtB,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;QAE5B,YAAY,EAAE,CAAC;QACf,aAAa,EAAE,CAAC;IAClB,CAAC;IAED,+BAA+B;IAC/B,MAAM,uBAAuB,GAAG,GAAG,EAAE;QACnC,IAAI,aAAa,GAAG,CAAC,CAAC;QAEtB,MAAM,SAAS,GAAG,KAAK,EAAE,WAAmB,EAAE,EAAE;YAC9C,oBAAoB;YACpB,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBAC7B,MAAM,eAAe,EAAE,CAAC;gBACxB,OAAO;YACT,CAAC;YACD,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;YAEzB,IAAI,YAAY,CAAC,OAAO;gBAAE,OAAO;YAEjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,kBAAkB,EAAE,CAAC;gBACrB,OAAO;YACT,CAAC;YAED,gBAAgB;YAChB,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;gBACxB,aAAa,GAAG,WAAW,CAAC;YAC9B,CAAC;YAED,MAAM,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;YAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7E,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAE9D,OAAO;YACP,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,iBAAiB,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC3B,IAAI,IAAI,KAAK,SAAS;oBAAE,MAAM;gBAE9B,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;oBACzB,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;oBAC3B,cAAc,CAAC,IAAI,CAAC,CAAC;gBACvB,CAAC;gBACD,YAAY;gBACZ,MAAM,wBAAwB,CAAC,IAAI,CAAC,CAAC;gBACrC,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBACzB,aAAa;gBACb,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC3B,CAAC;YAED,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAElC,QAAQ;YACR,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,iBAAiB,CAAC,OAAO,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;gBAC5B,YAAY,EAAE,CAAC;YACjB,CAAC;QACH,CAAC,CAAC;QAEF,iBAAiB,CAAC,OAAO,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC,CAAC;IAEF,cAAc;IACd,MAAM,kBAAkB,GAAG,CAAC,MAAM,GAAG,KAAK,EAAE,EAAE;QAC5C,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;QAC5B,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;YAC9B,oBAAoB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAChD,iBAAiB,CAAC,OAAO,GAAG,IAAI,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CAAC;IAEF,oBAAoB;IACpB,MAAM,gBAAgB,GAAG,GAAG,EAAE;QAC5B,MAAM,SAAS,GAAG,GAAG,EAAE;YACrB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;YACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,WAAW,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YACD,QAAQ,CAAC,OAAO,GAAG,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;QACjE,CAAC,CAAC;QAEF,MAAM,UAAU,GAAG,KAAK,EAAE,YAAY,GAAG,KAAK,EAAE,EAAE;YAChD,oBAAoB;YACpB,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBAC7B,eAAe,EAAE,CAAC;gBAClB,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;YACzB,IAAI,YAAY,CAAC,OAAO;gBAAE,OAAO;YAEjC,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;YAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;YAE3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,WAAW,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YAED,IAAI,YAAY,EAAE,CAAC;gBACjB,cAAc,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;YACD,YAAY;YACZ,MAAM,wBAAwB,CAAC,IAAI,CAAC,CAAC;YACrC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,aAAa;YACb,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,SAAS,EAAE,CAAC;QACd,CAAC,CAAC;QAEF,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,CAAC;IAEF,aAAa;IACb,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;QAC5B,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC/B,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;QAC1B,CAAC;QACD,YAAY,EAAE,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,SAAS,KAAK,uBAAuB,EAAE,CAAC;YAC1C,kBAAkB,EAAE,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,WAAW,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;IAEF,WAAW;IACX,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,oBAAoB,CAAC,OAAO,GAAG,IAAI,CAAC;QACpC,UAAU,EAAE,CAAC;IACf,CAAC,CAAC;IAEF,aAAa;IACb,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,UAAU,EAAE,CAAC;IACf,CAAC,CAAC;IAEF,SAAS,gBAAgB;QACvB,OAAO,EAAE,CAAC;QACV,iCAAiC;QACjC,QAAQ,CAAC,OAAO,CAAC,OAAO,CACtB,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YACrE,MAAM,IAAI,GAAU;gBAClB,OAAO,EAAE,QAAQ;gBACjB,UAAU,EAAE,UAAU;gBACtB,OAAO,EAAE,CAAC;gBACV,KAAK,EAAE,CAAC;aACT,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CACH,CAAC;QACF,QAAQ,CAAC,OAAO,CAAC,OAAO,CACtB,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YACnE,MAAM,IAAI,GAAU;gBAClB,OAAO,EAAE,QAAQ;gBACjB,UAAU,EAAE,QAAQ;gBACpB,OAAO,EAAE,CAAC;gBACV,KAAK,EAAE,CAAC;aACT,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CACH,CAAC;QACF,iBAAiB,EAAE,CAAC;QACpB,aAAa,EAAE,CAAC;QAChB,cAAc,EAAE,CAAC;IACnB,CAAC;IAED,SAAS,KAAK;QACZ,UAAU,EAAE,CAAC;IACf,CAAC;IAED,SAAS,MAAM;QACb,oBAAoB,CAAC,OAAO,GAAG,KAAK,CAAC;QACrC,cAAc,EAAE,CAAC;IACnB,CAAC;IAED,OAAO;QACL,KAAK,EAAE,cAAc;QACrB,OAAO,EAAE,gBAAgB;QACzB,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,KAAK;QACZ,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO;QACnC,oBAAoB;KACrB,CAAC;AACJ,CAAC,CAAC"}
|