@fougere/adapter-sql 0.2.0-alpha.2

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fougere contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # @fougere/adapter-sql
2
+ > Entity → SQL tables, through Kysely
3
+ The SQL realization of the schema: the tables, the additive migration and the
4
+ per-entity scoped ORM. Four dialects — SQLite, PostgreSQL, MySQL, SQL Server.
5
+
6
+ Validation judges, storage realizes: this ORM passes no judgment on what a handler
7
+ hands it — it applies the `lifecycle` rules.
8
+
9
+ ## Installation
10
+ ```bash
11
+ pnpm add @fougere/adapter-sql
12
+ ```
13
+
14
+ ---
15
+
16
+ Part of [Fougere](https://github.com/chok/fougere) — one schema, a gradient from
17
+ monolith to distributed, the same user code.
18
+ Reference documentation: [the site](https://chok.github.io/fougere/) (en/fr).
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Shape → CHECK constraints.
3
+ *
4
+ * `oneOf`, `min`, `max` were declared on the field and read by the façade alone: a
5
+ * handler writing through the ORM put `status: 'brouillon'` in a column that declares
6
+ * two values, and nothing said a word. The rule was in the schema; no one held it on
7
+ * that path.
8
+ *
9
+ * So the storage learns what the shape already says. `validate` judges what a client
10
+ * proposes; this holds what anyone writes — including us.
11
+ *
12
+ * Only the keywords a database can decide alone. `pattern` and `format` are left to
13
+ * the façade: regex dialects diverge (POSIX here, PCRE there, nothing in SQLite
14
+ * without an extension), and a constraint that means something different per engine
15
+ * is worse than none.
16
+ *
17
+ * Every value is inlined with `sql.lit`, not bound: SQLite answers `parameters
18
+ * prohibited in CHECK constraints`, and a constraint is part of the schema rather
19
+ * than of a query. The values are the author's own literals — `oneOf('draft', …)`,
20
+ * `max: 160` — never anything a request carried, and Kysely escapes them.
21
+ */
22
+ import { type Expression, type SqlBool } from 'kysely';
23
+ import type { ColumnDef } from './table.js';
24
+ /** What a column's shape can be checked for, beyond its type. */
25
+ export interface ShapeBounds {
26
+ enum?: readonly (string | number)[];
27
+ minLength?: number;
28
+ maxLength?: number;
29
+ minimum?: number;
30
+ maximum?: number;
31
+ }
32
+ /**
33
+ * The CHECK expression for one column, or nothing when its shape bounds nothing.
34
+ *
35
+ * A nullable column passes when it holds `null`: `NOT NULL` is the axis that decides
36
+ * presence, and stacking the two would make `optional()` unwritable.
37
+ */
38
+ export declare function checkFor(column: ColumnDef): Expression<SqlBool> | undefined;
39
+ /** Read the bounds off a field's base shape — the keywords a database can decide. */
40
+ export declare function boundsOf(shape: Record<string, unknown> | undefined): ShapeBounds | undefined;
41
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAO,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,SAAS,CAuB3E;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAU5F"}
package/dist/check.js ADDED
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Shape → CHECK constraints.
3
+ *
4
+ * `oneOf`, `min`, `max` were declared on the field and read by the façade alone: a
5
+ * handler writing through the ORM put `status: 'brouillon'` in a column that declares
6
+ * two values, and nothing said a word. The rule was in the schema; no one held it on
7
+ * that path.
8
+ *
9
+ * So the storage learns what the shape already says. `validate` judges what a client
10
+ * proposes; this holds what anyone writes — including us.
11
+ *
12
+ * Only the keywords a database can decide alone. `pattern` and `format` are left to
13
+ * the façade: regex dialects diverge (POSIX here, PCRE there, nothing in SQLite
14
+ * without an extension), and a constraint that means something different per engine
15
+ * is worse than none.
16
+ *
17
+ * Every value is inlined with `sql.lit`, not bound: SQLite answers `parameters
18
+ * prohibited in CHECK constraints`, and a constraint is part of the schema rather
19
+ * than of a query. The values are the author's own literals — `oneOf('draft', …)`,
20
+ * `max: 160` — never anything a request carried, and Kysely escapes them.
21
+ */
22
+ import { sql } from 'kysely';
23
+ /**
24
+ * The CHECK expression for one column, or nothing when its shape bounds nothing.
25
+ *
26
+ * A nullable column passes when it holds `null`: `NOT NULL` is the axis that decides
27
+ * presence, and stacking the two would make `optional()` unwritable.
28
+ */
29
+ export function checkFor(column) {
30
+ const bounds = column.bounds;
31
+ if (!bounds)
32
+ return undefined;
33
+ const col = sql.ref(column.name);
34
+ const terms = [];
35
+ if (bounds.enum?.length) {
36
+ terms.push(sql `${col} in (${sql.join(bounds.enum.map((v) => sql.lit(v)))})`);
37
+ }
38
+ // Length, not value: a text bound is about the string, and `maxLength` is already
39
+ // spent on the column type where the dialect uses it (varchar(n)) — stating it
40
+ // again costs nothing and holds where the type does not (text columns).
41
+ if (bounds.minLength !== undefined)
42
+ terms.push(sql `length(${col}) >= ${sql.lit(bounds.minLength)}`);
43
+ if (bounds.maxLength !== undefined)
44
+ terms.push(sql `length(${col}) <= ${sql.lit(bounds.maxLength)}`);
45
+ if (bounds.minimum !== undefined)
46
+ terms.push(sql `${col} >= ${sql.lit(bounds.minimum)}`);
47
+ if (bounds.maximum !== undefined)
48
+ terms.push(sql `${col} <= ${sql.lit(bounds.maximum)}`);
49
+ if (terms.length === 0)
50
+ return undefined;
51
+ const all = terms.reduce((left, right) => sql `${left} and ${right}`);
52
+ return column.nullable ? sql `${col} is null or (${all})` : all;
53
+ }
54
+ /** Read the bounds off a field's base shape — the keywords a database can decide. */
55
+ export function boundsOf(shape) {
56
+ if (!shape)
57
+ return undefined;
58
+ const bounds = {};
59
+ if (Array.isArray(shape.enum) && shape.enum.length > 0)
60
+ bounds.enum = shape.enum;
61
+ for (const key of ['minLength', 'maxLength', 'minimum', 'maximum']) {
62
+ if (typeof shape[key] === 'number')
63
+ bounds[key] = shape[key];
64
+ }
65
+ return Object.keys(bounds).length > 0 ? bounds : undefined;
66
+ }
67
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,GAAG,EAAiC,MAAM,QAAQ,CAAC;AAY5D;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAE9B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,KAAK,GAA0B,EAAE,CAAC;IAExC,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAS,GAAG,GAAG,QAAQ,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxF,CAAC;IACD,kFAAkF;IAClF,+EAA+E;IAC/E,wEAAwE;IACxE,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAS,UAAU,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC7G,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAS,UAAU,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC7G,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAS,GAAG,GAAG,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACjG,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAS,GAAG,GAAG,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEjG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEzC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAS,GAAG,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC;IAE9E,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAS,GAAG,GAAG,gBAAgB,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAC1E,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,QAAQ,CAAC,KAA0C;IACjE,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAE7B,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,IAAgB,CAAC;IAC7F,KAAK,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,CAAU,EAAE,CAAC;QAC5E,IAAI,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAW,CAAC;IACzE,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7D,CAAC"}
package/dist/crud.d.ts ADDED
@@ -0,0 +1,153 @@
1
+ /**
2
+ * SqlEntityOrm — per-entity ORM over Kysely, one implementation for every engine.
3
+ *
4
+ * Structurally matches @fougere/core's EntityOrm (duck typed, no dep). There is
5
+ * no generated table object: Kysely addresses tables and columns by name, so the
6
+ * entity stays the only description. The field↔column mapping is explicit rather
7
+ * than a global plugin — auth tables carry their own naming and must not be
8
+ * rewritten behind the caller's back.
9
+ *
10
+ * `create` and `update` re-read the row instead of using `RETURNING`: the
11
+ * contract is to hand back the COMPLETE row, including defaults realised by SQL.
12
+ * That also makes the code identical on MySQL and SQL Server, which have no
13
+ * `RETURNING` clause.
14
+ */
15
+ import { type Kysely } from 'kysely';
16
+ import { type SchemaView, type SchemaSource } from '@fougere/schema';
17
+ import { type DialectName } from './dialect.js';
18
+ /** ListOptions — duplicated from @fougere/core to avoid a runtime dep. */
19
+ interface ListOptions {
20
+ limit?: number;
21
+ offset?: number;
22
+ page?: number;
23
+ after?: string;
24
+ orderBy?: string;
25
+ order?: 'asc' | 'desc';
26
+ count?: boolean;
27
+ }
28
+ interface ListResult<T> extends Array<T> {
29
+ total?: number;
30
+ endCursor?: string;
31
+ hasMore?: boolean;
32
+ }
33
+ interface SelectOption {
34
+ select?: SchemaView;
35
+ }
36
+ export declare class SqlEntityOrm {
37
+ private db;
38
+ private table;
39
+ private pk;
40
+ /** The axes `applyCreate`/`applyUpdate` read — held once, they are asked per write. */
41
+ private fields;
42
+ private selectFields?;
43
+ /** field → column and back; the entity names travel, the SQL names stay inside. */
44
+ private toColumn;
45
+ private toField;
46
+ /** field → the value pair a driver needs; only for the shapes a driver can't bind. */
47
+ private codecs;
48
+ /** How many keys one statement may carry here — see `Dialect.maxBindings`. */
49
+ private maxBindings;
50
+ /** How this engine spells an upsert, or `false` when it cannot — see `Dialect.upsert`. */
51
+ private upsertClause;
52
+ constructor(db: Kysely<any>, source: SchemaSource, tableName: string, selectFields?: Set<string>, dialect?: DialectName);
53
+ /** The Kysely instance this ORM wraps — no judge sits behind it. See EntityOrm.client. */
54
+ get client(): Kysely<any>;
55
+ /** Returns a scoped ORM that restricts all read results to the fields of the given schema. */
56
+ output(schema: SchemaView): SqlEntityOrm;
57
+ private resolveSelect;
58
+ private column;
59
+ /** The value a driver can bind — `true` becomes 1, a Date becomes its ISO string. */
60
+ private write;
61
+ /** Entity keys → column keys, and entity values → bindable values. */
62
+ private toRow;
63
+ /** Column keys → entity keys, and column values → the values the entity declares. */
64
+ private fromRow;
65
+ /**
66
+ * Apply a primary-key filter (simple or composite).
67
+ *
68
+ * The key crosses to the column exactly like every other value — `whereAll` states
69
+ * the rule two lines below and this did not follow it. It cost nothing while every
70
+ * generated key was a string; a key that holds a Date (`primary(created())`) inserted
71
+ * fine and then failed its own re-read, with the row already persisted.
72
+ */
73
+ private wherePk;
74
+ private whereAll;
75
+ list(options?: ListOptions & SelectOption & {
76
+ where?: Record<string, unknown>;
77
+ }): Promise<ListResult<Record<string, unknown>>>;
78
+ /**
79
+ * One query for N keys, never N queries — what every page-level read stands on:
80
+ * a computed field, a relation, a resolver on the other side of a wire.
81
+ *
82
+ * A composite key has no list form: it is refused by name rather than answering a
83
+ * partial result that reads as complete.
84
+ */
85
+ findByKeys(ids: readonly string[], options?: SelectOption): Promise<Map<string, Record<string, unknown>>>;
86
+ /**
87
+ * The other direction of a relation, in one query — see the port's `findAllByKeys`.
88
+ *
89
+ * The grouping key is read off the ROW rather than trusted from the request: a codec
90
+ * may write a value one way and read it back another, and a group keyed on the
91
+ * request's spelling would then be empty while the rows sit there.
92
+ */
93
+ findAllByKeys(field: string, keys: readonly string[], options?: SelectOption): Promise<Map<string, Record<string, unknown>[]>>;
94
+ /**
95
+ * Write the row, or make the existing one look like this — one statement.
96
+ *
97
+ * The gesture an import needs and the port did not have: `create` throws on the
98
+ * second run (`UNIQUE constraint failed`), so re-reading anything meant deleting
99
+ * first. Measured pulling 500 rows from an API twice.
100
+ *
101
+ * Both lifecycles are realized, each on the side it belongs to: `applyCreate` fills
102
+ * what a first write owes (a generated key, `created()`, a declared default) and
103
+ * `applyUpdate` stamps what every write owes (`updated()`). On conflict the key and
104
+ * the creation stamps are left alone — a row keeps the moment it appeared, whatever
105
+ * later overwrites say.
106
+ */
107
+ upsert(input: Record<string, unknown>, options?: SelectOption): Promise<Record<string, unknown>>;
108
+ /**
109
+ * Upsert a whole page in one statement — what an import writes through.
110
+ *
111
+ * Row by row, 500 rows were 500 statements (measured pulling an API); the shape of
112
+ * an import is a page, so the write should be one too. Sliced like every other batch,
113
+ * but by rows × COLUMNS: a statement binds values, not rows, so the ceiling divides.
114
+ *
115
+ * Answers how many rows were written and not the rows themselves. `create` hands back
116
+ * the complete row because a caller acts on it; an import acts on none of them, and
117
+ * re-reading a page to satisfy a symmetry nobody uses would double the work.
118
+ */
119
+ upsertAll(inputs: readonly Record<string, unknown>[], _options?: SelectOption): Promise<number>;
120
+ /**
121
+ * The COLUMNS a later write must not touch: the key, and a stamp that is create-only.
122
+ * One that is also `update: 'now'` is the opposite — it exists to move.
123
+ */
124
+ private frozenColumns;
125
+ findById(id: string | Record<string, unknown>, options?: SelectOption): Promise<Record<string, unknown> | undefined>;
126
+ findBy(criteria: Record<string, unknown>, options?: SelectOption): Promise<Record<string, unknown> | undefined>;
127
+ findAllBy(criteria: Record<string, unknown>, options?: SelectOption): Promise<Record<string, unknown>[]>;
128
+ /**
129
+ * One criteria object per statement — the oversized set is the one that splits.
130
+ *
131
+ * Only ONE criterion may be split: two split sets would need their cross product,
132
+ * which is a different query, so the second is refused rather than silently wrong.
133
+ */
134
+ private refuseOversized;
135
+ private splitCriteria;
136
+ create(input: Record<string, unknown>, options?: SelectOption): Promise<Record<string, unknown>>;
137
+ update(id: string | Record<string, unknown>, input: Record<string, unknown>, options?: SelectOption): Promise<Record<string, unknown>>;
138
+ delete(id: string | Record<string, unknown>): Promise<boolean>;
139
+ }
140
+ export interface OrmFactoryOptions {
141
+ /** Override table name resolution. Default: camelCase → snake_case + 's'. */
142
+ tableName?: (entityName: string) => string;
143
+ }
144
+ /**
145
+ * Create an OrmFactory backed by Kysely — same call shape on every engine.
146
+ *
147
+ * ```ts
148
+ * const app = await createApp({ createContainer, ormFactory: createOrmFactory(db) });
149
+ * ```
150
+ */
151
+ export declare function createOrmFactory(db: Kysely<any>, options?: OrmFactoryOptions, dialect?: DialectName): (entity: SchemaSource, name: string) => SqlEntityOrm;
152
+ export {};
153
+ //# sourceMappingURL=crud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../src/crud.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAmD,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEtH,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhE,0EAA0E;AAC1E,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,UAAU,CAAC,CAAC,CAAE,SAAQ,KAAK,CAAC,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAgDD,qBAAa,YAAY;IAkBrB,OAAO,CAAC,EAAE;IAjBZ,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,EAAE,CAAiB;IAC3B,uFAAuF;IACvF,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,mFAAmF;IACnF,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,OAAO,CAA6B;IAC5C,sFAAsF;IACtF,OAAO,CAAC,MAAM,CAA0B;IAExC,8EAA8E;IAC9E,OAAO,CAAC,WAAW,CAAS;IAC5B,0FAA0F;IAC1F,OAAO,CAAC,YAAY,CAA6C;IAEjE,YACU,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EACvB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC1B,OAAO,GAAE,WAAsB,EAkBhC;IAED,0FAA0F;IAC1F,IAAI,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,CAExB;IAED,8FAA8F;IAC9F,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAIvC;IAED,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,MAAM;IAId,qFAAqF;IACrF,OAAO,CAAC,KAAK;IAIb,sEAAsE;IACtE,OAAO,CAAC,KAAK;IAMb,qFAAqF;IACrF,OAAO,CAAC,OAAO;IASf;;;;;;;OAOG;IACH,OAAO,CAAC,OAAO;IAiBf,OAAO,CAAC,QAAQ;IASV,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CA+DnI;IAED;;;;;;OAMG;IACG,UAAU,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAsB9G;IAED;;;;;;OAMG;IACG,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAUjD;IAED;;;;;;;;;;;;OAYG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA4BrG;IAED;;;;;;;;;;OAUG;IACG,SAAS,CAAC,MAAM,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BpG;IAED;;;OAGG;IACH,OAAO,CAAC,aAAa;IASf,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAMzH;IAEK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAQpH;IAEK,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAa7G;IAED;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,aAAa;IAef,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAiBrG;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAS3I;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAKnE;CACF;AAGD,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,iBAAiB,EAAE,OAAO,GAAE,WAAsB,YAE5F,YAAY,QAAQ,MAAM,kBAC3C"}