@rtif-sdk/web 1.0.0 → 1.1.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/dist/block-drag-handler.d.ts +5 -0
- package/dist/block-drag-handler.d.ts.map +1 -1
- package/dist/block-drag-handler.js +28 -2
- package/dist/block-drag-handler.js.map +1 -1
- package/dist/block-renderer.d.ts +12 -6
- package/dist/block-renderer.d.ts.map +1 -1
- package/dist/block-renderer.js +98 -9
- package/dist/block-renderer.js.map +1 -1
- package/dist/block-type-dropdown.d.ts +78 -0
- package/dist/block-type-dropdown.d.ts.map +1 -0
- package/dist/block-type-dropdown.js +276 -0
- package/dist/block-type-dropdown.js.map +1 -0
- package/dist/color-picker.d.ts +91 -0
- package/dist/color-picker.d.ts.map +1 -0
- package/dist/color-picker.js +346 -0
- package/dist/color-picker.js.map +1 -0
- package/dist/content-handlers.d.ts +7 -8
- package/dist/content-handlers.d.ts.map +1 -1
- package/dist/content-handlers.js +122 -93
- package/dist/content-handlers.js.map +1 -1
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +117 -14
- package/dist/editor.js.map +1 -1
- package/dist/embed-utils.d.ts +148 -0
- package/dist/embed-utils.d.ts.map +1 -0
- package/dist/embed-utils.js +197 -0
- package/dist/embed-utils.js.map +1 -0
- package/dist/font-family-picker.d.ts +105 -0
- package/dist/font-family-picker.d.ts.map +1 -0
- package/dist/font-family-picker.js +314 -0
- package/dist/font-family-picker.js.map +1 -0
- package/dist/font-size-picker.d.ts +82 -0
- package/dist/font-size-picker.d.ts.map +1 -0
- package/dist/font-size-picker.js +290 -0
- package/dist/font-size-picker.js.map +1 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.d.ts +2 -1
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +1 -1
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/link-plugin.d.ts +4 -0
- package/dist/plugins/link-plugin.d.ts.map +1 -1
- package/dist/plugins/link-plugin.js +17 -0
- package/dist/plugins/link-plugin.js.map +1 -1
- package/dist/plugins/mark-utils.d.ts +31 -0
- package/dist/plugins/mark-utils.d.ts.map +1 -1
- package/dist/plugins/mark-utils.js +46 -0
- package/dist/plugins/mark-utils.js.map +1 -1
- package/dist/renderer.d.ts +2 -2
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +62 -16
- package/dist/renderer.js.map +1 -1
- package/dist/selection-sync.d.ts +2 -26
- package/dist/selection-sync.d.ts.map +1 -1
- package/dist/selection-sync.js +49 -13
- package/dist/selection-sync.js.map +1 -1
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +17 -5
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block type dropdown — a combobox-style dropdown for switching block types.
|
|
3
|
+
*
|
|
4
|
+
* Shows the currently active block type (e.g., "Heading 1", "Bullet List")
|
|
5
|
+
* and lets the user switch to a different type. Uses the same
|
|
6
|
+
* `mousedown + preventDefault()` pattern as the toolbar to avoid stealing
|
|
7
|
+
* editor focus.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Module-scoped counter for unique IDs
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
let instanceCounter = 0;
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Factory
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/**
|
|
19
|
+
* Create a block type dropdown backed by a {@link CommandBus}.
|
|
20
|
+
*
|
|
21
|
+
* The dropdown reflects the currently active block type by querying
|
|
22
|
+
* `bus.isActive()` for each item. It subscribes to the bus for live updates.
|
|
23
|
+
*
|
|
24
|
+
* @param container - The DOM element to render the dropdown into
|
|
25
|
+
* @param bus - The CommandBus to execute commands and query state
|
|
26
|
+
* @param items - Array of dropdown item configurations
|
|
27
|
+
* @returns A handle for lifecycle management
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const dropdown = createBlockTypeDropdown(
|
|
32
|
+
* document.getElementById('toolbar')!,
|
|
33
|
+
* bus,
|
|
34
|
+
* [
|
|
35
|
+
* { command: null, label: 'Paragraph' },
|
|
36
|
+
* { command: 'toggleHeading', payload: { level: 1 }, label: 'Heading 1', icon: 'H1' },
|
|
37
|
+
* ],
|
|
38
|
+
* );
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function createBlockTypeDropdown(container, bus, items) {
|
|
42
|
+
const doc = container.ownerDocument;
|
|
43
|
+
const id = ++instanceCounter;
|
|
44
|
+
const menuId = `rtif-btd-menu-${id}`;
|
|
45
|
+
let isOpen = false;
|
|
46
|
+
let highlightIndex = -1;
|
|
47
|
+
let destroyed = false;
|
|
48
|
+
// -----------------------------------------------------------------------
|
|
49
|
+
// DOM creation
|
|
50
|
+
// -----------------------------------------------------------------------
|
|
51
|
+
const wrapper = doc.createElement('div');
|
|
52
|
+
wrapper.className = 'rtif-block-type-dropdown';
|
|
53
|
+
// Trigger button
|
|
54
|
+
const trigger = doc.createElement('button');
|
|
55
|
+
trigger.type = 'button';
|
|
56
|
+
trigger.className = 'rtif-block-type-dropdown-trigger';
|
|
57
|
+
trigger.setAttribute('role', 'combobox');
|
|
58
|
+
trigger.setAttribute('aria-haspopup', 'listbox');
|
|
59
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
60
|
+
trigger.setAttribute('aria-controls', menuId);
|
|
61
|
+
trigger.setAttribute('aria-label', 'Block type');
|
|
62
|
+
const iconSpan = doc.createElement('span');
|
|
63
|
+
iconSpan.className = 'rtif-block-type-dropdown-icon';
|
|
64
|
+
const labelSpan = doc.createElement('span');
|
|
65
|
+
labelSpan.className = 'rtif-block-type-dropdown-label';
|
|
66
|
+
const chevronSpan = doc.createElement('span');
|
|
67
|
+
chevronSpan.className = 'rtif-block-type-dropdown-chevron';
|
|
68
|
+
chevronSpan.textContent = '\u25BE'; // ▾
|
|
69
|
+
trigger.appendChild(iconSpan);
|
|
70
|
+
trigger.appendChild(labelSpan);
|
|
71
|
+
trigger.appendChild(chevronSpan);
|
|
72
|
+
// Menu
|
|
73
|
+
const menu = doc.createElement('div');
|
|
74
|
+
menu.id = menuId;
|
|
75
|
+
menu.className = 'rtif-block-type-dropdown-menu';
|
|
76
|
+
menu.setAttribute('role', 'listbox');
|
|
77
|
+
menu.setAttribute('aria-label', 'Block types');
|
|
78
|
+
menu.hidden = true;
|
|
79
|
+
// Options
|
|
80
|
+
const optionEls = [];
|
|
81
|
+
for (let i = 0; i < items.length; i++) {
|
|
82
|
+
const item = items[i];
|
|
83
|
+
const option = doc.createElement('div');
|
|
84
|
+
option.className = 'rtif-block-type-dropdown-option';
|
|
85
|
+
option.id = `rtif-btd-option-${id}-${i}`;
|
|
86
|
+
option.setAttribute('role', 'option');
|
|
87
|
+
option.setAttribute('aria-selected', 'false');
|
|
88
|
+
if (item.icon) {
|
|
89
|
+
const optIcon = doc.createElement('span');
|
|
90
|
+
optIcon.className = 'rtif-block-type-dropdown-option-icon';
|
|
91
|
+
optIcon.textContent = item.icon;
|
|
92
|
+
option.appendChild(optIcon);
|
|
93
|
+
}
|
|
94
|
+
const optLabel = doc.createElement('span');
|
|
95
|
+
optLabel.className = 'rtif-block-type-dropdown-option-label';
|
|
96
|
+
optLabel.textContent = item.label;
|
|
97
|
+
option.appendChild(optLabel);
|
|
98
|
+
option.addEventListener('mousedown', (e) => {
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
selectItem(i);
|
|
101
|
+
});
|
|
102
|
+
menu.appendChild(option);
|
|
103
|
+
optionEls.push(option);
|
|
104
|
+
}
|
|
105
|
+
wrapper.appendChild(trigger);
|
|
106
|
+
wrapper.appendChild(menu);
|
|
107
|
+
container.appendChild(wrapper);
|
|
108
|
+
// -----------------------------------------------------------------------
|
|
109
|
+
// Active state detection
|
|
110
|
+
// -----------------------------------------------------------------------
|
|
111
|
+
function findActiveIndex() {
|
|
112
|
+
for (let i = 0; i < items.length; i++) {
|
|
113
|
+
const item = items[i];
|
|
114
|
+
if (item.command !== null && bus.isActive(item.command, item.payload)) {
|
|
115
|
+
return i;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Default: find the null-command item (Paragraph), else fall back to 0
|
|
119
|
+
const nullIdx = items.findIndex((it) => it.command === null);
|
|
120
|
+
return nullIdx !== -1 ? nullIdx : 0;
|
|
121
|
+
}
|
|
122
|
+
function updateDisplay() {
|
|
123
|
+
const activeIdx = findActiveIndex();
|
|
124
|
+
const active = items[activeIdx];
|
|
125
|
+
iconSpan.textContent = active.icon ?? '';
|
|
126
|
+
labelSpan.textContent = active.label;
|
|
127
|
+
// Update aria-selected on options
|
|
128
|
+
for (let i = 0; i < optionEls.length; i++) {
|
|
129
|
+
optionEls[i].setAttribute('aria-selected', i === activeIdx ? 'true' : 'false');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// -----------------------------------------------------------------------
|
|
133
|
+
// Open / close
|
|
134
|
+
// -----------------------------------------------------------------------
|
|
135
|
+
function openMenu() {
|
|
136
|
+
if (isOpen)
|
|
137
|
+
return;
|
|
138
|
+
isOpen = true;
|
|
139
|
+
highlightIndex = -1;
|
|
140
|
+
menu.hidden = false;
|
|
141
|
+
trigger.setAttribute('aria-expanded', 'true');
|
|
142
|
+
trigger.removeAttribute('aria-activedescendant');
|
|
143
|
+
doc.addEventListener('mousedown', onDocumentMouseDown);
|
|
144
|
+
}
|
|
145
|
+
function closeMenu() {
|
|
146
|
+
if (!isOpen)
|
|
147
|
+
return;
|
|
148
|
+
isOpen = false;
|
|
149
|
+
highlightIndex = -1;
|
|
150
|
+
menu.hidden = true;
|
|
151
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
152
|
+
trigger.removeAttribute('aria-activedescendant');
|
|
153
|
+
// Clear highlight
|
|
154
|
+
for (const el of optionEls) {
|
|
155
|
+
el.classList.remove('rtif-block-type-dropdown-option-highlighted');
|
|
156
|
+
}
|
|
157
|
+
doc.removeEventListener('mousedown', onDocumentMouseDown);
|
|
158
|
+
}
|
|
159
|
+
// -----------------------------------------------------------------------
|
|
160
|
+
// Selection
|
|
161
|
+
// -----------------------------------------------------------------------
|
|
162
|
+
function selectItem(index) {
|
|
163
|
+
const item = items[index];
|
|
164
|
+
if (item.command === null) {
|
|
165
|
+
// "Paragraph" — toggle off the currently active type
|
|
166
|
+
const activeIdx = findActiveIndex();
|
|
167
|
+
const activeItem = items[activeIdx];
|
|
168
|
+
if (activeItem && activeItem.command !== null) {
|
|
169
|
+
bus.execute(activeItem.command, activeItem.payload);
|
|
170
|
+
}
|
|
171
|
+
// If already on paragraph, this is a no-op
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
bus.execute(item.command, item.payload);
|
|
175
|
+
}
|
|
176
|
+
closeMenu();
|
|
177
|
+
}
|
|
178
|
+
// -----------------------------------------------------------------------
|
|
179
|
+
// Keyboard navigation
|
|
180
|
+
// -----------------------------------------------------------------------
|
|
181
|
+
function onKeyDown(e) {
|
|
182
|
+
if (!isOpen)
|
|
183
|
+
return;
|
|
184
|
+
switch (e.key) {
|
|
185
|
+
case 'ArrowDown': {
|
|
186
|
+
e.preventDefault();
|
|
187
|
+
highlightIndex = (highlightIndex + 1) % items.length;
|
|
188
|
+
updateHighlight();
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
case 'ArrowUp': {
|
|
192
|
+
e.preventDefault();
|
|
193
|
+
highlightIndex = highlightIndex <= 0
|
|
194
|
+
? items.length - 1
|
|
195
|
+
: highlightIndex - 1;
|
|
196
|
+
updateHighlight();
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case 'Enter': {
|
|
200
|
+
e.preventDefault();
|
|
201
|
+
if (highlightIndex >= 0 && highlightIndex < items.length) {
|
|
202
|
+
selectItem(highlightIndex);
|
|
203
|
+
}
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
case 'Escape': {
|
|
207
|
+
e.preventDefault();
|
|
208
|
+
closeMenu();
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function updateHighlight() {
|
|
214
|
+
for (let i = 0; i < optionEls.length; i++) {
|
|
215
|
+
const el = optionEls[i];
|
|
216
|
+
if (i === highlightIndex) {
|
|
217
|
+
el.classList.add('rtif-block-type-dropdown-option-highlighted');
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
el.classList.remove('rtif-block-type-dropdown-option-highlighted');
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (highlightIndex >= 0 && highlightIndex < optionEls.length) {
|
|
224
|
+
trigger.setAttribute('aria-activedescendant', optionEls[highlightIndex].id);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
trigger.removeAttribute('aria-activedescendant');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// -----------------------------------------------------------------------
|
|
231
|
+
// Event handlers
|
|
232
|
+
// -----------------------------------------------------------------------
|
|
233
|
+
function onTriggerMouseDown(e) {
|
|
234
|
+
e.preventDefault();
|
|
235
|
+
}
|
|
236
|
+
function onTriggerClick() {
|
|
237
|
+
if (isOpen) {
|
|
238
|
+
closeMenu();
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
openMenu();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function onDocumentMouseDown(e) {
|
|
245
|
+
// Close on outside click, but not if clicking inside wrapper
|
|
246
|
+
if (!wrapper.contains(e.target)) {
|
|
247
|
+
closeMenu();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
trigger.addEventListener('mousedown', onTriggerMouseDown);
|
|
251
|
+
trigger.addEventListener('click', onTriggerClick);
|
|
252
|
+
trigger.addEventListener('keydown', onKeyDown);
|
|
253
|
+
// -----------------------------------------------------------------------
|
|
254
|
+
// Bus subscription
|
|
255
|
+
// -----------------------------------------------------------------------
|
|
256
|
+
updateDisplay();
|
|
257
|
+
const unsubscribe = bus.subscribe(() => updateDisplay());
|
|
258
|
+
// -----------------------------------------------------------------------
|
|
259
|
+
// Handle
|
|
260
|
+
// -----------------------------------------------------------------------
|
|
261
|
+
return {
|
|
262
|
+
element: wrapper,
|
|
263
|
+
destroy() {
|
|
264
|
+
if (destroyed)
|
|
265
|
+
return;
|
|
266
|
+
destroyed = true;
|
|
267
|
+
unsubscribe();
|
|
268
|
+
closeMenu();
|
|
269
|
+
trigger.removeEventListener('mousedown', onTriggerMouseDown);
|
|
270
|
+
trigger.removeEventListener('click', onTriggerClick);
|
|
271
|
+
trigger.removeEventListener('keydown', onKeyDown);
|
|
272
|
+
wrapper.remove();
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=block-type-dropdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-type-dropdown.js","sourceRoot":"","sources":["../src/block-type-dropdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color picker — a swatch grid dropdown for applying text colors.
|
|
3
|
+
*
|
|
4
|
+
* Shows the current text color in the trigger button and lets the user
|
|
5
|
+
* pick from preset swatches or enter a custom hex color. Uses the same
|
|
6
|
+
* `mousedown + preventDefault()` pattern as the toolbar to avoid stealing
|
|
7
|
+
* editor focus.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import type { IEditorEngine } from '@rtif-sdk/engine';
|
|
12
|
+
import type { CommandBus } from './command-bus.js';
|
|
13
|
+
/**
|
|
14
|
+
* Default color swatches displayed in the color picker grid.
|
|
15
|
+
*
|
|
16
|
+
* Row 1: dark/saturated colors.
|
|
17
|
+
* Row 2: light/pastel colors.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const picker = createColorPicker({
|
|
22
|
+
* container, bus, engine,
|
|
23
|
+
* swatches: DEFAULT_COLOR_SWATCHES.slice(0, 10), // first row only
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare const DEFAULT_COLOR_SWATCHES: readonly string[];
|
|
28
|
+
/**
|
|
29
|
+
* Configuration for the color picker.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* const picker = createColorPicker({
|
|
34
|
+
* container: document.getElementById('toolbar')!,
|
|
35
|
+
* bus: editor.commandBus,
|
|
36
|
+
* engine,
|
|
37
|
+
* swatches: DEFAULT_COLOR_SWATCHES,
|
|
38
|
+
* showCustom: true,
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export interface ColorPickerConfig {
|
|
43
|
+
/** The DOM element to render the picker into. */
|
|
44
|
+
readonly container: HTMLElement;
|
|
45
|
+
/** The command bus for executing color commands. */
|
|
46
|
+
readonly bus: CommandBus;
|
|
47
|
+
/** The engine for querying the current mark value. */
|
|
48
|
+
readonly engine: IEditorEngine;
|
|
49
|
+
/** Color swatches to display (default: {@link DEFAULT_COLOR_SWATCHES}). */
|
|
50
|
+
readonly swatches?: readonly string[];
|
|
51
|
+
/** Number of columns in the swatch grid (default: 10). */
|
|
52
|
+
readonly columns?: number;
|
|
53
|
+
/** Whether to show the custom hex color input (default: true). */
|
|
54
|
+
readonly showCustom?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Handle returned by {@link createColorPicker} for lifecycle management.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const picker = createColorPicker({ container, bus, engine });
|
|
62
|
+
* // ... later:
|
|
63
|
+
* picker.destroy();
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export interface ColorPickerHandle {
|
|
67
|
+
/** The picker's root wrapper element. */
|
|
68
|
+
readonly element: HTMLElement;
|
|
69
|
+
/** Remove all event listeners and DOM nodes. Idempotent. */
|
|
70
|
+
destroy(): void;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create a color picker dropdown backed by a {@link CommandBus}.
|
|
74
|
+
*
|
|
75
|
+
* The picker reflects the current text color by querying the engine's
|
|
76
|
+
* mark state. It subscribes to the bus for live updates.
|
|
77
|
+
*
|
|
78
|
+
* @param config - Picker configuration
|
|
79
|
+
* @returns A handle for lifecycle management
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* const picker = createColorPicker({
|
|
84
|
+
* container: toolbar,
|
|
85
|
+
* bus: editor.commandBus,
|
|
86
|
+
* engine,
|
|
87
|
+
* });
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare function createColorPicker(config: ColorPickerConfig): ColorPickerHandle;
|
|
91
|
+
//# sourceMappingURL=color-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-picker.d.ts","sourceRoot":"","sources":["../src/color-picker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAanD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAOnD,CAAC;AAMF;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC,oDAAoD;IACpD,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,4DAA4D;IAC5D,OAAO,IAAI,IAAI,CAAC;CACjB;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CA2V9E"}
|