@haklex/rich-editor 0.0.38 → 0.0.39
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/dist/{RichEditor-B9KIgSwn.js → RichEditor-BcbNmzGB.js} +531 -12
- package/dist/components/RichEditor.d.ts.map +1 -1
- package/dist/components/decorators/AlertEditDecorator.d.ts.map +1 -1
- package/dist/components/decorators/CodeBlockEditDecorator.d.ts.map +1 -1
- package/dist/components/renderers/CodeBlockRenderer.d.ts +5 -0
- package/dist/components/renderers/CodeBlockRenderer.d.ts.map +1 -1
- package/dist/editor.mjs +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +31 -28
- package/dist/nodes/CodeBlockEditNode.d.ts +9 -0
- package/dist/nodes/CodeBlockEditNode.d.ts.map +1 -1
- package/dist/nodes/CodeBlockNode.d.ts +1 -0
- package/dist/nodes/CodeBlockNode.d.ts.map +1 -1
- package/dist/nodes/MentionNode.d.ts +2 -0
- package/dist/nodes/MentionNode.d.ts.map +1 -1
- package/dist/plugins/BlockExitPlugin.d.ts +2 -0
- package/dist/plugins/BlockExitPlugin.d.ts.map +1 -0
- package/dist/rich-editor.css +1 -1
- package/dist/static-entry.mjs +1 -1
- package/dist/{theme-D1COY7pa.js → theme-gVNBI_ET.js} +79 -50
- package/dist/transformers/code-block.d.ts +3 -0
- package/dist/transformers/code-block.d.ts.map +1 -0
- package/dist/transformers/index.d.ts +1 -0
- package/dist/transformers/index.d.ts.map +1 -1
- package/dist/transformers/quote.d.ts +3 -0
- package/dist/transformers/quote.d.ts.map +1 -0
- package/dist/utils/codeBlockSelectionIntent.d.ts +4 -0
- package/dist/utils/codeBlockSelectionIntent.d.ts.map +1 -0
- package/package.json +4 -4
|
@@ -12,10 +12,10 @@ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
|
|
|
12
12
|
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
|
13
13
|
import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin";
|
|
14
14
|
import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
|
|
15
|
-
import {
|
|
16
|
-
import { $getNodeByKey, $insertNodes, createEditor, $
|
|
15
|
+
import { Y as $isAlertQuoteNode, d as RendererWrapper, Z as AlertRenderer, _ as SpoilerNode, T as MentionNode, a0 as FootnoteNode, O as KaTeXInlineNode, a1 as AlertQuoteNode, f as editorTheme, a2 as $isBannerNode, a3 as BannerRenderer, a4 as BannerNode, a5 as normalizeBannerType, a6 as $isCodeBlockNode, a7 as CodeBlockRenderer, a8 as CodeBlockNode, i as useFootnoteDefinitions, I as FootnoteSectionNode, v as $isGridContainerNode, K as GridContainerNode, b as builtinNodes, M as KaTeXBlockNode, L as ImageNode, a9 as VideoNode, Q as LinkCardNode, aa as DetailsNode, U as MermaidNode, F as FootnoteDefinitionsProvider, p as $createImageNode, W as computeImageMeta, V as OPEN_IMAGE_UPLOAD_DIALOG_COMMAND, ab as $createKaTeXInlineNode, ac as $createKaTeXBlockNode, ad as $createDetailsNode, ae as $createFootnoteNode, t as $isFootnoteSectionNode, $ as $createFootnoteSectionNode, r as $createMentionNode, g as extractTextContent, af as $createSpoilerNode, s as $createMermaidNode, C as ColorSchemeProvider, R as RendererConfigProvider } from "./theme-gVNBI_ET.js";
|
|
16
|
+
import { $getNodeByKey, KEY_ENTER_COMMAND, COMMAND_PRIORITY_CRITICAL, KEY_ARROW_DOWN_COMMAND, COMMAND_PRIORITY_HIGH, $getRoot, $createParagraphNode, $isParagraphNode, $getSelection, $isRangeSelection, $insertNodes, createEditor, $isElementNode, $isDecoratorNode, $createNodeSelection, $setSelection, $nodesOfType, createCommand, COMMAND_PRIORITY_EDITOR, $isRootNode, $isNodeSelection, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, KEY_ARROW_UP_COMMAND, $isTextNode, $parseSerializedNode, PASTE_COMMAND, $createTextNode, $createLineBreakNode } from "lexical";
|
|
17
17
|
import { Info, Lightbulb, TriangleAlert, Flag, LayoutGrid, Plus, Minus, Check, Upload, Link2 } from "lucide-react";
|
|
18
|
-
import { useCallback, createElement, useState,
|
|
18
|
+
import { useCallback, useEffect, createElement, useState, createContext, use, useRef, useMemo } from "react";
|
|
19
19
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
20
20
|
import { ContentEditable as ContentEditable$1 } from "@lexical/react/LexicalContentEditable";
|
|
21
21
|
import { LexicalNestedComposer } from "@lexical/react/LexicalNestedComposer";
|
|
@@ -23,13 +23,110 @@ import { CodeNode } from "@lexical/code";
|
|
|
23
23
|
import { HorizontalRuleNode, INSERT_HORIZONTAL_RULE_COMMAND, $createHorizontalRuleNode } from "@lexical/extension";
|
|
24
24
|
import { LinkNode, AutoLinkNode, createLinkMatcherWithRegExp, registerAutoLink } from "@lexical/link";
|
|
25
25
|
import { ListNode, ListItemNode } from "@lexical/list";
|
|
26
|
-
import { HeadingNode, QuoteNode, DRAG_DROP_PASTE } from "@lexical/rich-text";
|
|
26
|
+
import { HeadingNode, QuoteNode, $isQuoteNode, DRAG_DROP_PASTE, $createQuoteNode } from "@lexical/rich-text";
|
|
27
27
|
import { TableNode, TableCellNode, TableRowNode } from "@lexical/table";
|
|
28
|
+
import { useLexicalNodeSelection } from "@lexical/react/useLexicalNodeSelection";
|
|
28
29
|
import { Dialog, DialogPopup, DialogTitle, SegmentedControl } from "@haklex/rich-editor-ui";
|
|
29
30
|
import { b as clsx, g as getVariantClass } from "./utils-fpeaZV1R.js";
|
|
30
31
|
import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
|
|
31
|
-
import { CHECK_LIST, TRANSFORMERS } from "@lexical/markdown";
|
|
32
|
+
import { CHECK_LIST, TRANSFORMERS, QUOTE, CODE } from "@lexical/markdown";
|
|
32
33
|
import { GIT_ALERT_TRANSFORMER as GIT_ALERT_TRANSFORMER$1, CONTAINER_TRANSFORMER as CONTAINER_TRANSFORMER$1, FOOTNOTE_TRANSFORMER as FOOTNOTE_TRANSFORMER$1, FOOTNOTE_SECTION_TRANSFORMER as FOOTNOTE_SECTION_TRANSFORMER$1, KATEX_INLINE_TRANSFORMER as KATEX_INLINE_TRANSFORMER$1, KATEX_BLOCK_TRANSFORMER as KATEX_BLOCK_TRANSFORMER$1, MENTION_TRANSFORMER as MENTION_TRANSFORMER$1, SPOILER_TRANSFORMER as SPOILER_TRANSFORMER$1, INSERT_TRANSFORMER, SUPERSCRIPT_TRANSFORMER, SUBSCRIPT_TRANSFORMER, IMAGE_BLOCK_TRANSFORMER, VIDEO_BLOCK_TRANSFORMER, CODE_BLOCK_NODE_TRANSFORMER, LINK_CARD_BLOCK_TRANSFORMER, MERMAID_BLOCK_TRANSFORMER, HORIZONTAL_RULE_BLOCK_TRANSFORMER, TABLE_BLOCK_TRANSFORMER } from "@haklex/rich-headless/transformers";
|
|
34
|
+
function ExitBlockPlugin({
|
|
35
|
+
parentEditor,
|
|
36
|
+
nodeKey
|
|
37
|
+
}) {
|
|
38
|
+
const [editor] = useLexicalComposerContext();
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const focusParent = () => {
|
|
41
|
+
parentEditor.focus(() => {
|
|
42
|
+
parentEditor.update(() => {
|
|
43
|
+
const alertNode = $getNodeByKey(nodeKey);
|
|
44
|
+
if (alertNode) {
|
|
45
|
+
const next = alertNode.getNextSibling();
|
|
46
|
+
if (next) {
|
|
47
|
+
next.selectStart();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const exitAlert = (removeEmpty) => {
|
|
54
|
+
const root = $getRoot();
|
|
55
|
+
const lastChild = root.getLastChild();
|
|
56
|
+
const shouldRemoveAlert = removeEmpty && root.getChildrenSize() <= 1;
|
|
57
|
+
if (removeEmpty && lastChild) {
|
|
58
|
+
lastChild.remove();
|
|
59
|
+
}
|
|
60
|
+
if (shouldRemoveAlert) {
|
|
61
|
+
parentEditor.update(
|
|
62
|
+
() => {
|
|
63
|
+
const alertNode = $getNodeByKey(nodeKey);
|
|
64
|
+
if (alertNode) {
|
|
65
|
+
const paragraph = $createParagraphNode();
|
|
66
|
+
alertNode.insertAfter(paragraph);
|
|
67
|
+
alertNode.remove();
|
|
68
|
+
paragraph.selectStart();
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{ onUpdate: focusParent }
|
|
72
|
+
);
|
|
73
|
+
} else {
|
|
74
|
+
parentEditor.update(
|
|
75
|
+
() => {
|
|
76
|
+
const alertNode = $getNodeByKey(nodeKey);
|
|
77
|
+
if (alertNode) {
|
|
78
|
+
let next = alertNode.getNextSibling();
|
|
79
|
+
if (!next || !$isParagraphNode(next)) {
|
|
80
|
+
next = $createParagraphNode();
|
|
81
|
+
alertNode.insertAfter(next);
|
|
82
|
+
}
|
|
83
|
+
next.selectStart();
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{ onUpdate: focusParent }
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const isAtLastEmptyParagraph = () => {
|
|
91
|
+
const selection = $getSelection();
|
|
92
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed())
|
|
93
|
+
return false;
|
|
94
|
+
const anchorNode = selection.anchor.getNode();
|
|
95
|
+
const topLevelElement = anchorNode.getTopLevelElement();
|
|
96
|
+
return topLevelElement && $isParagraphNode(topLevelElement) && topLevelElement.getTextContent() === "" && topLevelElement.getNextSibling() === null;
|
|
97
|
+
};
|
|
98
|
+
const unregisterEnter = editor.registerCommand(
|
|
99
|
+
KEY_ENTER_COMMAND,
|
|
100
|
+
(event) => {
|
|
101
|
+
if (event?.metaKey || event?.ctrlKey) {
|
|
102
|
+
event.preventDefault();
|
|
103
|
+
exitAlert(false);
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
if (!isAtLastEmptyParagraph()) return false;
|
|
107
|
+
event?.preventDefault();
|
|
108
|
+
exitAlert(true);
|
|
109
|
+
return true;
|
|
110
|
+
},
|
|
111
|
+
COMMAND_PRIORITY_CRITICAL
|
|
112
|
+
);
|
|
113
|
+
const unregisterArrowDown = editor.registerCommand(
|
|
114
|
+
KEY_ARROW_DOWN_COMMAND,
|
|
115
|
+
(event) => {
|
|
116
|
+
if (!isAtLastEmptyParagraph()) return false;
|
|
117
|
+
event?.preventDefault();
|
|
118
|
+
exitAlert(false);
|
|
119
|
+
return true;
|
|
120
|
+
},
|
|
121
|
+
COMMAND_PRIORITY_HIGH
|
|
122
|
+
);
|
|
123
|
+
return () => {
|
|
124
|
+
unregisterEnter();
|
|
125
|
+
unregisterArrowDown();
|
|
126
|
+
};
|
|
127
|
+
}, [editor, parentEditor, nodeKey]);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
33
130
|
function AlertEditDecorator({
|
|
34
131
|
nodeKey,
|
|
35
132
|
alertType,
|
|
@@ -78,7 +175,8 @@ function AlertEditDecorator({
|
|
|
78
175
|
}
|
|
79
176
|
),
|
|
80
177
|
/* @__PURE__ */ jsx(ListPlugin, {}),
|
|
81
|
-
/* @__PURE__ */ jsx(LinkPlugin, {})
|
|
178
|
+
/* @__PURE__ */ jsx(LinkPlugin, {}),
|
|
179
|
+
/* @__PURE__ */ jsx(ExitBlockPlugin, { parentEditor: editor, nodeKey })
|
|
82
180
|
] }) })
|
|
83
181
|
] });
|
|
84
182
|
}
|
|
@@ -337,13 +435,31 @@ let BannerEditNode = _BannerEditNode;
|
|
|
337
435
|
function $createBannerEditNode(bannerType, contentState) {
|
|
338
436
|
return new BannerEditNode(bannerType, contentState);
|
|
339
437
|
}
|
|
438
|
+
const codeBlockCursorIntentMap = /* @__PURE__ */ new Map();
|
|
439
|
+
function setCodeBlockCursorIntent(nodeKey, placement) {
|
|
440
|
+
codeBlockCursorIntentMap.set(nodeKey, placement);
|
|
441
|
+
}
|
|
442
|
+
function consumeCodeBlockCursorIntent(nodeKey) {
|
|
443
|
+
const placement = codeBlockCursorIntentMap.get(nodeKey);
|
|
444
|
+
if (!placement) return null;
|
|
445
|
+
codeBlockCursorIntentMap.delete(nodeKey);
|
|
446
|
+
return placement;
|
|
447
|
+
}
|
|
340
448
|
function CodeBlockEditDecorator({
|
|
341
449
|
nodeKey,
|
|
342
450
|
code,
|
|
343
451
|
language
|
|
344
452
|
}) {
|
|
345
453
|
const [editor] = useLexicalComposerContext();
|
|
454
|
+
const [isSelected] = useLexicalNodeSelection(nodeKey);
|
|
455
|
+
const [cursorPlacement, setCursorPlacement] = useState(
|
|
456
|
+
"start"
|
|
457
|
+
);
|
|
346
458
|
const editable = editor.isEditable();
|
|
459
|
+
useEffect(() => {
|
|
460
|
+
if (!editable || !isSelected) return;
|
|
461
|
+
setCursorPlacement(consumeCodeBlockCursorIntent(nodeKey) ?? "start");
|
|
462
|
+
}, [editable, isSelected, nodeKey]);
|
|
347
463
|
const handleCodeChange = useCallback(
|
|
348
464
|
(newCode) => {
|
|
349
465
|
editor.update(() => {
|
|
@@ -355,6 +471,100 @@ function CodeBlockEditDecorator({
|
|
|
355
471
|
},
|
|
356
472
|
[editor, nodeKey]
|
|
357
473
|
);
|
|
474
|
+
const handleLanguageChange = useCallback(
|
|
475
|
+
(newLanguage) => {
|
|
476
|
+
editor.update(() => {
|
|
477
|
+
const node = $getNodeByKey(nodeKey);
|
|
478
|
+
if ($isCodeBlockNode(node)) {
|
|
479
|
+
node.setLanguage(newLanguage);
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
},
|
|
483
|
+
[editor, nodeKey]
|
|
484
|
+
);
|
|
485
|
+
const handleDelete = useCallback(() => {
|
|
486
|
+
editor.getRootElement()?.focus({ preventScroll: true });
|
|
487
|
+
editor.update(() => {
|
|
488
|
+
const node = $getNodeByKey(nodeKey);
|
|
489
|
+
if (!node) return;
|
|
490
|
+
const prev = node.getPreviousSibling();
|
|
491
|
+
const next = node.getNextSibling();
|
|
492
|
+
const parent = node.getParent();
|
|
493
|
+
node.remove();
|
|
494
|
+
if (prev) {
|
|
495
|
+
if ($isElementNode(prev)) {
|
|
496
|
+
prev.selectEnd();
|
|
497
|
+
} else {
|
|
498
|
+
if ($isDecoratorNode(prev) && prev.getType() === "code-block") {
|
|
499
|
+
setCodeBlockCursorIntent(prev.getKey(), "end");
|
|
500
|
+
}
|
|
501
|
+
const selection = $createNodeSelection();
|
|
502
|
+
selection.add(prev.getKey());
|
|
503
|
+
$setSelection(selection);
|
|
504
|
+
}
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
if (next) {
|
|
508
|
+
if ($isElementNode(next)) {
|
|
509
|
+
next.selectStart();
|
|
510
|
+
} else {
|
|
511
|
+
if ($isDecoratorNode(next) && next.getType() === "code-block") {
|
|
512
|
+
setCodeBlockCursorIntent(next.getKey(), "start");
|
|
513
|
+
}
|
|
514
|
+
const selection = $createNodeSelection();
|
|
515
|
+
selection.add(next.getKey());
|
|
516
|
+
$setSelection(selection);
|
|
517
|
+
}
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
if (parent) {
|
|
521
|
+
const p = $createParagraphNode();
|
|
522
|
+
parent.append(p);
|
|
523
|
+
p.selectStart();
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
}, [editor, nodeKey]);
|
|
527
|
+
const handleExitBlock = useCallback(
|
|
528
|
+
(direction) => {
|
|
529
|
+
editor.getRootElement()?.focus({ preventScroll: true });
|
|
530
|
+
editor.update(() => {
|
|
531
|
+
const node = $getNodeByKey(nodeKey);
|
|
532
|
+
if (!node) return;
|
|
533
|
+
if (direction === "before") {
|
|
534
|
+
const prev = node.getPreviousSibling();
|
|
535
|
+
if (!prev) return;
|
|
536
|
+
if ($isElementNode(prev)) {
|
|
537
|
+
prev.selectEnd();
|
|
538
|
+
} else {
|
|
539
|
+
if ($isDecoratorNode(prev) && prev.getType() === "code-block") {
|
|
540
|
+
setCodeBlockCursorIntent(prev.getKey(), "end");
|
|
541
|
+
}
|
|
542
|
+
const selection = $createNodeSelection();
|
|
543
|
+
selection.add(prev.getKey());
|
|
544
|
+
$setSelection(selection);
|
|
545
|
+
}
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
let next = node.getNextSibling();
|
|
549
|
+
if (!next) {
|
|
550
|
+
const p = $createParagraphNode();
|
|
551
|
+
node.insertAfter(p);
|
|
552
|
+
next = p;
|
|
553
|
+
}
|
|
554
|
+
if ($isElementNode(next)) {
|
|
555
|
+
next.selectStart();
|
|
556
|
+
} else {
|
|
557
|
+
if ($isDecoratorNode(next) && next.getType() === "code-block") {
|
|
558
|
+
setCodeBlockCursorIntent(next.getKey(), "start");
|
|
559
|
+
}
|
|
560
|
+
const selection = $createNodeSelection();
|
|
561
|
+
selection.add(next.getKey());
|
|
562
|
+
$setSelection(selection);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
},
|
|
566
|
+
[editor, nodeKey]
|
|
567
|
+
);
|
|
358
568
|
return /* @__PURE__ */ jsx(
|
|
359
569
|
RendererWrapper,
|
|
360
570
|
{
|
|
@@ -364,17 +574,22 @@ function CodeBlockEditDecorator({
|
|
|
364
574
|
code,
|
|
365
575
|
language,
|
|
366
576
|
editable,
|
|
367
|
-
onCodeChange: editable ? handleCodeChange : void 0
|
|
577
|
+
onCodeChange: editable ? handleCodeChange : void 0,
|
|
578
|
+
onLanguageChange: editable ? handleLanguageChange : void 0,
|
|
579
|
+
onDelete: editable ? handleDelete : void 0,
|
|
580
|
+
onExitBlock: editable ? handleExitBlock : void 0,
|
|
581
|
+
selected: editable ? isSelected : false,
|
|
582
|
+
cursorPlacement: editable ? cursorPlacement : "start"
|
|
368
583
|
}
|
|
369
584
|
}
|
|
370
585
|
);
|
|
371
586
|
}
|
|
372
|
-
class
|
|
587
|
+
const _CodeBlockEditNode = class _CodeBlockEditNode extends CodeBlockNode {
|
|
373
588
|
static clone(node) {
|
|
374
|
-
return new
|
|
589
|
+
return new _CodeBlockEditNode(node.__code, node.__language, node.__key);
|
|
375
590
|
}
|
|
376
591
|
static importJSON(serializedNode) {
|
|
377
|
-
return new
|
|
592
|
+
return new _CodeBlockEditNode(serializedNode.code, serializedNode.language);
|
|
378
593
|
}
|
|
379
594
|
decorate(_editor, _config) {
|
|
380
595
|
return createElement(CodeBlockEditDecorator, {
|
|
@@ -383,7 +598,16 @@ class CodeBlockEditNode extends CodeBlockNode {
|
|
|
383
598
|
language: this.__language
|
|
384
599
|
});
|
|
385
600
|
}
|
|
386
|
-
}
|
|
601
|
+
};
|
|
602
|
+
__publicField(_CodeBlockEditNode, "slashMenuItems", CodeBlockNode.slashMenuItems.map((item) => ({
|
|
603
|
+
...item,
|
|
604
|
+
onSelect: (editor) => {
|
|
605
|
+
editor.update(() => {
|
|
606
|
+
$insertNodes([new _CodeBlockEditNode("", "text")]);
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
})));
|
|
610
|
+
let CodeBlockEditNode = _CodeBlockEditNode;
|
|
387
611
|
function FootnoteSectionEditRenderer({
|
|
388
612
|
definitions
|
|
389
613
|
}) {
|
|
@@ -871,6 +1095,237 @@ function AutoLinkPlugin({ matchers }) {
|
|
|
871
1095
|
}, [editor, matchers]);
|
|
872
1096
|
return null;
|
|
873
1097
|
}
|
|
1098
|
+
function selectDecoratorNode(node, cursorPlacement = "start") {
|
|
1099
|
+
if (node.getType() === "code-block") {
|
|
1100
|
+
setCodeBlockCursorIntent(node.getKey(), cursorPlacement);
|
|
1101
|
+
}
|
|
1102
|
+
const selection = $createNodeSelection();
|
|
1103
|
+
selection.add(node.getKey());
|
|
1104
|
+
$setSelection(selection);
|
|
1105
|
+
}
|
|
1106
|
+
function isAtTopLevelBoundary(selection, direction) {
|
|
1107
|
+
const point = selection.anchor;
|
|
1108
|
+
const topLevel = point.getNode().getTopLevelElementOrThrow();
|
|
1109
|
+
const pointNode = point.getNode();
|
|
1110
|
+
if (point.type === "text") {
|
|
1111
|
+
if (!$isTextNode(pointNode)) return false;
|
|
1112
|
+
const expectedOffset = direction === "start" ? 0 : pointNode.getTextContentSize();
|
|
1113
|
+
if (point.offset !== expectedOffset) return false;
|
|
1114
|
+
} else {
|
|
1115
|
+
if (!$isElementNode(pointNode)) return false;
|
|
1116
|
+
const expectedOffset = direction === "start" ? 0 : pointNode.getChildrenSize();
|
|
1117
|
+
if (point.offset !== expectedOffset) return false;
|
|
1118
|
+
}
|
|
1119
|
+
let current = pointNode;
|
|
1120
|
+
while (current && current !== topLevel) {
|
|
1121
|
+
const sibling = direction === "start" ? current.getPreviousSibling() : current.getNextSibling();
|
|
1122
|
+
if (sibling !== null) return false;
|
|
1123
|
+
current = current.getParent();
|
|
1124
|
+
}
|
|
1125
|
+
return current === topLevel;
|
|
1126
|
+
}
|
|
1127
|
+
function isSingleLineParagraph(node) {
|
|
1128
|
+
return $isParagraphNode(node) && !node.getTextContent().includes("\n");
|
|
1129
|
+
}
|
|
1130
|
+
function BlockExitPlugin() {
|
|
1131
|
+
const [editor] = useLexicalComposerContext();
|
|
1132
|
+
useEffect(() => {
|
|
1133
|
+
const unregisterArrowDown = editor.registerCommand(
|
|
1134
|
+
KEY_ARROW_DOWN_COMMAND,
|
|
1135
|
+
(event) => {
|
|
1136
|
+
const selection = $getSelection();
|
|
1137
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
|
|
1138
|
+
return false;
|
|
1139
|
+
}
|
|
1140
|
+
const anchorNode = selection.anchor.getNode();
|
|
1141
|
+
const topLevelElement = anchorNode.getTopLevelElementOrThrow();
|
|
1142
|
+
const shouldSelectNextDecorator = isAtTopLevelBoundary(selection, "end") || isSingleLineParagraph(topLevelElement);
|
|
1143
|
+
if (!$isQuoteNode(topLevelElement) && shouldSelectNextDecorator) {
|
|
1144
|
+
const next2 = topLevelElement.getNextSibling();
|
|
1145
|
+
if (next2 && $isDecoratorNode(next2) && next2.isKeyboardSelectable()) {
|
|
1146
|
+
event?.preventDefault();
|
|
1147
|
+
selectDecoratorNode(next2, "start");
|
|
1148
|
+
return true;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
const element = $isElementNode(anchorNode) ? anchorNode : anchorNode.getParentOrThrow();
|
|
1152
|
+
let quoteChild = element;
|
|
1153
|
+
let quoteNode = null;
|
|
1154
|
+
let current = element;
|
|
1155
|
+
while (current) {
|
|
1156
|
+
const parent = current.getParent();
|
|
1157
|
+
if (!parent || $isRootNode(parent)) break;
|
|
1158
|
+
if ($isQuoteNode(parent)) {
|
|
1159
|
+
quoteNode = parent;
|
|
1160
|
+
quoteChild = current;
|
|
1161
|
+
break;
|
|
1162
|
+
}
|
|
1163
|
+
current = parent;
|
|
1164
|
+
}
|
|
1165
|
+
if (!quoteNode) return false;
|
|
1166
|
+
if (quoteChild.getNextSibling() !== null) return false;
|
|
1167
|
+
if (!$isParagraphNode(quoteChild) || quoteChild.getTextContent() !== "")
|
|
1168
|
+
return false;
|
|
1169
|
+
event?.preventDefault();
|
|
1170
|
+
let next = quoteNode.getNextSibling();
|
|
1171
|
+
if (!next) {
|
|
1172
|
+
next = $createParagraphNode();
|
|
1173
|
+
quoteNode.insertAfter(next);
|
|
1174
|
+
}
|
|
1175
|
+
next.selectStart();
|
|
1176
|
+
return true;
|
|
1177
|
+
},
|
|
1178
|
+
COMMAND_PRIORITY_CRITICAL
|
|
1179
|
+
);
|
|
1180
|
+
const unregisterCmdEnter = editor.registerCommand(
|
|
1181
|
+
KEY_ENTER_COMMAND,
|
|
1182
|
+
(event) => {
|
|
1183
|
+
if (!event?.metaKey && !event?.ctrlKey) return false;
|
|
1184
|
+
const selection = $getSelection();
|
|
1185
|
+
if ($isNodeSelection(selection)) {
|
|
1186
|
+
const nodes = selection.getNodes();
|
|
1187
|
+
if (nodes.length !== 1) return false;
|
|
1188
|
+
const node = nodes[0];
|
|
1189
|
+
if (!$isDecoratorNode(node)) return false;
|
|
1190
|
+
event.preventDefault();
|
|
1191
|
+
let next2 = node.getNextSibling();
|
|
1192
|
+
if (!next2) {
|
|
1193
|
+
next2 = $createParagraphNode();
|
|
1194
|
+
node.insertAfter(next2);
|
|
1195
|
+
}
|
|
1196
|
+
if ($isElementNode(next2)) {
|
|
1197
|
+
next2.selectStart();
|
|
1198
|
+
} else if ($isDecoratorNode(next2)) {
|
|
1199
|
+
selectDecoratorNode(next2, "start");
|
|
1200
|
+
}
|
|
1201
|
+
return true;
|
|
1202
|
+
}
|
|
1203
|
+
if (!$isRangeSelection(selection)) return false;
|
|
1204
|
+
const anchorNode = selection.anchor.getNode();
|
|
1205
|
+
const topLevelElement = anchorNode.getTopLevelElementOrThrow();
|
|
1206
|
+
if ($isParagraphNode(topLevelElement)) return false;
|
|
1207
|
+
event.preventDefault();
|
|
1208
|
+
let next = topLevelElement.getNextSibling();
|
|
1209
|
+
if (!next || !$isParagraphNode(next)) {
|
|
1210
|
+
next = $createParagraphNode();
|
|
1211
|
+
topLevelElement.insertAfter(next);
|
|
1212
|
+
}
|
|
1213
|
+
next.selectStart();
|
|
1214
|
+
return true;
|
|
1215
|
+
},
|
|
1216
|
+
COMMAND_PRIORITY_CRITICAL
|
|
1217
|
+
);
|
|
1218
|
+
function handleDeleteDecorator(event) {
|
|
1219
|
+
const selection = $getSelection();
|
|
1220
|
+
if (!$isNodeSelection(selection)) return false;
|
|
1221
|
+
const nodes = selection.getNodes();
|
|
1222
|
+
if (nodes.length !== 1) return false;
|
|
1223
|
+
const node = nodes[0];
|
|
1224
|
+
if (!$isDecoratorNode(node)) return false;
|
|
1225
|
+
event?.preventDefault();
|
|
1226
|
+
const prev = node.getPreviousSibling();
|
|
1227
|
+
const next = node.getNextSibling();
|
|
1228
|
+
node.remove();
|
|
1229
|
+
if (prev && $isElementNode(prev)) {
|
|
1230
|
+
prev.selectEnd();
|
|
1231
|
+
} else if (prev && $isDecoratorNode(prev)) {
|
|
1232
|
+
selectDecoratorNode(prev, "end");
|
|
1233
|
+
} else if (next && $isElementNode(next)) {
|
|
1234
|
+
next.selectStart();
|
|
1235
|
+
} else if (next && $isDecoratorNode(next)) {
|
|
1236
|
+
selectDecoratorNode(next, "start");
|
|
1237
|
+
} else {
|
|
1238
|
+
const root = $getRoot();
|
|
1239
|
+
if (root && $isElementNode(root)) {
|
|
1240
|
+
const p = $createParagraphNode();
|
|
1241
|
+
root.append(p);
|
|
1242
|
+
p.selectStart();
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
return true;
|
|
1246
|
+
}
|
|
1247
|
+
const unregisterBackspace = editor.registerCommand(
|
|
1248
|
+
KEY_BACKSPACE_COMMAND,
|
|
1249
|
+
handleDeleteDecorator,
|
|
1250
|
+
COMMAND_PRIORITY_HIGH
|
|
1251
|
+
);
|
|
1252
|
+
const unregisterDelete = editor.registerCommand(
|
|
1253
|
+
KEY_DELETE_COMMAND,
|
|
1254
|
+
handleDeleteDecorator,
|
|
1255
|
+
COMMAND_PRIORITY_HIGH
|
|
1256
|
+
);
|
|
1257
|
+
const unregisterArrowUpDecorator = editor.registerCommand(
|
|
1258
|
+
KEY_ARROW_UP_COMMAND,
|
|
1259
|
+
(event) => {
|
|
1260
|
+
const selection = $getSelection();
|
|
1261
|
+
if ($isRangeSelection(selection) && selection.isCollapsed()) {
|
|
1262
|
+
const anchorNode = selection.anchor.getNode();
|
|
1263
|
+
const topLevelElement = anchorNode.getTopLevelElementOrThrow();
|
|
1264
|
+
const shouldSelectPreviousDecorator = isAtTopLevelBoundary(selection, "start") || isSingleLineParagraph(topLevelElement);
|
|
1265
|
+
if (!$isQuoteNode(topLevelElement) && shouldSelectPreviousDecorator) {
|
|
1266
|
+
const prev2 = topLevelElement.getPreviousSibling();
|
|
1267
|
+
if (prev2 && $isDecoratorNode(prev2) && prev2.isKeyboardSelectable()) {
|
|
1268
|
+
event?.preventDefault();
|
|
1269
|
+
selectDecoratorNode(prev2, "end");
|
|
1270
|
+
return true;
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
if (!$isNodeSelection(selection)) return false;
|
|
1275
|
+
const nodes = selection.getNodes();
|
|
1276
|
+
if (nodes.length !== 1) return false;
|
|
1277
|
+
const node = nodes[0];
|
|
1278
|
+
if (!$isDecoratorNode(node)) return false;
|
|
1279
|
+
const prev = node.getPreviousSibling();
|
|
1280
|
+
if (prev && $isElementNode(prev)) {
|
|
1281
|
+
event?.preventDefault();
|
|
1282
|
+
prev.selectEnd();
|
|
1283
|
+
return true;
|
|
1284
|
+
}
|
|
1285
|
+
if (prev && $isDecoratorNode(prev)) {
|
|
1286
|
+
event?.preventDefault();
|
|
1287
|
+
selectDecoratorNode(prev, "end");
|
|
1288
|
+
return true;
|
|
1289
|
+
}
|
|
1290
|
+
return false;
|
|
1291
|
+
},
|
|
1292
|
+
COMMAND_PRIORITY_CRITICAL
|
|
1293
|
+
);
|
|
1294
|
+
const unregisterArrowDownDecorator = editor.registerCommand(
|
|
1295
|
+
KEY_ARROW_DOWN_COMMAND,
|
|
1296
|
+
(event) => {
|
|
1297
|
+
const selection = $getSelection();
|
|
1298
|
+
if (!$isNodeSelection(selection)) return false;
|
|
1299
|
+
const nodes = selection.getNodes();
|
|
1300
|
+
if (nodes.length !== 1) return false;
|
|
1301
|
+
const node = nodes[0];
|
|
1302
|
+
if (!$isDecoratorNode(node)) return false;
|
|
1303
|
+
const next = node.getNextSibling();
|
|
1304
|
+
if (next && $isElementNode(next)) {
|
|
1305
|
+
event?.preventDefault();
|
|
1306
|
+
next.selectStart();
|
|
1307
|
+
return true;
|
|
1308
|
+
}
|
|
1309
|
+
if (next && $isDecoratorNode(next)) {
|
|
1310
|
+
event?.preventDefault();
|
|
1311
|
+
selectDecoratorNode(next, "start");
|
|
1312
|
+
return true;
|
|
1313
|
+
}
|
|
1314
|
+
return false;
|
|
1315
|
+
},
|
|
1316
|
+
COMMAND_PRIORITY_CRITICAL
|
|
1317
|
+
);
|
|
1318
|
+
return () => {
|
|
1319
|
+
unregisterArrowDown();
|
|
1320
|
+
unregisterCmdEnter();
|
|
1321
|
+
unregisterBackspace();
|
|
1322
|
+
unregisterDelete();
|
|
1323
|
+
unregisterArrowUpDecorator();
|
|
1324
|
+
unregisterArrowDownDecorator();
|
|
1325
|
+
};
|
|
1326
|
+
}, [editor]);
|
|
1327
|
+
return null;
|
|
1328
|
+
}
|
|
874
1329
|
function EditorRefPlugin({ onEditorReady }) {
|
|
875
1330
|
const [editor] = useLexicalComposerContext();
|
|
876
1331
|
const callbackRef = useRef(onEditorReady);
|
|
@@ -1561,6 +2016,34 @@ const GIT_ALERT_TRANSFORMER = {
|
|
|
1561
2016
|
parentNode.replace(alertNode);
|
|
1562
2017
|
}
|
|
1563
2018
|
};
|
|
2019
|
+
function findCodeBlockKlass(nodes) {
|
|
2020
|
+
return nodes.find((n) => n.getType?.() === "code-block") || CodeBlockNode;
|
|
2021
|
+
}
|
|
2022
|
+
const CODE_BLOCK_MULTILINE_TRANSFORMER = {
|
|
2023
|
+
dependencies: [],
|
|
2024
|
+
regExpEnd: {
|
|
2025
|
+
optional: true,
|
|
2026
|
+
regExp: /[ \t]*```$/
|
|
2027
|
+
},
|
|
2028
|
+
regExpStart: /^[ \t]*```([\w-]+)?/,
|
|
2029
|
+
replace: (rootNode, _children, startMatch, _endMatch, linesInBetween) => {
|
|
2030
|
+
const lang = startMatch[1] || "";
|
|
2031
|
+
let code = "";
|
|
2032
|
+
if (linesInBetween) {
|
|
2033
|
+
const lines = [...linesInBetween];
|
|
2034
|
+
while (lines.length > 0 && !lines[0].length) lines.shift();
|
|
2035
|
+
while (lines.length > 0 && !lines.at(-1).length) lines.pop();
|
|
2036
|
+
code = lines.join("\n");
|
|
2037
|
+
}
|
|
2038
|
+
const Klass = findCodeBlockKlass(getResolvedEditNodes());
|
|
2039
|
+
const node = new Klass(code, lang);
|
|
2040
|
+
rootNode.replace(node);
|
|
2041
|
+
const selection = $createNodeSelection();
|
|
2042
|
+
selection.add(node.getKey());
|
|
2043
|
+
$setSelection(selection);
|
|
2044
|
+
},
|
|
2045
|
+
type: "multiline-element"
|
|
2046
|
+
};
|
|
1564
2047
|
const BANNER_TYPE_MAP = {
|
|
1565
2048
|
note: "note",
|
|
1566
2049
|
info: "note",
|
|
@@ -1683,6 +2166,39 @@ const MENTION_TRANSFORMER = {
|
|
|
1683
2166
|
textNode.replace(mentionNode);
|
|
1684
2167
|
}
|
|
1685
2168
|
};
|
|
2169
|
+
const QUOTE_TRANSFORMER = {
|
|
2170
|
+
dependencies: [QuoteNode],
|
|
2171
|
+
export: (node, exportChildren) => {
|
|
2172
|
+
if (!$isQuoteNode(node)) {
|
|
2173
|
+
return null;
|
|
2174
|
+
}
|
|
2175
|
+
const lines = exportChildren(node).split("\n");
|
|
2176
|
+
return lines.map((line) => `> ${line}`).join("\n");
|
|
2177
|
+
},
|
|
2178
|
+
regExp: /^>\s/,
|
|
2179
|
+
replace: (parentNode, children, _match, isImport) => {
|
|
2180
|
+
if (isImport) {
|
|
2181
|
+
const previousNode = parentNode.getPreviousSibling();
|
|
2182
|
+
if ($isQuoteNode(previousNode)) {
|
|
2183
|
+
previousNode.splice(previousNode.getChildrenSize(), 0, [
|
|
2184
|
+
$createLineBreakNode(),
|
|
2185
|
+
...children
|
|
2186
|
+
]);
|
|
2187
|
+
parentNode.remove();
|
|
2188
|
+
return;
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
const node = $createQuoteNode();
|
|
2192
|
+
const paragraph = $createParagraphNode();
|
|
2193
|
+
paragraph.append(...children);
|
|
2194
|
+
node.append(paragraph);
|
|
2195
|
+
parentNode.replace(node);
|
|
2196
|
+
if (!isImport) {
|
|
2197
|
+
paragraph.select(0, 0);
|
|
2198
|
+
}
|
|
2199
|
+
},
|
|
2200
|
+
type: "element"
|
|
2201
|
+
};
|
|
1686
2202
|
function quoteAttr(value) {
|
|
1687
2203
|
return value.replaceAll('"', '\\"');
|
|
1688
2204
|
}
|
|
@@ -1730,12 +2246,14 @@ const ALL_TRANSFORMERS = [
|
|
|
1730
2246
|
IMAGE_BLOCK_TRANSFORMER,
|
|
1731
2247
|
VIDEO_BLOCK_TRANSFORMER,
|
|
1732
2248
|
CODE_BLOCK_NODE_TRANSFORMER,
|
|
2249
|
+
CODE_BLOCK_MULTILINE_TRANSFORMER,
|
|
1733
2250
|
LINK_CARD_BLOCK_TRANSFORMER,
|
|
1734
2251
|
MERMAID_BLOCK_TRANSFORMER,
|
|
1735
2252
|
GRID_CONTAINER_BLOCK_TRANSFORMER,
|
|
1736
2253
|
HORIZONTAL_RULE_BLOCK_TRANSFORMER,
|
|
1737
2254
|
TABLE_BLOCK_TRANSFORMER,
|
|
1738
|
-
|
|
2255
|
+
QUOTE_TRANSFORMER,
|
|
2256
|
+
...TRANSFORMERS.filter((t) => t !== QUOTE && t !== CODE)
|
|
1739
2257
|
];
|
|
1740
2258
|
function MarkdownShortcutsPlugin() {
|
|
1741
2259
|
return /* @__PURE__ */ jsx(MarkdownShortcutPlugin, { transformers: ALL_TRANSFORMERS });
|
|
@@ -1914,6 +2432,7 @@ function RichEditor({
|
|
|
1914
2432
|
/* @__PURE__ */ jsx(MermaidPlugin, {}),
|
|
1915
2433
|
/* @__PURE__ */ jsx(HorizontalRulePlugin, {}),
|
|
1916
2434
|
/* @__PURE__ */ jsx(CheckListPlugin, {}),
|
|
2435
|
+
/* @__PURE__ */ jsx(BlockExitPlugin, {}),
|
|
1917
2436
|
/* @__PURE__ */ jsx(AutoLinkPlugin, {}),
|
|
1918
2437
|
/* @__PURE__ */ jsx(EditorRefPlugin, { onEditorReady }),
|
|
1919
2438
|
autoFocus && /* @__PURE__ */ jsx(AutoFocusPlugin, {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichEditor.d.ts","sourceRoot":"","sources":["../../src/components/RichEditor.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RichEditor.d.ts","sourceRoot":"","sources":["../../src/components/RichEditor.tsx"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAI/C,wBAAgB,UAAU,CAAC,EACzB,YAAY,EACZ,QAAQ,EACR,OAAmB,EACnB,KAAe,EACf,WAAkC,EAClC,QAAQ,EACR,SAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,KAAK,EACL,OAAO,EACP,aAAa,EACb,UAAU,EACV,cAAc,EACd,WAAW,EACX,UAAU,EACV,QAAQ,GACT,EAAE,eAAe,+BAyEjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlertEditDecorator.d.ts","sourceRoot":"","sources":["../../../src/components/decorators/AlertEditDecorator.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"AlertEditDecorator.d.ts","sourceRoot":"","sources":["../../../src/components/decorators/AlertEditDecorator.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAe5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AA2H3D,UAAU,uBAAuB;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,SAAS,CAAA;IACpB,aAAa,EAAE,aAAa,CAAA;CAC7B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,SAAS,EACT,aAAa,GACd,EAAE,uBAAuB,+BA+CzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockEditDecorator.d.ts","sourceRoot":"","sources":["../../../src/components/decorators/CodeBlockEditDecorator.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CodeBlockEditDecorator.d.ts","sourceRoot":"","sources":["../../../src/components/decorators/CodeBlockEditDecorator.tsx"],"names":[],"mappings":"AAoBA,UAAU,2BAA2B;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,sBAAsB,CAAC,EACrC,OAAO,EACP,IAAI,EACJ,QAAQ,GACT,EAAE,2BAA2B,+BAmJ7B"}
|
|
@@ -3,7 +3,12 @@ export interface CodeBlockRendererProps {
|
|
|
3
3
|
language: string;
|
|
4
4
|
showLineNumbers?: boolean;
|
|
5
5
|
editable?: boolean;
|
|
6
|
+
selected?: boolean;
|
|
7
|
+
cursorPlacement?: 'start' | 'end';
|
|
6
8
|
onCodeChange?: (code: string) => void;
|
|
9
|
+
onLanguageChange?: (language: string) => void;
|
|
10
|
+
onDelete?: () => void;
|
|
11
|
+
onExitBlock?: (direction: 'before' | 'after') => void;
|
|
7
12
|
}
|
|
8
13
|
export declare function CodeBlockRenderer({ code, language, showLineNumbers: showLineNumbersProp, }: CodeBlockRendererProps): import("react").JSX.Element;
|
|
9
14
|
//# sourceMappingURL=CodeBlockRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockRenderer.d.ts","sourceRoot":"","sources":["../../../src/components/renderers/CodeBlockRenderer.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"CodeBlockRenderer.d.ts","sourceRoot":"","sources":["../../../src/components/renderers/CodeBlockRenderer.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,eAAe,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;IACjC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,GAAG,OAAO,KAAK,IAAI,CAAA;CACtD;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,QAAQ,EACR,eAAe,EAAE,mBAAmB,GACrC,EAAE,sBAAsB,+BA8FxB"}
|