@anfenn/dync 1.0.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.
Files changed (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +212 -0
  3. package/dist/capacitor.cjs +228 -0
  4. package/dist/capacitor.cjs.map +1 -0
  5. package/dist/capacitor.d.cts +62 -0
  6. package/dist/capacitor.d.ts +62 -0
  7. package/dist/capacitor.js +9 -0
  8. package/dist/capacitor.js.map +1 -0
  9. package/dist/chunk-LGHOZECP.js +3884 -0
  10. package/dist/chunk-LGHOZECP.js.map +1 -0
  11. package/dist/chunk-SQB6E7V2.js +191 -0
  12. package/dist/chunk-SQB6E7V2.js.map +1 -0
  13. package/dist/dexie-Bv-fV10P.d.cts +444 -0
  14. package/dist/dexie-DJFApKsM.d.ts +444 -0
  15. package/dist/dexie.cjs +381 -0
  16. package/dist/dexie.cjs.map +1 -0
  17. package/dist/dexie.d.cts +3 -0
  18. package/dist/dexie.d.ts +3 -0
  19. package/dist/dexie.js +343 -0
  20. package/dist/dexie.js.map +1 -0
  21. package/dist/expoSqlite.cjs +98 -0
  22. package/dist/expoSqlite.cjs.map +1 -0
  23. package/dist/expoSqlite.d.cts +17 -0
  24. package/dist/expoSqlite.d.ts +17 -0
  25. package/dist/expoSqlite.js +61 -0
  26. package/dist/expoSqlite.js.map +1 -0
  27. package/dist/index.cjs +3916 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +8 -0
  30. package/dist/index.d.ts +8 -0
  31. package/dist/index.js +20 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/index.shared-CPIge2ZM.d.ts +234 -0
  34. package/dist/index.shared-YSn6c01d.d.cts +234 -0
  35. package/dist/node.cjs +126 -0
  36. package/dist/node.cjs.map +1 -0
  37. package/dist/node.d.cts +80 -0
  38. package/dist/node.d.ts +80 -0
  39. package/dist/node.js +89 -0
  40. package/dist/node.js.map +1 -0
  41. package/dist/react/index.cjs +1754 -0
  42. package/dist/react/index.cjs.map +1 -0
  43. package/dist/react/index.d.cts +40 -0
  44. package/dist/react/index.d.ts +40 -0
  45. package/dist/react/index.js +78 -0
  46. package/dist/react/index.js.map +1 -0
  47. package/dist/types-CSbIAfu2.d.cts +46 -0
  48. package/dist/types-CSbIAfu2.d.ts +46 -0
  49. package/dist/wa-sqlite.cjs +318 -0
  50. package/dist/wa-sqlite.cjs.map +1 -0
  51. package/dist/wa-sqlite.d.cts +175 -0
  52. package/dist/wa-sqlite.d.ts +175 -0
  53. package/dist/wa-sqlite.js +281 -0
  54. package/dist/wa-sqlite.js.map +1 -0
  55. package/package.json +171 -0
  56. package/src/addVisibilityChangeListener.native.ts +33 -0
  57. package/src/addVisibilityChangeListener.ts +24 -0
  58. package/src/capacitor.ts +4 -0
  59. package/src/core/StateManager.ts +272 -0
  60. package/src/core/firstLoad.ts +332 -0
  61. package/src/core/pullOperations.ts +212 -0
  62. package/src/core/pushOperations.ts +290 -0
  63. package/src/core/tableEnhancers.ts +457 -0
  64. package/src/core/types.ts +3 -0
  65. package/src/createLocalId.native.ts +8 -0
  66. package/src/createLocalId.ts +6 -0
  67. package/src/dexie.ts +2 -0
  68. package/src/expoSqlite.ts +2 -0
  69. package/src/helpers.ts +87 -0
  70. package/src/index.native.ts +28 -0
  71. package/src/index.shared.ts +613 -0
  72. package/src/index.ts +28 -0
  73. package/src/logger.ts +26 -0
  74. package/src/node.ts +4 -0
  75. package/src/react/index.ts +2 -0
  76. package/src/react/useDync.ts +156 -0
  77. package/src/storage/dexie/DexieAdapter.ts +72 -0
  78. package/src/storage/dexie/DexieQueryContext.ts +14 -0
  79. package/src/storage/dexie/DexieStorageCollection.ts +124 -0
  80. package/src/storage/dexie/DexieStorageTable.ts +123 -0
  81. package/src/storage/dexie/DexieStorageWhereClause.ts +103 -0
  82. package/src/storage/dexie/helpers.ts +1 -0
  83. package/src/storage/dexie/index.ts +7 -0
  84. package/src/storage/memory/MemoryAdapter.ts +55 -0
  85. package/src/storage/memory/MemoryCollection.ts +215 -0
  86. package/src/storage/memory/MemoryQueryContext.ts +14 -0
  87. package/src/storage/memory/MemoryTable.ts +336 -0
  88. package/src/storage/memory/MemoryWhereClause.ts +134 -0
  89. package/src/storage/memory/index.ts +7 -0
  90. package/src/storage/memory/types.ts +24 -0
  91. package/src/storage/sqlite/SQLiteAdapter.ts +564 -0
  92. package/src/storage/sqlite/SQLiteCollection.ts +294 -0
  93. package/src/storage/sqlite/SQLiteTable.ts +604 -0
  94. package/src/storage/sqlite/SQLiteWhereClause.ts +341 -0
  95. package/src/storage/sqlite/SqliteQueryContext.ts +30 -0
  96. package/src/storage/sqlite/drivers/BetterSqlite3Driver.ts +156 -0
  97. package/src/storage/sqlite/drivers/CapacitorFastSqlDriver.ts +114 -0
  98. package/src/storage/sqlite/drivers/CapacitorSQLiteDriver.ts +137 -0
  99. package/src/storage/sqlite/drivers/ExpoSQLiteDriver.native.ts +67 -0
  100. package/src/storage/sqlite/drivers/WaSqliteDriver.ts +537 -0
  101. package/src/storage/sqlite/drivers/wa-sqlite-vfs.d.ts +46 -0
  102. package/src/storage/sqlite/helpers.ts +144 -0
  103. package/src/storage/sqlite/index.ts +11 -0
  104. package/src/storage/sqlite/schema.ts +44 -0
  105. package/src/storage/sqlite/types.ts +164 -0
  106. package/src/storage/types.ts +112 -0
  107. package/src/types.ts +186 -0
  108. package/src/wa-sqlite.ts +4 -0
@@ -0,0 +1,80 @@
1
+ import * as better_sqlite3 from 'better-sqlite3';
2
+ import { S as SQLiteDatabaseDriver, a as SQLiteRunResult, b as SQLiteQueryResult } from './types-CSbIAfu2.cjs';
3
+
4
+ /**
5
+ * Options for configuring the BetterSqlite3Driver.
6
+ */
7
+ interface BetterSqlite3DriverOptions {
8
+ /**
9
+ * Open the database in readonly mode.
10
+ * @default false
11
+ */
12
+ readonly?: boolean;
13
+ /**
14
+ * Create the database file if it doesn't exist.
15
+ * Set to false to throw an error if the file doesn't exist.
16
+ * @default true
17
+ */
18
+ fileMustExist?: boolean;
19
+ /**
20
+ * Timeout in milliseconds when waiting for the database to become unlocked.
21
+ * @default 5000
22
+ */
23
+ timeout?: number;
24
+ /**
25
+ * Enable verbose mode for debugging SQL statements.
26
+ */
27
+ verbose?: (message?: unknown, ...additionalArgs: unknown[]) => void;
28
+ /**
29
+ * Enable WAL (Write-Ahead Logging) mode for better concurrent access.
30
+ * Recommended for most use cases.
31
+ * @default true
32
+ */
33
+ wal?: boolean;
34
+ }
35
+ /**
36
+ * SQLite driver for Node.js using better-sqlite3.
37
+ * This driver is synchronous but wraps operations in Promises for API compatibility.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { BetterSqlite3Driver } from '@anfenn/dync/node';
42
+ * import { SQLiteAdapter } from '@anfenn/dync';
43
+ *
44
+ * const driver = new BetterSqlite3Driver('myapp.db', { wal: true });
45
+ * const adapter = new SQLiteAdapter('myapp', driver);
46
+ * ```
47
+ */
48
+ declare class BetterSqlite3Driver implements SQLiteDatabaseDriver {
49
+ readonly type = "BetterSqlite3Driver";
50
+ private db;
51
+ private readonly options;
52
+ private opened;
53
+ readonly name: string;
54
+ constructor(databasePath: string, options?: BetterSqlite3DriverOptions);
55
+ open(): Promise<void>;
56
+ close(): Promise<void>;
57
+ execute(statement: string): Promise<void>;
58
+ run(statement: string, values?: unknown[]): Promise<SQLiteRunResult>;
59
+ query(statement: string, values?: unknown[]): Promise<SQLiteQueryResult>;
60
+ /**
61
+ * Access the underlying better-sqlite3 Database instance for advanced operations.
62
+ * Returns null if the database is not open.
63
+ */
64
+ getDatabase(): better_sqlite3.Database | null;
65
+ /**
66
+ * Execute a function within a transaction.
67
+ * This provides better performance when doing many writes.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * await driver.transaction(() => {
72
+ * driver.run('INSERT INTO users (name) VALUES (?)', ['Alice']);
73
+ * driver.run('INSERT INTO users (name) VALUES (?)', ['Bob']);
74
+ * });
75
+ * ```
76
+ */
77
+ transaction<T>(fn: () => T): T;
78
+ }
79
+
80
+ export { BetterSqlite3Driver, type BetterSqlite3DriverOptions, SQLiteDatabaseDriver, SQLiteQueryResult, SQLiteRunResult };
package/dist/node.d.ts ADDED
@@ -0,0 +1,80 @@
1
+ import * as better_sqlite3 from 'better-sqlite3';
2
+ import { S as SQLiteDatabaseDriver, a as SQLiteRunResult, b as SQLiteQueryResult } from './types-CSbIAfu2.js';
3
+
4
+ /**
5
+ * Options for configuring the BetterSqlite3Driver.
6
+ */
7
+ interface BetterSqlite3DriverOptions {
8
+ /**
9
+ * Open the database in readonly mode.
10
+ * @default false
11
+ */
12
+ readonly?: boolean;
13
+ /**
14
+ * Create the database file if it doesn't exist.
15
+ * Set to false to throw an error if the file doesn't exist.
16
+ * @default true
17
+ */
18
+ fileMustExist?: boolean;
19
+ /**
20
+ * Timeout in milliseconds when waiting for the database to become unlocked.
21
+ * @default 5000
22
+ */
23
+ timeout?: number;
24
+ /**
25
+ * Enable verbose mode for debugging SQL statements.
26
+ */
27
+ verbose?: (message?: unknown, ...additionalArgs: unknown[]) => void;
28
+ /**
29
+ * Enable WAL (Write-Ahead Logging) mode for better concurrent access.
30
+ * Recommended for most use cases.
31
+ * @default true
32
+ */
33
+ wal?: boolean;
34
+ }
35
+ /**
36
+ * SQLite driver for Node.js using better-sqlite3.
37
+ * This driver is synchronous but wraps operations in Promises for API compatibility.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { BetterSqlite3Driver } from '@anfenn/dync/node';
42
+ * import { SQLiteAdapter } from '@anfenn/dync';
43
+ *
44
+ * const driver = new BetterSqlite3Driver('myapp.db', { wal: true });
45
+ * const adapter = new SQLiteAdapter('myapp', driver);
46
+ * ```
47
+ */
48
+ declare class BetterSqlite3Driver implements SQLiteDatabaseDriver {
49
+ readonly type = "BetterSqlite3Driver";
50
+ private db;
51
+ private readonly options;
52
+ private opened;
53
+ readonly name: string;
54
+ constructor(databasePath: string, options?: BetterSqlite3DriverOptions);
55
+ open(): Promise<void>;
56
+ close(): Promise<void>;
57
+ execute(statement: string): Promise<void>;
58
+ run(statement: string, values?: unknown[]): Promise<SQLiteRunResult>;
59
+ query(statement: string, values?: unknown[]): Promise<SQLiteQueryResult>;
60
+ /**
61
+ * Access the underlying better-sqlite3 Database instance for advanced operations.
62
+ * Returns null if the database is not open.
63
+ */
64
+ getDatabase(): better_sqlite3.Database | null;
65
+ /**
66
+ * Execute a function within a transaction.
67
+ * This provides better performance when doing many writes.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * await driver.transaction(() => {
72
+ * driver.run('INSERT INTO users (name) VALUES (?)', ['Alice']);
73
+ * driver.run('INSERT INTO users (name) VALUES (?)', ['Bob']);
74
+ * });
75
+ * ```
76
+ */
77
+ transaction<T>(fn: () => T): T;
78
+ }
79
+
80
+ export { BetterSqlite3Driver, type BetterSqlite3DriverOptions, SQLiteDatabaseDriver, SQLiteQueryResult, SQLiteRunResult };
package/dist/node.js ADDED
@@ -0,0 +1,89 @@
1
+ // src/storage/sqlite/drivers/BetterSqlite3Driver.ts
2
+ var BetterSqlite3Driver = class {
3
+ type = "BetterSqlite3Driver";
4
+ db = null;
5
+ options;
6
+ opened = false;
7
+ name;
8
+ constructor(databasePath, options = {}) {
9
+ this.name = databasePath;
10
+ this.options = {
11
+ wal: true,
12
+ ...options
13
+ };
14
+ }
15
+ async open() {
16
+ if (this.opened) return;
17
+ const Database = (await import("better-sqlite3")).default;
18
+ this.db = new Database(this.name, {
19
+ readonly: this.options.readonly ?? false,
20
+ fileMustExist: this.options.fileMustExist ?? false,
21
+ timeout: this.options.timeout ?? 5e3,
22
+ verbose: this.options.verbose
23
+ });
24
+ if (this.options.wal && !this.options.readonly) {
25
+ this.db.pragma("journal_mode = WAL");
26
+ }
27
+ this.opened = true;
28
+ }
29
+ async close() {
30
+ if (!this.db) return;
31
+ this.db.close();
32
+ this.db = null;
33
+ this.opened = false;
34
+ }
35
+ async execute(statement) {
36
+ await this.open();
37
+ this.db.exec(statement);
38
+ }
39
+ async run(statement, values = []) {
40
+ await this.open();
41
+ const stmt = this.db.prepare(statement);
42
+ const result = stmt.run(...values);
43
+ return {
44
+ changes: result.changes,
45
+ lastId: result.lastInsertRowid !== void 0 ? Number(result.lastInsertRowid) : void 0
46
+ };
47
+ }
48
+ async query(statement, values = []) {
49
+ await this.open();
50
+ const stmt = this.db.prepare(statement);
51
+ const rows = stmt.all(...values);
52
+ if (rows.length === 0) {
53
+ return { columns: [], values: [] };
54
+ }
55
+ const firstRow = rows[0];
56
+ const columns = Object.keys(firstRow);
57
+ const valuesMatrix = rows.map((row) => columns.map((col) => row[col]));
58
+ return { columns, values: valuesMatrix };
59
+ }
60
+ /**
61
+ * Access the underlying better-sqlite3 Database instance for advanced operations.
62
+ * Returns null if the database is not open.
63
+ */
64
+ getDatabase() {
65
+ return this.db;
66
+ }
67
+ /**
68
+ * Execute a function within a transaction.
69
+ * This provides better performance when doing many writes.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * await driver.transaction(() => {
74
+ * driver.run('INSERT INTO users (name) VALUES (?)', ['Alice']);
75
+ * driver.run('INSERT INTO users (name) VALUES (?)', ['Bob']);
76
+ * });
77
+ * ```
78
+ */
79
+ transaction(fn) {
80
+ if (!this.db) {
81
+ throw new Error("Database not open. Call open() first.");
82
+ }
83
+ return this.db.transaction(fn)();
84
+ }
85
+ };
86
+ export {
87
+ BetterSqlite3Driver
88
+ };
89
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/storage/sqlite/drivers/BetterSqlite3Driver.ts"],"sourcesContent":["import type { SQLiteDatabaseDriver, SQLiteQueryResult, SQLiteRunResult } from '../types';\n\n/**\n * Options for configuring the BetterSqlite3Driver.\n */\nexport interface BetterSqlite3DriverOptions {\n /**\n * Open the database in readonly mode.\n * @default false\n */\n readonly?: boolean;\n\n /**\n * Create the database file if it doesn't exist.\n * Set to false to throw an error if the file doesn't exist.\n * @default true\n */\n fileMustExist?: boolean;\n\n /**\n * Timeout in milliseconds when waiting for the database to become unlocked.\n * @default 5000\n */\n timeout?: number;\n\n /**\n * Enable verbose mode for debugging SQL statements.\n */\n verbose?: (message?: unknown, ...additionalArgs: unknown[]) => void;\n\n /**\n * Enable WAL (Write-Ahead Logging) mode for better concurrent access.\n * Recommended for most use cases.\n * @default true\n */\n wal?: boolean;\n}\n\n/**\n * SQLite driver for Node.js using better-sqlite3.\n * This driver is synchronous but wraps operations in Promises for API compatibility.\n *\n * @example\n * ```ts\n * import { BetterSqlite3Driver } from '@anfenn/dync/node';\n * import { SQLiteAdapter } from '@anfenn/dync';\n *\n * const driver = new BetterSqlite3Driver('myapp.db', { wal: true });\n * const adapter = new SQLiteAdapter('myapp', driver);\n * ```\n */\nexport class BetterSqlite3Driver implements SQLiteDatabaseDriver {\n readonly type = 'BetterSqlite3Driver';\n private db: import('better-sqlite3').Database | null = null;\n private readonly options: BetterSqlite3DriverOptions;\n private opened = false;\n readonly name: string;\n\n constructor(databasePath: string, options: BetterSqlite3DriverOptions = {}) {\n this.name = databasePath;\n this.options = {\n wal: true,\n ...options,\n };\n }\n\n async open(): Promise<void> {\n if (this.opened) return;\n\n // Dynamic import to avoid bundling issues in non-Electron environments\n const Database = (await import('better-sqlite3')).default;\n\n this.db = new Database(this.name, {\n readonly: this.options.readonly ?? false,\n fileMustExist: this.options.fileMustExist ?? false,\n timeout: this.options.timeout ?? 5000,\n verbose: this.options.verbose,\n });\n\n // Enable WAL mode for better concurrent access (recommended)\n if (this.options.wal && !this.options.readonly) {\n this.db.pragma('journal_mode = WAL');\n }\n\n this.opened = true;\n }\n\n async close(): Promise<void> {\n if (!this.db) return;\n\n this.db.close();\n this.db = null;\n this.opened = false;\n }\n\n async execute(statement: string): Promise<void> {\n await this.open();\n this.db!.exec(statement);\n }\n\n async run(statement: string, values: unknown[] = []): Promise<SQLiteRunResult> {\n await this.open();\n\n const stmt = this.db!.prepare(statement);\n const result = stmt.run(...values);\n\n return {\n changes: result.changes,\n lastId: result.lastInsertRowid !== undefined ? Number(result.lastInsertRowid) : undefined,\n };\n }\n\n async query(statement: string, values: unknown[] = []): Promise<SQLiteQueryResult> {\n await this.open();\n\n const stmt = this.db!.prepare(statement);\n const rows = stmt.all(...values) as Record<string, unknown>[];\n\n if (rows.length === 0) {\n return { columns: [], values: [] };\n }\n\n const firstRow = rows[0]!;\n const columns = Object.keys(firstRow);\n const valuesMatrix = rows.map((row) => columns.map((col) => row[col]));\n\n return { columns, values: valuesMatrix };\n }\n\n /**\n * Access the underlying better-sqlite3 Database instance for advanced operations.\n * Returns null if the database is not open.\n */\n getDatabase(): import('better-sqlite3').Database | null {\n return this.db;\n }\n\n /**\n * Execute a function within a transaction.\n * This provides better performance when doing many writes.\n *\n * @example\n * ```ts\n * await driver.transaction(() => {\n * driver.run('INSERT INTO users (name) VALUES (?)', ['Alice']);\n * driver.run('INSERT INTO users (name) VALUES (?)', ['Bob']);\n * });\n * ```\n */\n transaction<T>(fn: () => T): T {\n if (!this.db) {\n throw new Error('Database not open. Call open() first.');\n }\n return this.db.transaction(fn)();\n }\n}\n"],"mappings":";AAmDO,IAAM,sBAAN,MAA0D;AAAA,EACpD,OAAO;AAAA,EACR,KAA+C;AAAA,EACtC;AAAA,EACT,SAAS;AAAA,EACR;AAAA,EAET,YAAY,cAAsB,UAAsC,CAAC,GAAG;AACxE,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,MACX,KAAK;AAAA,MACL,GAAG;AAAA,IACP;AAAA,EACJ;AAAA,EAEA,MAAM,OAAsB;AACxB,QAAI,KAAK,OAAQ;AAGjB,UAAM,YAAY,MAAM,OAAO,gBAAgB,GAAG;AAElD,SAAK,KAAK,IAAI,SAAS,KAAK,MAAM;AAAA,MAC9B,UAAU,KAAK,QAAQ,YAAY;AAAA,MACnC,eAAe,KAAK,QAAQ,iBAAiB;AAAA,MAC7C,SAAS,KAAK,QAAQ,WAAW;AAAA,MACjC,SAAS,KAAK,QAAQ;AAAA,IAC1B,CAAC;AAGD,QAAI,KAAK,QAAQ,OAAO,CAAC,KAAK,QAAQ,UAAU;AAC5C,WAAK,GAAG,OAAO,oBAAoB;AAAA,IACvC;AAEA,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,QAAuB;AACzB,QAAI,CAAC,KAAK,GAAI;AAEd,SAAK,GAAG,MAAM;AACd,SAAK,KAAK;AACV,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,QAAQ,WAAkC;AAC5C,UAAM,KAAK,KAAK;AAChB,SAAK,GAAI,KAAK,SAAS;AAAA,EAC3B;AAAA,EAEA,MAAM,IAAI,WAAmB,SAAoB,CAAC,GAA6B;AAC3E,UAAM,KAAK,KAAK;AAEhB,UAAM,OAAO,KAAK,GAAI,QAAQ,SAAS;AACvC,UAAM,SAAS,KAAK,IAAI,GAAG,MAAM;AAEjC,WAAO;AAAA,MACH,SAAS,OAAO;AAAA,MAChB,QAAQ,OAAO,oBAAoB,SAAY,OAAO,OAAO,eAAe,IAAI;AAAA,IACpF;AAAA,EACJ;AAAA,EAEA,MAAM,MAAM,WAAmB,SAAoB,CAAC,GAA+B;AAC/E,UAAM,KAAK,KAAK;AAEhB,UAAM,OAAO,KAAK,GAAI,QAAQ,SAAS;AACvC,UAAM,OAAO,KAAK,IAAI,GAAG,MAAM;AAE/B,QAAI,KAAK,WAAW,GAAG;AACnB,aAAO,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,EAAE;AAAA,IACrC;AAEA,UAAM,WAAW,KAAK,CAAC;AACvB,UAAM,UAAU,OAAO,KAAK,QAAQ;AACpC,UAAM,eAAe,KAAK,IAAI,CAAC,QAAQ,QAAQ,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;AAErE,WAAO,EAAE,SAAS,QAAQ,aAAa;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAwD;AACpD,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,YAAe,IAAgB;AAC3B,QAAI,CAAC,KAAK,IAAI;AACV,YAAM,IAAI,MAAM,uCAAuC;AAAA,IAC3D;AACA,WAAO,KAAK,GAAG,YAAY,EAAE,EAAE;AAAA,EACnC;AACJ;","names":[]}