@formspec/build 0.1.0-alpha.7 → 0.1.0-alpha.9

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 (137) hide show
  1. package/README.md +14 -14
  2. package/dist/__tests__/analyzer-edge-cases.test.d.ts +13 -0
  3. package/dist/__tests__/analyzer-edge-cases.test.d.ts.map +1 -0
  4. package/dist/__tests__/analyzer-edge-cases.test.js +376 -0
  5. package/dist/__tests__/analyzer-edge-cases.test.js.map +1 -0
  6. package/dist/__tests__/analyzer.test.d.ts +5 -0
  7. package/dist/__tests__/analyzer.test.d.ts.map +1 -0
  8. package/dist/__tests__/analyzer.test.js +190 -0
  9. package/dist/__tests__/analyzer.test.js.map +1 -0
  10. package/dist/__tests__/cli.test.js.map +1 -1
  11. package/dist/__tests__/codegen.test.d.ts +5 -0
  12. package/dist/__tests__/codegen.test.d.ts.map +1 -0
  13. package/dist/__tests__/codegen.test.js +506 -0
  14. package/dist/__tests__/codegen.test.js.map +1 -0
  15. package/dist/__tests__/decorator-pipeline.test.d.ts +11 -0
  16. package/dist/__tests__/decorator-pipeline.test.d.ts.map +1 -0
  17. package/dist/__tests__/decorator-pipeline.test.js +460 -0
  18. package/dist/__tests__/decorator-pipeline.test.js.map +1 -0
  19. package/dist/__tests__/edge-cases.test.js +2 -4
  20. package/dist/__tests__/edge-cases.test.js.map +1 -1
  21. package/dist/__tests__/fixtures/edge-cases.d.ts +110 -0
  22. package/dist/__tests__/fixtures/edge-cases.d.ts.map +1 -0
  23. package/dist/__tests__/fixtures/edge-cases.js +137 -0
  24. package/dist/__tests__/fixtures/edge-cases.js.map +1 -0
  25. package/dist/__tests__/fixtures/example-a-builtins.d.ts +12 -0
  26. package/dist/__tests__/fixtures/example-a-builtins.d.ts.map +1 -0
  27. package/dist/__tests__/fixtures/example-a-builtins.js +100 -0
  28. package/dist/__tests__/fixtures/example-a-builtins.js.map +1 -0
  29. package/dist/__tests__/fixtures/example-b-decorators.d.ts +5 -0
  30. package/dist/__tests__/fixtures/example-b-decorators.d.ts.map +1 -0
  31. package/dist/__tests__/fixtures/example-b-decorators.js +5 -0
  32. package/dist/__tests__/fixtures/example-b-decorators.js.map +1 -0
  33. package/dist/__tests__/fixtures/example-b-extended.d.ts +5 -0
  34. package/dist/__tests__/fixtures/example-b-extended.d.ts.map +1 -0
  35. package/dist/__tests__/fixtures/example-b-extended.js +60 -0
  36. package/dist/__tests__/fixtures/example-b-extended.js.map +1 -0
  37. package/dist/__tests__/fixtures/example-c-custom.d.ts +5 -0
  38. package/dist/__tests__/fixtures/example-c-custom.d.ts.map +1 -0
  39. package/dist/__tests__/fixtures/example-c-custom.js +61 -0
  40. package/dist/__tests__/fixtures/example-c-custom.js.map +1 -0
  41. package/dist/__tests__/fixtures/example-c-decorators.d.ts +5 -0
  42. package/dist/__tests__/fixtures/example-c-decorators.d.ts.map +1 -0
  43. package/dist/__tests__/fixtures/example-c-decorators.js +4 -0
  44. package/dist/__tests__/fixtures/example-c-decorators.js.map +1 -0
  45. package/dist/__tests__/fixtures/example-d-mixed-decorators.d.ts +6 -0
  46. package/dist/__tests__/fixtures/example-d-mixed-decorators.d.ts.map +1 -0
  47. package/dist/__tests__/fixtures/example-d-mixed-decorators.js +75 -0
  48. package/dist/__tests__/fixtures/example-d-mixed-decorators.js.map +1 -0
  49. package/dist/__tests__/fixtures/example-e-decorators.d.ts +11 -0
  50. package/dist/__tests__/fixtures/example-e-decorators.d.ts.map +1 -0
  51. package/dist/__tests__/fixtures/example-e-decorators.js +10 -0
  52. package/dist/__tests__/fixtures/example-e-decorators.js.map +1 -0
  53. package/dist/__tests__/fixtures/example-e-no-namespace.d.ts +5 -0
  54. package/dist/__tests__/fixtures/example-e-no-namespace.d.ts.map +1 -0
  55. package/dist/__tests__/fixtures/example-e-no-namespace.js +61 -0
  56. package/dist/__tests__/fixtures/example-e-no-namespace.js.map +1 -0
  57. package/dist/__tests__/fixtures/example-jsdoc-constraints.d.ts +16 -0
  58. package/dist/__tests__/fixtures/example-jsdoc-constraints.d.ts.map +1 -0
  59. package/dist/__tests__/fixtures/example-jsdoc-constraints.js +98 -0
  60. package/dist/__tests__/fixtures/example-jsdoc-constraints.js.map +1 -0
  61. package/dist/__tests__/fixtures/example-nested-class.d.ts +45 -0
  62. package/dist/__tests__/fixtures/example-nested-class.d.ts.map +1 -0
  63. package/dist/__tests__/fixtures/example-nested-class.js +248 -0
  64. package/dist/__tests__/fixtures/example-nested-class.js.map +1 -0
  65. package/dist/__tests__/fixtures/sample-forms.d.ts +55 -0
  66. package/dist/__tests__/fixtures/sample-forms.d.ts.map +1 -0
  67. package/dist/__tests__/fixtures/sample-forms.js +78 -0
  68. package/dist/__tests__/fixtures/sample-forms.js.map +1 -0
  69. package/dist/__tests__/generator.test.js +6 -6
  70. package/dist/__tests__/generator.test.js.map +1 -1
  71. package/dist/__tests__/integration.test.js +1 -3
  72. package/dist/__tests__/integration.test.js.map +1 -1
  73. package/dist/__tests__/jsdoc-constraints.test.d.ts +10 -0
  74. package/dist/__tests__/jsdoc-constraints.test.d.ts.map +1 -0
  75. package/dist/__tests__/jsdoc-constraints.test.js +199 -0
  76. package/dist/__tests__/jsdoc-constraints.test.js.map +1 -0
  77. package/dist/__tests__/write-schemas.test.js +10 -8
  78. package/dist/__tests__/write-schemas.test.js.map +1 -1
  79. package/dist/analyzer/class-analyzer.d.ts +85 -0
  80. package/dist/analyzer/class-analyzer.d.ts.map +1 -0
  81. package/dist/analyzer/class-analyzer.js +215 -0
  82. package/dist/analyzer/class-analyzer.js.map +1 -0
  83. package/dist/analyzer/decorator-extractor.d.ts +78 -0
  84. package/dist/analyzer/decorator-extractor.d.ts.map +1 -0
  85. package/dist/analyzer/decorator-extractor.js +336 -0
  86. package/dist/analyzer/decorator-extractor.js.map +1 -0
  87. package/dist/analyzer/jsdoc-constraints.d.ts +27 -0
  88. package/dist/analyzer/jsdoc-constraints.d.ts.map +1 -0
  89. package/dist/analyzer/jsdoc-constraints.js +91 -0
  90. package/dist/analyzer/jsdoc-constraints.js.map +1 -0
  91. package/dist/analyzer/program.d.ts +37 -0
  92. package/dist/analyzer/program.d.ts.map +1 -0
  93. package/dist/analyzer/program.js +87 -0
  94. package/dist/analyzer/program.js.map +1 -0
  95. package/dist/analyzer/type-converter.d.ts +75 -0
  96. package/dist/analyzer/type-converter.d.ts.map +1 -0
  97. package/dist/analyzer/type-converter.js +436 -0
  98. package/dist/analyzer/type-converter.js.map +1 -0
  99. package/dist/browser.d.ts +3 -2
  100. package/dist/browser.d.ts.map +1 -1
  101. package/dist/browser.js +1 -0
  102. package/dist/browser.js.map +1 -1
  103. package/dist/build.d.ts +196 -2
  104. package/dist/cli.js +1 -3
  105. package/dist/cli.js.map +1 -1
  106. package/dist/codegen/index.d.ts +75 -0
  107. package/dist/codegen/index.d.ts.map +1 -0
  108. package/dist/codegen/index.js +597 -0
  109. package/dist/codegen/index.js.map +1 -0
  110. package/dist/generators/class-schema.d.ts +84 -0
  111. package/dist/generators/class-schema.d.ts.map +1 -0
  112. package/dist/generators/class-schema.js +91 -0
  113. package/dist/generators/class-schema.js.map +1 -0
  114. package/dist/generators/method-schema.d.ts +67 -0
  115. package/dist/generators/method-schema.d.ts.map +1 -0
  116. package/dist/generators/method-schema.js +108 -0
  117. package/dist/generators/method-schema.js.map +1 -0
  118. package/dist/index.d.ts +8 -2
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +9 -1
  121. package/dist/index.js.map +1 -1
  122. package/dist/internals.d.ts +19 -0
  123. package/dist/internals.d.ts.map +1 -0
  124. package/dist/internals.js +22 -0
  125. package/dist/internals.js.map +1 -0
  126. package/dist/json-schema/generator.d.ts.map +1 -1
  127. package/dist/json-schema/generator.js +2 -3
  128. package/dist/json-schema/generator.js.map +1 -1
  129. package/dist/json-schema/types.d.ts +28 -0
  130. package/dist/json-schema/types.d.ts.map +1 -1
  131. package/dist/json-schema/types.js +27 -1
  132. package/dist/json-schema/types.js.map +1 -1
  133. package/dist/ui-schema/generator.d.ts.map +1 -1
  134. package/dist/ui-schema/generator.js +1 -3
  135. package/dist/ui-schema/generator.js.map +1 -1
  136. package/dist/ui-schema/types.d.ts.map +1 -1
  137. package/package.json +11 -3
package/dist/build.d.ts CHANGED
@@ -65,6 +65,30 @@ export declare interface BuildResult {
65
65
  readonly uiSchema: UISchema;
66
66
  }
67
67
 
68
+ /**
69
+ * Generated schemas for a class.
70
+ */
71
+ export declare interface ClassSchemas {
72
+ /** JSON Schema for validation */
73
+ jsonSchema: ExtendedJSONSchema7;
74
+ /** FormSpec/UI Schema for rendering */
75
+ uiSchema: {
76
+ elements: FormSpecField[];
77
+ };
78
+ }
79
+
80
+ /**
81
+ * Options for code generation.
82
+ */
83
+ export declare interface CodegenOptions {
84
+ /** Source files to analyze (glob patterns supported) */
85
+ files: string[];
86
+ /** Output file path */
87
+ output: string;
88
+ /** Base directory for relative imports */
89
+ baseDir?: string;
90
+ }
91
+
68
92
  /**
69
93
  * A Control element that binds to a JSON Schema property.
70
94
  */
@@ -74,6 +98,88 @@ export declare interface ControlElement extends UISchemaElementBase {
74
98
  label?: string;
75
99
  }
76
100
 
101
+ /**
102
+ * Information about a decorated class found during codegen analysis.
103
+ *
104
+ * Used to track which classes need type metadata patches and where
105
+ * they are located in the source tree.
106
+ */
107
+ export declare interface DecoratedClassInfo {
108
+ /** Class name as it appears in the source file */
109
+ name: string;
110
+ /** Import path to the source file (relative to output, without extension) */
111
+ sourcePath: string;
112
+ /** Type metadata for all decorated properties in the class */
113
+ typeMetadata: Record<string, TypeMetadata>;
114
+ /** Whether the class is exported from its source file */
115
+ isExported: boolean;
116
+ }
117
+
118
+ /** JSON Schema with FormSpec extension properties for arbitrary x-formspec-* keys. */
119
+ export declare type ExtendedJSONSchema7 = JSONSchema7 & FormSpecSchemaExtensions;
120
+
121
+ /**
122
+ * Finds all decorated classes in the given source files.
123
+ */
124
+ export declare function findDecoratedClasses(files: string[], baseDir: string): DecoratedClassInfo[];
125
+
126
+ /**
127
+ * FormSpec field definition (simplified for output).
128
+ */
129
+ export declare interface FormSpecField {
130
+ _field: string;
131
+ id: string;
132
+ label?: string;
133
+ placeholder?: string;
134
+ description?: string;
135
+ required?: boolean;
136
+ min?: number;
137
+ max?: number;
138
+ step?: number;
139
+ minLength?: number;
140
+ maxLength?: number;
141
+ minItems?: number;
142
+ maxItems?: number;
143
+ pattern?: string;
144
+ options?: (string | {
145
+ id: string;
146
+ label: string;
147
+ })[];
148
+ showWhen?: object;
149
+ group?: string;
150
+ fields?: FormSpecField[];
151
+ }
152
+
153
+ /** Extension properties for custom FormSpec decorators. */
154
+ export declare type FormSpecSchemaExtensions = Record<`x-formspec-${string}`, unknown>;
155
+
156
+ /**
157
+ * Generates the codegen output file content.
158
+ */
159
+ export declare function generateCodegenOutput(classes: DecoratedClassInfo[], outputPath: string, baseDir: string): string;
160
+
161
+ /**
162
+ * Options for generating schemas from a decorated class.
163
+ */
164
+ export declare interface GenerateFromClassOptions {
165
+ /** Path to the TypeScript source file */
166
+ filePath: string;
167
+ /** Class name to analyze */
168
+ className: string;
169
+ }
170
+
171
+ /**
172
+ * Result of generating schemas from a decorated class.
173
+ */
174
+ export declare interface GenerateFromClassResult {
175
+ /** JSON Schema for validation */
176
+ jsonSchema: ExtendedJSONSchema7;
177
+ /** FormSpec/UI Schema for rendering */
178
+ uiSchema: {
179
+ elements: FormSpecField[];
180
+ };
181
+ }
182
+
77
183
  /**
78
184
  * Generates a JSON Schema from a FormSpec.
79
185
  *
@@ -101,6 +207,27 @@ export declare interface ControlElement extends UISchemaElementBase {
101
207
  */
102
208
  export declare function generateJsonSchema<E extends readonly FormElement[]>(form: FormSpec<E>): JSONSchema7;
103
209
 
210
+ /**
211
+ * Generates JSON Schema and FormSpec/UI Schema from a decorated TypeScript class.
212
+ *
213
+ * This is a high-level entry point that handles the entire pipeline:
214
+ * creating a TypeScript program, finding the class, analyzing it,
215
+ * and generating schemas — all in one call.
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * const result = generateSchemasFromClass({
220
+ * filePath: "./src/forms.ts",
221
+ * className: "UserForm",
222
+ * });
223
+ * console.log(result.jsonSchema);
224
+ * ```
225
+ *
226
+ * @param options - File path, class name, and optional compiler options
227
+ * @returns Generated JSON Schema and FormSpec/UI Schema
228
+ */
229
+ export declare function generateSchemasFromClass(options: GenerateFromClassOptions): GenerateFromClassResult;
230
+
104
231
  /**
105
232
  * Generates a JSON Forms UI Schema from a FormSpec.
106
233
  *
@@ -144,6 +271,18 @@ export declare function generateJsonSchema<E extends readonly FormElement[]>(for
144
271
  */
145
272
  export declare function generateUiSchema<E extends readonly FormElement[]>(form: FormSpec<E>): UISchema;
146
273
 
274
+ /**
275
+ * Reads a FormSpec extension property from a JSON Schema node.
276
+ *
277
+ * Use this to safely read `x-formspec-*` properties from any schema,
278
+ * including nested schemas typed as `JSONSchema7`.
279
+ *
280
+ * @param schema - Any JSON Schema node
281
+ * @param key - Extension key (must start with `x-formspec-`)
282
+ * @returns The extension value, or `undefined` if not present
283
+ */
284
+ export declare function getSchemaExtension(schema: JSONSchema7, key: `x-formspec-${string}`): unknown;
285
+
147
286
  /**
148
287
  * A group element with a label.
149
288
  */
@@ -170,6 +309,7 @@ export declare interface JSONSchema7 {
170
309
  $ref?: string;
171
310
  title?: string;
172
311
  description?: string;
312
+ deprecated?: boolean;
173
313
  type?: JSONSchemaType | JSONSchemaType[];
174
314
  minLength?: number;
175
315
  maxLength?: number;
@@ -233,7 +373,7 @@ export declare interface Rule {
233
373
  /**
234
374
  * JSON Schema subset for rule conditions.
235
375
  */
236
- declare interface RuleConditionSchema {
376
+ export declare interface RuleConditionSchema {
237
377
  const?: unknown;
238
378
  enum?: readonly unknown[];
239
379
  type?: string;
@@ -248,6 +388,11 @@ declare interface RuleConditionSchema {
248
388
  */
249
389
  export declare type RuleEffect = "SHOW" | "HIDE" | "ENABLE" | "DISABLE";
250
390
 
391
+ /**
392
+ * Runs the code generation.
393
+ */
394
+ export declare function runCodegen(options: CodegenOptions): void;
395
+
251
396
  /**
252
397
  * Condition for a rule.
253
398
  */
@@ -256,6 +401,55 @@ export declare interface SchemaBasedCondition {
256
401
  schema: RuleConditionSchema;
257
402
  }
258
403
 
404
+ /**
405
+ * Sets a FormSpec extension property on a JSON Schema node.
406
+ *
407
+ * Use this to safely add `x-formspec-*` properties to any schema,
408
+ * including nested schemas typed as `JSONSchema7` (which don't carry
409
+ * the extension index signature).
410
+ *
411
+ * @param schema - Any JSON Schema node
412
+ * @param key - Extension key (must start with `x-formspec-`)
413
+ * @param value - Extension value
414
+ */
415
+ export declare function setSchemaExtension(schema: JSONSchema7, key: `x-formspec-${string}`, value: unknown): void;
416
+
417
+ /**
418
+ * Code generation for FormSpec type metadata.
419
+ *
420
+ * Generates a TypeScript file that patches decorated classes with
421
+ * their extracted type metadata, enabling runtime schema generation
422
+ * as an alternative to a TypeScript transformer.
423
+ *
424
+ * Usage:
425
+ * formspec codegen ./src/forms.ts -o ./src/__formspec_types__.ts
426
+ *
427
+ * Then in your code:
428
+ * import './__formspec_types__'; // Patches all decorated classes
429
+ * import { UserFormSchema, getUserFormFormSpec } from './__formspec_types__';
430
+ * const spec = getUserFormFormSpec();
431
+ */
432
+ /**
433
+ * Type metadata format used by `@formspec/decorators`.
434
+ *
435
+ * Represents the runtime type information for a field that TypeScript
436
+ * normally erases at compile time.
437
+ */
438
+ export declare interface TypeMetadata {
439
+ /** Base type: "string", "number", "boolean", "enum", "array", "object", "unknown" */
440
+ type: string;
441
+ /** For enum types, the possible literal values */
442
+ values?: unknown[];
443
+ /** For array types, metadata about the array element type */
444
+ itemType?: TypeMetadata;
445
+ /** For object types, metadata about each property */
446
+ properties?: Record<string, TypeMetadata>;
447
+ /** Whether the field accepts null */
448
+ nullable?: boolean;
449
+ /** Whether the field is optional (T | undefined or ?: modifier) */
450
+ optional?: boolean;
451
+ }
452
+
259
453
  /**
260
454
  * Root UI Schema (always a layout).
261
455
  */
@@ -269,7 +463,7 @@ export declare type UISchemaElement = ControlElement | VerticalLayout | Horizont
269
463
  /**
270
464
  * Base interface for all UI Schema elements.
271
465
  */
272
- declare interface UISchemaElementBase {
466
+ export declare interface UISchemaElementBase {
273
467
  type: UISchemaElementType;
274
468
  rule?: Rule;
275
469
  options?: Record<string, unknown>;
package/dist/cli.js CHANGED
@@ -107,9 +107,7 @@ async function main() {
107
107
  const module = (await import(fileUrl));
108
108
  // Look for the form export
109
109
  const form = module["default"] ?? module["form"];
110
- if (!form ||
111
- typeof form !== "object" ||
112
- !("elements" in form)) {
110
+ if (!form || typeof form !== "object" || !("elements" in form)) {
113
111
  console.error("Error: Input file must export a FormSpec as default export or as 'form'");
114
112
  console.error("Example:");
115
113
  console.error(' export default formspec(field.text("name"));');
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Code generation for FormSpec type metadata.
3
+ *
4
+ * Generates a TypeScript file that patches decorated classes with
5
+ * their extracted type metadata, enabling runtime schema generation
6
+ * as an alternative to a TypeScript transformer.
7
+ *
8
+ * Usage:
9
+ * formspec codegen ./src/forms.ts -o ./src/__formspec_types__.ts
10
+ *
11
+ * Then in your code:
12
+ * import './__formspec_types__'; // Patches all decorated classes
13
+ * import { UserFormSchema, getUserFormFormSpec } from './__formspec_types__';
14
+ * const spec = getUserFormFormSpec();
15
+ */
16
+ /**
17
+ * Type metadata format used by `@formspec/decorators`.
18
+ *
19
+ * Represents the runtime type information for a field that TypeScript
20
+ * normally erases at compile time.
21
+ */
22
+ export interface TypeMetadata {
23
+ /** Base type: "string", "number", "boolean", "enum", "array", "object", "unknown" */
24
+ type: string;
25
+ /** For enum types, the possible literal values */
26
+ values?: unknown[];
27
+ /** For array types, metadata about the array element type */
28
+ itemType?: TypeMetadata;
29
+ /** For object types, metadata about each property */
30
+ properties?: Record<string, TypeMetadata>;
31
+ /** Whether the field accepts null */
32
+ nullable?: boolean;
33
+ /** Whether the field is optional (T | undefined or ?: modifier) */
34
+ optional?: boolean;
35
+ }
36
+ /**
37
+ * Information about a decorated class found during codegen analysis.
38
+ *
39
+ * Used to track which classes need type metadata patches and where
40
+ * they are located in the source tree.
41
+ */
42
+ export interface DecoratedClassInfo {
43
+ /** Class name as it appears in the source file */
44
+ name: string;
45
+ /** Import path to the source file (relative to output, without extension) */
46
+ sourcePath: string;
47
+ /** Type metadata for all decorated properties in the class */
48
+ typeMetadata: Record<string, TypeMetadata>;
49
+ /** Whether the class is exported from its source file */
50
+ isExported: boolean;
51
+ }
52
+ /**
53
+ * Options for code generation.
54
+ */
55
+ export interface CodegenOptions {
56
+ /** Source files to analyze (glob patterns supported) */
57
+ files: string[];
58
+ /** Output file path */
59
+ output: string;
60
+ /** Base directory for relative imports */
61
+ baseDir?: string;
62
+ }
63
+ /**
64
+ * Finds all decorated classes in the given source files.
65
+ */
66
+ export declare function findDecoratedClasses(files: string[], baseDir: string): DecoratedClassInfo[];
67
+ /**
68
+ * Generates the codegen output file content.
69
+ */
70
+ export declare function generateCodegenOutput(classes: DecoratedClassInfo[], outputPath: string, baseDir: string): string;
71
+ /**
72
+ * Runs the code generation.
73
+ */
74
+ export declare function runCodegen(options: CodegenOptions): void;
75
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC1C,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3C,yDAAyD;IACzD,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAoC3F;AA6MD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,kBAAkB,EAAE,EAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,MAAM,CAuER;AA2RD;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CA6CxD"}