@quenk/wml 2.13.11 → 2.14.1
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/lib/cli.d.ts +8 -8
- package/lib/cli.js +1 -3
- package/lib/cli.js.map +1 -1
- package/lib/cli.ts +48 -60
- package/lib/compile/codegen.d.ts +4 -9
- package/lib/compile/codegen.js +161 -367
- package/lib/compile/codegen.js.map +1 -1
- package/lib/compile/codegen.ts +643 -952
- package/lib/compile/index.d.ts +2 -2
- package/lib/compile/index.js +4 -4
- package/lib/compile/index.js.map +1 -1
- package/lib/compile/index.ts +14 -17
- package/lib/compile/transform.d.ts +1 -1
- package/lib/compile/transform.js +9 -11
- package/lib/compile/transform.js.map +1 -1
- package/lib/compile/transform.ts +136 -143
- package/lib/{dom.d.ts → dom/index.d.ts} +8 -2
- package/lib/{dom.js → dom/index.js} +84 -70
- package/lib/dom/index.js.map +1 -0
- package/lib/dom/index.ts +425 -0
- package/lib/dom/monitor.d.ts +33 -0
- package/lib/dom/monitor.js +60 -0
- package/lib/dom/monitor.js.map +1 -0
- package/lib/dom/monitor.ts +75 -0
- package/lib/index.d.ts +10 -95
- package/lib/index.js +10 -10
- package/lib/index.js.map +1 -1
- package/lib/index.ts +57 -182
- package/lib/main.js +17 -17
- package/lib/main.js.map +1 -1
- package/lib/main.ts +38 -44
- package/lib/parse/ast.d.ts +2 -2
- package/lib/parse/ast.js +52 -53
- package/lib/parse/ast.js.map +1 -1
- package/lib/parse/ast.ts +396 -483
- package/lib/parse/generated.d.ts +3 -5
- package/lib/parse/generated.js +9504 -9264
- package/lib/parse/index.d.ts +2 -3
- package/lib/parse/index.js.map +1 -1
- package/lib/parse/index.ts +7 -9
- package/lib/parse/test.js +194 -192
- package/lib/parse/test.js.map +1 -1
- package/lib/parse/test.ts +294 -404
- package/lib/parse/wml.y +4 -0
- package/lib/tsconfig.json +19 -20
- package/lib/util.d.ts +10 -0
- package/lib/util.js +21 -0
- package/lib/util.js.map +1 -0
- package/lib/util.ts +39 -0
- package/lib/view/frame.d.ts +127 -0
- package/lib/view/frame.js +214 -0
- package/lib/view/frame.js.map +1 -0
- package/lib/view/frame.ts +295 -0
- package/lib/view/index.d.ts +58 -0
- package/lib/view/index.js +48 -0
- package/lib/view/index.js.map +1 -0
- package/lib/view/index.ts +98 -0
- package/package.json +3 -3
- package/lib/dom.js.map +0 -1
- package/lib/dom.ts +0 -479
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import * as dom from "../dom";
|
|
2
|
+
|
|
3
|
+
import { Maybe } from "@quenk/noni/lib/data/maybe";
|
|
4
|
+
|
|
5
|
+
import { DOMMonitor } from "../dom/monitor";
|
|
6
|
+
import { Attrs, Content, WMLId, Widget } from "..";
|
|
7
|
+
import { View } from ".";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Index used for lists and other data structures.
|
|
11
|
+
*
|
|
12
|
+
* TODO: migrate to noni.
|
|
13
|
+
*/
|
|
14
|
+
export type Index = number;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Entry contains the DOM node and optional widget for an WMLElement.
|
|
18
|
+
*/
|
|
19
|
+
export interface Entry {
|
|
20
|
+
node: Content;
|
|
21
|
+
widget?: Widget;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* SetList is a list like data structure that ensures an object is only added
|
|
26
|
+
* once.
|
|
27
|
+
*
|
|
28
|
+
* This allows for items to be added and their index returned without having
|
|
29
|
+
* to iterate over the members to determine if the item was added already.
|
|
30
|
+
*
|
|
31
|
+
* Instead a map of item -> index values is kept internally allowing for fast
|
|
32
|
+
* lookup of new items being added.
|
|
33
|
+
*
|
|
34
|
+
* TODO:
|
|
35
|
+
* 1. Migrate to noni.
|
|
36
|
+
* 2. Find a way to support nested objects, example: {node, widget}
|
|
37
|
+
*/
|
|
38
|
+
class SetList {
|
|
39
|
+
constructor(
|
|
40
|
+
public items: Content[] = [],
|
|
41
|
+
public cache: Map<Content, Index> = new Map(),
|
|
42
|
+
) {}
|
|
43
|
+
|
|
44
|
+
add(item: Content) {
|
|
45
|
+
let idx = this.cache.get(item) ?? this.items.push(item) - 1;
|
|
46
|
+
this.cache.set(item, idx);
|
|
47
|
+
return idx;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
set(id: Index, item: Content) {
|
|
51
|
+
let prev = this.items[id];
|
|
52
|
+
this.items[id] = item;
|
|
53
|
+
this.cache.delete(prev);
|
|
54
|
+
this.cache.set(item, id);
|
|
55
|
+
return id;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
has(id: Index) {
|
|
59
|
+
return Boolean(this.get(id));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get(id: Index) {
|
|
63
|
+
return this.items[id];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
delete(idx: Index) {
|
|
67
|
+
let node = this.items[idx];
|
|
68
|
+
this.items.splice(idx, 1);
|
|
69
|
+
this.cache.delete(node);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Frame serves as a container for the DOM elements a View's template
|
|
75
|
+
* renders.
|
|
76
|
+
*
|
|
77
|
+
* Each time the render() method is called a new Frame is created and passed
|
|
78
|
+
* to the rendering logic so that a DOM tree is built along with accesible
|
|
79
|
+
* wml ids and groups.
|
|
80
|
+
*/
|
|
81
|
+
export interface Frame {
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* root sets the root element of a View's tree.
|
|
85
|
+
*/
|
|
86
|
+
root(el: Content) : void
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* node constructs a DOM node to be used in the View's tree.
|
|
90
|
+
*
|
|
91
|
+
* Any id or group assignment will be honored.
|
|
92
|
+
*/
|
|
93
|
+
node(tag: string, attrs: Attrs, children: Content[]): Content
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* widget constructs a DOM sub-tree for a Widget in the View's tree.
|
|
97
|
+
*
|
|
98
|
+
* Any id or group assignment will be honored.
|
|
99
|
+
*/
|
|
100
|
+
widget(w: Widget, attrs: Attrs): Content
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* view renders the content of another view, saving its ids and groups to
|
|
104
|
+
* this one.
|
|
105
|
+
*/
|
|
106
|
+
view(view: View): Content
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* MultiFrame is a composite that allows more than one Frame to be rendered
|
|
111
|
+
* at the same time.
|
|
112
|
+
*/
|
|
113
|
+
export class MultiFrame implements Frame {
|
|
114
|
+
constructor(public frames: Frame[] = []) {}
|
|
115
|
+
|
|
116
|
+
root(el: Content) {
|
|
117
|
+
for (let f of this.frames) {
|
|
118
|
+
f.root(el);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
node(tag: string, attrs: Attrs, children: Content[]): Content {
|
|
123
|
+
let results = this.frames.map((f) => f.node(tag, attrs, children));
|
|
124
|
+
return results[0] ?? dom.createElement('div', {}, []);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
widget(w: Widget, attrs: Attrs): Content {
|
|
128
|
+
let results = this.frames.map((f) => f.widget(w, attrs));
|
|
129
|
+
return results[0] ?? dom.createElement('div', {}, []);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
view(view: View): Content {
|
|
133
|
+
let results = this.frames.map((f) => f.view(view));
|
|
134
|
+
return results[0] ?? dom.createElement('div', {}, []);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* ViewFrame contains helper methods for retreiving elements by id or
|
|
140
|
+
* group freeing the View class of such logic.
|
|
141
|
+
*/
|
|
142
|
+
export class ViewFrame implements Frame {
|
|
143
|
+
constructor(
|
|
144
|
+
public nodes = new SetList(),
|
|
145
|
+
public widgets = new Map<Index, Widget>(),
|
|
146
|
+
public groups: Map<WMLId, Index[]> = new Map(),
|
|
147
|
+
public ids = new Map<WMLId, Index>(),
|
|
148
|
+
public indexes = new Map<Index, WMLId>(),
|
|
149
|
+
public tree?: Content,
|
|
150
|
+
) {}
|
|
151
|
+
|
|
152
|
+
_register(id: WMLId, node: Content, widget?: Widget) {
|
|
153
|
+
let idx = this.nodes.add(node);
|
|
154
|
+
this.ids.set(id, idx);
|
|
155
|
+
this.indexes.set(idx, id);
|
|
156
|
+
if (widget) {
|
|
157
|
+
this.widgets.set(idx, widget);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
_registerGroupMember(id: WMLId, node: Content, widget?: Widget) {
|
|
162
|
+
let group = this.groups.get(id) ?? [];
|
|
163
|
+
let idx = this.nodes.add(node);
|
|
164
|
+
group.push(idx);
|
|
165
|
+
|
|
166
|
+
if (widget) this.widgets.set(idx, widget);
|
|
167
|
+
|
|
168
|
+
this.groups.set(id, group);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
root(el: Content) {
|
|
172
|
+
this.tree = el;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
node(tag: string, attrs: Attrs, children: Content[]): Content {
|
|
176
|
+
let elm = dom.createElement(
|
|
177
|
+
tag,
|
|
178
|
+
<dom.WMLDOMAttrs>attrs,
|
|
179
|
+
children,
|
|
180
|
+
(attrs.wml && attrs.wml.ns) || "",
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
if (attrs?.wml?.id) this._register(attrs.wml.id, elm);
|
|
184
|
+
|
|
185
|
+
if (attrs?.wml?.group) this._registerGroupMember(attrs.wml.group, elm);
|
|
186
|
+
|
|
187
|
+
return elm;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
widget(w: Widget, attrs: Attrs): Content {
|
|
191
|
+
let tree = w.render();
|
|
192
|
+
|
|
193
|
+
DOMMonitor.getInstance().monitor(tree, w);
|
|
194
|
+
|
|
195
|
+
if (attrs?.wml?.id) this._register(attrs.wml.id, tree, w);
|
|
196
|
+
|
|
197
|
+
if (attrs?.wml?.group) this._registerGroupMember(attrs.wml.group, tree, w);
|
|
198
|
+
|
|
199
|
+
return tree;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
view(view: View): Content {
|
|
203
|
+
let { root } = this;
|
|
204
|
+
let tree = view.render(this);
|
|
205
|
+
this.root = root;
|
|
206
|
+
return tree;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* findById returns the entry stored for the specified wml element.
|
|
211
|
+
*/
|
|
212
|
+
findById(id: WMLId): Maybe<Entry> {
|
|
213
|
+
let idx = this.ids.get(id) ?? -1;
|
|
214
|
+
let node = this.nodes.get(idx);
|
|
215
|
+
if (node == null) return Maybe.nothing();
|
|
216
|
+
return Maybe.just({
|
|
217
|
+
node,
|
|
218
|
+
widget: this.widgets.get(idx),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* findByGroup returns all the entries stored fro a group.
|
|
224
|
+
*/
|
|
225
|
+
findByGroup(id: WMLId): Entry[] {
|
|
226
|
+
let result = [];
|
|
227
|
+
for (let idx of this.groups.get(id) ?? []) {
|
|
228
|
+
let node = this.nodes.get(idx);
|
|
229
|
+
let widget = this.widgets.get(idx);
|
|
230
|
+
if (node == null) continue;
|
|
231
|
+
result.push({ node, widget });
|
|
232
|
+
}
|
|
233
|
+
return result;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* replaceByIndex performs the heavy work of replacing a WMLElement
|
|
238
|
+
* with the corresponding index from another ViewFrame.
|
|
239
|
+
*
|
|
240
|
+
* The replaced element will have its DOM content redrawn if a parentNode
|
|
241
|
+
* is detected.
|
|
242
|
+
*/
|
|
243
|
+
replaceByIndex(next: ViewFrame, idx: Index) {
|
|
244
|
+
let originalNode = this.nodes.get(idx);
|
|
245
|
+
let id = this.indexes.get(idx) ?? "";
|
|
246
|
+
|
|
247
|
+
if (idx == null || originalNode == null) {
|
|
248
|
+
console.warn(`Not replacing missing WMLElement for id "${id}"!`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
let { parentNode } = originalNode;
|
|
253
|
+
|
|
254
|
+
let node = next.nodes.get(idx);
|
|
255
|
+
let widget = next.widgets.get(idx);
|
|
256
|
+
if (node == null) {
|
|
257
|
+
// Remove references since the node no longer exists.
|
|
258
|
+
this.nodes.delete(idx);
|
|
259
|
+
this.widgets.delete(idx);
|
|
260
|
+
this.ids.delete(id);
|
|
261
|
+
this.indexes.delete(idx);
|
|
262
|
+
if (parentNode) parentNode.removeChild(originalNode);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
this.nodes.set(idx, node);
|
|
267
|
+
this.widgets.delete(idx);
|
|
268
|
+
|
|
269
|
+
if (widget) this.widgets.set(idx, widget);
|
|
270
|
+
|
|
271
|
+
if (parentNode) parentNode.replaceChild(node, originalNode);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* replaceById allows WMLElement replacement by using an id.
|
|
276
|
+
*/
|
|
277
|
+
replaceById(next: ViewFrame, id: WMLId) {
|
|
278
|
+
this.replaceByIndex(next, this.ids.get(id) ?? -1);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* replaceByGroup allows WMLElement replaced by using a group identifier.
|
|
283
|
+
*/
|
|
284
|
+
replaceByGroup(next: ViewFrame, id: WMLId) {
|
|
285
|
+
let group = this.groups.get(id) ?? [];
|
|
286
|
+
|
|
287
|
+
let newGroup = [];
|
|
288
|
+
for (let idx of group) {
|
|
289
|
+
this.replaceByIndex(next, idx);
|
|
290
|
+
if (this.nodes.has(idx)) newGroup.push(idx);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
this.groups.set(id, newGroup);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Maybe } from "@quenk/noni/lib/data/maybe";
|
|
2
|
+
import { Content, WMLElement, WMLId } from "..";
|
|
3
|
+
import { Frame, ViewFrame } from "./frame";
|
|
4
|
+
/**
|
|
5
|
+
* Renderer is a function that builds up a ViewFrame on behalf of the view.
|
|
6
|
+
*/
|
|
7
|
+
export type Renderer = (frame: Frame) => void;
|
|
8
|
+
/**
|
|
9
|
+
* View instances are compiled from wml template files.
|
|
10
|
+
*
|
|
11
|
+
* They provide an api for rendering user interfaces and
|
|
12
|
+
* querying individual objects(WMLElement) it is made of.
|
|
13
|
+
*/
|
|
14
|
+
export interface View {
|
|
15
|
+
/**
|
|
16
|
+
* render the View.
|
|
17
|
+
*
|
|
18
|
+
* If a ViewFrame is provided, it will be used instead of creating a new one
|
|
19
|
+
* internally. In this case the View itself will not be mutated internally.
|
|
20
|
+
*/
|
|
21
|
+
render(frame?: ViewFrame): Content;
|
|
22
|
+
/**
|
|
23
|
+
* invalidate this View causing the DOM to be re-rendered.
|
|
24
|
+
*
|
|
25
|
+
* Re-rendering is done by finding the parentNode of the root of the View's
|
|
26
|
+
* content and replacing it with a new version. If an id or a group prefixed
|
|
27
|
+
* by '$' is passed, then only the corresponding content is invalidated.
|
|
28
|
+
*
|
|
29
|
+
* It is an error to invaldiate a View that has not yet been added to the DOM.
|
|
30
|
+
*/
|
|
31
|
+
invalidate(target?: WMLId): void;
|
|
32
|
+
/**
|
|
33
|
+
* findById retrives a WMLElement that has been assigned a `wml:id`
|
|
34
|
+
* attribute matching id.
|
|
35
|
+
*/
|
|
36
|
+
findById<E extends WMLElement>(id: string): Maybe<E>;
|
|
37
|
+
/**
|
|
38
|
+
* findGroupById retrives an array of WMLElements that have a `wml:group`
|
|
39
|
+
* attribute matching name.
|
|
40
|
+
*/
|
|
41
|
+
findGroupById<E extends WMLElement>(name: string): E[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* BaseView used by generated view code.
|
|
45
|
+
*
|
|
46
|
+
* Previously logic was generated by the compiler but now the compiler
|
|
47
|
+
* generates classes that extend this one.
|
|
48
|
+
*/
|
|
49
|
+
export declare class BaseView implements View {
|
|
50
|
+
context: object;
|
|
51
|
+
renderer: Renderer;
|
|
52
|
+
frame: ViewFrame;
|
|
53
|
+
constructor(context: object, renderer: Renderer, frame?: ViewFrame);
|
|
54
|
+
findById<E extends WMLElement>(id: string): Maybe<E>;
|
|
55
|
+
findGroupById<E extends WMLElement>(name: string): E[];
|
|
56
|
+
invalidate(id?: WMLId): void;
|
|
57
|
+
render(frame?: Frame): Content;
|
|
58
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseView = void 0;
|
|
4
|
+
const frame_1 = require("./frame");
|
|
5
|
+
/**
|
|
6
|
+
* BaseView used by generated view code.
|
|
7
|
+
*
|
|
8
|
+
* Previously logic was generated by the compiler but now the compiler
|
|
9
|
+
* generates classes that extend this one.
|
|
10
|
+
*/
|
|
11
|
+
class BaseView {
|
|
12
|
+
constructor(context, renderer, frame = new frame_1.ViewFrame()) {
|
|
13
|
+
this.context = context;
|
|
14
|
+
this.renderer = renderer;
|
|
15
|
+
this.frame = frame;
|
|
16
|
+
}
|
|
17
|
+
findById(id) {
|
|
18
|
+
return this.frame
|
|
19
|
+
.findById(id)
|
|
20
|
+
.map((ent) => (ent.widget ?? ent.node));
|
|
21
|
+
}
|
|
22
|
+
findGroupById(name) {
|
|
23
|
+
return (this.frame.findByGroup(name).map((entry) => entry.widget ?? entry.node));
|
|
24
|
+
}
|
|
25
|
+
invalidate(id) {
|
|
26
|
+
let { frame } = this;
|
|
27
|
+
if (frame.tree == null || frame.tree.parentNode == null)
|
|
28
|
+
return console.warn("invalidate(): cannot invalidate this view, it has no parent node!");
|
|
29
|
+
if (id) {
|
|
30
|
+
let next = new frame_1.ViewFrame();
|
|
31
|
+
this.renderer(next);
|
|
32
|
+
if (id[0] === "$")
|
|
33
|
+
frame.replaceByGroup(next, id.slice(1));
|
|
34
|
+
else
|
|
35
|
+
frame.replaceById(next, id);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
frame.tree.parentNode.replaceChild(this.render(), frame.tree);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
render(frame) {
|
|
42
|
+
this.frame = new frame_1.ViewFrame();
|
|
43
|
+
this.renderer(frame ? new frame_1.MultiFrame([this.frame, frame]) : this.frame);
|
|
44
|
+
return this.frame.tree;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.BaseView = BaseView;
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAGA,mCAA8D;AA8C9D;;;;;GAKG;AACH,MAAa,QAAQ;IACnB,YACS,OAAe,EACf,QAAkB,EAClB,QAAQ,IAAI,iBAAS,EAAE;QAFvB,YAAO,GAAP,OAAO,CAAQ;QACf,aAAQ,GAAR,QAAQ,CAAU;QAClB,UAAK,GAAL,KAAK,CAAkB;IAC7B,CAAC;IAEJ,QAAQ,CAAuB,EAAU;QACvC,OAAO,IAAI,CAAC,KAAK;aACd,QAAQ,CAAC,EAAE,CAAC;aACZ,GAAG,CAAC,CAAC,GAAU,EAAE,EAAE,CAAI,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,aAAa,CAAuB,IAAY;QAC9C,OAAY,CACV,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CACxE,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,EAAU;QACnB,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QAErB,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI;YACrD,OAAO,OAAO,CAAC,IAAI,CACjB,mEAAmE,CACpE,CAAC;QAEJ,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,IAAI,GAAG,IAAI,iBAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG;gBAAE,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;;gBACtD,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAa;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,iBAAS,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,kBAAU,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxE,OAAgB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IAClC,CAAC;CACF;AA1CD,4BA0CC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Maybe } from "@quenk/noni/lib/data/maybe";
|
|
2
|
+
|
|
3
|
+
import { Content, WMLElement, WMLId } from "..";
|
|
4
|
+
import { Entry, Frame, MultiFrame, ViewFrame } from "./frame";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Renderer is a function that builds up a ViewFrame on behalf of the view.
|
|
8
|
+
*/
|
|
9
|
+
export type Renderer = (frame: Frame) => void;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* View instances are compiled from wml template files.
|
|
13
|
+
*
|
|
14
|
+
* They provide an api for rendering user interfaces and
|
|
15
|
+
* querying individual objects(WMLElement) it is made of.
|
|
16
|
+
*/
|
|
17
|
+
export interface View {
|
|
18
|
+
/**
|
|
19
|
+
* render the View.
|
|
20
|
+
*
|
|
21
|
+
* If a ViewFrame is provided, it will be used instead of creating a new one
|
|
22
|
+
* internally. In this case the View itself will not be mutated internally.
|
|
23
|
+
*/
|
|
24
|
+
render(frame?: ViewFrame): Content;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* invalidate this View causing the DOM to be re-rendered.
|
|
28
|
+
*
|
|
29
|
+
* Re-rendering is done by finding the parentNode of the root of the View's
|
|
30
|
+
* content and replacing it with a new version. If an id or a group prefixed
|
|
31
|
+
* by '$' is passed, then only the corresponding content is invalidated.
|
|
32
|
+
*
|
|
33
|
+
* It is an error to invaldiate a View that has not yet been added to the DOM.
|
|
34
|
+
*/
|
|
35
|
+
invalidate(target?: WMLId): void;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* findById retrives a WMLElement that has been assigned a `wml:id`
|
|
39
|
+
* attribute matching id.
|
|
40
|
+
*/
|
|
41
|
+
findById<E extends WMLElement>(id: string): Maybe<E>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* findGroupById retrives an array of WMLElements that have a `wml:group`
|
|
45
|
+
* attribute matching name.
|
|
46
|
+
*/
|
|
47
|
+
findGroupById<E extends WMLElement>(name: string): E[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* BaseView used by generated view code.
|
|
52
|
+
*
|
|
53
|
+
* Previously logic was generated by the compiler but now the compiler
|
|
54
|
+
* generates classes that extend this one.
|
|
55
|
+
*/
|
|
56
|
+
export class BaseView implements View {
|
|
57
|
+
constructor(
|
|
58
|
+
public context: object,
|
|
59
|
+
public renderer: Renderer,
|
|
60
|
+
public frame = new ViewFrame(),
|
|
61
|
+
) {}
|
|
62
|
+
|
|
63
|
+
findById<E extends WMLElement>(id: string): Maybe<E> {
|
|
64
|
+
return this.frame
|
|
65
|
+
.findById(id)
|
|
66
|
+
.map((ent: Entry) => <E>(ent.widget ?? ent.node));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
findGroupById<E extends WMLElement>(name: string): E[] {
|
|
70
|
+
return <E[]>(
|
|
71
|
+
this.frame.findByGroup(name).map((entry) => entry.widget ?? entry.node)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
invalidate(id?: WMLId): void {
|
|
76
|
+
let { frame } = this;
|
|
77
|
+
|
|
78
|
+
if (frame.tree == null || frame.tree.parentNode == null)
|
|
79
|
+
return console.warn(
|
|
80
|
+
"invalidate(): cannot invalidate this view, it has no parent node!",
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (id) {
|
|
84
|
+
let next = new ViewFrame();
|
|
85
|
+
this.renderer(next);
|
|
86
|
+
if (id[0] === "$") frame.replaceByGroup(next, id.slice(1));
|
|
87
|
+
else frame.replaceById(next, id);
|
|
88
|
+
} else {
|
|
89
|
+
frame.tree.parentNode.replaceChild(this.render(), frame.tree);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
render(frame?: Frame): Content {
|
|
94
|
+
this.frame = new ViewFrame();
|
|
95
|
+
this.renderer(frame ? new MultiFrame([this.frame, frame]) : this.frame);
|
|
96
|
+
return <Content>this.frame.tree;
|
|
97
|
+
}
|
|
98
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenk/wml",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.1",
|
|
4
4
|
"description": "(WML) is a DSL for describing user interfaces in web applications.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
"@quenk/test": "^2.4.0",
|
|
20
20
|
"@types/docopt": "^0.6.31",
|
|
21
21
|
"@types/mocha": "^8.2.2",
|
|
22
|
-
"@types/node": "^
|
|
22
|
+
"@types/node": "^24.3.0",
|
|
23
23
|
"jison-gho": "^0.6.1-216",
|
|
24
24
|
"mocha": "^9.0.0",
|
|
25
25
|
"prettier": "^3.5.3",
|
|
26
26
|
"ts-node": "^10.5.0",
|
|
27
|
-
"typescript": "^5.
|
|
27
|
+
"typescript": "^5.9.2"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@quenk/noni": "^1.40.14",
|
package/lib/dom.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dom.js","sourceRoot":"","sources":["dom.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,wDAAqE;AACrE,oDAAuE;AAEvE,MAAM,OAAO,GAAG,iBAAiB,CAAC;AAElC,MAAM,YAAY,GAA8B;IAE5C,GAAG,EAAE,SAAS;IAEd,GAAG,EAAE,SAAS;IAEd,GAAG,EAAE,SAAS;IAEd,GAAG,EAAE,SAAS;IAEd,GAAG,EAAE,SAAS;IAEd,QAAQ,EAAE,SAAS;IAEnB,QAAQ,EAAE,SAAS;IAEnB,QAAQ,EAAE,SAAS;CAEtB,CAAA;AAED,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,IAAI,IAAA,cAAK,EAAC,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAE/E,MAAM,YAAY,GAA8B;IAE5C,GAAG,EAAE,QAAQ;IAEb,GAAG,EAAE,OAAO;IAEZ,IAAI,EAAE,QAAQ;IAEd,GAAG,EAAE,MAAM;IAEX,GAAG,EAAE,MAAM;CAEd,CAAA;AAED,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,IAAI,IAAA,cAAK,EAAC,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAEvF,MAAM,YAAY,GAAG;IACjB,MAAM;IACN,MAAM;IACN,IAAI;IACJ,KAAK;IACL,SAAS;IACT,OAAO;IACP,IAAI;IACJ,KAAK;IACL,OAAO;IACP,QAAQ;IACR,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,KAAK;CACR,CAAC;AAOF;;;GAGG;AACH,MAAa,WAAW;IAAxB;QAII,WAAM,GAAG,CAAC,CAAC;IAUf,CAAC;IARG,IAAI;QAEA,OAAyB,IAAI,CAAC;IAElC,CAAC;IAED,OAAO,KAAK,CAAC;CAEhB;AAdD,kCAcC;AAED;;;;;;GAMG;AACH,MAAa,UAAU;IAEnB,YAAmB,QAAgB,EAAS,QAAgB;QAAzC,aAAQ,GAAR,QAAQ,CAAQ;QAAS,aAAQ,GAAR,QAAQ,CAAQ;QAEnD,mBAAc,GAAG,CAAC,CAAC;QAEnB,uBAAkB,GAAG,CAAC,CAAC;QAEvB,iBAAY,GAAG,CAAC,CAAC;QAEjB,2BAAsB,GAAG,EAAE,CAAC;QAE5B,kBAAa,GAAG,CAAC,CAAC;QAElB,mCAA8B,GAAG,EAAE,CAAC;QAEpC,+BAA0B,GAAG,CAAC,CAAC;QAE/B,mCAA8B,GAAG,CAAC,CAAC;QAEnC,gCAA2B,GAAG,CAAC,CAAC;QAEhC,8CAAyC,GAAG,EAAE,CAAC;QAE/C,gCAA2B,GAAG,CAAC,CAAC;QAEhC,uBAAkB,GAAG,EAAE,CAAC;QAExB,iBAAY,GAAG,CAAC,CAAC;QAEjB,gBAAW,GAAG,CAAC,CAAC;QAEhB,0BAAqB,GAAG,CAAC,CAAC;QAE1B,kBAAa,GAAG,EAAE,CAAC;QAEnB,gCAA2B,GAAG,CAAC,CAAC;QAEhC,cAAS,GAAG,CAAC,CAAC;QAEvB,YAAO,GAAG,EAAE,CAAC;QAEb,eAAU,GAAG,IAAI,WAAW,EAAE,CAAC;QAE/B,eAAU,GAAG,IAAI,CAAC;QAElB,gBAAW,GAAG,KAAK,CAAC;QAEpB,cAAS,GAAG,IAAI,CAAC;QAEjB,iBAAY,GAAG,IAAI,CAAC;QAEpB,gBAAW,GAAG,IAAI,CAAC;QAEnB,cAAS,GAAG,IAAI,CAAC;QAEjB,kBAAa,GAAG,IAAI,CAAC;QAErB,kBAAa,GAAG,IAAI,CAAC;QAErB,eAAU,GAAG,IAAI,CAAC;QAElB,oBAAe,GAAG,IAAI,CAAC;IA5DyC,CAAC;IA8DjE,IAAI,WAAW;QAEX,OAAO,EAAE,CAAC;IAEd,CAAC;IAED,gBAAgB,KAAK,CAAC;IAEtB,aAAa;QAET,OAAO,KAAK,CAAC;IAEjB,CAAC;IAED,mBAAmB,KAAK,CAAC;IAEzB,WAAW,CAAiB,QAAW;QAEnC,OAAO,QAAQ,CAAC;IAEpB,CAAC;IAED,SAAS;QAEL,OAAO,IAAI,CAAC;IAEhB,CAAC;IAED,uBAAuB;QAEnB,OAAO,CAAC,CAAC;IAEb,CAAC;IAED,QAAQ;QAEJ,OAAO,KAAK,CAAC;IAEjB,CAAC;IAED,WAAW;QAEP,OAAO,IAAI,CAAC;IAEhB,CAAC;IAED,aAAa;QAET,OAAO,KAAK,CAAC;IAEjB,CAAC;IAED,YAAY,CAAiB,QAAW;QAEpC,OAAO,QAAQ,CAAC;IAEpB,CAAC;IAED,kBAAkB;QAEd,OAAO,KAAK,CAAC;IAEjB,CAAC;IAED,WAAW;QAEP,OAAO,KAAK,CAAC;IAEjB,CAAC;IAED,UAAU;QAEN,OAAO,KAAK,CAAC;IAEjB,CAAC;IAED,kBAAkB;QAEd,OAAO,IAAI,CAAC;IAEhB,CAAC;IAED,YAAY;QAER,OAAO,IAAI,CAAC;IAEhB,CAAC;IAED,SAAS,KAAK,CAAC;IAEf,MAAM,KAAK,CAAC;IAEZ,MAAM,KAAK,CAAC;IAEZ,KAAK,KAAK,CAAC;IAEX,WAAW,KAAK,CAAC;IAEjB,WAAW,CAAiB,QAAW;QAEnC,OAAO,QAAQ,CAAC;IAEpB,CAAC;IAED,YAAY,CAAiB,CAAO,EAAE,QAAW;QAE7C,OAAO,QAAQ,CAAC;IAEpB,CAAC;CAEJ;AA9KD,gCA8KC;AAED;;;GAGG;AACH,MAAa,UAAW,SAAQ,UAAU;IAEtC,YAAmB,KAAa,EAAS,SAAS,IAAI;QAElD,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAFJ,UAAK,GAAL,KAAK,CAAQ;QAAS,WAAM,GAAN,MAAM,CAAO;IAItD,CAAC;IAED,IAAI,WAAW;QAEX,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,kBAAU,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IAE7D,CAAC;CAEJ;AAdD,gCAcC;AAED;;;GAGG;AACH,MAAa,aAAc,SAAQ,UAAU;IAEzC,YACW,GAAW,EACX,KAAkB,EAClB,WAAmB,EAAE;QAAI,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QAFxC,QAAG,GAAH,GAAG,CAAQ;QACX,UAAK,GAAL,KAAK,CAAa;QAClB,aAAQ,GAAR,QAAQ,CAAa;IAAoB,CAAC;IAErD,IAAI,SAAS;QAET,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC;YAC7C,CAAE,CAAC,WAAW,CAAC,CAAC;YACT,CAAE,CAAC,SAAS,CAC7B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,CAAC;IAED,IAAI,SAAS;QAET,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACnB,IAAI,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;QAE7B,IAAI,KAAK,GAAG,IAAA,cAAK,EAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAE1C,IAAI,IAAA,eAAQ,EAAC,KAAK,CAAC,IAAI,CAAC,KAAK,YAAY,UAAU,CAAC;gBAChD,OAAO,GAAG,IAAI,KAAK,KAAK,CAAC,WAAW,GAAG,CAAC;iBACvC,IAAI,IAAA,iBAAU,EAAC,KAAK,CAAC,IAAI,IAAA,eAAQ,EAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;gBAC5D,OAAO,EAAE,CAAC;;gBAEV,OAAO,GAAG,IAAI,KAAK,IAAA,uBAAe,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAA;QAE5D,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEb,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAEhD,IAAI,IAAI,GAAG,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC;QAE9B,IAAI,GAAG,KAAK,MAAM;YACd,IAAI,GAAG,GAAG,OAAO,GAAG,IAAI,EAAE,CAAA;QAE9B,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,OAAO,KAAK,GAAG,GAAG,CAAC;IAE5C,CAAC;IAED,YAAY,CAAC,GAAW,EAAE,KAAW;QAEjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAE5B,CAAC;IAED,WAAW,CAAiB,QAAW;QAEnC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,QAAQ,CAAC;IAEpB,CAAC;CAEJ;AAzDD,sCAyDC;AAED;;GAEG;AACU,QAAA,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC;AAEjG;;GAEG;AACI,MAAM,eAAe,GAAG,CAAC,KAAa,EAAE,EAAE,CAC7C,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;AAD9C,QAAA,eAAe,mBAC+B;AAE3D;;GAEG;AACI,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,EAAE,CACxC,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;AAD7C,QAAA,UAAU,cACmC;AAE1D;;GAEG;AACI,MAAM,cAAc,GAAG,CAAC,GAAS,EAAQ,EAAE;IAC9C,IAAI,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3C,OAAO,iBAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC1E,CAAC,CAAA;AAHY,QAAA,cAAc,kBAG1B;AAkB0B,eArBd,sBAAc,CAqBI;AAhB/B;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,GAAS,EAAQ,EAAE;IAChD,IAAI,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3C,OAAO,iBAAS,CAAC,CAAC,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACjF,CAAC,CAAA;AAHY,QAAA,gBAAgB,oBAG5B;AAQoD,iBAXxC,wBAAgB,CAW8B;AAN3D,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAE,EAAE;IAC7C,IAAI,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACtB,OAAO,IAAI,CAAC,OAAO,CAAC;AACxB,CAAC,CAAA;AAID,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,CAAC,KAAK,EAAE,4BAA4B,CAAC;CACtC,CAAC,CAAC;AAEH;;GAEG;AACI,MAAM,aAAa,GAAG,CACzB,GAAW,EACX,QAAqB,EAAE,EACvB,WAAmB,EAAE,EACrB,EAAE,GAAG,EAAE,EAAW,EAAE;;IAEpB,IAAI,CAAC,iBAAS,EAAE;QAEZ,oEAAoE;QACpE,+CAA+C;QAC/C,OAAsB,IAAI,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;KAEjE;SAAM;QAEH,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACR,QAAQ,CAAC,eAAe,CAAC,MAAA,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,mCAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;YACzD,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAEhC,IAAA,gBAAO,EAAC,KAAK,EAAE,CAAC,KAAW,EAAE,GAAG,EAAE,EAAE;YAEhC,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE;gBAEtB,CAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aAE1B;iBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;gBAElC,0CAA0C;gBAC1C,IAAI,KAAK,KAAK,EAAE;oBACZ,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;aAElC;iBAAM,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE;gBAEnC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;aAE3B;iBAAM,IAAI,CAAC,iBAAS,IAAI,KAAK,YAAY,UAAU,EAAE;gBAElD,CAAC,CAAC,YAAY,CAAC,GAAG,EAAQ,KAAK,CAAC,CAAC;aAEpC;QAEL,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YAEjB,QAAQ,OAAO,CAAC,EAAE;gBAEd,KAAK,QAAQ,CAAC;gBACd,KAAK,QAAQ,CAAC;gBACd,KAAK,SAAS;oBACV,CAAC,CAAC,WAAW,CAAO,QAAQ,CAAC,cAAc,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;gBACzD,KAAK,QAAQ;oBACT,CAAC,CAAC,WAAW,CAAO,CAAC,CAAC,CAAC;oBACvB,MAAM;gBACV;oBACI,MAAM,IAAI,SAAS,CACf,uBAAuB,CAAC,YAAY,OAAO,CAAC,EAAE,CACjD,CAAC;aAET;QAEL,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,CAAC;KAEZ;AAEL,CAAC,CAAA;AAlEY,QAAA,aAAa,iBAkEzB"}
|