@pwfabric/authoring 0.0.0-stage → 1.0.0-rc.0

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.
@@ -0,0 +1,277 @@
1
+ /**
2
+ * CustomBlockRegistry
3
+ *
4
+ * Registry for managing custom block definitions.
5
+ *
6
+ * @module @pwfabric/authoring/registry
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { createCustomBlockRegistry, defineBlock } from '@pwfabric/authoring'
11
+ * import { z } from 'zod'
12
+ *
13
+ * const registry = createCustomBlockRegistry()
14
+ *
15
+ * const MyBlock = defineBlock({
16
+ * type: 'my-block',
17
+ * name: 'My Block',
18
+ * schema: z.object({ title: z.string() }),
19
+ * defaultProps: { title: 'Default' },
20
+ * component: ({ props }) => <div>{props.title}</div>
21
+ * })
22
+ *
23
+ * registry.register(MyBlock)
24
+ *
25
+ * // Use with SurfaceRenderer
26
+ * <SurfaceRenderer components={registry.getComponents()} />
27
+ * ```
28
+ */
29
+ import { createElement } from 'react';
30
+ // ============================================================
31
+ // CUSTOM BLOCK REGISTRY
32
+ // ============================================================
33
+ /**
34
+ * CustomBlockRegistry
35
+ *
36
+ * Manages registration and retrieval of custom block definitions.
37
+ * Provides a bridge between custom block definitions and the
38
+ * SurfaceRenderer component registry.
39
+ */
40
+ export class CustomBlockRegistry {
41
+ definitions = new Map();
42
+ /**
43
+ * Register a custom block definition
44
+ *
45
+ * @param definition - The custom block definition to register
46
+ * @throws Error if block type already registered
47
+ */
48
+ register(definition) {
49
+ if (this.definitions.has(definition.type)) {
50
+ throw new Error(`Block type "${definition.type}" is already registered`);
51
+ }
52
+ this.definitions.set(definition.type, definition);
53
+ }
54
+ /**
55
+ * Register multiple custom block definitions
56
+ *
57
+ * @param definitions - Array of custom block definitions
58
+ */
59
+ registerMany(definitions) {
60
+ for (const definition of definitions) {
61
+ this.register(definition);
62
+ }
63
+ }
64
+ /**
65
+ * Get a custom block definition by type
66
+ *
67
+ * @param type - Block type identifier
68
+ * @returns The block definition or undefined
69
+ */
70
+ get(type) {
71
+ return this.definitions.get(type);
72
+ }
73
+ /**
74
+ * Check if a block type is registered
75
+ *
76
+ * @param type - Block type identifier
77
+ * @returns True if registered
78
+ */
79
+ has(type) {
80
+ return this.definitions.has(type);
81
+ }
82
+ /**
83
+ * Get all registered custom block definitions
84
+ *
85
+ * @returns Array of all block definitions
86
+ */
87
+ list() {
88
+ return Array.from(this.definitions.values());
89
+ }
90
+ /**
91
+ * Get block definitions by category
92
+ *
93
+ * @param category - Block category
94
+ * @returns Array of block definitions in category
95
+ */
96
+ getByCategory(category) {
97
+ return this.list().filter((def) => def.category === category);
98
+ }
99
+ /**
100
+ * Get all registered block types
101
+ *
102
+ * @returns Array of block type identifiers
103
+ */
104
+ types() {
105
+ return Array.from(this.definitions.keys());
106
+ }
107
+ /**
108
+ * Unregister a custom block
109
+ *
110
+ * @param type - Block type identifier
111
+ * @returns True if block was unregistered
112
+ */
113
+ unregister(type) {
114
+ return this.definitions.delete(type);
115
+ }
116
+ /**
117
+ * Clear all registrations
118
+ */
119
+ clear() {
120
+ this.definitions.clear();
121
+ }
122
+ /**
123
+ * Get number of registered blocks
124
+ */
125
+ get size() {
126
+ return this.definitions.size;
127
+ }
128
+ /**
129
+ * Get a component registry for use with SurfaceRenderer
130
+ *
131
+ * This method creates a BlockComponentRegistry that can be passed
132
+ * to the SurfaceRenderer's `components` prop to enable rendering
133
+ * of custom blocks.
134
+ *
135
+ * @returns BlockComponentRegistry with all registered custom blocks
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * import { SurfaceRenderer } from '@pwfabric/runtime'
140
+ *
141
+ * const registry = createCustomBlockRegistry()
142
+ * registry.register(MyCustomBlock)
143
+ *
144
+ * // Pass to SurfaceRenderer
145
+ * <SurfaceRenderer
146
+ * surface={mySurface}
147
+ * components={registry.getComponents()}
148
+ * />
149
+ * ```
150
+ */
151
+ getComponents() {
152
+ const components = {};
153
+ for (const definition of this.definitions.values()) {
154
+ components[definition.type] = createBlockComponentWrapper(definition);
155
+ }
156
+ return components;
157
+ }
158
+ }
159
+ /**
160
+ * Create a wrapper component that adapts CustomBlockComponent to BlockComponent
161
+ *
162
+ * This bridges the gap between the SDK's CustomBlockComponent interface
163
+ * and the runtime's BlockComponent interface.
164
+ */
165
+ /**
166
+ * Map runtime BlockContext to SDK CustomBlockContext
167
+ *
168
+ * Narrows the full runtime context to only what custom block authors need.
169
+ * Excludes: capabilities, imageAdapter, basePath (platform internals).
170
+ */
171
+ function mapToCustomBlockContext(runtimeContext) {
172
+ if (!runtimeContext || typeof runtimeContext !== 'object')
173
+ return undefined;
174
+ const ctx = runtimeContext;
175
+ return {
176
+ theme: ctx.theme ?? 'light',
177
+ viewport: ctx.viewport ?? 'lg',
178
+ onEvent: typeof ctx.onEvent === 'function'
179
+ ? (event) => {
180
+ ;
181
+ ctx.onEvent(event);
182
+ }
183
+ : undefined,
184
+ };
185
+ }
186
+ function createBlockComponentWrapper(definition) {
187
+ return function WrappedComponent({ block, props: rawProps, children, context, }) {
188
+ // Validate and apply defaults using the schema
189
+ const result = definition.schema.safeParse(rawProps);
190
+ const validatedProps = result.success ? result.data : definition.defaultProps;
191
+ // Map runtime context to custom block context
192
+ const customContext = mapToCustomBlockContext(context);
193
+ // Create the custom block component props
194
+ const customProps = {
195
+ props: validatedProps,
196
+ blockId: block.id,
197
+ children,
198
+ context: customContext,
199
+ };
200
+ // Render using the custom component
201
+ return createElement(definition.component, customProps);
202
+ };
203
+ }
204
+ // ============================================================
205
+ // FACTORY FUNCTIONS
206
+ // ============================================================
207
+ /**
208
+ * Create a new CustomBlockRegistry
209
+ *
210
+ * @returns A new CustomBlockRegistry instance
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * const registry = createCustomBlockRegistry()
215
+ * registry.register(MyBlock)
216
+ * ```
217
+ */
218
+ export function createCustomBlockRegistry() {
219
+ return new CustomBlockRegistry();
220
+ }
221
+ /**
222
+ * Get a singleton instance of CustomBlockRegistry
223
+ *
224
+ * Use this when you want a shared registry across your application.
225
+ * For isolated registries (e.g., in tests), use `createCustomBlockRegistry()`.
226
+ */
227
+ let globalRegistry = null;
228
+ export function getCustomBlockRegistry() {
229
+ if (!globalRegistry) {
230
+ globalRegistry = new CustomBlockRegistry();
231
+ }
232
+ return globalRegistry;
233
+ }
234
+ /**
235
+ * Reset the global registry
236
+ *
237
+ * Useful for testing or when you need to clear all registrations.
238
+ */
239
+ export function resetGlobalRegistry() {
240
+ globalRegistry = null;
241
+ }
242
+ // ============================================================
243
+ // MERGE UTILITIES
244
+ // ============================================================
245
+ /**
246
+ * Merge multiple custom block registries into one
247
+ *
248
+ * @param registries - Registries to merge
249
+ * @returns A new registry containing all blocks from input registries
250
+ * @throws Error if there are duplicate block types
251
+ */
252
+ export function mergeRegistries(...registries) {
253
+ const merged = new CustomBlockRegistry();
254
+ for (const registry of registries) {
255
+ for (const definition of registry.list()) {
256
+ merged.register(definition);
257
+ }
258
+ }
259
+ return merged;
260
+ }
261
+ /**
262
+ * Merge a custom block registry with a base BlockComponentRegistry
263
+ *
264
+ * This is useful when you want to extend the default block components
265
+ * with custom blocks.
266
+ *
267
+ * @param baseComponents - The base component registry (e.g., defaultBlockComponents)
268
+ * @param customRegistry - The custom block registry
269
+ * @returns A merged BlockComponentRegistry
270
+ */
271
+ export function mergeWithBaseComponents(baseComponents, customRegistry) {
272
+ return {
273
+ ...baseComponents,
274
+ ...customRegistry.getComponents(),
275
+ };
276
+ }
277
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,272 @@
1
+ /**
2
+ * @pwfabric/authoring Type Definitions
3
+ *
4
+ * Core type definitions for the Custom Block SDK.
5
+ *
6
+ * @module @pwfabric/authoring/types
7
+ */
8
+ import type { ZodSchema, ZodTypeDef } from 'zod';
9
+ import type { Block, BlockCategory } from '@pwfabric/core';
10
+ import type { BlockComponentRegistry } from '@pwfabric/runtime';
11
+ import type { ReactNode } from 'react';
12
+ /**
13
+ * Custom block definition options
14
+ *
15
+ * Used with `defineBlock()` to create a type-safe custom block.
16
+ */
17
+ export interface CustomBlockOptions<TProps extends Record<string, unknown> = Record<string, unknown>, TSchema extends ZodSchema<TProps, ZodTypeDef, unknown> = ZodSchema<TProps>> {
18
+ /** Unique block type identifier (kebab-case) */
19
+ readonly type: string;
20
+ /** Human-readable display name */
21
+ readonly name: string;
22
+ /** Block category for grouping */
23
+ readonly category?: BlockCategory;
24
+ /** Icon character or identifier */
25
+ readonly icon?: string;
26
+ /** Zod schema for props validation */
27
+ readonly schema: TSchema;
28
+ /** Default props for new instances */
29
+ readonly defaultProps: TProps;
30
+ /** Whether this block can contain children */
31
+ readonly canHaveChildren?: boolean;
32
+ /** Restrict which block types can be children */
33
+ readonly allowedChildren?: readonly string[];
34
+ /** Restrict which block types can be parents */
35
+ readonly allowedParents?: readonly string[];
36
+ /** open trait vocabulary this block carries (kebab-case). */
37
+ readonly traits?: readonly string[];
38
+ /** children must carry ANY of these traits (containers only). */
39
+ readonly allowedChildTraits?: readonly string[];
40
+ /** Maximum instances allowed in a surface */
41
+ readonly maxInstances?: number;
42
+ /** React component to render this block */
43
+ readonly component: CustomBlockComponent<TProps>;
44
+ }
45
+ /**
46
+ * Custom block context
47
+ *
48
+ * Narrowed view of the runtime BlockContext for custom block authors.
49
+ * Excludes platform internals (capabilities, imageAdapter, basePath).
50
+ */
51
+ export interface CustomBlockContext {
52
+ /** Current theme */
53
+ readonly theme: 'light' | 'dark';
54
+ /** Current viewport breakpoint */
55
+ readonly viewport: string;
56
+ /** Event handler for block-level events */
57
+ readonly onEvent?: ((event: {
58
+ type: string;
59
+ blockId?: string;
60
+ payload?: unknown;
61
+ }) => void) | undefined;
62
+ }
63
+ /**
64
+ * Custom block component props
65
+ */
66
+ export interface CustomBlockComponentProps<TProps = Record<string, unknown>> {
67
+ /** The resolved, type-safe props */
68
+ readonly props: TProps;
69
+ /** Block ID */
70
+ readonly blockId: string;
71
+ /** Rendered children (for container blocks) */
72
+ readonly children?: ReactNode;
73
+ /** Runtime context (theme, viewport, events) */
74
+ readonly context?: CustomBlockContext | undefined;
75
+ }
76
+ /**
77
+ * Custom block component type
78
+ */
79
+ export type CustomBlockComponent<TProps = Record<string, unknown>> = (props: CustomBlockComponentProps<TProps>) => ReactNode;
80
+ /**
81
+ * Custom block definition (result of defineBlock)
82
+ *
83
+ * Contains both the block metadata and the component for rendering.
84
+ */
85
+ export interface CustomBlockDefinition<TProps extends Record<string, unknown> = Record<string, unknown>> {
86
+ /** Unique block type identifier */
87
+ readonly type: string;
88
+ /** Human-readable display name */
89
+ readonly name: string;
90
+ /** Block category */
91
+ readonly category: BlockCategory;
92
+ /** Icon character or identifier */
93
+ readonly icon: string;
94
+ /** Zod schema for validation */
95
+ readonly schema: ZodSchema<TProps>;
96
+ /** Default props */
97
+ readonly defaultProps: TProps;
98
+ /** Whether this block can contain children */
99
+ readonly canHaveChildren: boolean;
100
+ /** Allowed child block types */
101
+ readonly allowedChildren?: readonly string[];
102
+ /** Allowed parent block types */
103
+ readonly allowedParents?: readonly string[];
104
+ /** open trait vocabulary this block carries (kebab-case). */
105
+ readonly traits?: readonly string[];
106
+ /** children must carry ANY of these traits (containers only). */
107
+ readonly allowedChildTraits?: readonly string[];
108
+ /** Maximum instances */
109
+ readonly maxInstances?: number;
110
+ /** React component */
111
+ readonly component: CustomBlockComponent<TProps>;
112
+ }
113
+ /**
114
+ * Factory configuration input
115
+ *
116
+ * Passed to the build function to customize the generated blocks.
117
+ */
118
+ export type FactoryConfig = Record<string, unknown>;
119
+ /**
120
+ * Block specification for factory output
121
+ *
122
+ * Simplified block definition without requiring an id (auto-generated).
123
+ */
124
+ export interface BlockSpec {
125
+ /** Block type */
126
+ readonly type: string;
127
+ /** Block props */
128
+ readonly props: Record<string, unknown>;
129
+ /** Nested children */
130
+ readonly children?: readonly BlockSpec[];
131
+ }
132
+ /**
133
+ * Factory definition options
134
+ *
135
+ * Used with `defineFactory()` to create a factory function.
136
+ */
137
+ export interface FactoryOptions<TConfig extends FactoryConfig = FactoryConfig> {
138
+ /** Unique factory identifier (kebab-case) */
139
+ readonly id: string;
140
+ /** Human-readable factory name */
141
+ readonly name?: string;
142
+ /** Factory description */
143
+ readonly description?: string;
144
+ /** Optional Zod schema for config validation */
145
+ readonly configSchema?: ZodSchema<TConfig>;
146
+ /** Build function that returns block specifications */
147
+ readonly build: (config: TConfig) => readonly BlockSpec[];
148
+ }
149
+ /**
150
+ * Factory definition (result of defineFactory)
151
+ */
152
+ export interface FactoryDefinition<TConfig extends FactoryConfig = FactoryConfig> {
153
+ /** Factory identifier */
154
+ readonly id: string;
155
+ /** Factory name */
156
+ readonly name: string;
157
+ /** Factory description */
158
+ readonly description: string;
159
+ /** Config schema (if provided) */
160
+ readonly configSchema?: ZodSchema<TConfig>;
161
+ /** Build function */
162
+ readonly build: (config: TConfig) => readonly Block[];
163
+ /** Validate config against schema (if provided) */
164
+ readonly validateConfig: (config: unknown) => FactoryValidationResult<TConfig>;
165
+ }
166
+ /**
167
+ * Factory validation result
168
+ */
169
+ export interface FactoryValidationResult<TConfig = FactoryConfig> {
170
+ /** Whether validation passed */
171
+ readonly valid: boolean;
172
+ /** Validated config (if valid) */
173
+ readonly config?: TConfig;
174
+ /** Validation errors (if invalid) */
175
+ readonly errors?: readonly FactoryValidationError[];
176
+ }
177
+ /**
178
+ * Factory validation error
179
+ */
180
+ export interface FactoryValidationError {
181
+ /** Error path in the config */
182
+ readonly path: string;
183
+ /** Error message */
184
+ readonly message: string;
185
+ }
186
+ /**
187
+ * Custom block registry interface
188
+ */
189
+ export interface ICustomBlockRegistry {
190
+ /**
191
+ * Register a custom block definition
192
+ */
193
+ register<TProps extends Record<string, unknown>>(definition: CustomBlockDefinition<TProps>): void;
194
+ /**
195
+ * Get a custom block definition by type
196
+ */
197
+ get(type: string): CustomBlockDefinition | undefined;
198
+ /**
199
+ * Check if a block type is registered
200
+ */
201
+ has(type: string): boolean;
202
+ /**
203
+ * Get all registered custom block definitions
204
+ */
205
+ list(): readonly CustomBlockDefinition[];
206
+ /**
207
+ * Get block definitions by category
208
+ */
209
+ getByCategory(category: BlockCategory): readonly CustomBlockDefinition[];
210
+ /**
211
+ * Get all registered block types
212
+ */
213
+ types(): readonly string[];
214
+ /**
215
+ * Unregister a custom block
216
+ */
217
+ unregister(type: string): boolean;
218
+ /**
219
+ * Clear all registrations
220
+ */
221
+ clear(): void;
222
+ /**
223
+ * Get a component registry for use with SurfaceRenderer
224
+ */
225
+ getComponents(): BlockComponentRegistry;
226
+ }
227
+ /**
228
+ * Block validation result
229
+ */
230
+ export interface BlockValidationResult {
231
+ /** Whether the block is valid */
232
+ readonly valid: boolean;
233
+ /** The validated block (with defaults applied) */
234
+ readonly block?: Block;
235
+ /** Validation errors */
236
+ readonly errors: readonly BlockValidationError[];
237
+ }
238
+ /**
239
+ * Block validation error
240
+ */
241
+ export interface BlockValidationError {
242
+ /** Error code */
243
+ readonly code: string;
244
+ /** Error message */
245
+ readonly message: string;
246
+ /** Path to the invalid property */
247
+ readonly path?: string;
248
+ }
249
+ /**
250
+ * Props validation result
251
+ */
252
+ export interface PropsValidationResult<TProps = Record<string, unknown>> {
253
+ /** Whether the props are valid */
254
+ readonly valid: boolean;
255
+ /** The validated props (with defaults applied) */
256
+ readonly props?: TProps;
257
+ /** Validation errors */
258
+ readonly errors: readonly BlockValidationError[];
259
+ }
260
+ /**
261
+ * Infer props type from a custom block definition
262
+ */
263
+ export type InferBlockProps<T> = T extends CustomBlockDefinition<infer TProps> ? TProps : never;
264
+ /**
265
+ * Infer config type from a factory definition
266
+ */
267
+ export type InferFactoryConfig<T> = T extends FactoryDefinition<infer TConfig> ? TConfig : never;
268
+ /**
269
+ * Infer props type from a Zod schema
270
+ */
271
+ export type InferSchemaProps<T> = T extends ZodSchema<infer TOutput> ? TOutput : never;
272
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @pwfabric/authoring Type Definitions
3
+ *
4
+ * Core type definitions for the Custom Block SDK.
5
+ *
6
+ * @module @pwfabric/authoring/types
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Validation Utilities
3
+ *
4
+ * Schema validation utilities for custom blocks.
5
+ *
6
+ * @module @pwfabric/authoring/validation
7
+ */
8
+ import type { ZodSchema } from 'zod';
9
+ import type { Block } from '@pwfabric/core';
10
+ import type { CustomBlockDefinition, BlockValidationResult, BlockValidationError, PropsValidationResult, ICustomBlockRegistry } from './types.js';
11
+ /**
12
+ * Validate props against a Zod schema
13
+ *
14
+ * @param props - The props to validate
15
+ * @param schema - The Zod schema to validate against
16
+ * @returns Validation result with validated props or errors
17
+ */
18
+ export declare function validateProps<TProps extends Record<string, unknown>>(props: unknown, schema: ZodSchema<TProps>): PropsValidationResult<TProps>;
19
+ /**
20
+ * Validate props with defaults applied
21
+ *
22
+ * If validation fails, returns the default props.
23
+ *
24
+ * @param props - The props to validate
25
+ * @param schema - The Zod schema
26
+ * @param defaultProps - Default props to use if validation fails
27
+ * @returns Validated props or defaults
28
+ */
29
+ export declare function validatePropsWithDefaults<TProps extends Record<string, unknown>>(props: unknown, schema: ZodSchema<TProps>, defaultProps: TProps): TProps;
30
+ /**
31
+ * Validate a block against its definition
32
+ *
33
+ * @param block - The block to validate
34
+ * @param definition - The block definition
35
+ * @returns Validation result
36
+ */
37
+ export declare function validateBlock<TProps extends Record<string, unknown>>(block: Block, definition: CustomBlockDefinition<TProps>): BlockValidationResult;
38
+ /**
39
+ * Validate a block tree against a registry of definitions
40
+ *
41
+ * Recursively validates all blocks in the tree.
42
+ *
43
+ * @param blocks - The blocks to validate
44
+ * @param registry - The block registry
45
+ * @returns Array of validation errors (empty if all valid)
46
+ */
47
+ export declare function validateBlockTree(blocks: readonly Block[], registry: ICustomBlockRegistry): readonly BlockValidationError[];
48
+ /**
49
+ * Create a validation function for a specific block type
50
+ *
51
+ * @param definition - The block definition
52
+ * @returns A validation function
53
+ */
54
+ export declare function createBlockValidator<TProps extends Record<string, unknown>>(definition: CustomBlockDefinition<TProps>): (block: Block) => BlockValidationResult;
55
+ /**
56
+ * Create a props validation function for a specific schema
57
+ *
58
+ * @param schema - The Zod schema
59
+ * @returns A validation function
60
+ */
61
+ export declare function createPropsValidator<TProps extends Record<string, unknown>>(schema: ZodSchema<TProps>): (props: unknown) => PropsValidationResult<TProps>;
62
+ /**
63
+ * Format validation errors as a human-readable string
64
+ *
65
+ * @param errors - The validation errors
66
+ * @returns Formatted error string
67
+ */
68
+ export declare function formatValidationErrors(errors: readonly BlockValidationError[]): string;
69
+ /**
70
+ * Check if a validation result has errors
71
+ */
72
+ export declare function hasErrors(result: BlockValidationResult | PropsValidationResult): boolean;
73
+ /**
74
+ * Check if a value is a valid Block
75
+ */
76
+ export declare function isBlock(value: unknown): value is Block;
77
+ /**
78
+ * Check if a value is a valid Block array
79
+ */
80
+ export declare function isBlockArray(value: unknown): value is Block[];
81
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AACpC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,YAAY,CAAA;AAMnB;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,GACxB,qBAAqB,CAAC,MAAM,CAAC,CAqB/B;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9E,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EACzB,YAAY,EAAE,MAAM,GACnB,MAAM,CAGR;AAMD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,qBAAqB,CAAC,MAAM,CAAC,GACxC,qBAAqB,CAoDvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,QAAQ,EAAE,oBAAoB,GAC7B,SAAS,oBAAoB,EAAE,CAuCjC;AAMD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,UAAU,EAAE,qBAAqB,CAAC,MAAM,CAAC,GACxC,CAAC,KAAK,EAAE,KAAK,KAAK,qBAAqB,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,GACxB,CAAC,KAAK,EAAE,OAAO,KAAK,qBAAqB,CAAC,MAAM,CAAC,CAEnD;AAMD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,GAAG,MAAM,CAWtF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,qBAAqB,GAAG,qBAAqB,GAAG,OAAO,CAExF;AAMD;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,CAWtD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,EAAE,CAE7D"}