svedit 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -21
- package/dist/{AnnotatedStringProperty.svelte → AnnotatedTextProperty.svelte} +28 -40
- package/dist/AnnotatedTextProperty.svelte.d.ts +7 -0
- package/dist/AnnotatedTextProperty.svelte.d.ts.map +1 -0
- package/dist/Document.svelte.d.ts +39 -16
- package/dist/Document.svelte.d.ts.map +1 -1
- package/dist/Document.svelte.js +192 -80
- package/dist/Svedit.svelte +149 -97
- package/dist/Svedit.svelte.d.ts.map +1 -1
- package/dist/Transaction.svelte.d.ts +4 -4
- package/dist/Transaction.svelte.d.ts.map +1 -1
- package/dist/Transaction.svelte.js +60 -77
- package/dist/commands.svelte.d.ts.map +1 -1
- package/dist/commands.svelte.js +18 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +66 -21
- package/dist/util.d.ts +16 -16
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +33 -34
- package/package.json +1 -1
- package/src/lib/{AnnotatedStringProperty.svelte → AnnotatedTextProperty.svelte} +28 -40
- package/src/lib/Document.svelte.js +192 -80
- package/src/lib/Svedit.svelte +149 -97
- package/src/lib/Transaction.svelte.js +60 -77
- package/src/lib/commands.svelte.js +18 -10
- package/src/lib/index.js +1 -1
- package/src/lib/types.d.ts +66 -21
- package/src/lib/util.js +33 -34
- package/dist/AnnotatedStringProperty.svelte.d.ts +0 -7
- package/dist/AnnotatedStringProperty.svelte.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Now make it your own. The next thing you probably want to do is define your own
|
|
|
39
39
|
|
|
40
40
|
**Chromeless canvas:** We keep the canvas chromeless, meaning there's no UI elements like toolbars or menus mingled with the content. You can interact with text directly, but everything else happens via tools are shown in separate overlays or in the fixed toolbar.
|
|
41
41
|
|
|
42
|
-
**Convention over configuration:** We use conventions and assumptions to reduce configuration code and limit the number of ways something can go wrong. For instance, we assume that a node with a property named `content` of type `
|
|
42
|
+
**Convention over configuration:** We use conventions and assumptions to reduce configuration code and limit the number of ways something can go wrong. For instance, we assume that a node with a property named `content` of type `annotated_text` is considered kind `text`, while all other nodes are considered kind `node`. Text nodes have special behavior in the system for editing (e.g. they can be splitted and joined).
|
|
43
43
|
|
|
44
44
|
**White-box library:** We expose the internals of the library to allow you to customize and extend it to your needs. That means a little bit more work upfront, but in return lets you control "everything" — the toolbar, the overlays, or how fast the node cursor blinks.
|
|
45
45
|
|
|
@@ -63,7 +63,7 @@ Properties of nodes can hold values:
|
|
|
63
63
|
- `string_array`: An array of good old JavaScript strings
|
|
64
64
|
- `integer_array`: An array of integers
|
|
65
65
|
- `number_array`: An array of numbers
|
|
66
|
-
- `
|
|
66
|
+
- `annotated_text`: a plain text string, but with annotations (bold, italic, link etc.)
|
|
67
67
|
|
|
68
68
|
Or references:
|
|
69
69
|
- `node`: References a single node (e.g. an image node can reference a global asset node)
|
|
@@ -73,35 +73,53 @@ Or references:
|
|
|
73
73
|
```js
|
|
74
74
|
const document_schema = {
|
|
75
75
|
page: {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
kind: 'document',
|
|
77
|
+
properties: {
|
|
78
|
+
body: {
|
|
79
|
+
type: 'node_array',
|
|
80
|
+
node_types: ['nav', 'paragraph', 'list'],
|
|
81
|
+
default_node_type: 'paragraph',
|
|
82
|
+
}
|
|
80
83
|
}
|
|
81
84
|
},
|
|
82
85
|
paragraph: {
|
|
83
|
-
|
|
86
|
+
kind: 'text',
|
|
87
|
+
properties: {
|
|
88
|
+
content: { type: 'annotated_text', allow_newlines: true }
|
|
89
|
+
}
|
|
84
90
|
},
|
|
85
91
|
list_item: {
|
|
86
|
-
|
|
92
|
+
kind: 'text',
|
|
93
|
+
properties: {
|
|
94
|
+
content: { type: 'annotated_text', allow_newlines: true },
|
|
95
|
+
}
|
|
87
96
|
},
|
|
88
97
|
list: {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
kind: 'block',
|
|
99
|
+
properties: {
|
|
100
|
+
list_items: {
|
|
101
|
+
type: 'node_array',
|
|
102
|
+
node_types: ['list_item'],
|
|
103
|
+
default_node_type: 'list_item',
|
|
104
|
+
}
|
|
93
105
|
}
|
|
94
106
|
},
|
|
95
107
|
nav: {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
108
|
+
kind: 'block',
|
|
109
|
+
properties: {
|
|
110
|
+
nav_items: {
|
|
111
|
+
type: 'node_array',
|
|
112
|
+
node_types: ['nav_item'],
|
|
113
|
+
default_node_type: 'nav_item',
|
|
114
|
+
}
|
|
100
115
|
}
|
|
101
116
|
},
|
|
102
117
|
nav_item: {
|
|
103
|
-
|
|
104
|
-
|
|
118
|
+
kind: 'block',
|
|
119
|
+
properties: {
|
|
120
|
+
url: { type: 'string' },
|
|
121
|
+
label: { type: 'string' },
|
|
122
|
+
}
|
|
105
123
|
}
|
|
106
124
|
};
|
|
107
125
|
```
|
|
@@ -192,7 +210,7 @@ const document_config = {
|
|
|
192
210
|
// Custom functions to insert new "blank" nodes and setting the selection
|
|
193
211
|
// depending on the intended behavior.
|
|
194
212
|
inserters: {
|
|
195
|
-
text: function(tr, content =
|
|
213
|
+
text: function(tr, content = {text: '', annotations: []}, layout = 1) {
|
|
196
214
|
const new_text = {
|
|
197
215
|
id: nanoid(),
|
|
198
216
|
type: 'text',
|
|
@@ -276,7 +294,7 @@ Selections are at the heart of Svedit. There are just three types of selections:
|
|
|
276
294
|
}
|
|
277
295
|
```
|
|
278
296
|
|
|
279
|
-
You can access the current selection through `doc.selection` anytime. And you can programmatically set the selection using `doc.
|
|
297
|
+
You can access the current selection through `doc.selection` anytime. And you can programmatically set the selection using `doc.selection = new_selection`.
|
|
280
298
|
|
|
281
299
|
## Rendering
|
|
282
300
|
|
|
@@ -320,7 +338,7 @@ a simplified version of the markup of `<NodeCursorTrap>` and why it is implement
|
|
|
320
338
|
Further things to consider:
|
|
321
339
|
|
|
322
340
|
- If you make a sub-tree `contenteditable="false"`, be aware that you can't create a `contenteditable="true"` segment somewhere inside it. Svedit can only work reliably when there's one contenteditable="true" at root (it's set by `<Svedit`>)
|
|
323
|
-
- `<
|
|
341
|
+
- `<AnnotatedTextProperty>` and `<CustomProperty>` must not be wrapped in `contenteditable="false"` to work properly.
|
|
324
342
|
- Never apply `position: relative` to the direct parent of `<AnnotatedTextProperty>`, it will cause a [weird Safari bug](https://bsky.app/profile/michaelaufreiter.com/post/3lxvdqyxc622s) to destroy the DOM.
|
|
325
343
|
- Never use an `<a>` tag inside a `contenteditable="true"` element, as it will cause unexpected behavior. Make it a `<div>` while editing, and an `<a>` in read-only mode.
|
|
326
344
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { getContext } from 'svelte';
|
|
3
|
-
import { char_slice, get_char_length } from './util.js';
|
|
3
|
+
import { char_slice, get_char_length, snake_to_pascal } from './util.js';
|
|
4
4
|
|
|
5
|
-
/** @import {
|
|
5
|
+
/** @import { AnnotatedTextPropertyProps, Annotation, AnnotationFragment } from './types.d.ts'; */
|
|
6
6
|
|
|
7
7
|
const svedit = getContext('svedit');
|
|
8
8
|
|
|
9
|
-
/** @type {
|
|
9
|
+
/** @type {AnnotatedTextPropertyProps} */
|
|
10
10
|
let {
|
|
11
11
|
path,
|
|
12
12
|
class: css_class,
|
|
@@ -20,32 +20,36 @@
|
|
|
20
20
|
/**
|
|
21
21
|
* Converts text with annotations into renderable fragments for display.
|
|
22
22
|
* @param {string} text - The plain text content
|
|
23
|
-
* @param {Array<Annotation>} annotations - Array of annotations where each is
|
|
23
|
+
* @param {Array<Annotation>} annotations - Array of annotations where each is {start_offset, end_offset, node_id}
|
|
24
24
|
* @returns {Array<string|AnnotationFragment>} Array of fragments - strings for plain text, AnnotationFragment objects for annotated content
|
|
25
25
|
*/
|
|
26
|
-
function
|
|
26
|
+
function get_fragments(text, annotations) {
|
|
27
27
|
let fragments = [];
|
|
28
28
|
let last_index = 0;
|
|
29
29
|
|
|
30
30
|
// Sort annotations by start_offset
|
|
31
|
-
const sorted_annotations = [...annotations].sort((a, b) => a
|
|
31
|
+
const sorted_annotations = [...annotations].sort((a, b) => a.start_offset - b.start_offset);
|
|
32
32
|
|
|
33
|
-
for (let [
|
|
33
|
+
for (let [, annotation] of sorted_annotations.entries()) {
|
|
34
34
|
// Add text before the annotation using character-aware slicing
|
|
35
|
-
if (annotation
|
|
36
|
-
fragments.push(char_slice(text, last_index, annotation
|
|
35
|
+
if (annotation.start_offset > last_index) {
|
|
36
|
+
fragments.push(char_slice(text, last_index, annotation.start_offset));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
// Add the annotated string using character-aware slicing
|
|
40
|
-
const annotated_content = char_slice(text, annotation
|
|
40
|
+
const annotated_content = char_slice(text, annotation.start_offset, annotation.end_offset);
|
|
41
|
+
const node = svedit.doc.get(annotation.node_id);
|
|
42
|
+
if (!node) throw new Error(`Node not found for annotation ${annotation.node_id}`);
|
|
43
|
+
|
|
41
44
|
fragments.push({
|
|
42
|
-
|
|
45
|
+
node,
|
|
43
46
|
content: annotated_content,
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
// NOTE: We need to provide the original index here, because the source data
|
|
48
|
+
// is the address space.
|
|
49
|
+
annotation_index: annotations.indexOf(annotation),
|
|
46
50
|
});
|
|
47
51
|
|
|
48
|
-
last_index = annotation
|
|
52
|
+
last_index = annotation.end_offset;
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
// Add any remaining text after the last annotation using character-aware slicing
|
|
@@ -56,15 +60,9 @@
|
|
|
56
60
|
return fragments;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
let fragments = $derived(
|
|
60
|
-
let plain_text = $derived(svedit.doc.get(path)
|
|
63
|
+
let fragments = $derived(get_fragments(svedit.doc.get(path).text, svedit.doc.get(path).annotations));
|
|
64
|
+
let plain_text = $derived(svedit.doc.get(path).text);
|
|
61
65
|
|
|
62
|
-
/**
|
|
63
|
-
* @param {MouseEvent} e - The click event
|
|
64
|
-
*/
|
|
65
|
-
function handle_link_click(e) {
|
|
66
|
-
e.preventDefault();
|
|
67
|
-
}
|
|
68
66
|
</script>
|
|
69
67
|
|
|
70
68
|
{#key plain_text}
|
|
@@ -79,21 +77,10 @@
|
|
|
79
77
|
placeholder={placeholder}
|
|
80
78
|
>
|
|
81
79
|
{#each fragments as fragment, index (index)}
|
|
82
|
-
{#if typeof fragment === 'string'}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
-->{:else if fragment.type === 'strong'}<!--
|
|
87
|
-
--><strong>{fragment.content}</strong><!--
|
|
88
|
-
-->{:else if fragment.type === 'link'}<!--
|
|
89
|
-
--><a
|
|
90
|
-
onclick={handle_link_click}
|
|
91
|
-
style="anchor-name: --{path.join('-') + '-' + fragment.annotation_index};"
|
|
92
|
-
href={fragment.data.href}
|
|
93
|
-
target={fragment.data.target || '_self'}>{fragment.content}</a><!--
|
|
94
|
-
-->{:else}<!--
|
|
95
|
-
-->{fragment.content}<!--
|
|
96
|
-
-->{/if}
|
|
80
|
+
{#if typeof fragment === 'string'}{fragment}{:else}
|
|
81
|
+
{@const AnnotationComponent = svedit.doc.config.node_components[snake_to_pascal(fragment.node.type)]}
|
|
82
|
+
<AnnotationComponent path={[...path, 'annotations', fragment.annotation_index, 'node_id']} content={fragment.content} />
|
|
83
|
+
{/if}
|
|
97
84
|
{/each}<!--
|
|
98
85
|
--><br>
|
|
99
86
|
</div>
|
|
@@ -118,12 +105,13 @@
|
|
|
118
105
|
|
|
119
106
|
/* We can safely hide the <br> element when the placeholder is empty and focused. */
|
|
120
107
|
/* No longer the cursor will be rendered after the placeholder when focused. */
|
|
108
|
+
/* ATTENTION: This hack has the side effect that in Safari Desktop the cursor sometimes disappears. */
|
|
121
109
|
[placeholder].empty.focused br {
|
|
122
110
|
display:none;
|
|
123
111
|
}
|
|
124
112
|
|
|
125
|
-
|
|
113
|
+
/*.text.focused {
|
|
126
114
|
background: none;
|
|
127
|
-
outline: 1px
|
|
128
|
-
}
|
|
115
|
+
outline: 1px solid var(--editing-stroke-color);
|
|
116
|
+
}*/
|
|
129
117
|
</style>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default AnnotatedTextProperty;
|
|
2
|
+
type AnnotatedTextProperty = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<AnnotatedTextPropertyProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const AnnotatedTextProperty: import("svelte").Component<import("./types.d.ts").AnnotatedTextPropertyProps, {}, "">;
|
|
7
|
+
//# sourceMappingURL=AnnotatedTextProperty.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnnotatedTextProperty.svelte.d.ts","sourceRoot":"","sources":["../src/lib/AnnotatedTextProperty.svelte.js"],"names":[],"mappings":";;;;;AAyFA,2HAAoE"}
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
* DocumentSchemaPrimitive,
|
|
9
9
|
* NodeProperty,
|
|
10
10
|
* NodeArrayProperty,
|
|
11
|
+
* NodeKind,
|
|
12
|
+
* NodeSchema,
|
|
13
|
+
* TextNodeSchema,
|
|
14
|
+
* NonTextNodeSchema,
|
|
11
15
|
* DocumentSchema,
|
|
12
16
|
* SerializedDocument
|
|
13
17
|
* } from './types.d.ts';
|
|
@@ -16,13 +20,11 @@
|
|
|
16
20
|
* Identity function — keeps schema at runtime & makes IDE infer types.
|
|
17
21
|
* Similar to your define_schema pattern but for document schemas.
|
|
18
22
|
*
|
|
19
|
-
* @template {Record<string,
|
|
23
|
+
* @template {Record<string, NodeSchema>} S
|
|
20
24
|
* @param {S} schema - The document schema to validate
|
|
21
25
|
* @returns {S} The same schema, but with type information preserved
|
|
22
26
|
*/
|
|
23
|
-
export function define_document_schema<S extends Record<string,
|
|
24
|
-
type: DocumentSchemaPrimitive;
|
|
25
|
-
}>>>(schema: S): S;
|
|
27
|
+
export function define_document_schema<S extends Record<string, NodeSchema>>(schema: S): S;
|
|
26
28
|
/**
|
|
27
29
|
* Check if a string represents a valid primitive type.
|
|
28
30
|
* @param {string} type - The type string to check
|
|
@@ -53,8 +55,6 @@ export default class Document {
|
|
|
53
55
|
selection?: Selection;
|
|
54
56
|
config?: any;
|
|
55
57
|
});
|
|
56
|
-
/** @type {Selection | undefined} */
|
|
57
|
-
selection: Selection | undefined;
|
|
58
58
|
config: any;
|
|
59
59
|
document_id: any;
|
|
60
60
|
nodes: any;
|
|
@@ -63,9 +63,32 @@ export default class Document {
|
|
|
63
63
|
can_undo: boolean;
|
|
64
64
|
can_redo: boolean;
|
|
65
65
|
selected_node: any;
|
|
66
|
+
layout_node: any;
|
|
67
|
+
available_annotation_types: any;
|
|
68
|
+
/**
|
|
69
|
+
* Sets the selection with validation
|
|
70
|
+
* @param {Selection | undefined} value - The new selection
|
|
71
|
+
* @throws {Error} Throws if the selection is invalid
|
|
72
|
+
*/
|
|
73
|
+
set selection(value: Selection | undefined);
|
|
74
|
+
/**
|
|
75
|
+
* Gets the current selection
|
|
76
|
+
* @returns {Selection | undefined}
|
|
77
|
+
*/
|
|
78
|
+
get selection(): Selection | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Validates that a selection is within bounds and refers to valid paths.
|
|
81
|
+
*
|
|
82
|
+
* @param {Selection} selection - The selection to validate
|
|
83
|
+
* @throws {Error} Throws if the selection is invalid
|
|
84
|
+
* @private
|
|
85
|
+
*/
|
|
86
|
+
private _validate_selection;
|
|
66
87
|
schema: DocumentSchema;
|
|
67
88
|
generate_id(): any;
|
|
89
|
+
get_available_annotation_types(): any;
|
|
68
90
|
get_selected_node(): any;
|
|
91
|
+
get_layout_node(): any;
|
|
69
92
|
_apply_op(op: any): void;
|
|
70
93
|
/**
|
|
71
94
|
* Validate a node against the document schema.
|
|
@@ -104,8 +127,8 @@ export default class Document {
|
|
|
104
127
|
* doc.get(['page_1', 'body', 3, 'list_items', 0]) // => { type: 'list_item', id: 'list_item_1', ... }
|
|
105
128
|
*
|
|
106
129
|
* @example
|
|
107
|
-
* // Get an annotated
|
|
108
|
-
* doc.get(['page_1', 'cover', 'title']) // =>
|
|
130
|
+
* // Get an annotated text property
|
|
131
|
+
* doc.get(['page_1', 'cover', 'title']) // => {text: 'Hello world', annotations: []}
|
|
109
132
|
*/
|
|
110
133
|
get(path: DocumentPath | string): any;
|
|
111
134
|
/**
|
|
@@ -139,12 +162,12 @@ export default class Document {
|
|
|
139
162
|
[key: string]: any;
|
|
140
163
|
};
|
|
141
164
|
/**
|
|
142
|
-
* Determines the kind of a node ('
|
|
143
|
-
*
|
|
165
|
+
* Determines the kind of a node ('block' for structured blocks, 'text' for pure
|
|
166
|
+
* text nodes or 'annotation' for annotation nodes.
|
|
144
167
|
* @param {any} node
|
|
145
|
-
* @returns {
|
|
168
|
+
* @returns {NodeKind}
|
|
146
169
|
*/
|
|
147
|
-
kind(node: any):
|
|
170
|
+
kind(node: any): NodeKind;
|
|
148
171
|
/**
|
|
149
172
|
* Returns the annotation object that is currently "under the cursor".
|
|
150
173
|
* NOTE: Annotations in Svedit are exclusive, so there can only be one active_annotation
|
|
@@ -155,8 +178,6 @@ export default class Document {
|
|
|
155
178
|
active_annotation(annotation_type: string): Annotation | null;
|
|
156
179
|
get_selected_plain_text(): string;
|
|
157
180
|
get_selected_nodes(): any;
|
|
158
|
-
move_node_cursor(direction: any): void;
|
|
159
|
-
expand_node_selection(direction: any): void;
|
|
160
181
|
select_parent(): void;
|
|
161
182
|
get_selection_range(): {
|
|
162
183
|
start: number;
|
|
@@ -169,15 +190,16 @@ export default class Document {
|
|
|
169
190
|
* @returns {SerializedDocument} The serialized document array
|
|
170
191
|
*/
|
|
171
192
|
to_json(): SerializedDocument;
|
|
172
|
-
property_type(type: any, property: any): "string" | "number" | "boolean" | "node" | "node_array" | "integer" | "datetime" | "string_array" | "number_array" | "boolean_array" | "integer_array"
|
|
193
|
+
property_type(type: any, property: any): "string" | "number" | "boolean" | "node" | "node_array" | "annotated_text" | "integer" | "datetime" | "string_array" | "number_array" | "boolean_array" | "integer_array";
|
|
173
194
|
count_references(node_id: any): number;
|
|
174
195
|
/**
|
|
175
196
|
* @param {NodeId} node_id
|
|
176
197
|
* @returns {NodeId[]}
|
|
177
198
|
*/
|
|
178
199
|
get_referenced_nodes(node_id: NodeId): NodeId[];
|
|
200
|
+
#private;
|
|
179
201
|
}
|
|
180
|
-
import type {
|
|
202
|
+
import type { NodeSchema } from './types.d.ts';
|
|
181
203
|
import type { PrimitiveType } from './types.d.ts';
|
|
182
204
|
import type { NodeProperty } from './types.d.ts';
|
|
183
205
|
import type { NodeArrayProperty } from './types.d.ts';
|
|
@@ -185,6 +207,7 @@ import type { DocumentSchema } from './types.d.ts';
|
|
|
185
207
|
import type { Selection } from './types.d.ts';
|
|
186
208
|
import Transaction from './Transaction.svelte.js';
|
|
187
209
|
import type { DocumentPath } from './types.d.ts';
|
|
210
|
+
import type { NodeKind } from './types.d.ts';
|
|
188
211
|
import type { Annotation } from './types.d.ts';
|
|
189
212
|
import type { SerializedDocument } from './types.d.ts';
|
|
190
213
|
import type { NodeId } from './types.d.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Document.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Document.svelte.js"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"Document.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Document.svelte.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;;;GAOG;AACH,uCAJ0C,CAAC,SAA7B,MAAM,CAAC,MAAM,EAAE,UAAU,CAAE,UAC9B,CAAC,GACC,CAAC,CAIb;AAED;;;;GAIG;AACH,wCAHW,MAAM,GACJ,IAAI,IAAI,aAAa,CAQjC;AAED;;;;GAIG;AACH,2DAHW,YAAY,GAAG,iBAAiB,GAC9B,MAAM,GAAG,IAAI,CASzB;AAED;;;;GAIG;AACH,0DAHW,cAAc,QAexB;AAuGD;IAgGE;;;;;;OAMG;IACH,oBANW,cAAc,kBACd,kBAAkB,0BAE1B;QAA4B,SAAS,GAA7B,SAAS;QACK,MAAM,GAApB,GAAG;KACb,EAqBA;IAxHD,YAAkB;IAClB,iBAAuB;IACvB,WAAiB;IACjB,eAAqB;IACrB,sBAA2B;IAG3B,kBAA6C;IAC7C,kBAAkE;IAGnE,mBAAmD;IACnD,iBAA+C;IAC/C,gCAA6E;IAU5E;;;;OAIG;IACH,qBAHW,SAAS,GAAG,SAAS,EAQ/B;IAlBD;;;OAGG;IACH,iBAFa,SAAS,GAAG,SAAS,CAIjC;IAcD;;;;;;OAMG;IACH,4BAiDC;IAaC,uBAAoB;IAkBtB,mBAMC;IAED,sCAKA;IAGD,yBAkBC;IAID,uBAoBC;IAGA,yBAWC;IAED;;;;OAIG;IACH,oBAHW,GAAG,QAKb;IAED;;;;OAIG;IACH,UAFa,WAAW,CASvB;IAED;;;;OAIG;IACH,mBAFW,WAAW,QAkBrB;IAED,aAWC;IAED,aAaC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,UAlBW,YAAY,GAAC,MAAM,GACjB,GAAG,CAoFf;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,cAHW,YAAY,GACV;QAAC,IAAI,EAAE,UAAU,GAAC,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAC,CAuBzD;IAED;;;;;OAKG;IACH,WAHW,GAAG,GACD,QAAQ,CAIpB;IAED;;;;;;OAMG;IACH,mCAHW,MAAM,GACJ,UAAU,GAAC,IAAI,CAqB3B;IAGD,kCAOC;IAED,0BAOC;IAED,sBAmCC;IAED;;;;MAaC;IAKD,8BAgCC;IAED;;;OAGG;IACH,WAFa,kBAAkB,CAI9B;IAID,mNAWC;IAGD,uCAkBC;IAGD;;;OAGG;IACH,8BAHW,MAAM,GACJ,MAAM,EAAE,CASpB;;CACF;gCAxwBS,cAAc;mCAAd,cAAc;kCAAd,cAAc;uCAAd,cAAc;oCAAd,cAAc;+BAAd,cAAc;wBAnBA,yBAAyB;kCAmBvC,cAAc;8BAAd,cAAc;gCAAd,cAAc;wCAAd,cAAc;4BAAd,cAAc"}
|