jiren 1.5.5 → 1.6.5

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 (45) hide show
  1. package/README.md +123 -313
  2. package/components/cache.ts +1 -1
  3. package/components/client-node-native.ts +602 -159
  4. package/components/client.ts +51 -29
  5. package/components/metrics.ts +1 -4
  6. package/components/native-node.ts +48 -3
  7. package/components/native.ts +29 -0
  8. package/components/persistent-worker.ts +73 -0
  9. package/components/subprocess-worker.ts +65 -0
  10. package/components/types.ts +2 -0
  11. package/components/worker-pool.ts +169 -0
  12. package/components/worker.ts +39 -23
  13. package/dist/components/cache.d.ts +76 -0
  14. package/dist/components/cache.d.ts.map +1 -0
  15. package/dist/components/cache.js +439 -0
  16. package/dist/components/cache.js.map +1 -0
  17. package/dist/components/client-node-native.d.ts +134 -0
  18. package/dist/components/client-node-native.d.ts.map +1 -0
  19. package/dist/components/client-node-native.js +811 -0
  20. package/dist/components/client-node-native.js.map +1 -0
  21. package/dist/components/metrics.d.ts +104 -0
  22. package/dist/components/metrics.d.ts.map +1 -0
  23. package/dist/components/metrics.js +296 -0
  24. package/dist/components/metrics.js.map +1 -0
  25. package/dist/components/native-node.d.ts +67 -0
  26. package/dist/components/native-node.d.ts.map +1 -0
  27. package/dist/components/native-node.js +137 -0
  28. package/dist/components/native-node.js.map +1 -0
  29. package/dist/components/types.d.ts +252 -0
  30. package/dist/components/types.d.ts.map +1 -0
  31. package/dist/components/types.js +5 -0
  32. package/dist/components/types.js.map +1 -0
  33. package/dist/index-node.d.ts +10 -0
  34. package/dist/index-node.d.ts.map +1 -0
  35. package/dist/index-node.js +12 -0
  36. package/dist/index-node.js.map +1 -0
  37. package/dist/types/index.d.ts +63 -0
  38. package/dist/types/index.d.ts.map +1 -0
  39. package/dist/types/index.js +6 -0
  40. package/dist/types/index.js.map +1 -0
  41. package/index-node.ts +6 -6
  42. package/index.ts +4 -3
  43. package/lib/libhttpclient.dylib +0 -0
  44. package/package.json +15 -8
  45. package/types/index.ts +0 -68
@@ -1,13 +1,22 @@
1
1
  import { parentPort } from "worker_threads";
2
2
  import { CString, type Pointer } from "bun:ffi";
3
3
  import { lib } from "./native";
4
- import type { RequestOptions } from "../types";
4
+ import type { RequestOptions } from "./types";
5
5
 
6
- // Each worker has its own isolated native client
7
- let ptr: Pointer | null = lib.symbols.zclient_new();
6
+ // LAZY INITIALIZATION: Don't create client until first request
7
+ // This avoids race conditions with library loading
8
+ let ptr: Pointer | null = null;
8
9
 
9
- if (!ptr) {
10
- throw new Error("Failed to create native client instance in worker");
10
+ function ensureClient(): Pointer {
11
+ if (!ptr) {
12
+ ptr = lib.symbols.zclient_new();
13
+ if (!ptr) {
14
+ throw new Error("Failed to create native client instance in worker");
15
+ }
16
+ // Enable benchmark mode for consistent performance
17
+ lib.symbols.zclient_set_benchmark_mode(ptr, true);
18
+ }
19
+ return ptr;
11
20
  }
12
21
 
13
22
  // Handle cleanup
@@ -37,20 +46,27 @@ if (parentPort) {
37
46
  }
38
47
 
39
48
  if (msg.type === "prefetch") {
40
- if (!ptr) return;
41
- const urls = msg.url as unknown as string[]; // hack: url field used for string[]
42
- for (const url of urls) {
43
- const urlBuffer = Buffer.from(url + "\0");
44
- lib.symbols.zclient_prefetch(ptr, urlBuffer);
49
+ try {
50
+ const client = ensureClient();
51
+ const urls = msg.url as unknown as string[];
52
+ for (const url of urls) {
53
+ const urlBuffer = Buffer.from(url + "\0");
54
+ lib.symbols.zclient_prefetch(client, urlBuffer);
55
+ }
56
+ parentPort?.postMessage({ type: "prefetch_done" });
57
+ } catch (err: any) {
58
+ parentPort?.postMessage({
59
+ type: "prefetch_done",
60
+ error: err.message,
61
+ });
45
62
  }
46
- parentPort?.postMessage({ type: "prefetch_done" });
47
63
  return;
48
64
  }
49
65
 
50
66
  const { id, url, options } = msg;
51
67
 
52
68
  try {
53
- if (!ptr) throw new Error("Worker client is closed");
69
+ const client = ensureClient();
54
70
 
55
71
  const method = options.method || "GET";
56
72
  const methodBuffer = Buffer.from(method + "\0");
@@ -78,8 +94,9 @@ if (parentPort) {
78
94
  const maxRedirects = options.maxRedirects ?? 5;
79
95
  const antibot = options.antibot ?? false;
80
96
 
81
- const respPtr = lib.symbols.zclient_request(
82
- ptr,
97
+ // Use the full request API for complete response
98
+ const respPtr = lib.symbols.zclient_request_full(
99
+ client,
83
100
  methodBuffer,
84
101
  urlBuffer,
85
102
  headersBuffer,
@@ -88,16 +105,15 @@ if (parentPort) {
88
105
  antibot
89
106
  );
90
107
 
91
- // Parse Response
92
108
  if (!respPtr) throw new Error("Native request failed");
93
109
 
94
- const status = lib.symbols.zclient_response_status(respPtr);
95
- const bodyLen = Number(lib.symbols.zclient_response_body_len(respPtr));
96
- const bodyPtr = lib.symbols.zclient_response_body(respPtr);
110
+ const status = lib.symbols.zfull_response_status(respPtr);
111
+ const bodyLen = Number(lib.symbols.zfull_response_body_len(respPtr));
112
+ const bodyPtr = lib.symbols.zfull_response_body(respPtr);
97
113
  const headersLen = Number(
98
- lib.symbols.zclient_response_headers_len(respPtr)
114
+ lib.symbols.zfull_response_headers_len(respPtr)
99
115
  );
100
- const headersPtr = lib.symbols.zclient_response_headers(respPtr);
116
+ const headersRawPtr = lib.symbols.zfull_response_headers(respPtr);
101
117
 
102
118
  let bodyString = "";
103
119
  if (bodyLen > 0 && bodyPtr) {
@@ -105,8 +121,8 @@ if (parentPort) {
105
121
  }
106
122
 
107
123
  const headers: Record<string, string> = {};
108
- if (headersLen > 0 && headersPtr) {
109
- const headersStr = new CString(headersPtr).toString();
124
+ if (headersLen > 0 && headersRawPtr) {
125
+ const headersStr = new CString(headersRawPtr).toString();
110
126
  const lines = headersStr.split("\r\n");
111
127
  for (const line of lines) {
112
128
  if (!line) continue;
@@ -119,7 +135,7 @@ if (parentPort) {
119
135
  }
120
136
  }
121
137
 
122
- lib.symbols.zclient_response_free(respPtr);
138
+ lib.symbols.zclient_response_full_free(respPtr);
123
139
 
124
140
  parentPort?.postMessage({
125
141
  id,
@@ -0,0 +1,76 @@
1
+ import type { JirenResponse } from "./types.js";
2
+ /**
3
+ * Two-Tier Response Cache
4
+ *
5
+ * L1: In-Memory LRU Cache (~0.001ms access) - hot data
6
+ * L2: Disk Cache with gzip (~5ms access) - persistence
7
+ *
8
+ * Read path: L1 → L2 → Network
9
+ * Write path: L1 + L2 (write-through)
10
+ */
11
+ export declare class ResponseCache {
12
+ private l1;
13
+ private cacheDir;
14
+ private maxDiskSize;
15
+ constructor(l1Capacity?: number, cacheDir?: string, maxDiskSize?: number);
16
+ /**
17
+ * Generate cache key from URL and options
18
+ */
19
+ private generateKey;
20
+ /**
21
+ * Get cache file path (compressed .gz file)
22
+ */
23
+ private getCacheFilePath;
24
+ /**
25
+ * Preload L2 disk cache entry into L1 memory cache.
26
+ * Call this during initialization to ensure first request hits L1.
27
+ * @param url - Base URL to preload
28
+ * @param path - Optional path
29
+ * @param options - Optional request options
30
+ * @returns true if entry was preloaded, false if not found/expired
31
+ */
32
+ preloadL1(url: string, path?: string, options?: any): boolean;
33
+ /**
34
+ * Get cached response - checks L1 first, then L2
35
+ */
36
+ get(url: string, path?: string, options?: any): JirenResponse | null;
37
+ /**
38
+ * Get from L2 disk cache
39
+ */
40
+ private getFromDisk;
41
+ /**
42
+ * Store response in both L1 and L2 (write-through)
43
+ */
44
+ set(url: string, response: JirenResponse, ttl: number, path?: string, options?: any): void;
45
+ /**
46
+ * Write to L2 disk cache
47
+ */
48
+ private setToDisk;
49
+ /**
50
+ * Clear cache for a specific URL or all
51
+ */
52
+ clear(url?: string): void;
53
+ /**
54
+ * Clear all L2 disk cache files
55
+ */
56
+ private clearAllDisk;
57
+ /**
58
+ * Get combined cache statistics
59
+ */
60
+ stats(): {
61
+ l1: {
62
+ size: number;
63
+ capacity: number;
64
+ hits: number;
65
+ misses: number;
66
+ hitRate: string;
67
+ };
68
+ l2: {
69
+ size: number;
70
+ maxSize: number;
71
+ cacheDir: string;
72
+ totalSizeKB: string;
73
+ };
74
+ };
75
+ }
76
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../components/cache.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AAqOnE;;;;;;;;GAQG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;gBAEhB,UAAU,SAAM,EAAE,QAAQ,SAAiB,EAAE,WAAW,SAAM;IAW1E;;OAEG;IACH,OAAO,CAAC,WAAW;IAUnB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;;;;;;OAOG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO;IAkB7D;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,aAAa,GAAG,IAAI;IAoBpE;;OAEG;IACH,OAAO,CAAC,WAAW;IAkDnB;;OAEG;IACH,GAAG,CACD,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,GAAG,GACZ,IAAI;IAgBP;;OAEG;YACW,SAAS;IAuDvB;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAezB;;OAEG;IACH,OAAO,CAAC,YAAY;IAapB;;OAEG;IACH,KAAK;;;;;;;;;;;;;;;CA6BN"}
@@ -0,0 +1,439 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, readdirSync, statSync, } from "fs";
2
+ import { gzipSync, gunzipSync } from "zlib";
3
+ import { createHash } from "crypto";
4
+ import { join } from "path";
5
+ /**
6
+ * Reconstruct body methods from raw data
7
+ */
8
+ function reconstructBody(bodyData, isText) {
9
+ let buffer;
10
+ if (isText) {
11
+ // Text data stored directly
12
+ const encoder = new TextEncoder();
13
+ buffer = encoder.encode(bodyData).buffer;
14
+ }
15
+ else {
16
+ // Binary data stored as base64
17
+ const binaryString = atob(bodyData);
18
+ const bytes = new Uint8Array(binaryString.length);
19
+ for (let i = 0; i < binaryString.length; i++) {
20
+ bytes[i] = binaryString.charCodeAt(i);
21
+ }
22
+ buffer = bytes.buffer;
23
+ }
24
+ return {
25
+ bodyUsed: false,
26
+ text: async () => {
27
+ if (isText)
28
+ return bodyData;
29
+ const decoder = new TextDecoder();
30
+ return decoder.decode(buffer);
31
+ },
32
+ json: async () => {
33
+ const text = isText ? bodyData : new TextDecoder().decode(buffer);
34
+ return JSON.parse(text);
35
+ },
36
+ arrayBuffer: async () => buffer,
37
+ blob: async () => new Blob([buffer]),
38
+ };
39
+ }
40
+ /**
41
+ * L1 In-Memory LRU Cache
42
+ * Provides ~0.001ms access time (vs ~5ms for disk)
43
+ */
44
+ class L1MemoryCache {
45
+ capacity;
46
+ cache = new Map();
47
+ head = null; // Most recently used
48
+ tail = null; // Least recently used
49
+ // Stats
50
+ hits = 0;
51
+ misses = 0;
52
+ constructor(capacity = 100) {
53
+ this.capacity = capacity;
54
+ }
55
+ /**
56
+ * Get from L1 cache (O(1) lookup + LRU update)
57
+ */
58
+ get(key) {
59
+ const node = this.cache.get(key);
60
+ if (!node) {
61
+ this.misses++;
62
+ return null;
63
+ }
64
+ // Check if expired
65
+ const now = Date.now();
66
+ if (now - node.entry.timestamp > node.entry.ttl) {
67
+ this.delete(key);
68
+ this.misses++;
69
+ return null;
70
+ }
71
+ // Move to front (most recently used)
72
+ this.moveToFront(node);
73
+ this.hits++;
74
+ return node.entry;
75
+ }
76
+ /**
77
+ * Set in L1 cache with LRU eviction
78
+ */
79
+ set(key, entry) {
80
+ // If key exists, update and move to front
81
+ const existing = this.cache.get(key);
82
+ if (existing) {
83
+ existing.entry = entry;
84
+ this.moveToFront(existing);
85
+ return;
86
+ }
87
+ // Create new node
88
+ const node = {
89
+ key,
90
+ entry,
91
+ prev: null,
92
+ next: this.head,
93
+ };
94
+ // Add to front
95
+ if (this.head) {
96
+ this.head.prev = node;
97
+ }
98
+ this.head = node;
99
+ if (!this.tail) {
100
+ this.tail = node;
101
+ }
102
+ this.cache.set(key, node);
103
+ // Evict LRU if over capacity
104
+ if (this.cache.size > this.capacity) {
105
+ this.evictLRU();
106
+ }
107
+ }
108
+ /**
109
+ * Delete from L1 cache
110
+ */
111
+ delete(key) {
112
+ const node = this.cache.get(key);
113
+ if (!node)
114
+ return;
115
+ this.removeNode(node);
116
+ this.cache.delete(key);
117
+ }
118
+ /**
119
+ * Clear all L1 cache
120
+ */
121
+ clear() {
122
+ this.cache.clear();
123
+ this.head = null;
124
+ this.tail = null;
125
+ }
126
+ /**
127
+ * Get L1 cache stats
128
+ */
129
+ stats() {
130
+ return {
131
+ size: this.cache.size,
132
+ capacity: this.capacity,
133
+ hits: this.hits,
134
+ misses: this.misses,
135
+ hitRate: this.hits + this.misses > 0
136
+ ? ((this.hits / (this.hits + this.misses)) * 100).toFixed(2) + "%"
137
+ : "0%",
138
+ };
139
+ }
140
+ moveToFront(node) {
141
+ if (node === this.head)
142
+ return; // Already at front
143
+ this.removeNode(node);
144
+ // Add to front
145
+ node.prev = null;
146
+ node.next = this.head;
147
+ if (this.head) {
148
+ this.head.prev = node;
149
+ }
150
+ this.head = node;
151
+ if (!this.tail) {
152
+ this.tail = node;
153
+ }
154
+ }
155
+ removeNode(node) {
156
+ if (node.prev) {
157
+ node.prev.next = node.next;
158
+ }
159
+ else {
160
+ this.head = node.next;
161
+ }
162
+ if (node.next) {
163
+ node.next.prev = node.prev;
164
+ }
165
+ else {
166
+ this.tail = node.prev;
167
+ }
168
+ }
169
+ evictLRU() {
170
+ if (!this.tail)
171
+ return;
172
+ const key = this.tail.key;
173
+ this.removeNode(this.tail);
174
+ this.cache.delete(key);
175
+ }
176
+ }
177
+ /**
178
+ * Two-Tier Response Cache
179
+ *
180
+ * L1: In-Memory LRU Cache (~0.001ms access) - hot data
181
+ * L2: Disk Cache with gzip (~5ms access) - persistence
182
+ *
183
+ * Read path: L1 → L2 → Network
184
+ * Write path: L1 + L2 (write-through)
185
+ */
186
+ export class ResponseCache {
187
+ l1;
188
+ cacheDir;
189
+ maxDiskSize;
190
+ constructor(l1Capacity = 100, cacheDir = ".cache/jiren", maxDiskSize = 100) {
191
+ this.l1 = new L1MemoryCache(l1Capacity);
192
+ this.maxDiskSize = maxDiskSize;
193
+ this.cacheDir = cacheDir;
194
+ // Create cache directory if it doesn't exist
195
+ if (!existsSync(this.cacheDir)) {
196
+ mkdirSync(this.cacheDir, { recursive: true });
197
+ }
198
+ }
199
+ /**
200
+ * Generate cache key from URL and options
201
+ */
202
+ generateKey(url, path, options) {
203
+ const fullUrl = path ? `${url}${path}` : url;
204
+ const method = options?.method || "GET";
205
+ const headers = JSON.stringify(options?.headers || {});
206
+ const key = `${method}:${fullUrl}:${headers}`;
207
+ // Hash the key to create a valid filename
208
+ return createHash("md5").update(key).digest("hex");
209
+ }
210
+ /**
211
+ * Get cache file path (compressed .gz file)
212
+ */
213
+ getCacheFilePath(key) {
214
+ return join(this.cacheDir, `${key}.json.gz`);
215
+ }
216
+ /**
217
+ * Preload L2 disk cache entry into L1 memory cache.
218
+ * Call this during initialization to ensure first request hits L1.
219
+ * @param url - Base URL to preload
220
+ * @param path - Optional path
221
+ * @param options - Optional request options
222
+ * @returns true if entry was preloaded, false if not found/expired
223
+ */
224
+ preloadL1(url, path, options) {
225
+ const key = this.generateKey(url, path, options);
226
+ // Check if already in L1
227
+ if (this.l1.get(key)) {
228
+ return true;
229
+ }
230
+ // Try to load from L2 disk
231
+ const l2Entry = this.getFromDisk(key);
232
+ if (l2Entry) {
233
+ this.l1.set(key, l2Entry);
234
+ return true;
235
+ }
236
+ return false;
237
+ }
238
+ /**
239
+ * Get cached response - checks L1 first, then L2
240
+ */
241
+ get(url, path, options) {
242
+ const key = this.generateKey(url, path, options);
243
+ // L1: Check in-memory cache first (~0.001ms)
244
+ const l1Entry = this.l1.get(key);
245
+ if (l1Entry) {
246
+ return l1Entry.response;
247
+ }
248
+ // L2: Check disk cache (~5ms)
249
+ const l2Entry = this.getFromDisk(key);
250
+ if (l2Entry) {
251
+ // Promote to L1 for faster future access
252
+ this.l1.set(key, l2Entry);
253
+ return l2Entry.response;
254
+ }
255
+ return null;
256
+ }
257
+ /**
258
+ * Get from L2 disk cache
259
+ */
260
+ getFromDisk(key) {
261
+ const filePath = this.getCacheFilePath(key);
262
+ if (!existsSync(filePath))
263
+ return null;
264
+ try {
265
+ // Read compressed file
266
+ const compressed = readFileSync(filePath);
267
+ // Decompress
268
+ const decompressed = gunzipSync(compressed);
269
+ const data = decompressed.toString("utf-8");
270
+ const serialized = JSON.parse(data);
271
+ // Check if expired
272
+ const now = Date.now();
273
+ if (now - serialized.timestamp > serialized.ttl) {
274
+ // Delete expired cache file
275
+ try {
276
+ unlinkSync(filePath);
277
+ }
278
+ catch { }
279
+ return null;
280
+ }
281
+ // Reconstruct the response with working body methods
282
+ const response = {
283
+ status: serialized.status,
284
+ statusText: serialized.statusText,
285
+ headers: serialized.headers,
286
+ url: serialized.url,
287
+ ok: serialized.ok,
288
+ redirected: serialized.redirected,
289
+ type: serialized.type || "default",
290
+ body: reconstructBody(serialized.bodyData, serialized.bodyIsText),
291
+ };
292
+ return {
293
+ response,
294
+ timestamp: serialized.timestamp,
295
+ ttl: serialized.ttl,
296
+ };
297
+ }
298
+ catch (error) {
299
+ // Invalid cache file, delete it
300
+ try {
301
+ unlinkSync(filePath);
302
+ }
303
+ catch { }
304
+ return null;
305
+ }
306
+ }
307
+ /**
308
+ * Store response in both L1 and L2 (write-through)
309
+ */
310
+ set(url, response, ttl, path, options) {
311
+ const key = this.generateKey(url, path, options);
312
+ const entry = {
313
+ response,
314
+ timestamp: Date.now(),
315
+ ttl,
316
+ };
317
+ // L1: Store in memory (~0.001ms)
318
+ this.l1.set(key, entry);
319
+ // L2: Store on disk (async-ish, for persistence)
320
+ this.setToDisk(key, entry);
321
+ }
322
+ /**
323
+ * Write to L2 disk cache
324
+ */
325
+ async setToDisk(key, entry) {
326
+ const filePath = this.getCacheFilePath(key);
327
+ try {
328
+ // Extract body text for serialization
329
+ let bodyData;
330
+ let bodyIsText = true;
331
+ try {
332
+ bodyData = await entry.response.body.text();
333
+ }
334
+ catch {
335
+ // If text fails, try arrayBuffer and convert to base64
336
+ try {
337
+ const buffer = await entry.response.body.arrayBuffer();
338
+ const bytes = new Uint8Array(buffer);
339
+ let binary = "";
340
+ for (let i = 0; i < bytes.length; i++) {
341
+ binary += String.fromCharCode(bytes[i]);
342
+ }
343
+ bodyData = btoa(binary);
344
+ bodyIsText = false;
345
+ }
346
+ catch {
347
+ bodyData = "";
348
+ }
349
+ }
350
+ // Create serializable entry
351
+ const serialized = {
352
+ status: entry.response.status,
353
+ statusText: entry.response.statusText,
354
+ headers: entry.response.headers,
355
+ url: entry.response.url,
356
+ ok: entry.response.ok,
357
+ redirected: entry.response.redirected,
358
+ type: entry.response.type || "default",
359
+ bodyData,
360
+ bodyIsText,
361
+ timestamp: entry.timestamp,
362
+ ttl: entry.ttl,
363
+ };
364
+ // Convert to JSON
365
+ const json = JSON.stringify(serialized);
366
+ // Compress with gzip
367
+ const compressed = gzipSync(json);
368
+ // Write compressed file
369
+ writeFileSync(filePath, compressed);
370
+ }
371
+ catch (error) {
372
+ // Silently fail if can't write cache
373
+ console.warn("Failed to write cache:", error);
374
+ }
375
+ }
376
+ /**
377
+ * Clear cache for a specific URL or all
378
+ */
379
+ clear(url) {
380
+ // Clear L1
381
+ this.l1.clear();
382
+ // Clear L2
383
+ if (url) {
384
+ // Clear all cache files for this URL
385
+ // This is approximate since we hash the keys
386
+ // For now, just clear all to be safe
387
+ this.clearAllDisk();
388
+ }
389
+ else {
390
+ this.clearAllDisk();
391
+ }
392
+ }
393
+ /**
394
+ * Clear all L2 disk cache files
395
+ */
396
+ clearAllDisk() {
397
+ try {
398
+ const files = readdirSync(this.cacheDir);
399
+ for (const file of files) {
400
+ if (file.endsWith(".json.gz")) {
401
+ unlinkSync(join(this.cacheDir, file));
402
+ }
403
+ }
404
+ }
405
+ catch (error) {
406
+ // Silently fail
407
+ }
408
+ }
409
+ /**
410
+ * Get combined cache statistics
411
+ */
412
+ stats() {
413
+ const l1Stats = this.l1.stats();
414
+ // L2 disk stats
415
+ let diskSize = 0;
416
+ let diskFiles = 0;
417
+ let totalDiskBytes = 0;
418
+ try {
419
+ const files = readdirSync(this.cacheDir);
420
+ const cacheFiles = files.filter((f) => f.endsWith(".json.gz"));
421
+ diskFiles = cacheFiles.length;
422
+ for (const file of cacheFiles) {
423
+ const stats = statSync(join(this.cacheDir, file));
424
+ totalDiskBytes += stats.size;
425
+ }
426
+ }
427
+ catch { }
428
+ return {
429
+ l1: l1Stats,
430
+ l2: {
431
+ size: diskFiles,
432
+ maxSize: this.maxDiskSize,
433
+ cacheDir: this.cacheDir,
434
+ totalSizeKB: (totalDiskBytes / 1024).toFixed(2),
435
+ },
436
+ };
437
+ }
438
+ }
439
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../components/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,SAAS,EACT,YAAY,EACZ,aAAa,EACb,UAAU,EACV,WAAW,EACX,QAAQ,GACT,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AA6B5B;;GAEG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,MAAe;IACxD,IAAI,MAAmB,CAAC;IAExB,IAAI,MAAM,EAAE,CAAC;QACX,4BAA4B;QAC5B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAqB,CAAC;IAC1D,CAAC;SAAM,CAAC;QACN,+BAA+B;QAC/B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,KAAK,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAC;IACvC,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,IAAI,MAAM;gBAAE,OAAO,QAAQ,CAAC;YAC5B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;YAClC,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAClE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QACD,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM;QAC/B,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;KACrC,CAAC;AACJ,CAAC;AAYD;;;GAGG;AACH,MAAM,aAAa;IACT,QAAQ,CAAS;IACjB,KAAK,GAAyB,IAAI,GAAG,EAAE,CAAC;IACxC,IAAI,GAAmB,IAAI,CAAC,CAAC,qBAAqB;IAClD,IAAI,GAAmB,IAAI,CAAC,CAAC,sBAAsB;IAE3D,QAAQ;IACD,IAAI,GAAG,CAAC,CAAC;IACT,MAAM,GAAG,CAAC,CAAC;IAElB,YAAY,QAAQ,GAAG,GAAG;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW;QACb,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mBAAmB;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAChD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjB,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC;QAED,qCAAqC;QACrC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW,EAAE,KAAiB;QAChC,0CAA0C;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,kBAAkB;QAClB,MAAM,IAAI,GAAY;YACpB,GAAG;YACH,KAAK;YACL,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;QAEF,eAAe;QACf,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAE1B,6BAA6B;QAC7B,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,GAAW;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EACL,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;gBACzB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG;gBAClE,CAAC,CAAC,IAAI;SACX,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,IAAa;QAC/B,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,mBAAmB;QAEnD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,eAAe;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,IAAa;QAC9B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACxB,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;IAEO,QAAQ;QACd,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QAEvB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,OAAO,aAAa;IAChB,EAAE,CAAgB;IAClB,QAAQ,CAAS;IACjB,WAAW,CAAS;IAE5B,YAAY,UAAU,GAAG,GAAG,EAAE,QAAQ,GAAG,cAAc,EAAE,WAAW,GAAG,GAAG;QACxE,IAAI,CAAC,EAAE,GAAG,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC;QACxC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,6CAA6C;QAC7C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,GAAW,EAAE,IAAa,EAAE,OAAa;QAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAC7C,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,KAAK,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;QAE9C,0CAA0C;QAC1C,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,GAAW;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,GAAW,EAAE,IAAa,EAAE,OAAa;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAEjD,yBAAyB;QACzB,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,2BAA2B;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW,EAAE,IAAa,EAAE,OAAa;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAEjD,6CAA6C;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC,QAAQ,CAAC;QAC1B,CAAC;QAED,8BAA8B;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,OAAO,EAAE,CAAC;YACZ,yCAAyC;YACzC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC1B,OAAO,OAAO,CAAC,QAAQ,CAAC;QAC1B,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,GAAW;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAE5C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QAEvC,IAAI,CAAC;YACH,uBAAuB;YACvB,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YAE1C,aAAa;YACb,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,UAAU,GAA2B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAE5D,mBAAmB;YACnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,IAAI,GAAG,GAAG,UAAU,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;gBAChD,4BAA4B;gBAC5B,IAAI,CAAC;oBACH,UAAU,CAAC,QAAQ,CAAC,CAAC;gBACvB,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;gBACV,OAAO,IAAI,CAAC;YACd,CAAC;YAED,qDAAqD;YACrD,MAAM,QAAQ,GAAkB;gBAC9B,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,GAAG,EAAE,UAAU,CAAC,GAAG;gBACnB,EAAE,EAAE,UAAU,CAAC,EAAE;gBACjB,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,SAAS;gBAClC,IAAI,EAAE,eAAe,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC;aAClE,CAAC;YAEF,OAAO;gBACL,QAAQ;gBACR,SAAS,EAAE,UAAU,CAAC,SAAS;gBAC/B,GAAG,EAAE,UAAU,CAAC,GAAG;aACpB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gCAAgC;YAChC,IAAI,CAAC;gBACH,UAAU,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,GAAG,CACD,GAAW,EACX,QAAuB,EACvB,GAAW,EACX,IAAa,EACb,OAAa;QAEb,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAEjD,MAAM,KAAK,GAAe;YACxB,QAAQ;YACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,GAAG;SACJ,CAAC;QAEF,iCAAiC;QACjC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAExB,iDAAiD;QACjD,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CAAC,GAAW,EAAE,KAAiB;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAE5C,IAAI,CAAC;YACH,sCAAsC;YACtC,IAAI,QAAgB,CAAC;YACrB,IAAI,UAAU,GAAG,IAAI,CAAC;YAEtB,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9C,CAAC;YAAC,MAAM,CAAC;gBACP,uDAAuD;gBACvD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;oBACvD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;oBACrC,IAAI,MAAM,GAAG,EAAE,CAAC;oBAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACtC,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;oBAC3C,CAAC;oBACD,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;oBACxB,UAAU,GAAG,KAAK,CAAC;gBACrB,CAAC;gBAAC,MAAM,CAAC;oBACP,QAAQ,GAAG,EAAE,CAAC;gBAChB,CAAC;YACH,CAAC;YAED,4BAA4B;YAC5B,MAAM,UAAU,GAA2B;gBACzC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;gBAC7B,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU;gBACrC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAiC;gBACzD,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG;gBACvB,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE;gBACrB,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU;gBACrC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,SAAS;gBACtC,QAAQ;gBACR,UAAU;gBACV,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,GAAG,EAAE,KAAK,CAAC,GAAG;aACf,CAAC;YAEF,kBAAkB;YAClB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YAExC,qBAAqB;YACrB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAElC,wBAAwB;YACxB,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qCAAqC;YACrC,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAY;QAChB,WAAW;QACX,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAEhB,WAAW;QACX,IAAI,GAAG,EAAE,CAAC;YACR,qCAAqC;YACrC,6CAA6C;YAC7C,qCAAqC;YACrC,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED;;OAEG;IACK,YAAY;QAClB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC9B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAgB;QAClB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAEhC,gBAAgB;QAChB,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;YACvE,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC;YAE9B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;gBAClD,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC;YAC/B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,OAAO;YACL,EAAE,EAAE,OAAO;YACX,EAAE,EAAE;gBACF,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,IAAI,CAAC,WAAW;gBACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,WAAW,EAAE,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;aAChD;SACF,CAAC;IACJ,CAAC;CACF"}