@vibeorm/generator 1.3.1 → 2.0.0-alpha.10
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 +43 -39
- package/dist/emit-dts.d.ts +32 -0
- package/dist/emit-dts.d.ts.map +1 -0
- package/dist/emit-js.d.ts +34 -0
- package/dist/emit-js.d.ts.map +1 -0
- package/dist/extension-bake.d.ts +42 -0
- package/dist/extension-bake.d.ts.map +1 -0
- package/dist/generate.d.ts +29 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2154 -0
- package/dist/index.js.map +16 -0
- package/dist/schema-view.d.ts +103 -0
- package/dist/schema-view.d.ts.map +1 -0
- package/dist/type-names.d.ts +30 -0
- package/dist/type-names.d.ts.map +1 -0
- package/dist/util.d.ts +39 -0
- package/dist/util.d.ts.map +1 -0
- package/package.json +31 -23
- package/src/generate.ts +0 -70
- package/src/generators/generate-args.ts +0 -322
- package/src/generators/generate-client.ts +0 -252
- package/src/generators/generate-delegates.ts +0 -590
- package/src/generators/generate-enums.ts +0 -28
- package/src/generators/generate-inputs.ts +0 -655
- package/src/generators/generate-models.ts +0 -130
- package/src/generators/generate-result.ts +0 -182
- package/src/generators/generate-schemas.ts +0 -474
- package/src/generators/generate-view-types.ts +0 -446
- package/src/index.ts +0 -2
- package/src/utils.ts +0 -51
package/README.md
CHANGED
|
@@ -1,58 +1,62 @@
|
|
|
1
1
|
# @vibeorm/generator
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Part of **[VibeORM](https://github.com/vibeorm/vibeorm)** — a type-safe TypeScript ORM for Bun and Node. Prisma-schema or TypeScript-DSL input, a canonical schema IR, a generated client, and a dialect-aware SQL layer over PostgreSQL, PGlite, SQLite and MySQL.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Turns a `SchemaIR` into a client module directory: plain JavaScript plus a declaration file that is written as text rather than inferred by `tsc`. It is a separate package because the schema-to-client emission is used by the CLI, by build tooling and by tests, none of which want the runtime or the migration engine in scope.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
bun add @vibeorm/generator
|
|
8
|
+
bun add @vibeorm/generator@alpha
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
> **Pre-release.** `2.0.0-alpha.x`, published under the `alpha` dist-tag. `npm i vibeorm` still resolves to the stable v1 line.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
import { parsePrismaSchema } from "@vibeorm/parser";
|
|
15
|
-
import { generate } from "@vibeorm/generator";
|
|
16
|
-
import { writeFileSync, mkdirSync } from "fs";
|
|
17
|
-
import { join } from "path";
|
|
13
|
+
Most users never install this directly — it ships as a dependency of [`vibeorm`](https://www.npmjs.com/package/vibeorm) and of the generated client. Reach for it when you are writing an adapter or tooling against the runtime.
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
const files = generate({ schema });
|
|
15
|
+
## What it emits
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
mkdirSync(outputDir, { recursive: true });
|
|
17
|
+
`generateClient` writes exactly three files into `outDir`, in this order:
|
|
24
18
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
| File | Contents |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `index.js` | The runtime glue: the normalized IR embedded as plain data, frozen enum objects, a `VibeError` re-export, and the `VibeClient(options)` factory that wires the IR to `@vibeorm/runtime`'s dynamic client. |
|
|
22
|
+
| `index.d.ts` | The entire typed surface, written directly as text. |
|
|
23
|
+
| `README.md` | A short do-not-edit note pointing back at `vibeorm generate`. |
|
|
29
24
|
|
|
30
|
-
|
|
25
|
+
Output is byte-identical for structurally identical IR: models, enums and extensions are sorted by name, object keys serialize sorted, and every emitter iterates deterministically. That makes a regenerated client a reviewable diff instead of noise.
|
|
31
26
|
|
|
32
|
-
|
|
27
|
+
## Why the .d.ts is written, not inferred
|
|
33
28
|
|
|
34
|
-
|
|
29
|
+
v1 shipped `.ts` source with inference-heavy generated types, so the consumer's TypeScript server re-derived the ORM's types on every keystroke. v2 emits the declarations as text, and consumers typecheck declarations instead of internals. The cost is measured as the ORM's share of a reference app's typecheck and gated in CI:
|
|
30
|
+
|
|
31
|
+
| Metric | v1 baseline | v2 measured |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| Instantiations | 210,840 | **1,531** |
|
|
34
|
+
| Types | 70,558 | **2,006** |
|
|
35
|
+
|
|
36
|
+
Any feature that would blow that budget ships pre-resolved (generated) rather than inferred. This is the reason the runtime's own delegate types are deliberately broad — precision lives only in the emitted `.d.ts`.
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
35
39
|
|
|
36
40
|
```ts
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
import { generateClient } from "@vibeorm/generator";
|
|
42
|
+
import type { GenerateResult } from "@vibeorm/generator";
|
|
43
|
+
|
|
44
|
+
const result: GenerateResult = await generateClient({
|
|
45
|
+
schema, // SchemaIR from @vibeorm/parser or @vibeorm/dsl
|
|
46
|
+
outDir: "./generated/vibeorm",
|
|
47
|
+
extensions: [], // configured VibeExtension instances, optional
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
console.log(result.files); // the written paths, in emission order
|
|
41
51
|
```
|
|
42
52
|
|
|
43
|
-
|
|
53
|
+
`generateClient` throws `VibeError` with code `VIBE_SCHEMA_INVALID` when the IR fails validation, before writing anything.
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
| `schemas.ts` | Zod v4 runtime validation schemas |
|
|
54
|
-
| `index.ts` | `VibeClient()` factory that wires model metadata into the runtime |
|
|
55
|
-
|
|
56
|
-
## License
|
|
57
|
-
|
|
58
|
-
[MIT](../../LICENSE)
|
|
55
|
+
Extension surfaces are baked into the client rather than resolved at runtime. `bakeExtensions({ schema, extensions })` returns the `BakedExtensions` the emitters consume, and is exported for tooling that needs that view without writing files.
|
|
56
|
+
|
|
57
|
+
## Links
|
|
58
|
+
|
|
59
|
+
- [Documentation](https://github.com/vibeorm/vibeorm/tree/master/docs)
|
|
60
|
+
- [Query API](https://github.com/vibeorm/vibeorm/blob/master/docs/queries.md)
|
|
61
|
+
- [Repository and issues](https://github.com/vibeorm/vibeorm)
|
|
62
|
+
- MIT licensed
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emits the generated client's index.d.ts as text (decision D3): the entire
|
|
3
|
+
* typed surface, written directly — no tsc run, no inference for the consumer's
|
|
4
|
+
* tsserver to pay for.
|
|
5
|
+
*
|
|
6
|
+
* Type-budget rules this file is built around (plan §6, constitution rule 2):
|
|
7
|
+
* - concrete per-model base types; narrowing via mapped lookups over them;
|
|
8
|
+
* - no conditional type deeper than a single level per key — recursion exists
|
|
9
|
+
* only where the API is recursive (nested select/include), and each hop is
|
|
10
|
+
* one shallow conditional + one mapped lookup;
|
|
11
|
+
* - no distributive conditionals over model unions — every model's types are
|
|
12
|
+
* spelled out flat;
|
|
13
|
+
* - no Zod, no `as const` inference trees, no mega-unions.
|
|
14
|
+
*/
|
|
15
|
+
import type { ComputedManifestEntry } from "@vibeorm/schema";
|
|
16
|
+
import type { BakedExtensions } from "./extension-bake.ts";
|
|
17
|
+
import type { SchemaView } from "./schema-view.ts";
|
|
18
|
+
/**
|
|
19
|
+
* Emit enums.d.ts: every enum's constant, literal union and flat validator
|
|
20
|
+
* type, plus the grouped `enumValidators`. Fully pre-resolved — no generics,
|
|
21
|
+
* no imports — and independent of the client surface in index.d.ts.
|
|
22
|
+
*/
|
|
23
|
+
export declare function emitEnumsDts(params: {
|
|
24
|
+
view: SchemaView;
|
|
25
|
+
}): string;
|
|
26
|
+
/** Emit the full index.d.ts for a resolved schema view. */
|
|
27
|
+
export declare function emitDts(params: {
|
|
28
|
+
view: SchemaView;
|
|
29
|
+
baked?: BakedExtensions;
|
|
30
|
+
computed?: readonly ComputedManifestEntry[];
|
|
31
|
+
}): string;
|
|
32
|
+
//# sourceMappingURL=emit-dts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-dts.d.ts","sourceRoot":"","sources":["../src/emit-dts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAoB,MAAM,iBAAiB,CAAC;AAG/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAgD,UAAU,EAAE,MAAM,kBAAkB,CAAC;AA4VjG;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,MAAM,CAejE;AAogDD,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,MAAM,EAAE;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC7C,GAAG,MAAM,CA8ET"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emits the generated client's index.js — runtime glue ONLY. All typing lives
|
|
3
|
+
* in the directly-written index.d.ts (see emit-dts.ts); this file embeds the
|
|
4
|
+
* normalized Schema IR as plain data (no `as const` inference trees), exports
|
|
5
|
+
* re-exports the enum constants and `enumValidators` from the lightweight
|
|
6
|
+
* enums.js entry (emitted here too, by `emitEnumsJs`) and wires `VibeClient()`
|
|
7
|
+
* to the dynamic client in @vibeorm/runtime. Import specifiers stay bare — the
|
|
8
|
+
* consumer resolves @vibeorm/runtime and @vibeorm/schema from its own
|
|
9
|
+
* node_modules.
|
|
10
|
+
*/
|
|
11
|
+
import type { ComputedManifestEntry } from "@vibeorm/schema";
|
|
12
|
+
import type { BakedExtensions } from "./extension-bake.ts";
|
|
13
|
+
import type { SchemaView } from "./schema-view.ts";
|
|
14
|
+
/** The names index.js / index.d.ts re-export from the enums entry (enum constants + the parser group). */
|
|
15
|
+
export declare function enumEntryExports(params: {
|
|
16
|
+
view: SchemaView;
|
|
17
|
+
}): readonly string[];
|
|
18
|
+
/**
|
|
19
|
+
* Emit the lightweight enums.js entry: one frozen constant object per enum
|
|
20
|
+
* (the SAME declaration index.js re-exports — one source of truth) and the
|
|
21
|
+
* grouped `enumValidators` boundary parsers. Depends on `@vibeorm/schema`
|
|
22
|
+
* (for the typed `VibeError`) and nothing else — never on the runtime
|
|
23
|
+
* client or the application schema module, so a frontend can import it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function emitEnumsJs(params: {
|
|
26
|
+
view: SchemaView;
|
|
27
|
+
}): string;
|
|
28
|
+
/** Emit the full index.js for a resolved schema view. */
|
|
29
|
+
export declare function emitJs(params: {
|
|
30
|
+
view: SchemaView;
|
|
31
|
+
baked?: BakedExtensions;
|
|
32
|
+
computed?: readonly ComputedManifestEntry[];
|
|
33
|
+
}): string;
|
|
34
|
+
//# sourceMappingURL=emit-js.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-js.d.ts","sourceRoot":"","sources":["../src/emit-js.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAOnD,0GAA0G;AAC1G,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,SAAS,MAAM,EAAE,CAEhF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,MAAM,CA0DhE;AAmDD,yDAAyD;AACzD,wBAAgB,MAAM,CAAC,MAAM,EAAE;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC7C,GAAG,MAAM,CA0ET"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate-time extension baking (plan D9).
|
|
3
|
+
*
|
|
4
|
+
* Each configured extension's client plane contributes runtime glue (JS
|
|
5
|
+
* expressions over its own module's exports) and d.ts text per opted-in model
|
|
6
|
+
* / per client. This module collects those contributions once, validates the
|
|
7
|
+
* one-identifier rule against the exported reserved-name lists, and hands the
|
|
8
|
+
* emitters plain string blocks — the emitted types stay fully pre-resolved
|
|
9
|
+
* (no inference), keeping the tsserver budget flat.
|
|
10
|
+
*/
|
|
11
|
+
import type { ExtensionManifestEntry, SchemaIR, VibeExtension } from "@vibeorm/schema";
|
|
12
|
+
/** Everything the js/d.ts emitters need, pre-stringified. */
|
|
13
|
+
export type BakedExtensions = {
|
|
14
|
+
/** `import { x } from "…";` lines for index.js. */
|
|
15
|
+
readonly jsImports: readonly string[];
|
|
16
|
+
/** JS object-literal expressions — one ClientExtensionMount each. */
|
|
17
|
+
readonly mounts: readonly string[];
|
|
18
|
+
/** Manifest entries (name-sorted) for the staleness gate. */
|
|
19
|
+
readonly manifest: readonly ExtensionManifestEntry[];
|
|
20
|
+
/** `import type { x } from "…";` lines for index.d.ts. */
|
|
21
|
+
readonly dtsImports: readonly string[];
|
|
22
|
+
/** Model name → delegate-body lines (already 2-space indented). */
|
|
23
|
+
readonly delegateDts: ReadonlyMap<string, readonly string[]>;
|
|
24
|
+
/** Module-scope type declaration blocks. */
|
|
25
|
+
readonly moduleDts: readonly string[];
|
|
26
|
+
/** VibeClientInstance-body lines for root `$name` namespaces. */
|
|
27
|
+
readonly clientDts: readonly string[];
|
|
28
|
+
/** True when nothing was configured — emitters keep their baseline output. */
|
|
29
|
+
readonly empty: boolean;
|
|
30
|
+
};
|
|
31
|
+
export declare const EMPTY_BAKED_EXTENSIONS: BakedExtensions;
|
|
32
|
+
/**
|
|
33
|
+
* Collect every configured extension's baked surface for this schema.
|
|
34
|
+
*
|
|
35
|
+
* @throws VibeError VIBE_CONFIG on duplicate names/claims (registry) and on
|
|
36
|
+
* contributions that break the one-identifier rule (D9).
|
|
37
|
+
*/
|
|
38
|
+
export declare function bakeExtensions(params: {
|
|
39
|
+
schema: SchemaIR;
|
|
40
|
+
extensions: readonly VibeExtension[];
|
|
41
|
+
}): BakedExtensions;
|
|
42
|
+
//# sourceMappingURL=extension-bake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-bake.d.ts","sourceRoot":"","sources":["../src/extension-bake.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EAGV,sBAAsB,EACtB,QAAQ,EACR,aAAa,EACd,MAAM,iBAAiB,CAAC;AAIzB,6DAA6D;AAC7D,MAAM,MAAM,eAAe,GAAG;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACrD,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IAC7D,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eASpC,CAAC;AA+BF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,MAAM,EAAE,QAAQ,CAAC;IACjB,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;CACtC,GAAG,eAAe,CAuGlB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The generator's public entry point: SchemaIR → a consumable client module
|
|
3
|
+
* directory (index.js + directly-written index.d.ts, the lightweight enums.js +
|
|
4
|
+
* enums.d.ts entry index re-exports from, and README.md).
|
|
5
|
+
*
|
|
6
|
+
* Output is byte-identical for structurally identical IR: models, enums and
|
|
7
|
+
* extensions are sorted by name, object keys are serialized sorted, and every
|
|
8
|
+
* emitter iterates deterministically.
|
|
9
|
+
*/
|
|
10
|
+
import type { ComputedConfig, SchemaIR, VibeExtension } from "@vibeorm/schema";
|
|
11
|
+
/** What `generateClient` wrote. */
|
|
12
|
+
export type GenerateResult = {
|
|
13
|
+
/** Paths of the written files (outDir-joined, in emission order). */
|
|
14
|
+
files: string[];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Generate the client module for a schema into `outDir` (created if missing).
|
|
18
|
+
*
|
|
19
|
+
* @throws VibeError `VIBE_SCHEMA_INVALID` when the IR fails validation.
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateClient(params: {
|
|
22
|
+
schema: SchemaIR;
|
|
23
|
+
outDir: string;
|
|
24
|
+
/** Configured extension instances — their surfaces bake into the client (D9). */
|
|
25
|
+
extensions?: readonly VibeExtension[];
|
|
26
|
+
/** Computed-field config — types bake into the .d.ts, the manifest into index.js. */
|
|
27
|
+
computed?: ComputedConfig;
|
|
28
|
+
}): Promise<GenerateResult>;
|
|
29
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAyB,QAAQ,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAMtG,mCAAmC;AACnC,MAAM,MAAM,cAAc,GAAG;IAC3B,qEAAqE;IACrE,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAOF;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE;IAC3C,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,UAAU,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACtC,qFAAqF;IACrF,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B,GAAG,OAAO,CAAC,cAAc,CAAC,CA2B1B"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vibeorm/generator — Schema IR → generated client (.js + directly-written .d.ts).
|
|
3
|
+
*
|
|
4
|
+
* The generated module embeds the normalized IR as plain data, wires
|
|
5
|
+
* `VibeClient()` to @vibeorm/runtime's dynamic client, and declares the entire
|
|
6
|
+
* typed surface in an index.d.ts written as text (decision D3) — the consumer's
|
|
7
|
+
* tsserver never re-infers ORM internals (constitution rules 1–2).
|
|
8
|
+
*/
|
|
9
|
+
export { generateClient } from "./generate.ts";
|
|
10
|
+
export type { GenerateResult } from "./generate.ts";
|
|
11
|
+
export { bakeExtensions } from "./extension-bake.ts";
|
|
12
|
+
export type { BakedExtensions } from "./extension-bake.ts";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
|