@webda/ql 4.0.0-beta.5 → 4.0.0-beta.6

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.
Files changed (55) hide show
  1. package/README.md +68 -27
  2. package/lib/WebdaQLLexer.d.ts +44 -30
  3. package/lib/WebdaQLLexer.d.ts.map +1 -1
  4. package/lib/WebdaQLLexer.js +257 -152
  5. package/lib/WebdaQLLexer.js.map +1 -1
  6. package/lib/WebdaQLParserLexer.d.ts +44 -30
  7. package/lib/WebdaQLParserLexer.d.ts.map +1 -1
  8. package/lib/WebdaQLParserLexer.js +257 -152
  9. package/lib/WebdaQLParserLexer.js.map +1 -1
  10. package/lib/WebdaQLParserListener.d.ts +203 -30
  11. package/lib/WebdaQLParserListener.d.ts.map +1 -1
  12. package/lib/WebdaQLParserParser.d.ts +242 -44
  13. package/lib/WebdaQLParserParser.d.ts.map +1 -1
  14. package/lib/WebdaQLParserParser.js +2054 -715
  15. package/lib/WebdaQLParserParser.js.map +1 -1
  16. package/lib/WebdaQLParserVisitor.d.ts +126 -17
  17. package/lib/WebdaQLParserVisitor.d.ts.map +1 -1
  18. package/lib/aggregation-query.d.ts +95 -0
  19. package/lib/aggregation-query.d.ts.map +1 -0
  20. package/lib/aggregation-query.js +104 -0
  21. package/lib/aggregation-query.js.map +1 -0
  22. package/lib/aggregation-select.spec.d.ts +2 -0
  23. package/lib/aggregation-select.spec.d.ts.map +1 -0
  24. package/lib/aggregation-select.spec.js +164 -0
  25. package/lib/aggregation-select.spec.js.map +1 -0
  26. package/lib/aggregation.d.ts +97 -0
  27. package/lib/aggregation.d.ts.map +1 -0
  28. package/lib/aggregation.js +241 -0
  29. package/lib/aggregation.js.map +1 -0
  30. package/lib/aggregation.spec.d.ts +2 -0
  31. package/lib/aggregation.spec.d.ts.map +1 -0
  32. package/lib/aggregation.spec.js +360 -0
  33. package/lib/aggregation.spec.js.map +1 -0
  34. package/lib/bind.d.ts.map +1 -1
  35. package/lib/bind.js +29 -0
  36. package/lib/bind.js.map +1 -1
  37. package/lib/index.d.ts +1 -0
  38. package/lib/index.d.ts.map +1 -1
  39. package/lib/index.js +1 -0
  40. package/lib/index.js.map +1 -1
  41. package/lib/query.d.ts +162 -8
  42. package/lib/query.d.ts.map +1 -1
  43. package/lib/query.js +489 -45
  44. package/lib/query.js.map +1 -1
  45. package/lib/query.spec.js +6 -4
  46. package/lib/query.spec.js.map +1 -1
  47. package/lib/statements.spec.d.ts +2 -0
  48. package/lib/statements.spec.d.ts.map +1 -0
  49. package/lib/statements.spec.js +422 -0
  50. package/lib/statements.spec.js.map +1 -0
  51. package/lib/webdaql-string.d.ts +9 -0
  52. package/lib/webdaql-string.d.ts.map +1 -1
  53. package/lib/webdaql-string.js +9 -8
  54. package/lib/webdaql-string.js.map +1 -1
  55. package/package.json +2 -2
package/README.md CHANGED
@@ -23,14 +23,10 @@ You need WQL when you call `store.query()` or a relation's `.query()` method. Ev
23
23
 
24
24
  ```typescript
25
25
  // Query the User repository
26
- const { results } = await User.getRepository().query(
27
- `email = 'alice@example.com' LIMIT 1`
28
- );
26
+ const { results } = await User.getRepository().query(`email = 'alice@example.com' LIMIT 1`);
29
27
 
30
28
  // Query a relation
31
- const { results: posts } = await user.posts.query(
32
- `status = 'published' ORDER BY createdAt DESC LIMIT 10`
33
- );
29
+ const { results: posts } = await user.posts.query(`status = 'published' ORDER BY createdAt DESC LIMIT 10`);
34
30
  ```
35
31
 
36
32
  ### Install
@@ -44,10 +40,19 @@ npm install @webda/ql
44
40
  ### Syntax overview
45
41
 
46
42
  ```
47
- expression? orderExpression? limitExpression? offsetExpression?
43
+ expression? orderExpression? limitExpression? offsetExpression? -- a filter query (implicit SELECT)
44
+ SELECT f1, f2 [WHERE expression] [ORDER BY ...] [LIMIT n] [OFFSET t]
45
+ SELECT g, COUNT(*) AS n, SUM(f) AS s [WHERE expression] [GROUP BY g] [ORDER BY ...] [LIMIT n]
46
+ DELETE [WHERE expression] [LIMIT n]
47
+ UPDATE SET a = v, b.c = v [WHERE expression] [LIMIT n]
48
48
  ```
49
49
 
50
+ Keywords are uppercase only: `select`, `delete`, `set`, `where`... in lowercase are field names. Since the
51
+ aggregation syntax, uppercase `COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, `AS`, `DISTINCT` and `GROUP BY` are reserved too
52
+ (breaking for attributes with those uppercase names).
53
+
50
54
  **Filter expressions** support:
55
+
51
56
  - Comparison: `field = value`, `field != value`, `field > value`, `field >= value`, `field < value`, `field <= value`
52
57
  - Pattern match: `field LIKE "pattern"` (`_` = single char, `%` = any chars)
53
58
  - Set membership: `field IN [value, value, ...]`
@@ -56,6 +61,7 @@ expression? orderExpression? limitExpression? offsetExpression?
56
61
  - Logic: `AND`, `OR`, `( ... )`
57
62
 
58
63
  **Pagination / ordering:**
64
+
59
65
  - `ORDER BY field [ASC|DESC], ...`
60
66
  - `LIMIT <integer>`
61
67
  - `OFFSET "<continuationToken>"`
@@ -66,17 +72,12 @@ expression? orderExpression? limitExpression? offsetExpression?
66
72
  import * as WebdaQL from "@webda/ql";
67
73
 
68
74
  // Parse and evaluate against an in-memory object
69
- const validator = new WebdaQL.QueryValidator(
70
- `status = 'published' AND viewCount >= 100`
71
- );
75
+ const validator = new WebdaQL.QueryValidator(`status = 'published' AND viewCount >= 100`);
72
76
  const post = { status: "published", viewCount: 150 };
73
77
  console.log(validator.eval(post)); // true
74
78
 
75
79
  // Prepend a mandatory condition to a user-supplied query
76
- const merged = WebdaQL.PrependCondition(
77
- `status = 'published' ORDER BY title LIMIT 10`,
78
- `authorId = 'u-123'`
79
- );
80
+ const merged = WebdaQL.PrependCondition(`status = 'published' ORDER BY title LIMIT 10`, `authorId = 'u-123'`);
80
81
  // => 'status = "published" AND authorId = "u-123" ORDER BY title ASC LIMIT 10'
81
82
  ```
82
83
 
@@ -93,30 +94,70 @@ WebdaQL.bind("priority >= ? LIMIT ?", [2, 10]); // priority >= 2 LIMIT 10
93
94
 
94
95
  Placeholders are only allowed where a value is expected, values are escaped by type, and `= ?` / `!= ?` with `null` become `IS NULL` / `IS NOT NULL`. Template literals passed straight to a query method are escaped the same way at compile time by `webdac`. See [Parameters](../../docs/pages/Modules/ql/Parameters.md).
95
96
 
97
+ ### Statements: SELECT, DELETE, UPDATE
98
+
99
+ WebdaQL parses `SELECT`, `DELETE` and `UPDATE` statements; the parsed `Query` carries `type` (`"SELECT"` for a plain filter), `fields` (SELECT) and `assignments` (UPDATE), and `toString()` round-trips them.
100
+
101
+ - **Field lists are parse-level only**: the Query operations (REST, gRPC, MCP, GraphQL) refuse a `SELECT` field list with a 400, and repositories refuse it in `query()`.
102
+ - **DELETE and UPDATE are repository-level operations**: `useRepository(Model).deleteMany("DELETE WHERE ...")` and `updateMany("UPDATE SET ... WHERE ...")` run them in bulk and return the affected count. They **bypass events, hooks, validation and `canAct`**. The Query operations refuse them with a 400, and `query()` / `iterate()` refuse them.
103
+
104
+ ```typescript
105
+ const q = WebdaQL.parse("UPDATE SET status = 'archived' WHERE owner = 'bob' LIMIT 10");
106
+ q.type; // "UPDATE"
107
+ q.assignments; // [{ field: "status", value: "archived" }]
108
+ await useRepository(Task).updateMany("UPDATE SET status = ? WHERE owner = ?", ["archived", "bob"]); // count
109
+ ```
110
+
111
+ See [Statements](../../docs/pages/Modules/ql/Statements.md).
112
+
113
+ ### Aggregations
114
+
115
+ A `SELECT` with aggregate functions or `GROUP BY` parses into an `AggregationQuery` (`parse(q).aggregation`), the
116
+ same AST `toAggregationQuery()` builds from the object form used by `Model.aggregate()`. Stores translate it
117
+ natively, or stream objects through the in-memory `Aggregator`.
118
+
119
+ ```typescript
120
+ const q = WebdaQL.parse("SELECT status, COUNT(*) AS n, SUM(points) AS total GROUP BY status ORDER BY total DESC");
121
+ q.aggregation.metrics; // { n: { fn: "COUNT" }, total: { fn: "SUM", field: "points" } }
122
+ ```
123
+
124
+ See [Statements](../../docs/pages/Modules/ql/Statements.md#aggregation-select--group-by) and
125
+ [Repositories](../../docs/pages/Concepts/Stores/Repositories.md#aggregation).
126
+
96
127
  ### API reference
97
128
 
98
- | Export | Description |
99
- |--------|-------------|
100
- | `QueryValidator` | Parses a WQL string; `eval(obj)` evaluates it, `toString()` normalizes it |
101
- | `bind(query, params)` | Binds `?` / `:name` placeholders to escaped values |
102
- | `escape(parts, values)` | Escapes template literal values (used by the compile-time rewrite) |
103
- | `validateSyntax(query)` | Checks a query against the grammar without evaluating it; placeholders allowed |
104
- | `PrependCondition(query, condition)` | Merges a condition in front of an existing query, preserving ORDER BY / LIMIT / OFFSET |
105
- | `ExpressionBuilder` | ANTLR visitor that builds the optimized expression AST |
106
- | `AndExpression` | Logic AND node |
107
- | `OrExpression` | Logic OR node |
108
- | `ComparisonExpression` | Comparison leaf node |
109
- | `Query` | Parsed query result: `{ filter, orderBy?, limit?, continuationToken? }` |
110
- | `OrderBy` | `{ field: string; direction: "ASC" \| "DESC" }` |
129
+ | Export | Description |
130
+ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
131
+ | `QueryValidator` | Parses a WQL string; `eval(obj)` evaluates it, `toString()` normalizes it |
132
+ | `bind(query, params)` | Binds `?` / `:name` placeholders to escaped values |
133
+ | `escape(parts, values)` | Escapes template literal values (used by the compile-time rewrite) |
134
+ | `validateSyntax(query)` | Checks a query against the grammar without evaluating it; placeholders allowed |
135
+ | `PrependCondition(query, condition)` | Merges a condition in front of an existing query, preserving ORDER BY / LIMIT / OFFSET |
136
+ | `ExpressionBuilder` | ANTLR visitor that builds the optimized expression AST |
137
+ | `AndExpression` | Logic AND node |
138
+ | `OrExpression` | Logic OR node |
139
+ | `ComparisonExpression` | Comparison leaf node |
140
+ | `parse(query, allowedFields?)` | Parses a filter or statement; `allowedFields` checks SELECT fields and SET targets |
141
+ | `validateQueryFields(query, allowed)` | Checks SELECT fields and SET targets against a field list |
142
+ | `assertFilterQuery(query)` | Refuses DELETE, UPDATE, SELECT field lists and aggregations |
143
+ | `toAggregationQuery(input, params?)` | Converts the object form of an aggregation to a validated `AggregationQuery` |
144
+ | `validateAggregation(query)` | Validates an `AggregationQuery` (paths, aliases, functions, ORDER BY, LIMIT) |
145
+ | `Aggregator` | In-memory aggregation engine: `add(item)` then `rows()` |
146
+ | `compareValues(a, b)` | The cross-backend ordering of aggregated values (null < numbers < strings) |
147
+ | `AggregationError` | Runtime aggregation error with a `code` (`AGGREGATION_NOT_NATIVE`, `AGGREGATION_TOO_MANY_GROUPS`) |
148
+ | `Query` | Parsed query result: `{ type, filter, fields?, assignments?, aggregation?, orderBy?, limit?, continuationToken? }` |
149
+ | `OrderBy` | `{ field: string; direction: "ASC" \| "DESC" }` |
111
150
 
112
151
  ### See also
113
152
 
114
153
  - [WQL Syntax reference](../../docs/pages/Modules/ql/Syntax.md)
115
154
  - [Operators](../../docs/pages/Modules/ql/Operators.md)
116
155
  - [Parameters](../../docs/pages/Modules/ql/Parameters.md) — binding values safely
156
+ - [Statements](../../docs/pages/Modules/ql/Statements.md) — SELECT, DELETE, UPDATE and repository bulk operations
117
157
  - [Store Translators](../../docs/pages/Modules/ql/Translators.md) — how each Store backend converts WQL
118
158
 
119
159
  <!-- README_FOOTER -->
160
+
120
161
  ## Sponsors
121
162
 
122
163
  <!--
@@ -11,36 +11,50 @@ export declare class WebdaQLLexer extends Lexer {
11
11
  static readonly DOUBLE_QUOTE_SYMB = 6;
12
12
  static readonly LR_SQ_BRACKET = 7;
13
13
  static readonly RR_SQ_BRACKET = 8;
14
- static readonly AND = 9;
15
- static readonly OR = 10;
16
- static readonly EQUAL = 11;
17
- static readonly NOT_EQUAL = 12;
18
- static readonly GREATER = 13;
19
- static readonly GREATER_OR_EQUAL = 14;
20
- static readonly LESS = 15;
21
- static readonly LESS_OR_EQUAL = 16;
22
- static readonly LIKE = 17;
23
- static readonly IN = 18;
24
- static readonly CONTAINS = 19;
25
- static readonly IS = 20;
26
- static readonly NOT = 21;
27
- static readonly NULL = 22;
28
- static readonly TRUE = 23;
29
- static readonly FALSE = 24;
30
- static readonly LIMIT = 25;
31
- static readonly OFFSET = 26;
32
- static readonly ORDER_BY = 27;
33
- static readonly ASC = 28;
34
- static readonly DESC = 29;
35
- static readonly DQUOTED_STRING_LITERAL = 30;
36
- static readonly SQUOTED_STRING_LITERAL = 31;
37
- static readonly INTEGER_LITERAL = 32;
38
- static readonly NUMBER_LITERAL = 33;
39
- static readonly POSITIONAL_PARAMETER = 34;
40
- static readonly NAMED_PARAMETER = 35;
41
- static readonly IDENTIFIER = 36;
42
- static readonly IDENTIFIER_WITH_NUMBER = 37;
43
- static readonly FUNCTION_IDENTIFIER_WITH_UNDERSCORE = 38;
14
+ static readonly DELETE = 9;
15
+ static readonly UPDATE = 10;
16
+ static readonly SELECT = 11;
17
+ static readonly SET = 12;
18
+ static readonly WHERE = 13;
19
+ static readonly AND = 14;
20
+ static readonly OR = 15;
21
+ static readonly EQUAL = 16;
22
+ static readonly NOT_EQUAL = 17;
23
+ static readonly GREATER = 18;
24
+ static readonly GREATER_OR_EQUAL = 19;
25
+ static readonly LESS = 20;
26
+ static readonly LESS_OR_EQUAL = 21;
27
+ static readonly LIKE = 22;
28
+ static readonly IN = 23;
29
+ static readonly CONTAINS = 24;
30
+ static readonly IS = 25;
31
+ static readonly NOT = 26;
32
+ static readonly NULL = 27;
33
+ static readonly TRUE = 28;
34
+ static readonly FALSE = 29;
35
+ static readonly LIMIT = 30;
36
+ static readonly OFFSET = 31;
37
+ static readonly ORDER_BY = 32;
38
+ static readonly ASC = 33;
39
+ static readonly DESC = 34;
40
+ static readonly GROUP_BY = 35;
41
+ static readonly AS = 36;
42
+ static readonly DISTINCT = 37;
43
+ static readonly COUNT = 38;
44
+ static readonly SUM = 39;
45
+ static readonly AVG = 40;
46
+ static readonly MIN = 41;
47
+ static readonly MAX = 42;
48
+ static readonly STAR = 43;
49
+ static readonly DQUOTED_STRING_LITERAL = 44;
50
+ static readonly SQUOTED_STRING_LITERAL = 45;
51
+ static readonly INTEGER_LITERAL = 46;
52
+ static readonly NUMBER_LITERAL = 47;
53
+ static readonly POSITIONAL_PARAMETER = 48;
54
+ static readonly NAMED_PARAMETER = 49;
55
+ static readonly IDENTIFIER = 50;
56
+ static readonly IDENTIFIER_WITH_NUMBER = 51;
57
+ static readonly FUNCTION_IDENTIFIER_WITH_UNDERSCORE = 52;
44
58
  static readonly channelNames: string[];
45
59
  static readonly modeNames: string[];
46
60
  static readonly ruleNames: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"WebdaQLLexer.d.ts","sourceRoot":"","sources":["../src/WebdaQLLexer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKpD,qBAAa,YAAa,SAAQ,KAAK;IACrC,gBAAuB,KAAK,KAAK;IACjC,gBAAuB,UAAU,KAAK;IACtC,gBAAuB,UAAU,KAAK;IACtC,gBAAuB,KAAK,KAAK;IACjC,gBAAuB,iBAAiB,KAAK;IAC7C,gBAAuB,iBAAiB,KAAK;IAC7C,gBAAuB,aAAa,KAAK;IACzC,gBAAuB,aAAa,KAAK;IACzC,gBAAuB,GAAG,KAAK;IAC/B,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,SAAS,MAAM;IACtC,gBAAuB,OAAO,MAAM;IACpC,gBAAuB,gBAAgB,MAAM;IAC7C,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,aAAa,MAAM;IAC1C,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,MAAM,MAAM;IACnC,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,sBAAsB,MAAM;IACnD,gBAAuB,sBAAsB,MAAM;IACnD,gBAAuB,eAAe,MAAM;IAC5C,gBAAuB,cAAc,MAAM;IAC3C,gBAAuB,oBAAoB,MAAM;IACjD,gBAAuB,eAAe,MAAM;IAC5C,gBAAuB,UAAU,MAAM;IACvC,gBAAuB,sBAAsB,MAAM;IACnD,gBAAuB,mCAAmC,MAAM;IAGhE,gBAAuB,YAAY,EAAE,MAAM,EAAE,CAAuC;IAGpF,gBAAuB,SAAS,EAAE,MAAM,EAAE,CAAoB;IAE9D,gBAAuB,SAAS,EAAE,MAAM,EAAE,CA6CxC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAoCpC;IACF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAwCrC;IACF,gBAAuB,UAAU,EAAE,UAAU,CAI3C;IAIF,IAAW,UAAU,IAAI,UAAU,CAElC;IAGD,YAAY,KAAK,EAAE,UAAU,EAG5B;IAGD,IAAW,eAAe,IAAI,MAAM,CAEnC;IAGD,IAAW,SAAS,IAAI,MAAM,EAAE,CAE/B;IAGD,IAAW,aAAa,IAAI,MAAM,CAEjC;IAGD,IAAW,YAAY,IAAI,MAAM,EAAE,CAElC;IAGD,IAAW,SAAS,IAAI,MAAM,EAAE,CAE/B;IAED,gBAAuB,cAAc,EAAE,MAAM,CAuIU;IACvD,OAAc,KAAK,EAAE,GAAG,CAAC;IACzB,WAAkB,IAAI,IAAI,GAAG,CAM5B;CACF"}
1
+ {"version":3,"file":"WebdaQLLexer.d.ts","sourceRoot":"","sources":["../src/WebdaQLLexer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKpD,qBAAa,YAAa,SAAQ,KAAK;IACrC,gBAAuB,KAAK,KAAK;IACjC,gBAAuB,UAAU,KAAK;IACtC,gBAAuB,UAAU,KAAK;IACtC,gBAAuB,KAAK,KAAK;IACjC,gBAAuB,iBAAiB,KAAK;IAC7C,gBAAuB,iBAAiB,KAAK;IAC7C,gBAAuB,aAAa,KAAK;IACzC,gBAAuB,aAAa,KAAK;IACzC,gBAAuB,MAAM,KAAK;IAClC,gBAAuB,MAAM,MAAM;IACnC,gBAAuB,MAAM,MAAM;IACnC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,SAAS,MAAM;IACtC,gBAAuB,OAAO,MAAM;IACpC,gBAAuB,gBAAgB,MAAM;IAC7C,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,aAAa,MAAM;IAC1C,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,MAAM,MAAM;IACnC,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,EAAE,MAAM;IAC/B,gBAAuB,QAAQ,MAAM;IACrC,gBAAuB,KAAK,MAAM;IAClC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,GAAG,MAAM;IAChC,gBAAuB,IAAI,MAAM;IACjC,gBAAuB,sBAAsB,MAAM;IACnD,gBAAuB,sBAAsB,MAAM;IACnD,gBAAuB,eAAe,MAAM;IAC5C,gBAAuB,cAAc,MAAM;IAC3C,gBAAuB,oBAAoB,MAAM;IACjD,gBAAuB,eAAe,MAAM;IAC5C,gBAAuB,UAAU,MAAM;IACvC,gBAAuB,sBAAsB,MAAM;IACnD,gBAAuB,mCAAmC,MAAM;IAGhE,gBAAuB,YAAY,EAAE,MAAM,EAAE,CAAuC;IAGpF,gBAAuB,SAAS,EAAE,MAAM,EAAE,CAAoB;IAE9D,gBAAuB,SAAS,EAAE,MAAM,EAAE,CA2DxC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAkDpC;IACF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAsDrC;IACF,gBAAuB,UAAU,EAAE,UAAU,CAI3C;IAIF,IAAW,UAAU,IAAI,UAAU,CAElC;IAGD,YAAY,KAAK,EAAE,UAAU,EAG5B;IAGD,IAAW,eAAe,IAAI,MAAM,CAEnC;IAGD,IAAW,SAAS,IAAI,MAAM,EAAE,CAE/B;IAGD,IAAW,aAAa,IAAI,MAAM,CAEjC;IAGD,IAAW,YAAY,IAAI,MAAM,EAAE,CAElC;IAGD,IAAW,SAAS,IAAI,MAAM,EAAE,CAE/B;IAED,gBAAuB,cAAc,EAAE,MAAM,CAwL4B;IACzE,OAAc,KAAK,EAAE,GAAG,CAAC;IACzB,WAAkB,IAAI,IAAI,GAAG,CAM5B;CACF"}