@wgtechlabs/nuvex 0.1.1

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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +427 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/cjs/core/client.js +981 -0
  5. package/dist/cjs/core/client.js.map +1 -0
  6. package/dist/cjs/core/database.js +297 -0
  7. package/dist/cjs/core/database.js.map +1 -0
  8. package/dist/cjs/core/engine.js +1202 -0
  9. package/dist/cjs/core/engine.js.map +1 -0
  10. package/dist/cjs/core/index.js +35 -0
  11. package/dist/cjs/core/index.js.map +1 -0
  12. package/dist/cjs/index.js +109 -0
  13. package/dist/cjs/index.js.map +1 -0
  14. package/dist/cjs/interfaces/index.js +12 -0
  15. package/dist/cjs/interfaces/index.js.map +1 -0
  16. package/dist/cjs/layers/index.js +22 -0
  17. package/dist/cjs/layers/index.js.map +1 -0
  18. package/dist/cjs/layers/memory.js +388 -0
  19. package/dist/cjs/layers/memory.js.map +1 -0
  20. package/dist/cjs/layers/postgres.js +492 -0
  21. package/dist/cjs/layers/postgres.js.map +1 -0
  22. package/dist/cjs/layers/redis.js +388 -0
  23. package/dist/cjs/layers/redis.js.map +1 -0
  24. package/dist/cjs/types/index.js +52 -0
  25. package/dist/cjs/types/index.js.map +1 -0
  26. package/dist/esm/core/client.js +944 -0
  27. package/dist/esm/core/client.js.map +1 -0
  28. package/dist/esm/core/database.js +289 -0
  29. package/dist/esm/core/database.js.map +1 -0
  30. package/dist/esm/core/engine.js +1198 -0
  31. package/dist/esm/core/engine.js.map +1 -0
  32. package/dist/esm/core/index.js +16 -0
  33. package/dist/esm/core/index.js.map +1 -0
  34. package/dist/esm/index.js +87 -0
  35. package/dist/esm/index.js.map +1 -0
  36. package/dist/esm/interfaces/index.js +11 -0
  37. package/dist/esm/interfaces/index.js.map +1 -0
  38. package/dist/esm/layers/index.js +16 -0
  39. package/dist/esm/layers/index.js.map +1 -0
  40. package/dist/esm/layers/memory.js +384 -0
  41. package/dist/esm/layers/memory.js.map +1 -0
  42. package/dist/esm/layers/postgres.js +485 -0
  43. package/dist/esm/layers/postgres.js.map +1 -0
  44. package/dist/esm/layers/redis.js +384 -0
  45. package/dist/esm/layers/redis.js.map +1 -0
  46. package/dist/esm/types/index.js +49 -0
  47. package/dist/esm/types/index.js.map +1 -0
  48. package/dist/types/core/client.d.ts +561 -0
  49. package/dist/types/core/client.d.ts.map +1 -0
  50. package/dist/types/core/database.d.ts +130 -0
  51. package/dist/types/core/database.d.ts.map +1 -0
  52. package/dist/types/core/engine.d.ts +450 -0
  53. package/dist/types/core/engine.d.ts.map +1 -0
  54. package/dist/types/core/index.d.ts +13 -0
  55. package/dist/types/core/index.d.ts.map +1 -0
  56. package/dist/types/index.d.ts +85 -0
  57. package/dist/types/index.d.ts.map +1 -0
  58. package/dist/types/interfaces/index.d.ts +209 -0
  59. package/dist/types/interfaces/index.d.ts.map +1 -0
  60. package/dist/types/layers/index.d.ts +16 -0
  61. package/dist/types/layers/index.d.ts.map +1 -0
  62. package/dist/types/layers/memory.d.ts +261 -0
  63. package/dist/types/layers/memory.d.ts.map +1 -0
  64. package/dist/types/layers/postgres.d.ts +313 -0
  65. package/dist/types/layers/postgres.d.ts.map +1 -0
  66. package/dist/types/layers/redis.d.ts +248 -0
  67. package/dist/types/layers/redis.d.ts.map +1 -0
  68. package/dist/types/types/index.d.ts +410 -0
  69. package/dist/types/types/index.d.ts.map +1 -0
  70. package/package.json +90 -0
@@ -0,0 +1,492 @@
1
+ "use strict";
2
+ /**
3
+ * Nuvex - PostgreSQL Storage Layer (L3)
4
+ * Next-gen Unified Vault Experience
5
+ *
6
+ * PostgreSQL persistent storage layer serving as the source of truth for all data.
7
+ * Provides ACID-compliant, durable storage with full data integrity guarantees.
8
+ *
9
+ * Features:
10
+ * - ACID-compliant persistent storage
11
+ * - Source of truth for all data
12
+ * - JSON support for flexible data structures
13
+ * - Automatic TTL-based expiration
14
+ * - Connection pooling for optimal performance
15
+ * - Health monitoring with SELECT 1 queries
16
+ *
17
+ * @author Waren Gonzaga, WG Technology Labs
18
+ * @since 2025
19
+ */
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.PostgresStorage = void 0;
25
+ const pg_1 = __importDefault(require("pg"));
26
+ const { Pool } = pg_1.default;
27
+ const database_js_1 = require("../core/database.js");
28
+ /**
29
+ * PostgreSQL Storage Layer - L3 Persistent Storage
30
+ *
31
+ * Implements persistent storage using PostgreSQL. This is the authoritative
32
+ * source of truth for all data in the system. All writes must succeed here
33
+ * for the operation to be considered successful.
34
+ *
35
+ * **Key Features:**
36
+ * - ACID compliance for data integrity
37
+ * - Durable storage that survives restarts
38
+ * - JSON/JSONB support for complex objects
39
+ * - TTL-based automatic expiration
40
+ * - Connection pooling for performance
41
+ * - Transaction support for complex operations
42
+ *
43
+ * **Storage Schema:**
44
+ * - Table: nuvex_storage
45
+ * - Columns: id, key (unique), value (JSONB), expires_at, created_at, updated_at
46
+ * - Indexes: key, expires_at, key pattern (trigram)
47
+ *
48
+ * **Performance Characteristics:**
49
+ * - Get: O(log n) with index lookup
50
+ * - Set: O(log n) with index update
51
+ * - Latency: 5-50ms typical (storage + network)
52
+ *
53
+ * **Error Handling:**
54
+ * - Returns null on read errors (graceful degradation)
55
+ * - Logs errors for monitoring
56
+ * - Throws on critical connection failures
57
+ *
58
+ * @implements {StorageLayerInterface}
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * // Create PostgreSQL layer
63
+ * const postgres = new PostgresStorage({
64
+ * host: 'localhost',
65
+ * port: 5432,
66
+ * database: 'myapp',
67
+ * user: 'postgres',
68
+ * password: 'password'
69
+ * });
70
+ *
71
+ * // Connect (creates pool)
72
+ * await postgres.connect();
73
+ *
74
+ * // Store data (source of truth)
75
+ * await postgres.set('user:123', userData, 86400);
76
+ *
77
+ * // Retrieve data
78
+ * const data = await postgres.get('user:123');
79
+ *
80
+ * // Check health
81
+ * const isHealthy = await postgres.ping();
82
+ * ```
83
+ *
84
+ * @class PostgresStorage
85
+ * @since 1.0.0
86
+ */
87
+ class PostgresStorage {
88
+ /**
89
+ * Creates a new PostgresStorage instance
90
+ *
91
+ * Accepts either a PostgreSQL configuration object or an existing Pool instance.
92
+ * If a Pool is provided, the caller is responsible for managing its lifecycle.
93
+ *
94
+ * Schema configuration is extracted from the config object when creating a new pool.
95
+ * When using an existing pool, schema defaults to standard Nuvex naming.
96
+ *
97
+ * @param config - PostgreSQL configuration or existing Pool instance
98
+ * @param logger - Optional logger for debugging
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * // With configuration (supports schema customization)
103
+ * const postgres = new PostgresStorage({
104
+ * host: 'localhost',
105
+ * database: 'myapp',
106
+ * user: 'postgres',
107
+ * password: 'password',
108
+ * schema: {
109
+ * tableName: 'storage_cache',
110
+ * columns: { key: 'key', value: 'value' }
111
+ * }
112
+ * });
113
+ *
114
+ * // With existing pool (uses default schema)
115
+ * const existingPool = new Pool({ ... });
116
+ * const postgres = new PostgresStorage(existingPool);
117
+ * ```
118
+ */
119
+ constructor(config, logger = null) {
120
+ this.config = config;
121
+ this.pool = null;
122
+ this.connected = false;
123
+ this.logger = logger;
124
+ // Check if config is already a Pool instance
125
+ this.ownsPool = !('query' in config && typeof config.query === 'function');
126
+ // Extract schema configuration with defaults
127
+ // Note: Schema is only extracted from config objects, not from existing Pool instances
128
+ const schema = this.ownsPool ? config.schema : undefined;
129
+ this.tableName = schema?.tableName ?? 'nuvex_storage';
130
+ this.keyColumn = schema?.columns?.key ?? 'nuvex_key';
131
+ this.valueColumn = schema?.columns?.value ?? 'nuvex_data';
132
+ // Validate all identifiers to prevent SQL injection
133
+ (0, database_js_1.validateSQLIdentifier)(this.tableName, 'table name');
134
+ (0, database_js_1.validateSQLIdentifier)(this.keyColumn, 'key column name');
135
+ (0, database_js_1.validateSQLIdentifier)(this.valueColumn, 'value column name');
136
+ }
137
+ /**
138
+ * Establish connection to PostgreSQL
139
+ *
140
+ * Creates a connection pool (if not already provided) and tests the connection.
141
+ * Should be called before any storage operations.
142
+ *
143
+ * @throws {Error} If connection test fails
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * try {
148
+ * await postgres.connect();
149
+ * console.log('PostgreSQL connected');
150
+ * } catch (error) {
151
+ * console.error('PostgreSQL connection failed:', error);
152
+ * }
153
+ * ```
154
+ */
155
+ async connect() {
156
+ try {
157
+ if (this.ownsPool) {
158
+ // Create new pool from config
159
+ this.pool = new Pool(this.config);
160
+ }
161
+ else {
162
+ // Use existing pool
163
+ this.pool = this.config;
164
+ }
165
+ // Test connection
166
+ if (this.pool) {
167
+ await this.pool.query('SELECT 1');
168
+ this.connected = true;
169
+ this.log('info', 'PostgreSQL L3: Connected successfully');
170
+ }
171
+ }
172
+ catch (error) {
173
+ this.connected = false;
174
+ this.log('error', 'PostgreSQL L3: Connection failed', {
175
+ error: error instanceof Error ? error.message : String(error)
176
+ });
177
+ throw error;
178
+ }
179
+ }
180
+ /**
181
+ * Close PostgreSQL connection pool
182
+ *
183
+ * Only closes the pool if we created it. If an existing pool was provided,
184
+ * the caller is responsible for closing it.
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * await postgres.disconnect();
189
+ * ```
190
+ */
191
+ async disconnect() {
192
+ if (this.pool && this.ownsPool) {
193
+ await this.pool.end();
194
+ this.log('info', 'PostgreSQL L3: Disconnected');
195
+ }
196
+ this.connected = false;
197
+ }
198
+ /**
199
+ * Retrieve a value from PostgreSQL
200
+ *
201
+ * Queries the nuvex_storage table and automatically filters out expired entries.
202
+ * Deserializes the JSON-stored value.
203
+ *
204
+ * @param key - The key to retrieve
205
+ * @returns Promise resolving to the value or null if not found/expired
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * const userData = await postgres.get('user:123');
210
+ * if (userData !== null) {
211
+ * console.log('Found in PostgreSQL');
212
+ * }
213
+ * ```
214
+ */
215
+ async get(key) {
216
+ if (!this.connected || !this.pool) {
217
+ return null;
218
+ }
219
+ try {
220
+ const result = await this.pool.query(`SELECT ${this.valueColumn} FROM ${this.tableName} WHERE ${this.keyColumn} = $1 AND (expires_at IS NULL OR expires_at > NOW())`, [key]);
221
+ if (result.rows.length === 0) {
222
+ return null;
223
+ }
224
+ // Value is already parsed by PostgreSQL JSONB type
225
+ return result.rows[0][this.valueColumn];
226
+ }
227
+ catch (error) {
228
+ // Table might not exist yet, that's okay
229
+ this.log('debug', `PostgreSQL L3: Error getting key: ${key}`, {
230
+ error: error instanceof Error ? error.message : String(error)
231
+ });
232
+ return null;
233
+ }
234
+ }
235
+ /**
236
+ * Store a value in PostgreSQL
237
+ *
238
+ * Inserts or updates the value in the nuvex_storage table. Uses UPSERT
239
+ * (INSERT ... ON CONFLICT) to handle existing keys efficiently.
240
+ *
241
+ * **Note:** This is the authoritative write. If this fails, the entire
242
+ * write operation should be considered failed.
243
+ *
244
+ * @param key - The key to store
245
+ * @param value - The value to store (will be JSON serialized)
246
+ * @param ttlSeconds - Optional TTL in seconds
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * // Store with 24 hour TTL
251
+ * await postgres.set('user:123', userData, 86400);
252
+ *
253
+ * // Store without TTL (persists until deleted)
254
+ * await postgres.set('config:app', configData);
255
+ * ```
256
+ */
257
+ async set(key, value, ttlSeconds) {
258
+ if (!this.connected || !this.pool) {
259
+ this.log('warn', 'PostgreSQL L3: Cannot set - not connected', { key });
260
+ throw new Error('PostgreSQL not connected');
261
+ }
262
+ try {
263
+ const expiresAt = ttlSeconds ? new Date(Date.now() + (ttlSeconds * 1000)) : null;
264
+ await this.pool.query(`INSERT INTO ${this.tableName} (${this.keyColumn}, ${this.valueColumn}, expires_at)
265
+ VALUES ($1, $2, $3)
266
+ ON CONFLICT (${this.keyColumn})
267
+ DO UPDATE SET ${this.valueColumn} = $2, expires_at = $3, updated_at = NOW()`, [key, JSON.stringify(value), expiresAt]);
268
+ }
269
+ catch (error) {
270
+ // If table doesn't exist, this is a critical error for L3
271
+ this.log('error', `PostgreSQL L3: Error setting key: ${key}`, {
272
+ error: error instanceof Error ? error.message : String(error)
273
+ });
274
+ throw error;
275
+ }
276
+ }
277
+ /**
278
+ * Delete a value from PostgreSQL
279
+ *
280
+ * Permanently removes the key from the nuvex_storage table.
281
+ *
282
+ * @param key - The key to delete
283
+ *
284
+ * @example
285
+ * ```typescript
286
+ * await postgres.delete('user:123');
287
+ * ```
288
+ */
289
+ async delete(key) {
290
+ if (!this.connected || !this.pool) {
291
+ return;
292
+ }
293
+ try {
294
+ await this.pool.query(`DELETE FROM ${this.tableName} WHERE ${this.keyColumn} = $1`, [key]);
295
+ }
296
+ catch (error) {
297
+ this.log('error', `PostgreSQL L3: Error deleting key: ${key}`, {
298
+ error: error instanceof Error ? error.message : String(error)
299
+ });
300
+ }
301
+ }
302
+ /**
303
+ * Check if a key exists in PostgreSQL
304
+ *
305
+ * Queries for the key and verifies it hasn't expired.
306
+ *
307
+ * @param key - The key to check
308
+ * @returns Promise resolving to true if the key exists and is not expired
309
+ *
310
+ * @example
311
+ * ```typescript
312
+ * if (await postgres.exists('user:123')) {
313
+ * console.log('Key exists in PostgreSQL');
314
+ * }
315
+ * ```
316
+ */
317
+ async exists(key) {
318
+ if (!this.connected || !this.pool) {
319
+ return false;
320
+ }
321
+ try {
322
+ const result = await this.pool.query(`SELECT 1 FROM ${this.tableName} WHERE ${this.keyColumn} = $1 AND (expires_at IS NULL OR expires_at > NOW())`, [key]);
323
+ return result.rows.length > 0;
324
+ }
325
+ catch (error) {
326
+ this.log('error', `PostgreSQL L3: Error checking existence: ${key}`, {
327
+ error: error instanceof Error ? error.message : String(error)
328
+ });
329
+ return false;
330
+ }
331
+ }
332
+ /**
333
+ * Clear all keys from PostgreSQL
334
+ *
335
+ * **WARNING:** This operation deletes all data from nuvex_storage table.
336
+ * Use with extreme caution in production environments.
337
+ *
338
+ * @example
339
+ * ```typescript
340
+ * await postgres.clear(); // Deletes all data
341
+ * ```
342
+ */
343
+ async clear() {
344
+ if (!this.connected || !this.pool) {
345
+ return;
346
+ }
347
+ try {
348
+ await this.pool.query(`DELETE FROM ${this.tableName}`);
349
+ this.log('info', 'PostgreSQL L3: All data cleared');
350
+ }
351
+ catch (error) {
352
+ this.log('error', 'PostgreSQL L3: Error clearing data', {
353
+ error: error instanceof Error ? error.message : String(error)
354
+ });
355
+ }
356
+ }
357
+ /**
358
+ * Health check for PostgreSQL connection
359
+ *
360
+ * Executes a simple SELECT 1 query to verify connectivity and database
361
+ * responsiveness. This is a lightweight operation that tests the full
362
+ * connection path including pool, connection, and database.
363
+ *
364
+ * @returns Promise resolving to true if PostgreSQL is healthy and responsive
365
+ *
366
+ * @example
367
+ * ```typescript
368
+ * const isHealthy = await postgres.ping();
369
+ * if (!isHealthy) {
370
+ * console.error('PostgreSQL connection is down');
371
+ * }
372
+ * ```
373
+ */
374
+ async ping() {
375
+ if (!this.connected || !this.pool) {
376
+ return false;
377
+ }
378
+ let client;
379
+ try {
380
+ // Get a client from the pool and run a simple query
381
+ client = await this.pool.connect();
382
+ try {
383
+ await client.query('SELECT 1');
384
+ return true;
385
+ }
386
+ finally {
387
+ client.release();
388
+ }
389
+ }
390
+ catch (error) {
391
+ this.log('error', 'PostgreSQL L3: Ping failed', {
392
+ error: error instanceof Error ? error.message : String(error)
393
+ });
394
+ return false;
395
+ }
396
+ }
397
+ /**
398
+ * Check if PostgreSQL is connected
399
+ *
400
+ * @returns True if connected
401
+ */
402
+ isConnected() {
403
+ return this.connected;
404
+ }
405
+ /**
406
+ * Get the PostgreSQL connection pool
407
+ *
408
+ * Useful for executing custom queries or transactions.
409
+ *
410
+ * @returns The connection pool or null if not connected
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * const pool = postgres.getPool();
415
+ * if (pool) {
416
+ * const result = await pool.query('SELECT * FROM custom_table');
417
+ * }
418
+ * ```
419
+ */
420
+ getPool() {
421
+ return this.pool;
422
+ }
423
+ /**
424
+ * Atomically increment a numeric value
425
+ *
426
+ * Uses PostgreSQL UPDATE with row-level locking for true atomic increments.
427
+ * If the key doesn't exist, it's created with the delta value.
428
+ *
429
+ * This operation is safe for concurrent access across multiple instances.
430
+ *
431
+ * @param key - The key to increment
432
+ * @param delta - The amount to increment by
433
+ * @param ttlSeconds - Optional TTL in seconds
434
+ * @returns Promise resolving to the new value after increment
435
+ *
436
+ * @example
437
+ * ```typescript
438
+ * // Atomic increment - safe for concurrent access
439
+ * const newValue = await postgres.increment('counter', 1, 86400);
440
+ * ```
441
+ */
442
+ async increment(key, delta, ttlSeconds) {
443
+ if (!this.connected || !this.pool) {
444
+ this.log('warn', 'PostgreSQL L3: Cannot increment - not connected', { key });
445
+ throw new Error('PostgreSQL not connected');
446
+ }
447
+ try {
448
+ const expiresAt = ttlSeconds ? new Date(Date.now() + (ttlSeconds * 1000)) : null;
449
+ // Atomic upsert to handle both insert and update cases
450
+ // This avoids race conditions when multiple concurrent increments happen on non-existent keys
451
+ const result = await this.pool.query(`INSERT INTO ${this.tableName} (${this.keyColumn}, ${this.valueColumn}, expires_at)
452
+ VALUES ($1, to_jsonb($2), $3)
453
+ ON CONFLICT (${this.keyColumn}) DO UPDATE
454
+ SET ${this.valueColumn} = to_jsonb(
455
+ CASE
456
+ WHEN ${this.tableName}.expires_at IS NULL OR ${this.tableName}.expires_at > NOW()
457
+ THEN (${this.tableName}.${this.valueColumn}::text)::numeric + (EXCLUDED.${this.valueColumn}::text)::numeric
458
+ ELSE (EXCLUDED.${this.valueColumn}::text)::numeric
459
+ END
460
+ ),
461
+ expires_at = EXCLUDED.expires_at,
462
+ updated_at = NOW()
463
+ RETURNING (${this.valueColumn}::text)::numeric as value`, [key, delta, expiresAt]);
464
+ if (result.rows.length > 0) {
465
+ return Number(result.rows[0].value);
466
+ }
467
+ // Fallback: should not reach here, but return delta if no rows returned
468
+ return delta;
469
+ }
470
+ catch (error) {
471
+ this.log('error', `PostgreSQL L3: Error incrementing key: ${key}`, {
472
+ error: error instanceof Error ? error.message : String(error)
473
+ });
474
+ throw error;
475
+ }
476
+ }
477
+ /**
478
+ * Log a message if logger is configured
479
+ *
480
+ * @private
481
+ * @param level - Log level
482
+ * @param message - Log message
483
+ * @param meta - Optional metadata
484
+ */
485
+ log(level, message, meta) {
486
+ if (this.logger) {
487
+ this.logger[level](message, meta);
488
+ }
489
+ }
490
+ }
491
+ exports.PostgresStorage = PostgresStorage;
492
+ //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/layers/postgres.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;;;;AAEH,4CAAqB;AACrB,MAAM,EAAE,IAAI,EAAE,GAAG,YAAG,CAAC;AAIrB,qDAA4D;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,MAAa,eAAe;IAyB1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,YAAY,MAAiC,EAAE,SAAwB,IAAI;QACzE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,6CAA6C;QAC7C,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,OAAO,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC;QAE3E,6CAA6C;QAC7C,uFAAuF;QACvF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,MAAyB,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,IAAI,CAAC,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,eAAe,CAAC;QACtD,IAAI,CAAC,SAAS,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,WAAW,CAAC;QACrD,IAAI,CAAC,WAAW,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,YAAY,CAAC;QAE1D,oDAAoD;QACpD,IAAA,mCAAqB,EAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACpD,IAAA,mCAAqB,EAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;QACzD,IAAA,mCAAqB,EAAC,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,OAAO;QACX,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,8BAA8B;gBAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,MAAwB,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,oBAAoB;gBACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAkB,CAAC;YACtC,CAAC;YAED,kBAAkB;YAClB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAClC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,uCAAuC,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,kCAAkC,EAAE;gBACpD,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAClC,UAAU,IAAI,CAAC,WAAW,SAAS,IAAI,CAAC,SAAS,UAAU,IAAI,CAAC,SAAS,sDAAsD,EAC/H,CAAC,GAAG,CAAC,CACN,CAAC;YAEF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,OAAO,IAAI,CAAC;YACd,CAAC;YAED,mDAAmD;YACnD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yCAAyC;YACzC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,qCAAqC,GAAG,EAAE,EAAE;gBAC5D,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAc,EAAE,UAAmB;QACxD,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,2CAA2C,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAEjF,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB,eAAe,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,WAAW;;wBAErD,IAAI,CAAC,SAAS;yBACb,IAAI,CAAC,WAAW,4CAA4C,EAC7E,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CACxC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,0DAA0D;YAC1D,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,qCAAqC,GAAG,EAAE,EAAE;gBAC5D,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,SAAS,UAAU,IAAI,CAAC,SAAS,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,sCAAsC,GAAG,EAAE,EAAE;gBAC7D,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAClC,iBAAiB,IAAI,CAAC,SAAS,UAAU,IAAI,CAAC,SAAS,sDAAsD,EAC7G,CAAC,GAAG,CAAC,CACN,CAAC;YAEF,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,4CAA4C,GAAG,EAAE,EAAE;gBACnE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YACvD,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,iCAAiC,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,oCAAoC,EAAE;gBACtD,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,MAAM,CAAC;QACX,IAAI,CAAC;YACH,oDAAoD;YACpD,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC/B,OAAO,IAAI,CAAC;YACd,CAAC;oBAAS,CAAC;gBACT,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,4BAA4B,EAAE;gBAC9C,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,SAAS,CAAC,GAAW,EAAE,KAAa,EAAE,UAAmB;QAC7D,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,iDAAiD,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YAC7E,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAEjF,uDAAuD;YACvD,8FAA8F;YAC9F,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAClC,eAAe,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,WAAW;;wBAErD,IAAI,CAAC,SAAS;iBACrB,IAAI,CAAC,WAAW;;0BAEP,IAAI,CAAC,SAAS,0BAA0B,IAAI,CAAC,SAAS;2BACrD,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,gCAAgC,IAAI,CAAC,WAAW;oCACzE,IAAI,CAAC,WAAW;;;;;sBAK9B,IAAI,CAAC,WAAW,2BAA2B,EACzD,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,CACxB,CAAC;YAEF,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;YAED,wEAAwE;YACxE,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,0CAA0C,GAAG,EAAE,EAAE;gBACjE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,GAAG,CAAC,KAA0C,EAAE,OAAe,EAAE,IAA8B;QACrG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;CACF;AA3cD,0CA2cC"}