@outburn/fume-mapping-provider 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Outburn
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,397 @@
1
+ # @outburn/fume-mapping-provider
2
+
3
+ A TypeScript module for managing pre-defined, named FUME expressions (mappings) from multiple sources: files, FHIR servers, and FHIR packages.
4
+
5
+ ## Features
6
+
7
+ - 🚀 **Lightning-fast user mappings**: In-memory cache for file and server mappings
8
+ - 📁 **File mappings**: Load from local `.fume` files (or custom extensions)
9
+ - 🌐 **Server mappings**: Load from FHIR servers with automatic pagination
10
+ - 📦 **Package mappings**: Load from FHIR packages via `fhir-package-explorer`
11
+ - 🔄 **Smart collision handling**: File mappings override server mappings
12
+ - 🔍 **Flexible search**: Find package mappings by URL, ID, or name
13
+ - 📝 **Structured logging**: Optional logger interface support
14
+ - ✅ **FUME validation**: Filters StructureMaps by FUME-specific extensions
15
+
16
+ ## Architecture
17
+
18
+ The provider separates mappings into two categories:
19
+
20
+ ### User Mappings (File + Server)
21
+ - **Fast access**: Loaded once, cached in memory
22
+ - **Key-based lookup**: Use unique keys for instant retrieval
23
+ - **Collision resolution**: File mappings override server mappings with warnings
24
+ - **Refresh by key**: Update individual mappings without full reload
25
+
26
+ ### Package Mappings
27
+ - **Always fresh**: Queried from FPE on demand (FPE handles caching)
28
+ - **Immutable**: Packages never change once installed
29
+ - **Smart identifier resolution**: Try URL → ID → name automatically
30
+ - **Package filtering**: Filter by package context
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ npm install @outburn/fume-mapping-provider
36
+
37
+ # Dependencies based on usage:
38
+ npm install fhir-package-explorer # For package mappings
39
+ npm install @outburn/fhir-client # For server mappings
40
+ ```
41
+
42
+ ## Quick Start
43
+
44
+ ```typescript
45
+ import { FumeMappingProvider } from '@outburn/fume-mapping-provider';
46
+ import { FhirPackageExplorer } from 'fhir-package-explorer';
47
+ import { FhirClient } from '@outburn/fhir-client';
48
+
49
+ // Setup dependencies
50
+ const fhirClient = new FhirClient({ baseUrl: 'https://hapi.fhir.org/baseR4' });
51
+ const packageExplorer = await FhirPackageExplorer.create({
52
+ context: ['hl7.fhir.us.core@6.1.0']
53
+ });
54
+
55
+ // Create provider
56
+ const provider = new FumeMappingProvider({
57
+ mappingsFolder: './mappings',
58
+ fileExtension: '.fume', // Optional, default is '.fume'
59
+ fhirClient: fhirClient,
60
+ packageExplorer: packageExplorer,
61
+ logger: console // Optional
62
+ });
63
+
64
+ // Initialize (loads user mappings into cache)
65
+ await provider.initialize();
66
+ ```
67
+
68
+ ## User Mappings API
69
+
70
+ ### Load and Cache
71
+
72
+ ```typescript
73
+ // Initialize loads all user mappings (file + server) into memory
74
+ await provider.initialize();
75
+
76
+ // Reload all user mappings
77
+ await provider.reloadUserMappings();
78
+
79
+ // Refresh specific mapping by key (fetches from source)
80
+ await provider.refreshUserMapping('my-mapping-key');
81
+
82
+ // Optimistic update - provide mapping directly to avoid roundtrip
83
+ // Useful after successfully updating the FHIR server
84
+ const updatedMapping = {
85
+ key: 'my-mapping-key',
86
+ expression: '$output = { updated: true }',
87
+ source: 'server',
88
+ sourceServer: 'http://my-server.com'
89
+ };
90
+ await provider.refreshUserMapping('my-mapping-key', updatedMapping);
91
+
92
+ // Optimistic delete - pass null to remove from cache
93
+ await provider.refreshUserMapping('deleted-key', null);
94
+ ```
95
+
96
+ ### Get User Mappings (Lightning Fast ⚡)
97
+
98
+ ```typescript
99
+ // Get all user mappings
100
+ const mappings = provider.getUserMappings();
101
+ // Returns: UserMapping[]
102
+
103
+ // Get all user mapping keys
104
+ const keys = provider.getUserMappingKeys();
105
+ // Returns: string[]
106
+
107
+ // Get metadata only (without expressions)
108
+ const metadata = provider.getUserMappingsMetadata();
109
+ // Returns: UserMappingMetadata[]
110
+
111
+ // Get specific mapping by key
112
+ const mapping = provider.getUserMapping('my-key');
113
+ // Returns: UserMapping | undefined
114
+ ```
115
+
116
+ ### UserMapping Structure
117
+
118
+ ```typescript
119
+ interface UserMapping {
120
+ key: string; // Unique identifier
121
+ expression: string; // FUME expression
122
+ source: 'file' | 'server'; // Origin
123
+ filename?: string; // For file mappings
124
+ sourceServer?: string; // For server mappings
125
+ name?: string; // StructureMap.name
126
+ url?: string; // StructureMap.url
127
+ }
128
+ ```
129
+
130
+ ## Package Mappings API
131
+
132
+ ### Get Package Mappings
133
+
134
+ ```typescript
135
+ // Get all package mappings
136
+ const mappings = await provider.getPackageMappings();
137
+
138
+ // Filter by package context
139
+ const mappings = await provider.getPackageMappings({
140
+ packageContext: 'hl7.fhir.us.core@6.1.0'
141
+ });
142
+
143
+ // Get metadata only (without expressions)
144
+ const metadata = await provider.getPackageMappingsMetadata();
145
+ ```
146
+
147
+ ## Aliases API
148
+
149
+ ### Overview
150
+
151
+ Aliases are simple key-value string mappings stored in a special ConceptMap resource on the FHIR server. Unlike mappings, aliases are:
152
+ - **Server-only**: Not loaded from files or packages
153
+ - **Consolidated**: Always served as a single object
154
+ - **Cached**: Loaded once during initialization for fast access
155
+
156
+ ### Alias Resource Structure
157
+
158
+ FUME aliases are stored in a ConceptMap resource with this specific `useContext`:
159
+
160
+ ```typescript
161
+ {
162
+ code: {
163
+ system: "http://snomed.info/sct",
164
+ code: "706594005"
165
+ },
166
+ valueCodeableConcept: {
167
+ coding: [{
168
+ system: "http://codes.fume.health",
169
+ code: "fume"
170
+ }]
171
+ }
172
+ }
173
+ ```
174
+
175
+ The server is queried with: `GET [baseUrl]/ConceptMap?context=http://codes.fume.health|fume&name=FumeAliases`
176
+
177
+ ### Get Aliases
178
+
179
+ ```typescript
180
+ // Get all aliases (fast, cached)
181
+ const aliases = provider.getAliases();
182
+ // Returns: { [key: string]: string }
183
+
184
+ // Example:
185
+ // {
186
+ // "patientSystemUrl": "http://example.com/patients",
187
+ // "defaultLanguage": "en-US",
188
+ // "apiVersion": "v1"
189
+ // }
190
+ ```
191
+
192
+ ### Reload Aliases
193
+
194
+ ```typescript
195
+ // Reload from server (updates cache)
196
+ await provider.reloadAliases();
197
+ ```
198
+
199
+ ### Optimistic Updates
200
+
201
+ ```typescript
202
+ // Register or update a single alias (no server roundtrip)
203
+ provider.registerAlias('newKey', 'newValue');
204
+
205
+ // Delete an alias from cache
206
+ provider.deleteAlias('oldKey');
207
+ ```
208
+
209
+ ### Transforming Alias Resources
210
+
211
+ ```typescript
212
+ // ConceptMap → Alias Object
213
+ const aliases = FumeMappingProvider.conceptMapToAliasObject(conceptMap);
214
+
215
+ // Alias Object → ConceptMap
216
+ const conceptMap = FumeMappingProvider.aliasObjectToConceptMap(
217
+ aliases,
218
+ 'http://example.com', // canonical base URL
219
+ existingConceptMap // optional: update existing resource
220
+ );
221
+ ```
222
+
223
+ ## Package Mappings API
224
+
225
+ ### Get by Identifier
226
+
227
+ Automatically tries URL → ID → name in order, returns first match:
228
+
229
+ ```typescript
230
+ // Try to find by URL, ID, or name
231
+ const mapping = await provider.getPackageMapping('patient-transform');
232
+ // First tries as URL, then ID, then name
233
+
234
+ // With package filtering
235
+ const mapping = await provider.getPackageMapping('patient-transform', {
236
+ packageContext: 'hl7.fhir.us.core@6.1.0'
237
+ });
238
+ ```
239
+
240
+ ### PackageMapping Structure
241
+
242
+ ```typescript
243
+ interface PackageMapping {
244
+ id: string; // StructureMap.id
245
+ expression: string; // FUME expression
246
+ packageId: string; // Package ID
247
+ packageVersion: string; // Package version
248
+ filename: string; // File in package
249
+ name?: string; // StructureMap.name
250
+ url?: string; // StructureMap.url
251
+ }
252
+ ```
253
+
254
+ ## Collision Handling
255
+
256
+ When a file mapping has the same key as a server mapping:
257
+
258
+ 1. **File mapping wins** (overrides server mapping)
259
+ 2. **Warning is logged** (if logger provided)
260
+ 3. **Refresh checks file first**, falls back to server if file deleted
261
+
262
+ ```typescript
263
+ // File: ./mappings/my-mapping.fume
264
+ // expression: InstanceOf: Patient
265
+
266
+ // Server: StructureMap with id="my-mapping"
267
+ // expression: InstanceOf: Patient
268
+
269
+ // After initialize():
270
+ const mapping = provider.getUserMapping('my-mapping');
271
+ // mapping.source === 'file'
272
+ // mapping.expression === 'InstanceOf: Patient'
273
+ // Warning logged: "File mapping 'my-mapping' overrides server mapping"
274
+ ```
275
+
276
+ ## Examples
277
+
278
+ ### File-Only Setup
279
+
280
+ ```typescript
281
+ const provider = new FumeMappingProvider({
282
+ mappingsFolder: './mappings'
283
+ });
284
+
285
+ await provider.initialize();
286
+
287
+ const keys = provider.getUserMappingKeys();
288
+ // ['mapping1', 'mapping2', 'mapping3']
289
+
290
+ const mapping = provider.getUserMapping('mapping1');
291
+ // { key: 'mapping1', expression: '...', source: 'file' }
292
+ ```
293
+
294
+ ### Server-Only Setup
295
+
296
+ ```typescript
297
+ const provider = new FumeMappingProvider({
298
+ fhirClient: new FhirClient({ baseUrl: 'https://fhir.server.com' })
299
+ });
300
+
301
+ await provider.initialize();
302
+
303
+ const mappings = provider.getUserMappings();
304
+ // All StructureMaps from server (with FUME extensions)
305
+ ```
306
+
307
+ ### Package-Only Setup
308
+
309
+ ```typescript
310
+ const explorer = await FhirPackageExplorer.create({
311
+ context: ['hl7.fhir.us.core@6.1.0']
312
+ });
313
+
314
+ const provider = new FumeMappingProvider({
315
+ packageExplorer: explorer
316
+ });
317
+
318
+ // No initialize needed for package-only
319
+ const mappings = await provider.getPackageMappings();
320
+ ```
321
+
322
+ ### Combined Setup
323
+
324
+ ```typescript
325
+ const provider = new FumeMappingProvider({
326
+ mappingsFolder: './mappings',
327
+ fhirClient: fhirClient,
328
+ packageExplorer: explorer,
329
+ logger: console
330
+ });
331
+
332
+ await provider.initialize(); // Loads user mappings only
333
+
334
+ // User mappings (fast, cached)
335
+ const userKeys = provider.getUserMappingKeys();
336
+ const userMapping = provider.getUserMapping('my-key');
337
+
338
+ // Package mappings (on-demand)
339
+ const pkgMappings = await provider.getPackageMappings();
340
+ const pkgMapping = await provider.getPackageMapping('patient-transform');
341
+ ```
342
+ ## API Reference
343
+
344
+ ### FumeMappingProvider
345
+
346
+ #### Constructor
347
+
348
+ ```typescript
349
+ new FumeMappingProvider(config: FumeMappingProviderConfig)
350
+ ```
351
+
352
+ #### Methods
353
+
354
+ **Initialization:**
355
+ - `initialize(): Promise<void>` - Load user mappings into cache
356
+ - `reloadUserMappings(): Promise<void>` - Reload all user mappings
357
+ - `refreshUserMapping(key: string): Promise<UserMapping | null>` - Refresh specific user mapping
358
+
359
+ **User Mappings (Cached, Fast):**
360
+ - `getUserMappings(): UserMapping[]` - Get all user mappings
361
+ - `getUserMappingKeys(): string[]` - Get all user mapping keys
362
+ - `getUserMappingsMetadata(): UserMappingMetadata[]` - Get metadata only
363
+ - `getUserMapping(key: string): UserMapping | undefined` - Get specific mapping
364
+
365
+ **Package Mappings (On-Demand):**
366
+ - `getPackageMappings(options?: GetPackageMappingOptions): Promise<PackageMapping[]>` - Get all package mappings
367
+ - `getPackageMappingsMetadata(options?: GetPackageMappingOptions): Promise<PackageMappingMetadata[]>` - Get metadata only
368
+ - `getPackageMapping(identifier: string, options?: GetPackageMappingOptions): Promise<PackageMapping | null>` - Get by identifier
369
+
370
+ **Aliases (Cached, Fast):**
371
+ - `reloadAliases(): Promise<void>` - Reload all aliases from server
372
+ - `registerAlias(name: string, value: string): void` - Register/update a single alias (optimistic cache update)
373
+ - `deleteAlias(name: string): void` - Delete a specific alias from cache
374
+ - `getAliases(): AliasObject` - Get all cached aliases as single object
375
+
376
+ **Static Converters:**
377
+ - `FumeMappingProvider.structureMapToExpression(structureMap: StructureMap): string | null` - Extract FUME expression from StructureMap
378
+ - `FumeMappingProvider.expressionToStructureMap(mappingId: string, expression: string, canonicalBaseUrl?: string): StructureMap` - Create StructureMap from expression
379
+ - `FumeMappingProvider.conceptMapToAliasObject(conceptMap: ConceptMap): AliasObject` - Transform ConceptMap to alias object
380
+ - `FumeMappingProvider.aliasObjectToConceptMap(aliases: AliasObject, canonicalBaseUrl?: string, existingConceptMap?: ConceptMap): ConceptMap` - Transform alias object to ConceptMap
381
+
382
+ ### Configuration
383
+
384
+ ```typescript
385
+ interface FumeMappingProviderConfig {
386
+ mappingsFolder?: string; // Path to .fume files
387
+ fileExtension?: string; // Default: '.fume'
388
+ fhirClient?: any; // FHIR client instance
389
+ packageExplorer?: any; // FPE instance
390
+ logger?: Logger; // Optional logger
391
+ }
392
+ ```
393
+
394
+ ## License
395
+
396
+ MIT
397
+ © Outburn Ltd. 2022–2025. All Rights Reserved.
@@ -0,0 +1,112 @@
1
+ import { FumeMappingProviderConfig, UserMapping, UserMappingMetadata, PackageMapping, PackageMappingMetadata, GetPackageMappingOptions, AliasObject, ConceptMap, StructureMap } from './types';
2
+ /**
3
+ * Main orchestrator for FUME mappings from multiple sources
4
+ * Separates user mappings (file + server) from package mappings
5
+ */
6
+ export declare class FumeMappingProvider {
7
+ private config;
8
+ private logger?;
9
+ private userProvider?;
10
+ private packageProvider?;
11
+ private aliasProvider?;
12
+ private userMappingsCache;
13
+ private cachedAliases;
14
+ constructor(config: FumeMappingProviderConfig);
15
+ /**
16
+ * Initialize providers based on configuration
17
+ */
18
+ private initializeProviders;
19
+ /**
20
+ * Initialize all providers (load user mappings and aliases into cache)
21
+ */
22
+ initialize(): Promise<void>;
23
+ /**
24
+ * Reload all user mappings
25
+ */
26
+ reloadUserMappings(): Promise<void>;
27
+ /**
28
+ * Refresh a specific user mapping by key
29
+ * @param key - The mapping key to refresh
30
+ * @param mapping - Optional mapping to use directly (avoids server roundtrip)
31
+ * @returns The refreshed mapping or null if not found
32
+ */
33
+ refreshUserMapping(key: string, mapping?: UserMapping | null): Promise<UserMapping | null>;
34
+ /**
35
+ * Get all user mappings (lightning-fast - from cache)
36
+ */
37
+ getUserMappings(): UserMapping[];
38
+ /**
39
+ * Get all user mapping keys (lightning-fast - from cache)
40
+ */
41
+ getUserMappingKeys(): string[];
42
+ /**
43
+ * Get user mapping metadata (lightning-fast - from cache)
44
+ */
45
+ getUserMappingsMetadata(): UserMappingMetadata[];
46
+ /**
47
+ * Get a user mapping by key (lightning-fast - from cache)
48
+ */
49
+ getUserMapping(key: string): UserMapping | undefined;
50
+ /**
51
+ * Get all package mappings
52
+ * Always fresh from FPE (packages are immutable, FPE handles caching)
53
+ */
54
+ getPackageMappings(options?: GetPackageMappingOptions): Promise<PackageMapping[]>;
55
+ /**
56
+ * Get package mapping metadata
57
+ */
58
+ getPackageMappingsMetadata(options?: GetPackageMappingOptions): Promise<PackageMappingMetadata[]>;
59
+ /**
60
+ * Get a package mapping by identifier (tries url, id, name in order)
61
+ */
62
+ getPackageMapping(identifier: string, options?: GetPackageMappingOptions): Promise<PackageMapping | null>;
63
+ /**
64
+ * Reload all aliases from server
65
+ */
66
+ reloadAliases(): Promise<void>;
67
+ /**
68
+ * Register or update a single alias (optimistic cache update without server roundtrip)
69
+ * @param name - The alias name/key
70
+ * @param value - The alias value
71
+ */
72
+ registerAlias(name: string, value: string): void;
73
+ /**
74
+ * Delete a specific alias from the cache
75
+ * @param name - The alias name/key to delete
76
+ */
77
+ deleteAlias(name: string): void;
78
+ /**
79
+ * Get all cached aliases as a single object (lightning-fast - from cache)
80
+ * @returns The alias object with all key-value mappings
81
+ */
82
+ getAliases(): AliasObject;
83
+ /**
84
+ * Transform a ConceptMap resource into an alias object
85
+ * @param conceptMap - The ConceptMap resource
86
+ * @returns An alias object with key-value mappings
87
+ */
88
+ static conceptMapToAliasObject(conceptMap: ConceptMap): AliasObject;
89
+ /**
90
+ * Transform an alias object into a ConceptMap resource
91
+ * @param aliases - The alias object
92
+ * @param canonicalBaseUrl - Base URL for canonical references (defaults to example.com)
93
+ * @param existingConceptMap - Optional existing ConceptMap to update
94
+ * @returns A ConceptMap resource
95
+ */
96
+ static aliasObjectToConceptMap(aliases: AliasObject, canonicalBaseUrl?: string, existingConceptMap?: ConceptMap): ConceptMap;
97
+ /**
98
+ * Extract FUME expression from a StructureMap resource
99
+ * @param structureMap - The StructureMap resource
100
+ * @returns The FUME expression or null if not found
101
+ */
102
+ static structureMapToExpression(structureMap: StructureMap): string | null;
103
+ /**
104
+ * Create a StructureMap resource from a FUME expression
105
+ * @param mappingId - The mapping identifier
106
+ * @param expression - The FUME expression
107
+ * @param canonicalBaseUrl - Base URL for canonical references (defaults to example.com)
108
+ * @returns A StructureMap resource
109
+ */
110
+ static expressionToStructureMap(mappingId: string, expression: string, canonicalBaseUrl?: string): StructureMap;
111
+ }
112
+ //# sourceMappingURL=FumeMappingProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FumeMappingProvider.d.ts","sourceRoot":"","sources":["../src/FumeMappingProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK/L;;;GAGG;AACH,qBAAa,mBAAmB;IAQlB,OAAO,CAAC,MAAM;IAP1B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,YAAY,CAAC,CAAsB;IAC3C,OAAO,CAAC,eAAe,CAAC,CAAyB;IACjD,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,iBAAiB,CAAuC;IAChE,OAAO,CAAC,aAAa,CAAmB;gBAEpB,MAAM,EAAE,yBAAyB;IAKrD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA+B3B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBjC;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAWzC;;;;;OAKG;IACG,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAiChG;;OAEG;IACH,eAAe,IAAI,WAAW,EAAE;IAIhC;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,uBAAuB,IAAI,mBAAmB,EAAE;IAWhD;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAMpD;;;OAGG;IACG,kBAAkB,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAQvF;;OAEG;IACG,0BAA0B,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAYvG;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAW/G;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAWpC;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKhD;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK/B;;;OAGG;IACH,UAAU,IAAI,WAAW;IAMzB;;;;OAIG;IACH,MAAM,CAAC,uBAAuB,CAAC,UAAU,EAAE,UAAU,GAAG,WAAW;IAInE;;;;;;OAMG;IACH,MAAM,CAAC,uBAAuB,CAC5B,OAAO,EAAE,WAAW,EACpB,gBAAgB,CAAC,EAAE,MAAM,EACzB,kBAAkB,CAAC,EAAE,UAAU,GAC9B,UAAU;IAMb;;;;OAIG;IACH,MAAM,CAAC,wBAAwB,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI;IAI1E;;;;;;OAMG;IACH,MAAM,CAAC,wBAAwB,CAC7B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,MAAM,GACxB,YAAY;CAGhB"}