react-native-richify 1.0.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/LICENSE +21 -0
- package/README.md +231 -0
- package/lib/commonjs/components/OverlayText.d.js +6 -0
- package/lib/commonjs/components/OverlayText.d.js.map +1 -0
- package/lib/commonjs/components/OverlayText.js +45 -0
- package/lib/commonjs/components/OverlayText.js.map +1 -0
- package/lib/commonjs/components/RichTextInput.d.js +6 -0
- package/lib/commonjs/components/RichTextInput.d.js.map +1 -0
- package/lib/commonjs/components/RichTextInput.js +160 -0
- package/lib/commonjs/components/RichTextInput.js.map +1 -0
- package/lib/commonjs/components/Toolbar.d.js +6 -0
- package/lib/commonjs/components/Toolbar.d.js.map +1 -0
- package/lib/commonjs/components/Toolbar.js +99 -0
- package/lib/commonjs/components/Toolbar.js.map +1 -0
- package/lib/commonjs/components/ToolbarButton.d.js +6 -0
- package/lib/commonjs/components/ToolbarButton.d.js.map +1 -0
- package/lib/commonjs/components/ToolbarButton.js +63 -0
- package/lib/commonjs/components/ToolbarButton.js.map +1 -0
- package/lib/commonjs/constants/defaultStyles.d.js +6 -0
- package/lib/commonjs/constants/defaultStyles.d.js.map +1 -0
- package/lib/commonjs/constants/defaultStyles.js +172 -0
- package/lib/commonjs/constants/defaultStyles.js.map +1 -0
- package/lib/commonjs/context/RichTextContext.d.js +6 -0
- package/lib/commonjs/context/RichTextContext.d.js.map +1 -0
- package/lib/commonjs/context/RichTextContext.js +61 -0
- package/lib/commonjs/context/RichTextContext.js.map +1 -0
- package/lib/commonjs/hooks/useFormatting.d.js +6 -0
- package/lib/commonjs/hooks/useFormatting.d.js.map +1 -0
- package/lib/commonjs/hooks/useFormatting.js +82 -0
- package/lib/commonjs/hooks/useFormatting.js.map +1 -0
- package/lib/commonjs/hooks/useRichText.d.js +6 -0
- package/lib/commonjs/hooks/useRichText.d.js.map +1 -0
- package/lib/commonjs/hooks/useRichText.js +136 -0
- package/lib/commonjs/hooks/useRichText.js.map +1 -0
- package/lib/commonjs/hooks/useSelection.d.js +6 -0
- package/lib/commonjs/hooks/useSelection.d.js.map +1 -0
- package/lib/commonjs/hooks/useSelection.js +39 -0
- package/lib/commonjs/hooks/useSelection.js.map +1 -0
- package/lib/commonjs/index.d.js +186 -0
- package/lib/commonjs/index.d.js.map +1 -0
- package/lib/commonjs/index.js +186 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types/index.d.js +6 -0
- package/lib/commonjs/types/index.d.js.map +1 -0
- package/lib/commonjs/types/index.js +6 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/utils/formatter.d.js +13 -0
- package/lib/commonjs/utils/formatter.d.js.map +1 -0
- package/lib/commonjs/utils/formatter.js +229 -0
- package/lib/commonjs/utils/formatter.js.map +1 -0
- package/lib/commonjs/utils/parser.d.js +6 -0
- package/lib/commonjs/utils/parser.d.js.map +1 -0
- package/lib/commonjs/utils/parser.js +221 -0
- package/lib/commonjs/utils/parser.js.map +1 -0
- package/lib/commonjs/utils/styleMapper.d.js +6 -0
- package/lib/commonjs/utils/styleMapper.d.js.map +1 -0
- package/lib/commonjs/utils/styleMapper.js +87 -0
- package/lib/commonjs/utils/styleMapper.js.map +1 -0
- package/lib/module/components/OverlayText.d.js +4 -0
- package/lib/module/components/OverlayText.d.js.map +1 -0
- package/lib/module/components/OverlayText.js +41 -0
- package/lib/module/components/OverlayText.js.map +1 -0
- package/lib/module/components/RichTextInput.d.js +4 -0
- package/lib/module/components/RichTextInput.d.js.map +1 -0
- package/lib/module/components/RichTextInput.js +155 -0
- package/lib/module/components/RichTextInput.js.map +1 -0
- package/lib/module/components/Toolbar.d.js +4 -0
- package/lib/module/components/Toolbar.d.js.map +1 -0
- package/lib/module/components/Toolbar.js +95 -0
- package/lib/module/components/Toolbar.js.map +1 -0
- package/lib/module/components/ToolbarButton.d.js +4 -0
- package/lib/module/components/ToolbarButton.d.js.map +1 -0
- package/lib/module/components/ToolbarButton.js +59 -0
- package/lib/module/components/ToolbarButton.js.map +1 -0
- package/lib/module/constants/defaultStyles.d.js +4 -0
- package/lib/module/constants/defaultStyles.d.js.map +1 -0
- package/lib/module/constants/defaultStyles.js +168 -0
- package/lib/module/constants/defaultStyles.js.map +1 -0
- package/lib/module/context/RichTextContext.d.js +4 -0
- package/lib/module/context/RichTextContext.d.js.map +1 -0
- package/lib/module/context/RichTextContext.js +55 -0
- package/lib/module/context/RichTextContext.js.map +1 -0
- package/lib/module/hooks/useFormatting.d.js +11 -0
- package/lib/module/hooks/useFormatting.d.js.map +1 -0
- package/lib/module/hooks/useFormatting.js +78 -0
- package/lib/module/hooks/useFormatting.js.map +1 -0
- package/lib/module/hooks/useRichText.d.js +4 -0
- package/lib/module/hooks/useRichText.d.js.map +1 -0
- package/lib/module/hooks/useRichText.js +132 -0
- package/lib/module/hooks/useRichText.js.map +1 -0
- package/lib/module/hooks/useSelection.d.js +4 -0
- package/lib/module/hooks/useSelection.d.js.map +1 -0
- package/lib/module/hooks/useSelection.js +35 -0
- package/lib/module/hooks/useSelection.js.map +1 -0
- package/lib/module/index.d.js +15 -0
- package/lib/module/index.d.js.map +1 -0
- package/lib/module/index.js +25 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types/index.d.js +4 -0
- package/lib/module/types/index.d.js.map +1 -0
- package/lib/module/types/index.js +4 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/utils/formatter.d.js +30 -0
- package/lib/module/utils/formatter.d.js.map +1 -0
- package/lib/module/utils/formatter.js +217 -0
- package/lib/module/utils/formatter.js.map +1 -0
- package/lib/module/utils/parser.d.js +4 -0
- package/lib/module/utils/parser.d.js.map +1 -0
- package/lib/module/utils/parser.js +211 -0
- package/lib/module/utils/parser.js.map +1 -0
- package/lib/module/utils/styleMapper.d.js +4 -0
- package/lib/module/utils/styleMapper.d.js.map +1 -0
- package/lib/module/utils/styleMapper.js +82 -0
- package/lib/module/utils/styleMapper.js.map +1 -0
- package/lib/typescript/src/components/OverlayText.d.ts +11 -0
- package/lib/typescript/src/components/OverlayText.d.ts.map +1 -0
- package/lib/typescript/src/components/RichTextInput.d.ts +21 -0
- package/lib/typescript/src/components/RichTextInput.d.ts.map +1 -0
- package/lib/typescript/src/components/Toolbar.d.ts +13 -0
- package/lib/typescript/src/components/Toolbar.d.ts.map +1 -0
- package/lib/typescript/src/components/ToolbarButton.d.ts +8 -0
- package/lib/typescript/src/components/ToolbarButton.d.ts.map +1 -0
- package/lib/typescript/src/constants/defaultStyles.d.ts +46 -0
- package/lib/typescript/src/constants/defaultStyles.d.ts.map +1 -0
- package/lib/typescript/src/context/RichTextContext.d.ts +31 -0
- package/lib/typescript/src/context/RichTextContext.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useFormatting.d.ts +26 -0
- package/lib/typescript/src/hooks/useFormatting.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useRichText.d.ts +17 -0
- package/lib/typescript/src/hooks/useRichText.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useSelection.d.ts +14 -0
- package/lib/typescript/src/hooks/useSelection.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +16 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +245 -0
- package/lib/typescript/src/types/index.d.ts.map +1 -0
- package/lib/typescript/src/utils/formatter.d.ts +29 -0
- package/lib/typescript/src/utils/formatter.d.ts.map +1 -0
- package/lib/typescript/src/utils/parser.d.ts +46 -0
- package/lib/typescript/src/utils/parser.d.ts.map +1 -0
- package/lib/typescript/src/utils/styleMapper.d.ts +16 -0
- package/lib/typescript/src/utils/styleMapper.d.ts.map +1 -0
- package/package.json +83 -0
- package/src/components/OverlayText.d.ts +10 -0
- package/src/components/OverlayText.tsx +46 -0
- package/src/components/RichTextInput.d.ts +20 -0
- package/src/components/RichTextInput.tsx +174 -0
- package/src/components/Toolbar.d.ts +12 -0
- package/src/components/Toolbar.tsx +100 -0
- package/src/components/ToolbarButton.d.ts +7 -0
- package/src/components/ToolbarButton.tsx +65 -0
- package/src/constants/defaultStyles.d.ts +45 -0
- package/src/constants/defaultStyles.ts +144 -0
- package/src/context/RichTextContext.d.ts +30 -0
- package/src/context/RichTextContext.tsx +63 -0
- package/src/hooks/useFormatting.d.ts +25 -0
- package/src/hooks/useFormatting.ts +135 -0
- package/src/hooks/useRichText.d.ts +16 -0
- package/src/hooks/useRichText.ts +171 -0
- package/src/hooks/useSelection.d.ts +13 -0
- package/src/hooks/useSelection.ts +40 -0
- package/src/index.d.ts +15 -0
- package/src/index.ts +68 -0
- package/src/types/index.d.ts +244 -0
- package/src/types/index.ts +295 -0
- package/src/utils/formatter.d.ts +28 -0
- package/src/utils/formatter.ts +276 -0
- package/src/utils/parser.d.ts +45 -0
- package/src/utils/parser.ts +252 -0
- package/src/utils/styleMapper.d.ts +15 -0
- package/src/utils/styleMapper.ts +92 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useState, useCallback, useRef } from 'react';
|
|
4
|
+
import { EMPTY_FORMAT_STYLE } from '@/constants/defaultStyles';
|
|
5
|
+
import { createSegment, segmentsToPlainText, reconcileTextChange, findPositionInSegments } from '@/utils/parser';
|
|
6
|
+
import { useSelection } from '@/hooks/useSelection';
|
|
7
|
+
import { useFormatting } from '@/hooks/useFormatting';
|
|
8
|
+
/**
|
|
9
|
+
* Main hook for the rich text editor.
|
|
10
|
+
*
|
|
11
|
+
* Manages the complete editor state (segments, selection, active styles)
|
|
12
|
+
* and exposes all actions needed to build a rich text UI.
|
|
13
|
+
*/
|
|
14
|
+
export function useRichText(options = {}) {
|
|
15
|
+
const {
|
|
16
|
+
initialSegments,
|
|
17
|
+
onChangeSegments,
|
|
18
|
+
onChangeText
|
|
19
|
+
} = options;
|
|
20
|
+
|
|
21
|
+
// ─── State ───────────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
const [segments, setSegments] = useState(() => {
|
|
24
|
+
if (initialSegments && initialSegments.length > 0) {
|
|
25
|
+
return initialSegments;
|
|
26
|
+
}
|
|
27
|
+
return [createSegment('')];
|
|
28
|
+
});
|
|
29
|
+
const [activeStyles, setActiveStyles] = useState({
|
|
30
|
+
...EMPTY_FORMAT_STYLE
|
|
31
|
+
});
|
|
32
|
+
const {
|
|
33
|
+
selection,
|
|
34
|
+
handleSelectionChange
|
|
35
|
+
} = useSelection();
|
|
36
|
+
|
|
37
|
+
// Refs for stable access in callbacks
|
|
38
|
+
const segmentsRef = useRef(segments);
|
|
39
|
+
segmentsRef.current = segments;
|
|
40
|
+
const activeStylesRef = useRef(activeStyles);
|
|
41
|
+
activeStylesRef.current = activeStyles;
|
|
42
|
+
|
|
43
|
+
// ─── Segment Change Handler ──────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
const updateSegments = useCallback(newSegments => {
|
|
46
|
+
setSegments(newSegments);
|
|
47
|
+
onChangeSegments?.(newSegments);
|
|
48
|
+
onChangeText?.(segmentsToPlainText(newSegments));
|
|
49
|
+
}, [onChangeSegments, onChangeText]);
|
|
50
|
+
|
|
51
|
+
// ─── Formatting ──────────────────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
const formatting = useFormatting({
|
|
54
|
+
segments,
|
|
55
|
+
selection,
|
|
56
|
+
activeStyles,
|
|
57
|
+
onSegmentsChange: updateSegments,
|
|
58
|
+
onActiveStylesChange: setActiveStyles
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// ─── Text Change Handler ─────────────────────────────────────────────────
|
|
62
|
+
|
|
63
|
+
const handleTextChange = useCallback(newText => {
|
|
64
|
+
const currentSegments = segmentsRef.current;
|
|
65
|
+
const currentActiveStyles = activeStylesRef.current;
|
|
66
|
+
const newSegments = reconcileTextChange(currentSegments, newText, currentActiveStyles);
|
|
67
|
+
updateSegments(newSegments);
|
|
68
|
+
}, [updateSegments]);
|
|
69
|
+
|
|
70
|
+
// ─── Selection Change Handler ────────────────────────────────────────────
|
|
71
|
+
|
|
72
|
+
const onSelectionChange = useCallback(newSelection => {
|
|
73
|
+
handleSelectionChange(newSelection);
|
|
74
|
+
|
|
75
|
+
// Update active styles based on cursor position
|
|
76
|
+
if (newSelection.start === newSelection.end) {
|
|
77
|
+
const pos = findPositionInSegments(segmentsRef.current, newSelection.start);
|
|
78
|
+
if (segmentsRef.current.length > 0) {
|
|
79
|
+
const seg = segmentsRef.current[pos.segmentIndex];
|
|
80
|
+
setActiveStyles({
|
|
81
|
+
...seg.styles
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, [handleSelectionChange]);
|
|
86
|
+
|
|
87
|
+
// ─── Export / Import ─────────────────────────────────────────────────────
|
|
88
|
+
|
|
89
|
+
const getPlainText = useCallback(() => {
|
|
90
|
+
return segmentsToPlainText(segmentsRef.current);
|
|
91
|
+
}, []);
|
|
92
|
+
const exportJSON = useCallback(() => {
|
|
93
|
+
return JSON.parse(JSON.stringify(segmentsRef.current));
|
|
94
|
+
}, []);
|
|
95
|
+
const importJSON = useCallback(newSegments => {
|
|
96
|
+
const safeSegments = newSegments.length > 0 ? newSegments : [createSegment('')];
|
|
97
|
+
updateSegments(safeSegments);
|
|
98
|
+
}, [updateSegments]);
|
|
99
|
+
const clear = useCallback(() => {
|
|
100
|
+
updateSegments([createSegment('')]);
|
|
101
|
+
setActiveStyles({
|
|
102
|
+
...EMPTY_FORMAT_STYLE
|
|
103
|
+
});
|
|
104
|
+
}, [updateSegments]);
|
|
105
|
+
|
|
106
|
+
// ─── Build Return Value ──────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
const state = {
|
|
109
|
+
segments,
|
|
110
|
+
selection,
|
|
111
|
+
activeStyles
|
|
112
|
+
};
|
|
113
|
+
const actions = {
|
|
114
|
+
toggleFormat: formatting.toggleFormat,
|
|
115
|
+
setStyleProperty: formatting.setStyleProperty,
|
|
116
|
+
setHeading: formatting.setHeading,
|
|
117
|
+
setColor: formatting.setColor,
|
|
118
|
+
setBackgroundColor: formatting.setBackgroundColor,
|
|
119
|
+
setFontSize: formatting.setFontSize,
|
|
120
|
+
handleTextChange,
|
|
121
|
+
handleSelectionChange: onSelectionChange,
|
|
122
|
+
getPlainText,
|
|
123
|
+
exportJSON,
|
|
124
|
+
importJSON,
|
|
125
|
+
clear
|
|
126
|
+
};
|
|
127
|
+
return {
|
|
128
|
+
state,
|
|
129
|
+
actions
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=useRichText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useState","useCallback","useRef","EMPTY_FORMAT_STYLE","createSegment","segmentsToPlainText","reconcileTextChange","findPositionInSegments","useSelection","useFormatting","useRichText","options","initialSegments","onChangeSegments","onChangeText","segments","setSegments","length","activeStyles","setActiveStyles","selection","handleSelectionChange","segmentsRef","current","activeStylesRef","updateSegments","newSegments","formatting","onSegmentsChange","onActiveStylesChange","handleTextChange","newText","currentSegments","currentActiveStyles","onSelectionChange","newSelection","start","end","pos","seg","segmentIndex","styles","getPlainText","exportJSON","JSON","parse","stringify","importJSON","safeSegments","clear","state","actions","toggleFormat","setStyleProperty","setHeading","setColor","setBackgroundColor","setFontSize"],"sourceRoot":"..\\..\\..\\src","sources":["hooks/useRichText.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["hooks/useSelection.d.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useState, useCallback, useRef } from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Hook for tracking TextInput selection state.
|
|
6
|
+
*
|
|
7
|
+
* Returns the current selection and a handler to update it.
|
|
8
|
+
*/
|
|
9
|
+
export function useSelection(initialSelection) {
|
|
10
|
+
const [selection, setSelection] = useState(initialSelection ?? {
|
|
11
|
+
start: 0,
|
|
12
|
+
end: 0
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Use a ref to avoid stale closures in callbacks
|
|
16
|
+
const selectionRef = useRef(selection);
|
|
17
|
+
selectionRef.current = selection;
|
|
18
|
+
const handleSelectionChange = useCallback(newSelection => {
|
|
19
|
+
setSelection(newSelection);
|
|
20
|
+
}, []);
|
|
21
|
+
const getSelection = useCallback(() => {
|
|
22
|
+
return selectionRef.current;
|
|
23
|
+
}, []);
|
|
24
|
+
const hasSelection = useCallback(() => {
|
|
25
|
+
return selectionRef.current.start !== selectionRef.current.end;
|
|
26
|
+
}, []);
|
|
27
|
+
return {
|
|
28
|
+
selection,
|
|
29
|
+
setSelection,
|
|
30
|
+
handleSelectionChange,
|
|
31
|
+
getSelection,
|
|
32
|
+
hasSelection
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=useSelection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useState","useCallback","useRef","useSelection","initialSelection","selection","setSelection","start","end","selectionRef","current","handleSelectionChange","newSelection","getSelection","hasSelection"],"sourceRoot":"..\\..\\..\\src","sources":["hooks/useSelection.ts"],"mappings":";;AAAA,SAASA,QAAQ,EAAEC,WAAW,EAAEC,MAAM,QAAQ,OAAO;AAGrD;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAACC,gBAAiC,EAAE;EAC9D,MAAM,CAACC,SAAS,EAAEC,YAAY,CAAC,GAAGN,QAAQ,CACxCI,gBAAgB,IAAI;IAAEG,KAAK,EAAE,CAAC;IAAEC,GAAG,EAAE;EAAE,CACzC,CAAC;;EAED;EACA,MAAMC,YAAY,GAAGP,MAAM,CAACG,SAAS,CAAC;EACtCI,YAAY,CAACC,OAAO,GAAGL,SAAS;EAEhC,MAAMM,qBAAqB,GAAGV,WAAW,CACtCW,YAA4B,IAAK;IAChCN,YAAY,CAACM,YAAY,CAAC;EAC5B,CAAC,EACD,EACF,CAAC;EAED,MAAMC,YAAY,GAAGZ,WAAW,CAAC,MAAsB;IACrD,OAAOQ,YAAY,CAACC,OAAO;EAC7B,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMI,YAAY,GAAGb,WAAW,CAAC,MAAe;IAC9C,OAAOQ,YAAY,CAACC,OAAO,CAACH,KAAK,KAAKE,YAAY,CAACC,OAAO,CAACF,GAAG;EAChE,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IACLH,SAAS;IACTC,YAAY;IACZK,qBAAqB;IACrBE,YAAY;IACZC;EACF,CAAC;AACH","ignoreList":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export { RichTextInput } from '@/components/RichTextInput';
|
|
4
|
+
export { OverlayText } from '@/components/OverlayText';
|
|
5
|
+
export { Toolbar } from '@/components/Toolbar';
|
|
6
|
+
export { ToolbarButton } from '@/components/ToolbarButton';
|
|
7
|
+
export { useRichText } from '@/hooks/useRichText';
|
|
8
|
+
export { useSelection } from '@/hooks/useSelection';
|
|
9
|
+
export { useFormatting } from '@/hooks/useFormatting';
|
|
10
|
+
export { RichTextProvider, useRichTextContext } from '@/context/RichTextContext';
|
|
11
|
+
export { createSegment, segmentsToPlainText, getTotalLength, mergeAdjacentSegments, reconcileTextChange } from '@/utils/parser';
|
|
12
|
+
export { toggleFormatOnSelection, setStyleOnSelection, setHeadingOnLine, isFormatActiveInSelection, getSelectionStyle } from '@/utils/formatter';
|
|
13
|
+
export { formatStyleToTextStyle, segmentToTextStyle, segmentsToTextStyles } from '@/utils/styleMapper';
|
|
14
|
+
export { DEFAULT_COLORS, DEFAULT_THEME, DEFAULT_TOOLBAR_ITEMS, DEFAULT_BASE_TEXT_STYLE, HEADING_FONT_SIZES, EMPTY_FORMAT_STYLE } from '@/constants/defaultStyles';
|
|
15
|
+
//# sourceMappingURL=index.d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["RichTextInput","OverlayText","Toolbar","ToolbarButton","useRichText","useSelection","useFormatting","RichTextProvider","useRichTextContext","createSegment","segmentsToPlainText","getTotalLength","mergeAdjacentSegments","reconcileTextChange","toggleFormatOnSelection","setStyleOnSelection","setHeadingOnLine","isFormatActiveInSelection","getSelectionStyle","formatStyleToTextStyle","segmentToTextStyle","segmentsToTextStyles","DEFAULT_COLORS","DEFAULT_THEME","DEFAULT_TOOLBAR_ITEMS","DEFAULT_BASE_TEXT_STYLE","HEADING_FONT_SIZES","EMPTY_FORMAT_STYLE"],"sourceRoot":"..\\..\\src","sources":["index.d.ts"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,WAAW,QAAQ,0BAA0B;AACtD,SAASC,OAAO,QAAQ,sBAAsB;AAC9C,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,WAAW,QAAQ,qBAAqB;AAEjD,SAASC,YAAY,QAAQ,sBAAsB;AACnD,SAASC,aAAa,QAAQ,uBAAuB;AACrD,SAASC,gBAAgB,EAAEC,kBAAkB,QAAS,2BAA2B;AAEjF,SAASC,aAAa,EAAEC,mBAAmB,EAAEC,cAAc,EAAEC,qBAAqB,EAAEC,mBAAmB,QAAS,gBAAgB;AAChI,SAASC,uBAAuB,EAAEC,mBAAmB,EAAEC,gBAAgB,EAAEC,yBAAyB,EAAEC,iBAAiB,QAAS,mBAAmB;AACjJ,SAASC,sBAAsB,EAAEC,kBAAkB,EAAEC,oBAAoB,QAAS,qBAAqB;AACvG,SAASC,cAAc,EAAEC,aAAa,EAAEC,qBAAqB,EAAEC,uBAAuB,EAAEC,kBAAkB,EAAEC,kBAAkB,QAAS,2BAA2B","ignoreList":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// ─── Components ──────────────────────────────────────────────────────────────
|
|
4
|
+
export { RichTextInput } from '@/components/RichTextInput';
|
|
5
|
+
export { OverlayText } from '@/components/OverlayText';
|
|
6
|
+
export { Toolbar } from '@/components/Toolbar';
|
|
7
|
+
export { ToolbarButton } from '@/components/ToolbarButton';
|
|
8
|
+
|
|
9
|
+
// ─── Hooks ───────────────────────────────────────────────────────────────────
|
|
10
|
+
export { useRichText } from '@/hooks/useRichText';
|
|
11
|
+
export { useSelection } from '@/hooks/useSelection';
|
|
12
|
+
export { useFormatting } from '@/hooks/useFormatting';
|
|
13
|
+
|
|
14
|
+
// ─── Context ─────────────────────────────────────────────────────────────────
|
|
15
|
+
export { RichTextProvider, useRichTextContext } from '@/context/RichTextContext';
|
|
16
|
+
// ─── Utilities ───────────────────────────────────────────────────────────────
|
|
17
|
+
export { createSegment, segmentsToPlainText, getTotalLength, mergeAdjacentSegments, reconcileTextChange } from '@/utils/parser';
|
|
18
|
+
export { toggleFormatOnSelection, setStyleOnSelection, setHeadingOnLine, isFormatActiveInSelection, getSelectionStyle } from '@/utils/formatter';
|
|
19
|
+
export { formatStyleToTextStyle, segmentToTextStyle, segmentsToTextStyles } from '@/utils/styleMapper';
|
|
20
|
+
|
|
21
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
22
|
+
export { DEFAULT_COLORS, DEFAULT_THEME, DEFAULT_TOOLBAR_ITEMS, DEFAULT_BASE_TEXT_STYLE, HEADING_FONT_SIZES, EMPTY_FORMAT_STYLE } from '@/constants/defaultStyles';
|
|
23
|
+
|
|
24
|
+
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["RichTextInput","OverlayText","Toolbar","ToolbarButton","useRichText","useSelection","useFormatting","RichTextProvider","useRichTextContext","createSegment","segmentsToPlainText","getTotalLength","mergeAdjacentSegments","reconcileTextChange","toggleFormatOnSelection","setStyleOnSelection","setHeadingOnLine","isFormatActiveInSelection","getSelectionStyle","formatStyleToTextStyle","segmentToTextStyle","segmentsToTextStyles","DEFAULT_COLORS","DEFAULT_THEME","DEFAULT_TOOLBAR_ITEMS","DEFAULT_BASE_TEXT_STYLE","HEADING_FONT_SIZES","EMPTY_FORMAT_STYLE"],"sourceRoot":"..\\..\\src","sources":["index.ts"],"mappings":";;AAAA;AACA,SAASA,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,WAAW,QAAQ,0BAA0B;AACtD,SAASC,OAAO,QAAQ,sBAAsB;AAC9C,SAASC,aAAa,QAAQ,4BAA4B;;AAE1D;AACA,SAASC,WAAW,QAAQ,qBAAqB;AAEjD,SAASC,YAAY,QAAQ,sBAAsB;AACnD,SAASC,aAAa,QAAQ,uBAAuB;;AAErD;AACA,SACEC,gBAAgB,EAChBC,kBAAkB,QACb,2BAA2B;AAGlC;AACA,SACEC,aAAa,EACbC,mBAAmB,EACnBC,cAAc,EACdC,qBAAqB,EACrBC,mBAAmB,QACd,gBAAgB;AACvB,SACEC,uBAAuB,EACvBC,mBAAmB,EACnBC,gBAAgB,EAChBC,yBAAyB,EACzBC,iBAAiB,QACZ,mBAAmB;AAC1B,SACEC,sBAAsB,EACtBC,kBAAkB,EAClBC,oBAAoB,QACf,qBAAqB;;AAE5B;AACA,SACEC,cAAc,EACdC,aAAa,EACbC,qBAAqB,EACrBC,uBAAuB,EACvBC,kBAAkB,EAClBC,kBAAkB,QACb,2BAA2B;;AAElC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["types/index.d.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["types/index.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Toggle an inline format (bold, italic, etc.) on the selected range.
|
|
5
|
+
*
|
|
6
|
+
* If the entire selection already has the format, it is removed.
|
|
7
|
+
* Otherwise, it is applied to the entire selection.
|
|
8
|
+
*
|
|
9
|
+
* Returns the new segments array.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Set a specific style property on the selected range.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Apply a heading level to the line containing the cursor/selection.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Checks whether the given format is active across the entire selection.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Gets the format style that is common across the entire selection.
|
|
26
|
+
* For properties where segments disagree, the value is undefined.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
export { createSegment } from '@/utils/parser';
|
|
30
|
+
//# sourceMappingURL=formatter.d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createSegment"],"sourceRoot":"..\\..\\..\\src","sources":["utils/formatter.d.ts"],"mappings":";;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,SAASA,aAAa,QAAQ,gBAAgB","ignoreList":[]}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { createSegment, findPositionInSegments, mergeAdjacentSegments, segmentsToPlainText } from '@/utils/parser';
|
|
4
|
+
import { HEADING_FONT_SIZES } from '@/constants/defaultStyles';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Toggle an inline format (bold, italic, etc.) on the selected range.
|
|
8
|
+
*
|
|
9
|
+
* If the entire selection already has the format, it is removed.
|
|
10
|
+
* Otherwise, it is applied to the entire selection.
|
|
11
|
+
*
|
|
12
|
+
* Returns the new segments array.
|
|
13
|
+
*/
|
|
14
|
+
export function toggleFormatOnSelection(segments, selection, format) {
|
|
15
|
+
if (selection.start === selection.end) {
|
|
16
|
+
// No selection — return unchanged (active styles handle this case)
|
|
17
|
+
return segments;
|
|
18
|
+
}
|
|
19
|
+
const {
|
|
20
|
+
start,
|
|
21
|
+
end
|
|
22
|
+
} = normalizeSelection(selection);
|
|
23
|
+
|
|
24
|
+
// Extract the selected segments to check current state
|
|
25
|
+
const selectedSegments = extractSegmentsInRange(segments, start, end);
|
|
26
|
+
const allHaveFormat = selectedSegments.every(s => !!s.styles[format]);
|
|
27
|
+
|
|
28
|
+
// Apply or remove the format
|
|
29
|
+
return applyStyleToRange(segments, start, end, {
|
|
30
|
+
[format]: !allHaveFormat
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Set a specific style property on the selected range.
|
|
36
|
+
*/
|
|
37
|
+
export function setStyleOnSelection(segments, selection, key, value) {
|
|
38
|
+
if (selection.start === selection.end) {
|
|
39
|
+
return segments;
|
|
40
|
+
}
|
|
41
|
+
const {
|
|
42
|
+
start,
|
|
43
|
+
end
|
|
44
|
+
} = normalizeSelection(selection);
|
|
45
|
+
return applyStyleToRange(segments, start, end, {
|
|
46
|
+
[key]: value
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Apply a heading level to the line containing the cursor/selection.
|
|
52
|
+
*/
|
|
53
|
+
export function setHeadingOnLine(segments, selection, level) {
|
|
54
|
+
const plainText = segmentsToPlainText(segments);
|
|
55
|
+
const {
|
|
56
|
+
lineStart,
|
|
57
|
+
lineEnd
|
|
58
|
+
} = getLineRange(plainText, selection.start);
|
|
59
|
+
const headingStyle = {
|
|
60
|
+
heading: level,
|
|
61
|
+
fontSize: HEADING_FONT_SIZES[level],
|
|
62
|
+
bold: level !== 'none' ? true : undefined
|
|
63
|
+
};
|
|
64
|
+
return applyStyleToRange(segments, lineStart, lineEnd, headingStyle);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Checks whether the given format is active across the entire selection.
|
|
69
|
+
*/
|
|
70
|
+
export function isFormatActiveInSelection(segments, selection, format) {
|
|
71
|
+
if (selection.start === selection.end) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
const {
|
|
75
|
+
start,
|
|
76
|
+
end
|
|
77
|
+
} = normalizeSelection(selection);
|
|
78
|
+
const selected = extractSegmentsInRange(segments, start, end);
|
|
79
|
+
return selected.length > 0 && selected.every(s => !!s.styles[format]);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Gets the format style that is common across the entire selection.
|
|
84
|
+
* For properties where segments disagree, the value is undefined.
|
|
85
|
+
*/
|
|
86
|
+
export function getSelectionStyle(segments, selection) {
|
|
87
|
+
if (selection.start === selection.end) {
|
|
88
|
+
// Return style at cursor position
|
|
89
|
+
const pos = findPositionInSegments(segments, selection.start);
|
|
90
|
+
if (segments.length > 0) {
|
|
91
|
+
return {
|
|
92
|
+
...segments[pos.segmentIndex].styles
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return {};
|
|
96
|
+
}
|
|
97
|
+
const {
|
|
98
|
+
start,
|
|
99
|
+
end
|
|
100
|
+
} = normalizeSelection(selection);
|
|
101
|
+
const selected = extractSegmentsInRange(segments, start, end);
|
|
102
|
+
if (selected.length === 0) return {};
|
|
103
|
+
const result = {
|
|
104
|
+
...selected[0].styles
|
|
105
|
+
};
|
|
106
|
+
for (let i = 1; i < selected.length; i++) {
|
|
107
|
+
const s = selected[i].styles;
|
|
108
|
+
if (result.bold !== undefined && result.bold !== !!s.bold) result.bold = undefined;
|
|
109
|
+
if (result.italic !== undefined && result.italic !== !!s.italic) result.italic = undefined;
|
|
110
|
+
if (result.underline !== undefined && result.underline !== !!s.underline) result.underline = undefined;
|
|
111
|
+
if (result.strikethrough !== undefined && result.strikethrough !== !!s.strikethrough) result.strikethrough = undefined;
|
|
112
|
+
if (result.code !== undefined && result.code !== !!s.code) result.code = undefined;
|
|
113
|
+
if (result.color !== s.color) result.color = undefined;
|
|
114
|
+
if (result.backgroundColor !== s.backgroundColor) result.backgroundColor = undefined;
|
|
115
|
+
if (result.fontSize !== s.fontSize) result.fontSize = undefined;
|
|
116
|
+
if (result.heading !== s.heading) result.heading = undefined;
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ─── Internal Helpers ────────────────────────────────────────────────────────
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Normalize selection so start <= end.
|
|
125
|
+
*/
|
|
126
|
+
function normalizeSelection(selection) {
|
|
127
|
+
return {
|
|
128
|
+
start: Math.min(selection.start, selection.end),
|
|
129
|
+
end: Math.max(selection.start, selection.end)
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Extract the text segments that fall within [start, end) of the global text.
|
|
135
|
+
*/
|
|
136
|
+
function extractSegmentsInRange(segments, start, end) {
|
|
137
|
+
const result = [];
|
|
138
|
+
let pos = 0;
|
|
139
|
+
for (const seg of segments) {
|
|
140
|
+
const segStart = pos;
|
|
141
|
+
const segEnd = pos + seg.text.length;
|
|
142
|
+
if (segEnd <= start) {
|
|
143
|
+
pos = segEnd;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (segStart >= end) {
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// This segment overlaps with [start, end)
|
|
151
|
+
const overlapStart = Math.max(segStart, start);
|
|
152
|
+
const overlapEnd = Math.min(segEnd, end);
|
|
153
|
+
result.push(createSegment(seg.text.slice(overlapStart - segStart, overlapEnd - segStart), seg.styles));
|
|
154
|
+
pos = segEnd;
|
|
155
|
+
}
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Apply a partial style to a character range within the segments array.
|
|
161
|
+
* Splits segments at boundaries and applies the style delta to all segments in range.
|
|
162
|
+
*/
|
|
163
|
+
function applyStyleToRange(segments, start, end, styleDelta) {
|
|
164
|
+
const result = [];
|
|
165
|
+
let pos = 0;
|
|
166
|
+
for (const seg of segments) {
|
|
167
|
+
const segStart = pos;
|
|
168
|
+
const segEnd = pos + seg.text.length;
|
|
169
|
+
if (segEnd <= start || segStart >= end) {
|
|
170
|
+
// Outside the range — keep as-is
|
|
171
|
+
result.push(createSegment(seg.text, seg.styles));
|
|
172
|
+
} else {
|
|
173
|
+
// Overlaps with range — may need to split
|
|
174
|
+
if (segStart < start) {
|
|
175
|
+
// Portion before the range
|
|
176
|
+
result.push(createSegment(seg.text.slice(0, start - segStart), seg.styles));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// The overlapping portion — apply style delta
|
|
180
|
+
const overlapStart = Math.max(segStart, start);
|
|
181
|
+
const overlapEnd = Math.min(segEnd, end);
|
|
182
|
+
const newStyles = {
|
|
183
|
+
...seg.styles,
|
|
184
|
+
...styleDelta
|
|
185
|
+
};
|
|
186
|
+
result.push(createSegment(seg.text.slice(overlapStart - segStart, overlapEnd - segStart), newStyles));
|
|
187
|
+
if (segEnd > end) {
|
|
188
|
+
// Portion after the range
|
|
189
|
+
result.push(createSegment(seg.text.slice(end - segStart), seg.styles));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
pos = segEnd;
|
|
193
|
+
}
|
|
194
|
+
return mergeAdjacentSegments(result);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get the line start and end positions for the line containing the given position.
|
|
199
|
+
*/
|
|
200
|
+
function getLineRange(text, position) {
|
|
201
|
+
let lineStart = position;
|
|
202
|
+
while (lineStart > 0 && text[lineStart - 1] !== '\n') {
|
|
203
|
+
lineStart--;
|
|
204
|
+
}
|
|
205
|
+
let lineEnd = position;
|
|
206
|
+
while (lineEnd < text.length && text[lineEnd] !== '\n') {
|
|
207
|
+
lineEnd++;
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
lineStart,
|
|
211
|
+
lineEnd
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Re-export for convenience
|
|
216
|
+
export { createSegment } from '@/utils/parser';
|
|
217
|
+
//# sourceMappingURL=formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createSegment","findPositionInSegments","mergeAdjacentSegments","segmentsToPlainText","HEADING_FONT_SIZES","toggleFormatOnSelection","segments","selection","format","start","end","normalizeSelection","selectedSegments","extractSegmentsInRange","allHaveFormat","every","s","styles","applyStyleToRange","setStyleOnSelection","key","value","setHeadingOnLine","level","plainText","lineStart","lineEnd","getLineRange","headingStyle","heading","fontSize","bold","undefined","isFormatActiveInSelection","selected","length","getSelectionStyle","pos","segmentIndex","result","i","italic","underline","strikethrough","code","color","backgroundColor","Math","min","max","seg","segStart","segEnd","text","overlapStart","overlapEnd","push","slice","styleDelta","newStyles","position"],"sourceRoot":"..\\..\\..\\src","sources":["utils/formatter.ts"],"mappings":";;AAOA,SACEA,aAAa,EACbC,sBAAsB,EAEtBC,qBAAqB,EACrBC,mBAAmB,QACd,gBAAgB;AACvB,SAASC,kBAAkB,QAAQ,2BAA2B;;AAE9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,uBAAuBA,CACrCC,QAAyB,EACzBC,SAAyB,EACzBC,MAAkB,EACD;EACjB,IAAID,SAAS,CAACE,KAAK,KAAKF,SAAS,CAACG,GAAG,EAAE;IACrC;IACA,OAAOJ,QAAQ;EACjB;EAEA,MAAM;IAAEG,KAAK;IAAEC;EAAI,CAAC,GAAGC,kBAAkB,CAACJ,SAAS,CAAC;;EAEpD;EACA,MAAMK,gBAAgB,GAAGC,sBAAsB,CAACP,QAAQ,EAAEG,KAAK,EAAEC,GAAG,CAAC;EACrE,MAAMI,aAAa,GAAGF,gBAAgB,CAACG,KAAK,CAAEC,CAAC,IAAK,CAAC,CAACA,CAAC,CAACC,MAAM,CAACT,MAAM,CAAC,CAAC;;EAEvE;EACA,OAAOU,iBAAiB,CAACZ,QAAQ,EAAEG,KAAK,EAAEC,GAAG,EAAE;IAC7C,CAACF,MAAM,GAAG,CAACM;EACb,CAAC,CAAC;AACJ;;AAEA;AACA;AACA;AACA,OAAO,SAASK,mBAAmBA,CACjCb,QAAyB,EACzBC,SAAyB,EACzBa,GAAM,EACNC,KAAqB,EACJ;EACjB,IAAId,SAAS,CAACE,KAAK,KAAKF,SAAS,CAACG,GAAG,EAAE;IACrC,OAAOJ,QAAQ;EACjB;EAEA,MAAM;IAAEG,KAAK;IAAEC;EAAI,CAAC,GAAGC,kBAAkB,CAACJ,SAAS,CAAC;EACpD,OAAOW,iBAAiB,CAACZ,QAAQ,EAAEG,KAAK,EAAEC,GAAG,EAAE;IAAE,CAACU,GAAG,GAAGC;EAAM,CAAC,CAAC;AAClE;;AAEA;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAC9BhB,QAAyB,EACzBC,SAAyB,EACzBgB,KAAmB,EACF;EACjB,MAAMC,SAAS,GAAGrB,mBAAmB,CAACG,QAAQ,CAAC;EAC/C,MAAM;IAAEmB,SAAS;IAAEC;EAAQ,CAAC,GAAGC,YAAY,CAACH,SAAS,EAAEjB,SAAS,CAACE,KAAK,CAAC;EAEvE,MAAMmB,YAAkC,GAAG;IACzCC,OAAO,EAAEN,KAAK;IACdO,QAAQ,EAAE1B,kBAAkB,CAACmB,KAAK,CAAC;IACnCQ,IAAI,EAAER,KAAK,KAAK,MAAM,GAAG,IAAI,GAAGS;EAClC,CAAC;EAED,OAAOd,iBAAiB,CAACZ,QAAQ,EAAEmB,SAAS,EAAEC,OAAO,EAAEE,YAAY,CAAC;AACtE;;AAEA;AACA;AACA;AACA,OAAO,SAASK,yBAAyBA,CACvC3B,QAAyB,EACzBC,SAAyB,EACzBC,MAAkB,EACT;EACT,IAAID,SAAS,CAACE,KAAK,KAAKF,SAAS,CAACG,GAAG,EAAE;IACrC,OAAO,KAAK;EACd;EAEA,MAAM;IAAED,KAAK;IAAEC;EAAI,CAAC,GAAGC,kBAAkB,CAACJ,SAAS,CAAC;EACpD,MAAM2B,QAAQ,GAAGrB,sBAAsB,CAACP,QAAQ,EAAEG,KAAK,EAAEC,GAAG,CAAC;EAC7D,OAAOwB,QAAQ,CAACC,MAAM,GAAG,CAAC,IAAID,QAAQ,CAACnB,KAAK,CAAEC,CAAC,IAAK,CAAC,CAACA,CAAC,CAACC,MAAM,CAACT,MAAM,CAAC,CAAC;AACzE;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAAS4B,iBAAiBA,CAC/B9B,QAAyB,EACzBC,SAAyB,EACZ;EACb,IAAIA,SAAS,CAACE,KAAK,KAAKF,SAAS,CAACG,GAAG,EAAE;IACrC;IACA,MAAM2B,GAAG,GAAGpC,sBAAsB,CAACK,QAAQ,EAAEC,SAAS,CAACE,KAAK,CAAC;IAC7D,IAAIH,QAAQ,CAAC6B,MAAM,GAAG,CAAC,EAAE;MACvB,OAAO;QAAE,GAAG7B,QAAQ,CAAC+B,GAAG,CAACC,YAAY,CAAC,CAACrB;MAAO,CAAC;IACjD;IACA,OAAO,CAAC,CAAC;EACX;EAEA,MAAM;IAAER,KAAK;IAAEC;EAAI,CAAC,GAAGC,kBAAkB,CAACJ,SAAS,CAAC;EACpD,MAAM2B,QAAQ,GAAGrB,sBAAsB,CAACP,QAAQ,EAAEG,KAAK,EAAEC,GAAG,CAAC;EAE7D,IAAIwB,QAAQ,CAACC,MAAM,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;EAEpC,MAAMI,MAAmB,GAAG;IAAE,GAAGL,QAAQ,CAAC,CAAC,CAAC,CAACjB;EAAO,CAAC;EAErD,KAAK,IAAIuB,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGN,QAAQ,CAACC,MAAM,EAAEK,CAAC,EAAE,EAAE;IACxC,MAAMxB,CAAC,GAAGkB,QAAQ,CAACM,CAAC,CAAC,CAACvB,MAAM;IAC5B,IAAIsB,MAAM,CAACR,IAAI,KAAKC,SAAS,IAAIO,MAAM,CAACR,IAAI,KAAK,CAAC,CAACf,CAAC,CAACe,IAAI,EACvDQ,MAAM,CAACR,IAAI,GAAGC,SAAS;IACzB,IAAIO,MAAM,CAACE,MAAM,KAAKT,SAAS,IAAIO,MAAM,CAACE,MAAM,KAAK,CAAC,CAACzB,CAAC,CAACyB,MAAM,EAC7DF,MAAM,CAACE,MAAM,GAAGT,SAAS;IAC3B,IAAIO,MAAM,CAACG,SAAS,KAAKV,SAAS,IAAIO,MAAM,CAACG,SAAS,KAAK,CAAC,CAAC1B,CAAC,CAAC0B,SAAS,EACtEH,MAAM,CAACG,SAAS,GAAGV,SAAS;IAC9B,IACEO,MAAM,CAACI,aAAa,KAAKX,SAAS,IAClCO,MAAM,CAACI,aAAa,KAAK,CAAC,CAAC3B,CAAC,CAAC2B,aAAa,EAE1CJ,MAAM,CAACI,aAAa,GAAGX,SAAS;IAClC,IAAIO,MAAM,CAACK,IAAI,KAAKZ,SAAS,IAAIO,MAAM,CAACK,IAAI,KAAK,CAAC,CAAC5B,CAAC,CAAC4B,IAAI,EACvDL,MAAM,CAACK,IAAI,GAAGZ,SAAS;IACzB,IAAIO,MAAM,CAACM,KAAK,KAAK7B,CAAC,CAAC6B,KAAK,EAAEN,MAAM,CAACM,KAAK,GAAGb,SAAS;IACtD,IAAIO,MAAM,CAACO,eAAe,KAAK9B,CAAC,CAAC8B,eAAe,EAC9CP,MAAM,CAACO,eAAe,GAAGd,SAAS;IACpC,IAAIO,MAAM,CAACT,QAAQ,KAAKd,CAAC,CAACc,QAAQ,EAAES,MAAM,CAACT,QAAQ,GAAGE,SAAS;IAC/D,IAAIO,MAAM,CAACV,OAAO,KAAKb,CAAC,CAACa,OAAO,EAAEU,MAAM,CAACV,OAAO,GAAGG,SAAS;EAC9D;EAEA,OAAOO,MAAM;AACf;;AAEA;;AAEA;AACA;AACA;AACA,SAAS5B,kBAAkBA,CAACJ,SAAyB,EAAkB;EACrE,OAAO;IACLE,KAAK,EAAEsC,IAAI,CAACC,GAAG,CAACzC,SAAS,CAACE,KAAK,EAAEF,SAAS,CAACG,GAAG,CAAC;IAC/CA,GAAG,EAAEqC,IAAI,CAACE,GAAG,CAAC1C,SAAS,CAACE,KAAK,EAAEF,SAAS,CAACG,GAAG;EAC9C,CAAC;AACH;;AAEA;AACA;AACA;AACA,SAASG,sBAAsBA,CAC7BP,QAAyB,EACzBG,KAAa,EACbC,GAAW,EACM;EACjB,MAAM6B,MAAuB,GAAG,EAAE;EAClC,IAAIF,GAAG,GAAG,CAAC;EAEX,KAAK,MAAMa,GAAG,IAAI5C,QAAQ,EAAE;IAC1B,MAAM6C,QAAQ,GAAGd,GAAG;IACpB,MAAMe,MAAM,GAAGf,GAAG,GAAGa,GAAG,CAACG,IAAI,CAAClB,MAAM;IAEpC,IAAIiB,MAAM,IAAI3C,KAAK,EAAE;MACnB4B,GAAG,GAAGe,MAAM;MACZ;IACF;IACA,IAAID,QAAQ,IAAIzC,GAAG,EAAE;MACnB;IACF;;IAEA;IACA,MAAM4C,YAAY,GAAGP,IAAI,CAACE,GAAG,CAACE,QAAQ,EAAE1C,KAAK,CAAC;IAC9C,MAAM8C,UAAU,GAAGR,IAAI,CAACC,GAAG,CAACI,MAAM,EAAE1C,GAAG,CAAC;IACxC6B,MAAM,CAACiB,IAAI,CACTxD,aAAa,CACXkD,GAAG,CAACG,IAAI,CAACI,KAAK,CAACH,YAAY,GAAGH,QAAQ,EAAEI,UAAU,GAAGJ,QAAQ,CAAC,EAC9DD,GAAG,CAACjC,MACN,CACF,CAAC;IAEDoB,GAAG,GAAGe,MAAM;EACd;EAEA,OAAOb,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA,SAASrB,iBAAiBA,CACxBZ,QAAyB,EACzBG,KAAa,EACbC,GAAW,EACXgD,UAAgC,EACf;EACjB,MAAMnB,MAAuB,GAAG,EAAE;EAClC,IAAIF,GAAG,GAAG,CAAC;EAEX,KAAK,MAAMa,GAAG,IAAI5C,QAAQ,EAAE;IAC1B,MAAM6C,QAAQ,GAAGd,GAAG;IACpB,MAAMe,MAAM,GAAGf,GAAG,GAAGa,GAAG,CAACG,IAAI,CAAClB,MAAM;IAEpC,IAAIiB,MAAM,IAAI3C,KAAK,IAAI0C,QAAQ,IAAIzC,GAAG,EAAE;MACtC;MACA6B,MAAM,CAACiB,IAAI,CAACxD,aAAa,CAACkD,GAAG,CAACG,IAAI,EAAEH,GAAG,CAACjC,MAAM,CAAC,CAAC;IAClD,CAAC,MAAM;MACL;MACA,IAAIkC,QAAQ,GAAG1C,KAAK,EAAE;QACpB;QACA8B,MAAM,CAACiB,IAAI,CACTxD,aAAa,CAACkD,GAAG,CAACG,IAAI,CAACI,KAAK,CAAC,CAAC,EAAEhD,KAAK,GAAG0C,QAAQ,CAAC,EAAED,GAAG,CAACjC,MAAM,CAC/D,CAAC;MACH;;MAEA;MACA,MAAMqC,YAAY,GAAGP,IAAI,CAACE,GAAG,CAACE,QAAQ,EAAE1C,KAAK,CAAC;MAC9C,MAAM8C,UAAU,GAAGR,IAAI,CAACC,GAAG,CAACI,MAAM,EAAE1C,GAAG,CAAC;MACxC,MAAMiD,SAAS,GAAG;QAAE,GAAGT,GAAG,CAACjC,MAAM;QAAE,GAAGyC;MAAW,CAAC;MAClDnB,MAAM,CAACiB,IAAI,CACTxD,aAAa,CACXkD,GAAG,CAACG,IAAI,CAACI,KAAK,CAACH,YAAY,GAAGH,QAAQ,EAAEI,UAAU,GAAGJ,QAAQ,CAAC,EAC9DQ,SACF,CACF,CAAC;MAED,IAAIP,MAAM,GAAG1C,GAAG,EAAE;QAChB;QACA6B,MAAM,CAACiB,IAAI,CACTxD,aAAa,CAACkD,GAAG,CAACG,IAAI,CAACI,KAAK,CAAC/C,GAAG,GAAGyC,QAAQ,CAAC,EAAED,GAAG,CAACjC,MAAM,CAC1D,CAAC;MACH;IACF;IAEAoB,GAAG,GAAGe,MAAM;EACd;EAEA,OAAOlD,qBAAqB,CAACqC,MAAM,CAAC;AACtC;;AAEA;AACA;AACA;AACA,SAASZ,YAAYA,CACnB0B,IAAY,EACZO,QAAgB,EACwB;EACxC,IAAInC,SAAS,GAAGmC,QAAQ;EACxB,OAAOnC,SAAS,GAAG,CAAC,IAAI4B,IAAI,CAAC5B,SAAS,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE;IACpDA,SAAS,EAAE;EACb;EAEA,IAAIC,OAAO,GAAGkC,QAAQ;EACtB,OAAOlC,OAAO,GAAG2B,IAAI,CAAClB,MAAM,IAAIkB,IAAI,CAAC3B,OAAO,CAAC,KAAK,IAAI,EAAE;IACtDA,OAAO,EAAE;EACX;EAEA,OAAO;IAAED,SAAS;IAAEC;EAAQ,CAAC;AAC/B;;AAEA;AACA,SAAS1B,aAAa,QAAQ,gBAAgB","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["utils/parser.d.ts"],"mappings":"","ignoreList":[]}
|