@khapu2906/treasure-chest 1.0.4 → 1.3.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,491 @@
1
+ "use strict";
2
+ /**
3
+ * Container class for dependency injection
4
+ *
5
+ * @module Container
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.Container = void 0;
9
+ const Lazy_1 = require("./Lazy");
10
+ const Scope_1 = require("./Scope");
11
+ /**
12
+ * Container class for dependency injection
13
+ * Manages service bindings, instances, and resolution logic
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const container = new Container();
18
+ * container.bind('logger', () => new Logger());
19
+ * const logger = container.resolve<Logger>('logger');
20
+ * ```
21
+ */
22
+ class Container {
23
+ /**
24
+ * Create a new container
25
+ * @param parent Optional parent container for hierarchy
26
+ */
27
+ constructor(parent) {
28
+ /** Map-based storage for bindings - O(1) lookup */
29
+ this.bindings = new Map();
30
+ /** Cache for singleton instances */
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ this.instances = new Map();
33
+ /** Mapping of aliases to original keys */
34
+ this.aliases = new Map();
35
+ /** Cache for resolved bindings - performance optimization */
36
+ this.bindingCache = new Map();
37
+ /** Composed containers for composition pattern */
38
+ this.composedContainers = [];
39
+ /** Resolution stack for circular dependency detection */
40
+ this.resolutionStack = [];
41
+ this.parent = parent;
42
+ }
43
+ /**
44
+ * Register a transient binding (new instance on each resolve)
45
+ *
46
+ * @template T The type of service being bound
47
+ * @param key The unique identifier for this service
48
+ * @param factory Factory function that creates the service instance
49
+ * @param condition Optional condition function for conditional binding
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * container.bind('database', (c) => new Database());
54
+ * container.bind('cache', (c) => new Cache(), (c) => process.env.CACHE_ENABLED === 'true');
55
+ * ```
56
+ */
57
+ bind(key, factory, condition) {
58
+ const existing = this.bindings.get(key) || [];
59
+ existing.push({ key, factory, lifecycle: 'transient', condition });
60
+ this.bindings.set(key, existing);
61
+ this.bindingCache.clear(); // Invalidate cache
62
+ }
63
+ /**
64
+ * Register a singleton binding (single instance shared across all resolves)
65
+ *
66
+ * @template T The type of service being bound
67
+ * @param key The unique identifier for this service
68
+ * @param factory Factory function that creates the service instance
69
+ * @param condition Optional condition function for conditional binding
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * container.singleton('config', (c) => new Config());
74
+ * ```
75
+ */
76
+ singleton(key, factory, condition) {
77
+ const existing = this.bindings.get(key) || [];
78
+ existing.push({ key, factory, lifecycle: 'singleton', condition });
79
+ this.bindings.set(key, existing);
80
+ this.bindingCache.clear();
81
+ }
82
+ /**
83
+ * Register a scoped binding (single instance per scope)
84
+ *
85
+ * @template T The type of service being bound
86
+ * @param key The unique identifier for this service
87
+ * @param factory Factory function that creates the service instance
88
+ * @param dispose Optional disposal function for cleanup
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * container.scoped('dbConnection', (c) => new DbConnection(), () => {
93
+ * console.log('Closing connection');
94
+ * });
95
+ * ```
96
+ */
97
+ scoped(key, factory, dispose) {
98
+ const existing = this.bindings.get(key) || [];
99
+ existing.push({ key, factory, lifecycle: 'scoped', dispose });
100
+ this.bindings.set(key, existing);
101
+ this.bindingCache.clear();
102
+ }
103
+ /**
104
+ * Register a lazy binding (deferred initialization)
105
+ *
106
+ * @template T The type of service being bound
107
+ * @param key The unique identifier for this service
108
+ * @param factory Factory function that creates the service instance
109
+ * @param lifecycle The lifecycle type (default: singleton)
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * container.lazy('heavyService', (c) => new HeavyService());
114
+ * const lazy = container.resolve<Lazy<HeavyService>>('heavyService');
115
+ * // Not initialized yet
116
+ * const service = lazy.value; // Initialized now
117
+ * ```
118
+ */
119
+ lazy(key, factory, lifecycle = 'singleton') {
120
+ const existing = this.bindings.get(key) || [];
121
+ existing.push({ key, factory, lifecycle, lazy: true });
122
+ this.bindings.set(key, existing);
123
+ this.bindingCache.clear();
124
+ }
125
+ /**
126
+ * Create an alias for an existing service key
127
+ *
128
+ * @param aliasKey The new alias name
129
+ * @param originalKey The original service key to alias
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * container.bind('UserRepository', () => new UserRepo());
134
+ * container.alias('UserRepo', 'UserRepository');
135
+ * // Both keys now resolve to the same binding
136
+ * ```
137
+ */
138
+ alias(aliasKey, originalKey) {
139
+ this.aliases.set(aliasKey, originalKey);
140
+ }
141
+ /**
142
+ * Create a child container that inherits from this container
143
+ *
144
+ * @returns A new child container
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const parent = new Container();
149
+ * parent.singleton('config', () => new Config());
150
+ *
151
+ * const child = parent.createChild();
152
+ * child.bind('logger', () => new Logger());
153
+ *
154
+ * // Child can resolve both parent and own bindings
155
+ * const config = child.resolve('config'); // From parent
156
+ * const logger = child.resolve('logger'); // From child
157
+ * ```
158
+ */
159
+ createChild() {
160
+ return new Container(this);
161
+ }
162
+ /**
163
+ * Create a new scope for scoped instances
164
+ *
165
+ * @returns A new scope
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * const scope = container.createScope();
170
+ * container.scoped('request', () => new Request());
171
+ *
172
+ * const req1 = container.resolve('request'); // Same instance within scope
173
+ * const req2 = container.resolve('request'); // Same as req1
174
+ *
175
+ * await scope.dispose(); // Clean up scoped instances
176
+ * ```
177
+ */
178
+ createScope() {
179
+ const scope = new Scope_1.Scope();
180
+ this.currentScope = scope;
181
+ return scope;
182
+ }
183
+ /**
184
+ * Execute a callback with a temporary scope
185
+ * Auto-disposes the scope when done (like C# using statement)
186
+ *
187
+ * @param callback Function to execute within the scope
188
+ * @returns The result of the callback
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * await container.withScope(async (scope) => {
193
+ * const db = container.resolve('dbConnection');
194
+ * await db.query('...');
195
+ * // Auto-disposed when callback completes
196
+ * });
197
+ * ```
198
+ */
199
+ async withScope(callback) {
200
+ const scope = this.createScope();
201
+ try {
202
+ return await callback(scope);
203
+ }
204
+ finally {
205
+ await scope.dispose();
206
+ }
207
+ }
208
+ /**
209
+ * Find the appropriate binding for a given key and context
210
+ * Searches in current container and parent containers
211
+ * Uses cached result when possible for performance
212
+ *
213
+ * @private
214
+ * @param key The service key to find
215
+ * @param context Optional context for contextual binding
216
+ * @returns The matching binding or undefined
217
+ */
218
+ findBinding(key, context) {
219
+ const realKey = this.aliases.get(key) || key;
220
+ const cacheKey = context ? `${realKey}::${context}` : realKey;
221
+ // Check cache first
222
+ if (this.bindingCache.has(cacheKey)) {
223
+ return this.bindingCache.get(cacheKey);
224
+ }
225
+ // O(1) Map lookup instead of O(n) array filter
226
+ const bindings = this.bindings.get(realKey);
227
+ if (bindings && bindings.length > 0) {
228
+ // Priority:
229
+ // 1. Binding with context and condition true
230
+ // 2. Binding without context but condition true
231
+ // 3. Binding default first
232
+ const match = bindings.find((b) => b.context === context && (!b.condition || b.condition(this))) ||
233
+ bindings.find((b) => !b.context && (!b.condition || b.condition(this))) ||
234
+ bindings[0];
235
+ // Cache the result only if no conditions (conditions are dynamic)
236
+ if (match && !match.condition) {
237
+ this.bindingCache.set(cacheKey, match);
238
+ }
239
+ return match;
240
+ }
241
+ // Try parent container
242
+ if (this.parent) {
243
+ return this.parent.findBinding(key, context);
244
+ }
245
+ return undefined;
246
+ }
247
+ /**
248
+ * Resolve a service instance from the container
249
+ * Handles transient, singleton, scoped, and lazy bindings
250
+ *
251
+ * @template T The expected type of the resolved service
252
+ * @param key The service key to resolve
253
+ * @param context Optional context for contextual resolution
254
+ * @returns The resolved service instance
255
+ * @throws Error if no binding exists for the key
256
+ * @throws Error if circular dependency is detected
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * const logger = container.resolve<Logger>('logger');
261
+ * const userRepo = container.resolve('UserRepo', 'UserService');
262
+ * ```
263
+ */
264
+ resolve(key, context) {
265
+ const realKey = this.aliases.get(key) || key;
266
+ // Circular dependency detection
267
+ if (this.resolutionStack.includes(realKey)) {
268
+ const chain = [...this.resolutionStack, realKey].join(' -> ');
269
+ throw new Error(`Circular dependency detected: ${chain}`);
270
+ }
271
+ const prevContext = this.currentContext;
272
+ this.currentContext = context || key;
273
+ const binding = this.findBinding(key, this.currentContext);
274
+ if (!binding) {
275
+ throw new Error(`No binding found for key: ${realKey}`);
276
+ }
277
+ // Add to resolution stack
278
+ this.resolutionStack.push(realKey);
279
+ try {
280
+ // Handle lazy binding
281
+ if (binding.lazy) {
282
+ const instance = this.resolveLazy(binding, realKey);
283
+ return instance;
284
+ }
285
+ // Handle different lifecycles
286
+ switch (binding.lifecycle) {
287
+ case 'singleton':
288
+ return this.resolveSingleton(binding, realKey);
289
+ case 'scoped':
290
+ return this.resolveScoped(binding, realKey);
291
+ case 'transient':
292
+ default:
293
+ return this.resolveTransient(binding);
294
+ }
295
+ }
296
+ finally {
297
+ // Remove from resolution stack
298
+ this.resolutionStack.pop();
299
+ this.currentContext = prevContext;
300
+ }
301
+ }
302
+ /**
303
+ * Resolve a transient instance
304
+ * @private
305
+ */
306
+ resolveTransient(binding) {
307
+ return binding.factory(this);
308
+ }
309
+ /**
310
+ * Resolve a singleton instance
311
+ * @private
312
+ */
313
+ resolveSingleton(binding, cacheKey) {
314
+ const fullCacheKey = binding.context
315
+ ? `${cacheKey}::${binding.context}`
316
+ : cacheKey;
317
+ if (this.instances.has(fullCacheKey)) {
318
+ return this.instances.get(fullCacheKey);
319
+ }
320
+ const instance = binding.factory(this);
321
+ this.instances.set(fullCacheKey, instance);
322
+ return instance;
323
+ }
324
+ /**
325
+ * Resolve a scoped instance
326
+ * @private
327
+ */
328
+ resolveScoped(binding, key) {
329
+ if (!this.currentScope) {
330
+ throw new Error(`No active scope for scoped binding: ${key}. Call createScope() first.`);
331
+ }
332
+ if (this.currentScope.has(key)) {
333
+ return this.currentScope.get(key);
334
+ }
335
+ const instance = binding.factory(this);
336
+ this.currentScope.set(key, instance, binding.dispose);
337
+ return instance;
338
+ }
339
+ /**
340
+ * Resolve a lazy instance
341
+ * @private
342
+ */
343
+ resolveLazy(binding, cacheKey) {
344
+ const fullCacheKey = `lazy::${cacheKey}`;
345
+ if (this.instances.has(fullCacheKey)) {
346
+ return this.instances.get(fullCacheKey);
347
+ }
348
+ const lazy = new Lazy_1.Lazy(() => binding.factory(this));
349
+ if (binding.lifecycle === 'singleton') {
350
+ this.instances.set(fullCacheKey, lazy);
351
+ }
352
+ return lazy;
353
+ }
354
+ /**
355
+ * Create a contextual binding (different implementations based on context)
356
+ * Provides a fluent API for defining context-specific dependencies
357
+ *
358
+ * @param context The context identifier (usually a service name)
359
+ * @returns A fluent API object with needs() method
360
+ *
361
+ * @example
362
+ * ```typescript
363
+ * // UserService will receive MockUserRepo
364
+ * container.when('UserService').needs('UserRepo').give(() => new MockUserRepo());
365
+ *
366
+ * // OrderService will receive RealUserRepo
367
+ * container.when('OrderService').needs('UserRepo').give(() => new RealUserRepo());
368
+ * ```
369
+ */
370
+ when(context) {
371
+ return {
372
+ needs: (depKey) => ({
373
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
374
+ give: (factory) => {
375
+ const existing = this.bindings.get(depKey) || [];
376
+ existing.push({
377
+ key: depKey,
378
+ factory,
379
+ lifecycle: 'transient',
380
+ context,
381
+ });
382
+ this.bindings.set(depKey, existing);
383
+ this.bindingCache.clear();
384
+ },
385
+ }),
386
+ };
387
+ }
388
+ /**
389
+ * Check if a binding exists for a key
390
+ *
391
+ * @param key The service key to check
392
+ * @returns True if binding exists
393
+ *
394
+ * @example
395
+ * ```typescript
396
+ * if (container.has('logger')) {
397
+ * const logger = container.resolve('logger');
398
+ * }
399
+ * ```
400
+ */
401
+ has(key) {
402
+ return this.findBinding(key) !== undefined;
403
+ }
404
+ /**
405
+ * Get all registered service keys
406
+ *
407
+ * @returns Array of service keys
408
+ *
409
+ * @example
410
+ * ```typescript
411
+ * const keys = container.keys();
412
+ * console.log('Registered services:', keys);
413
+ * ```
414
+ */
415
+ keys() {
416
+ const ownKeys = Array.from(this.bindings.keys());
417
+ const parentKeys = this.parent ? this.parent.keys() : [];
418
+ return [...new Set([...ownKeys, ...parentKeys])];
419
+ }
420
+ /**
421
+ * Reset the container to its initial state
422
+ * Clears all bindings, instances, aliases, and context
423
+ * Useful for testing scenarios
424
+ *
425
+ * @example
426
+ * ```typescript
427
+ * afterEach(() => {
428
+ * container.reset();
429
+ * });
430
+ * ```
431
+ */
432
+ reset() {
433
+ this.bindings.clear();
434
+ this.instances.clear();
435
+ this.aliases.clear();
436
+ this.bindingCache.clear();
437
+ this.currentContext = undefined;
438
+ this.currentScope = undefined;
439
+ this.resolutionStack = [];
440
+ }
441
+ /**
442
+ * Compose multiple containers into a new container
443
+ * This allows mixing services from different domains without inheritance
444
+ *
445
+ * @param containers Array of containers to compose
446
+ * @returns New composed container
447
+ */
448
+ static compose(containers) {
449
+ const composed = new Container();
450
+ // Validate containers
451
+ if (!containers || containers.length === 0) {
452
+ throw new Error('At least one container must be provided for composition');
453
+ }
454
+ // Store composed containers
455
+ composed.composedContainers = [...containers];
456
+ // Create proxy bindings for all keys from composed containers
457
+ const allKeys = new Set();
458
+ containers.forEach((container) => {
459
+ container.keys().forEach((key) => allKeys.add(key));
460
+ });
461
+ // Bind proxy resolvers
462
+ for (const key of allKeys) {
463
+ composed.bind(key, (c) => c.resolveFromComposition(key));
464
+ }
465
+ return composed;
466
+ }
467
+ /**
468
+ * Resolve a service from composed containers
469
+ * @private
470
+ */
471
+ resolveFromComposition(key) {
472
+ // Search through composed containers in order
473
+ for (const container of this.composedContainers) {
474
+ if (container.has(key)) {
475
+ return container.resolve(key);
476
+ }
477
+ }
478
+ throw new Error(`No binding found for key: ${key}`);
479
+ }
480
+ /**
481
+ * Dispose the container and all its scoped instances
482
+ */
483
+ async dispose() {
484
+ if (this.currentScope) {
485
+ await this.currentScope.dispose();
486
+ }
487
+ this.reset();
488
+ }
489
+ }
490
+ exports.Container = Container;
491
+ //# sourceMappingURL=Container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Container.js","sourceRoot":"","sources":["../../src/Container.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /**
3
+ * Lazy wrapper for deferred initialization
4
+ *
5
+ * @module Lazy
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.Lazy = void 0;
9
+ /**
10
+ * Lazy wrapper for deferred initialization
11
+ * Delays the creation of an instance until it's actually accessed
12
+ *
13
+ * @template T The type of the lazy value
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const lazy = new Lazy(() => new ExpensiveService());
18
+ * console.log(lazy.isInitialized); // false
19
+ * const service = lazy.value; // NOW it's created
20
+ * console.log(lazy.isInitialized); // true
21
+ * ```
22
+ */
23
+ class Lazy {
24
+ constructor(factory) {
25
+ this.factory = factory;
26
+ this._initialized = false;
27
+ }
28
+ /**
29
+ * Get the lazy value, initializing it if necessary
30
+ */
31
+ get value() {
32
+ if (!this._initialized) {
33
+ this._value = this.factory();
34
+ this._initialized = true;
35
+ }
36
+ return this._value;
37
+ }
38
+ /**
39
+ * Check if the lazy value has been initialized
40
+ */
41
+ get isInitialized() {
42
+ return this._initialized;
43
+ }
44
+ }
45
+ exports.Lazy = Lazy;
46
+ //# sourceMappingURL=Lazy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Lazy.js","sourceRoot":"","sources":["../../src/Lazy.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAa,IAAI;IAIf,YAAoB,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;QAF5B,iBAAY,GAAG,KAAK,CAAC;IAEU,CAAC;IAExC;;OAEG;IACH,IAAI,KAAK;QACP,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,CAAC,MAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;CACF;AAvBD,oBAuBC"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ /**
3
+ * Scope management for scoped instances
4
+ *
5
+ * @module Scope
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.Scope = void 0;
9
+ /**
10
+ * Scope class for managing scoped instances
11
+ * A scope contains instances that live for a specific duration (e.g., per HTTP request)
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const scope = container.createScope();
16
+ * const conn = container.resolve('dbConnection'); // Scoped instance
17
+ * await scope.dispose(); // Cleanup all scoped resources
18
+ * ```
19
+ */
20
+ class Scope {
21
+ constructor() {
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ this.instances = new Map();
24
+ this.disposables = [];
25
+ }
26
+ /**
27
+ * Get an instance from this scope
28
+ * @param key The service key
29
+ * @returns The instance or undefined
30
+ */
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ get(key) {
33
+ return this.instances.get(key);
34
+ }
35
+ /**
36
+ * Set an instance in this scope with optional cleanup
37
+ * Auto-detects IDisposable instances
38
+ *
39
+ * @param key The service key
40
+ * @param value The instance to store
41
+ * @param dispose Optional disposal function
42
+ */
43
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
+ set(key, value, dispose) {
45
+ this.instances.set(key, value);
46
+ // Auto-detect IDisposable
47
+ if (!dispose && this.isDisposable(value)) {
48
+ dispose = () => value.dispose();
49
+ }
50
+ if (dispose) {
51
+ this.disposables.push(dispose);
52
+ }
53
+ }
54
+ /**
55
+ * Check if instance exists in scope
56
+ * @param key The service key
57
+ * @returns True if the instance exists
58
+ */
59
+ has(key) {
60
+ return this.instances.has(key);
61
+ }
62
+ /**
63
+ * Check if value implements IDisposable interface
64
+ * @private
65
+ * @param value The value to check
66
+ * @returns True if the value is disposable
67
+ */
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ isDisposable(value) {
70
+ return (value !== null &&
71
+ value !== undefined &&
72
+ typeof value === 'object' &&
73
+ typeof value.dispose === 'function');
74
+ }
75
+ /**
76
+ * Dispose all instances in this scope
77
+ * Calls all registered disposal functions and clears the scope
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * await scope.dispose();
82
+ * ```
83
+ */
84
+ async dispose() {
85
+ for (const disposeFn of this.disposables) {
86
+ await disposeFn();
87
+ }
88
+ this.instances.clear();
89
+ this.disposables = [];
90
+ }
91
+ }
92
+ exports.Scope = Scope;
93
+ //# sourceMappingURL=Scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scope.js","sourceRoot":"","sources":["../../src/Scope.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAIH;;;;;;;;;;GAUG;AACH,MAAa,KAAK;IAAlB;QACE,8DAA8D;QACtD,cAAS,GAAqB,IAAI,GAAG,EAAE,CAAC;QACxC,gBAAW,GAAgB,EAAE,CAAC;IA2ExC,CAAC;IAzEC;;;;OAIG;IACH,8DAA8D;IAC9D,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;OAOG;IACH,8DAA8D;IAC9D,GAAG,CAAC,GAAW,EAAE,KAAU,EAAE,OAAmB;QAC9C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE/B,0BAA0B;QAC1B,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAClC,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH,8DAA8D;IACtD,YAAY,CAAC,KAAU;QAC7B,OAAO,CACL,KAAK,KAAK,IAAI;YACd,KAAK,KAAK,SAAS;YACnB,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,CACpC,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO;QACX,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,SAAS,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;IACxB,CAAC;CACF;AA9ED,sBA8EC"}