@commandkit/cache 0.0.0-dev.20250604020336 → 0.0.0-dev.20250604160656

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.
@@ -1,4 +1,4 @@
1
- import { AsyncFunction, GenericFunction } from 'commandkit';
1
+ import { GenericFunction } from 'commandkit';
2
2
  /**
3
3
  * Context for managing cache operations within an async scope
4
4
  */
@@ -8,6 +8,7 @@ export interface CacheContext {
8
8
  name?: string;
9
9
  /** Time-to-live in milliseconds */
10
10
  ttl?: number | null;
11
+ tags: Set<string>;
11
12
  };
12
13
  }
13
14
  /**
@@ -18,22 +19,8 @@ export interface CacheMetadata {
18
19
  ttl?: number | string;
19
20
  /** Custom name for the cache entry */
20
21
  name?: string;
22
+ tags?: string[];
21
23
  }
22
- /**
23
- * Wraps an async function with caching capability
24
- * @template R - Array of argument types
25
- * @template F - Type of the async function
26
- * @param fn - The async function to cache
27
- * @param params - Optional cache configuration
28
- * @returns The wrapped function with caching behavior
29
- * @example
30
- * ```ts
31
- * const cachedFetch = cache(async (id: string) => {
32
- * return await db.findOne(id);
33
- * }, { ttl: '1h' });
34
- * ```
35
- */
36
- export declare function cache<R extends any[], F extends AsyncFunction<R>>(fn: F, params?: CacheMetadata): F;
37
24
  /**
38
25
  * Sets a custom identifier for the current cache operation
39
26
  * @param tag - The custom cache tag
@@ -61,30 +48,14 @@ export declare function cacheTag(tag: string): void;
61
48
  */
62
49
  export declare function cacheLife(ttl: number | string): void;
63
50
  /**
64
- * Removes a cached value by its tag
65
- * @param tag - The cache tag to invalidate. Can be a single tag or an array of tags.
66
- * @throws {Error} When the cache key is not found
67
- * @example
68
- * ```ts
69
- * await invalidate('user:123');
70
- * // or
71
- * await invalidate(['user:123', 'user:456']);
72
- * ```
73
- */
74
- export declare function invalidate(tag: string | string[]): Promise<void>;
75
- /**
76
- * Forces a refresh of cached data by its tag (on-demand revalidation)
77
- * @template T - Type of the cached value
51
+ * Marks cache entries for invalidation by their tag. The invalidation only happens when the path is next visited.
78
52
  * @param tag - The cache tag to revalidate
79
- * @param args - Arguments to pass to the cached function
80
- * @returns Fresh data from the cached function
81
- * @throws {Error} When the cache key or function is not found
82
53
  * @example
83
54
  * ```ts
84
- * const freshData = await revalidate('user:123');
55
+ * await revalidateTag('user:123');
85
56
  * ```
86
57
  */
87
- export declare function revalidate<T = unknown>(tag: string, ...args: any[]): Promise<T>;
58
+ export declare function revalidateTag(tag: string): Promise<void>;
88
59
  /**
89
60
  * Checks if a function is wrapped with cache functionality
90
61
  * @param fn - Function to check
@@ -97,6 +68,7 @@ export declare function revalidate<T = unknown>(tag: string, ...args: any[]): Pr
97
68
  * ```
98
69
  */
99
70
  export declare function isCachedFunction(fn: GenericFunction): boolean;
71
+ export declare function cleanup(maxAge?: number): Promise<void>;
100
72
  /**
101
73
  * @private
102
74
  * @internal
package/dist/use-cache.js CHANGED
@@ -4,21 +4,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.$ckitiucw = void 0;
7
- exports.cache = cache;
8
7
  exports.cacheTag = cacheTag;
9
8
  exports.cacheLife = cacheLife;
10
- exports.invalidate = invalidate;
11
- exports.revalidate = revalidate;
9
+ exports.revalidateTag = revalidateTag;
12
10
  exports.isCachedFunction = isCachedFunction;
11
+ exports.cleanup = cleanup;
13
12
  const node_async_hooks_1 = require("node:async_hooks");
14
13
  const node_crypto_1 = require("node:crypto");
15
14
  const ms_1 = __importDefault(require("ms"));
16
- const utils_1 = require("./utils");
17
15
  const cache_plugin_1 = require("./cache-plugin");
16
+ const stable_hash_1 = __importDefault(require("stable-hash"));
18
17
  const cacheContext = new node_async_hooks_1.AsyncLocalStorage();
19
18
  const fnStore = new Map();
20
19
  const CACHE_FN_ID = `__cache_fn_id_${Date.now()}__${Math.random()}__`;
21
20
  const CACHED_FN_SYMBOL = Symbol('commandkit.cache.sentinel');
21
+ // WeakMap to store function metadata without preventing garbage collection
22
+ const fnMetadata = new WeakMap();
23
+ // Generate a stable build ID that persists across restarts
24
+ const BUILD_ID = (0, node_crypto_1.randomUUID)();
22
25
  /**
23
26
  * Internal cache implementation
24
27
  * @internal
@@ -38,10 +41,21 @@ function useCache(fn, id, params) {
38
41
  if (id && !isLocal) {
39
42
  throw new Error('Illegal use of cache function.');
40
43
  }
41
- const fnId = (0, node_crypto_1.randomUUID)();
44
+ // Get or create function metadata
45
+ let metadata = fnMetadata.get(fn);
46
+ if (!metadata) {
47
+ metadata = {
48
+ id: (0, node_crypto_1.randomUUID)(),
49
+ buildId: BUILD_ID,
50
+ };
51
+ fnMetadata.set(fn, metadata);
52
+ }
42
53
  const memo = (async (...args) => {
43
- const forcedName = isLocal ? params?.name : null;
44
- const keyHash = forcedName ?? (await (0, utils_1.createObjectHash)(fnId, ...args));
54
+ const keyHash = await (0, stable_hash_1.default)({
55
+ fnId: metadata.id,
56
+ buildId: metadata.buildId,
57
+ args,
58
+ });
45
59
  const resolvedTTL = isLocal && params?.ttl != null
46
60
  ? typeof params.ttl === 'string'
47
61
  ? (0, ms_1.default)(params.ttl)
@@ -49,8 +63,8 @@ function useCache(fn, id, params) {
49
63
  : null;
50
64
  return cacheContext.run({
51
65
  params: {
52
- name: keyHash,
53
66
  ttl: resolvedTTL,
67
+ tags: new Set(params?.tags ?? []),
54
68
  },
55
69
  }, async () => {
56
70
  const provider = (0, cache_plugin_1.getCacheProvider)();
@@ -58,29 +72,28 @@ function useCache(fn, id, params) {
58
72
  if (!context) {
59
73
  throw new Error('Cache context was not found.');
60
74
  }
61
- // Get the effective cache key, preferring any existing association
62
75
  const storedFn = fnStore.get(keyHash);
63
- const effectiveKey = storedFn?.key ?? context.params.name;
64
- // Try to get cached value using effective key
76
+ const effectiveKey = storedFn?.key ?? keyHash;
77
+ // Update last access time
78
+ if (storedFn) {
79
+ storedFn.lastAccess = Date.now();
80
+ }
65
81
  const cached = await provider.get(effectiveKey);
66
- if (cached && cached.value != null)
82
+ if (cached && cached.value != null) {
67
83
  return cached.value;
68
- // If we reach here, we need to cache the value
84
+ }
69
85
  const result = await fn(...args);
70
- // Only cache if result is not null/undefined
71
86
  if (result != null) {
72
- // Get the final key name (might have been modified by cacheTag)
73
- const finalKey = context.params.name;
74
87
  const ttl = context.params.ttl;
75
- // Store the result
76
- await provider.set(finalKey, result, ttl ?? undefined);
77
- // Update function store
88
+ await provider.set(keyHash, result, ttl ?? undefined);
78
89
  fnStore.set(keyHash, {
79
- key: finalKey,
90
+ key: keyHash,
80
91
  hash: keyHash,
81
92
  ttl: ttl ?? undefined,
82
93
  original: fn,
83
94
  memo,
95
+ tags: context.params.tags,
96
+ lastAccess: Date.now(),
84
97
  });
85
98
  }
86
99
  return result;
@@ -97,23 +110,6 @@ function useCache(fn, id, params) {
97
110
  }
98
111
  return memo;
99
112
  }
100
- /**
101
- * Wraps an async function with caching capability
102
- * @template R - Array of argument types
103
- * @template F - Type of the async function
104
- * @param fn - The async function to cache
105
- * @param params - Optional cache configuration
106
- * @returns The wrapped function with caching behavior
107
- * @example
108
- * ```ts
109
- * const cachedFetch = cache(async (id: string) => {
110
- * return await db.findOne(id);
111
- * }, { ttl: '1h' });
112
- * ```
113
- */
114
- function cache(fn, params) {
115
- return useCache(fn, CACHE_FN_ID, params);
116
- }
117
113
  /**
118
114
  * Sets a custom identifier for the current cache operation
119
115
  * @param tag - The custom cache tag
@@ -134,7 +130,7 @@ function cacheTag(tag) {
134
130
  if (!tag) {
135
131
  throw new Error('cacheTag() must be called with a tag name.');
136
132
  }
137
- context.params.name = tag;
133
+ context.params.tags.add(tag);
138
134
  }
139
135
  /**
140
136
  * Sets the TTL for the current cache operation
@@ -159,55 +155,18 @@ function cacheLife(ttl) {
159
155
  context.params.ttl = typeof ttl === 'string' ? (0, ms_1.default)(ttl) : ttl;
160
156
  }
161
157
  /**
162
- * Removes a cached value by its tag
163
- * @param tag - The cache tag to invalidate. Can be a single tag or an array of tags.
164
- * @throws {Error} When the cache key is not found
165
- * @example
166
- * ```ts
167
- * await invalidate('user:123');
168
- * // or
169
- * await invalidate(['user:123', 'user:456']);
170
- * ```
171
- */
172
- async function invalidate(tag) {
173
- const provider = (0, cache_plugin_1.getCacheProvider)();
174
- let errors = [];
175
- for (const t of Array.isArray(tag) ? tag : [tag]) {
176
- try {
177
- const entry = Array.from(fnStore.values()).find((v) => v.key === t || v.hash === t);
178
- if (!entry)
179
- continue;
180
- await provider.delete(entry.key);
181
- }
182
- catch (e) {
183
- errors.push(e);
184
- }
185
- }
186
- if (errors.length > 0) {
187
- throw new Error(`Failed to invalidate cache for tags: ${errors
188
- .map((e) => e.message)
189
- .join(', ')}`);
190
- }
191
- }
192
- /**
193
- * Forces a refresh of cached data by its tag (on-demand revalidation)
194
- * @template T - Type of the cached value
158
+ * Marks cache entries for invalidation by their tag. The invalidation only happens when the path is next visited.
195
159
  * @param tag - The cache tag to revalidate
196
- * @param args - Arguments to pass to the cached function
197
- * @returns Fresh data from the cached function
198
- * @throws {Error} When the cache key or function is not found
199
160
  * @example
200
161
  * ```ts
201
- * const freshData = await revalidate('user:123');
162
+ * await revalidateTag('user:123');
202
163
  * ```
203
164
  */
204
- async function revalidate(tag, ...args) {
165
+ async function revalidateTag(tag) {
205
166
  const provider = (0, cache_plugin_1.getCacheProvider)();
206
- const entry = Array.from(fnStore.values()).find((v) => v.key === tag || v.hash === tag);
207
- if (!entry)
208
- return undefined;
209
- await provider.delete(entry.key);
210
- return entry.memo(...args);
167
+ const entries = Array.from(fnStore.values()).filter((v) => v.tags.has(tag));
168
+ // Batch delete operations for better performance
169
+ await Promise.all(entries.map((entry) => provider.delete(entry.key)));
211
170
  }
212
171
  /**
213
172
  * Checks if a function is wrapped with cache functionality
@@ -223,6 +182,16 @@ async function revalidate(tag, ...args) {
223
182
  function isCachedFunction(fn) {
224
183
  return Object.prototype.hasOwnProperty.call(fn, CACHED_FN_SYMBOL);
225
184
  }
185
+ // Cleanup function to remove stale entries
186
+ async function cleanup(maxAge = 24 * 60 * 60 * 1000) {
187
+ const now = Date.now();
188
+ const staleEntries = Array.from(fnStore.entries()).filter(([_, entry]) => now - entry.lastAccess > maxAge);
189
+ const provider = (0, cache_plugin_1.getCacheProvider)();
190
+ await Promise.all(staleEntries.map(async ([key, entry]) => {
191
+ await provider.delete(entry.key);
192
+ fnStore.delete(key);
193
+ }));
194
+ }
226
195
  /**
227
196
  * @private
228
197
  * @internal
@@ -236,4 +205,4 @@ if (!('$ckitiucw' in globalThis)) {
236
205
  writable: false,
237
206
  });
238
207
  }
239
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3VzZS1jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUE4SkEsc0JBS0M7QUFjRCw0QkFZQztBQWNELDhCQVlDO0FBYUQsZ0NBeUJDO0FBY0QsZ0NBY0M7QUFhRCw0Q0FFQztBQXhTRCx1REFBcUQ7QUFFckQsNkNBQXlDO0FBQ3pDLDRDQUEwQztBQUMxQyxtQ0FBMkM7QUFDM0MsaURBQWtEO0FBRWxELE1BQU0sWUFBWSxHQUFHLElBQUksb0NBQWlCLEVBQWdCLENBQUM7QUFDM0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBU3BCLENBQUM7QUFDSixNQUFNLFdBQVcsR0FBRyxpQkFBaUIsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDO0FBQ3RFLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLDJCQUEyQixDQUFDLENBQUM7QUF3QjdEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxTQUFTLFFBQVEsQ0FDZixFQUFLLEVBQ0wsRUFBVyxFQUNYLE1BQXNCO0lBRXRCLE1BQU0sT0FBTyxHQUFHLEVBQUUsS0FBSyxXQUFXLENBQUM7SUFFbkMsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLElBQUEsd0JBQVUsR0FBRSxDQUFDO0lBRTFCLE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBSyxFQUFFLEdBQUcsSUFBSSxFQUFFLEVBQUU7UUFDOUIsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDakQsTUFBTSxPQUFPLEdBQUcsVUFBVSxJQUFJLENBQUMsTUFBTSxJQUFBLHdCQUFn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
208
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3VzZS1jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFvTEEsNEJBWUM7QUFjRCw4QkFZQztBQVVELHNDQU1DO0FBYUQsNENBRUM7QUFHRCwwQkFlQztBQTNRRCx1REFBcUQ7QUFFckQsNkNBQXlDO0FBQ3pDLDRDQUEwQztBQUMxQyxpREFBa0Q7QUFDbEQsOERBQXFDO0FBRXJDLE1BQU0sWUFBWSxHQUFHLElBQUksb0NBQWlCLEVBQWdCLENBQUM7QUFDM0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBV3BCLENBQUM7QUFDSixNQUFNLFdBQVcsR0FBRyxpQkFBaUIsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDO0FBQ3RFLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLDJCQUEyQixDQUFDLENBQUM7QUFFN0QsMkVBQTJFO0FBQzNFLE1BQU0sVUFBVSxHQUFHLElBQUksT0FBTyxFQUczQixDQUFDO0FBRUosMkRBQTJEO0FBQzNELE1BQU0sUUFBUSxHQUFHLElBQUEsd0JBQVUsR0FBRSxDQUFDO0FBMEI5Qjs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsU0FBUyxRQUFRLENBQ2YsRUFBSyxFQUNMLEVBQVcsRUFDWCxNQUFzQjtJQUV0QixNQUFNLE9BQU8sR0FBRyxFQUFFLEtBQUssV0FBVyxDQUFDO0lBRW5DLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFRCxrQ0FBa0M7SUFDbEMsSUFBSSxRQUFRLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNsQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDZCxRQUFRLEdBQUc7WUFDVCxFQUFFLEVBQUUsSUFB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commandkit/cache",
3
- "version": "0.0.0-dev.20250604020336",
3
+ "version": "0.0.0-dev.20250604160656",
4
4
  "description": "CommandKit plugin that provides caching apis",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -27,11 +27,12 @@
27
27
  "devDependencies": {
28
28
  "@types/ms": "^2.0.0",
29
29
  "typescript": "^5.7.3",
30
- "tsconfig": "0.0.0-dev.20250604020336",
31
- "commandkit": "1.0.0-dev.20250604020336"
30
+ "commandkit": "1.0.0-dev.20250604160656",
31
+ "tsconfig": "0.0.0-dev.20250604160656"
32
32
  },
33
33
  "dependencies": {
34
- "ms": "^2.1.3"
34
+ "ms": "^2.1.3",
35
+ "stable-hash": "^0.0.6"
35
36
  },
36
37
  "scripts": {
37
38
  "lint": "tsc --noEmit",
package/dist/utils.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function createObjectHash(...args: any[]): Promise<string>;
package/dist/utils.js DELETED
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createObjectHash = createObjectHash;
4
- const node_crypto_1 = require("node:crypto");
5
- let tracker = 0n;
6
- const references = new WeakMap();
7
- const PRIMITIVE_TYPES = new Set([
8
- 'string',
9
- 'number',
10
- 'boolean',
11
- 'bigint',
12
- 'undefined',
13
- ]);
14
- function isSerializablePrimitive(value) {
15
- return value === null || PRIMITIVE_TYPES.has(typeof value);
16
- }
17
- function createKey(val) {
18
- return `commandkit:cache:object:${val}`;
19
- }
20
- // returns runtime object id of the given argument
21
- function getObjectId(obj) {
22
- const primitive = isSerializablePrimitive(obj);
23
- if (primitive)
24
- return createKey(obj);
25
- if (obj instanceof Date)
26
- return createKey(obj.getTime());
27
- if (obj instanceof RegExp)
28
- return createKey(obj);
29
- const ref = references.get(obj);
30
- if (ref)
31
- return createKey(ref);
32
- const id = tracker++;
33
- references.set(obj, id);
34
- return createKey(id);
35
- }
36
- async function createObjectHash(...args) {
37
- const serializedKey = args.map(getObjectId).join(':');
38
- try {
39
- const hash = (0, node_crypto_1.createHash)('sha256');
40
- hash.update(serializedKey);
41
- return hash.digest('hex');
42
- }
43
- catch {
44
- return serializedKey;
45
- }
46
- }
47
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUF1Q0EsNENBVUM7QUFqREQsNkNBQXlDO0FBRXpDLElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUVqQixNQUFNLFVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBZSxDQUFDO0FBQzlDLE1BQU0sZUFBZSxHQUFHLElBQUksR0FBRyxDQUFDO0lBQzlCLFFBQVE7SUFDUixRQUFRO0lBQ1IsU0FBUztJQUNULFFBQVE7SUFDUixXQUFXO0NBQ1osQ0FBQyxDQUFDO0FBRUgsU0FBUyx1QkFBdUIsQ0FBQyxLQUFVO0lBQ3pDLE9BQU8sS0FBSyxLQUFLLElBQUksSUFBSSxlQUFlLENBQUMsR0FBRyxDQUFDLE9BQU8sS0FBSyxDQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLEdBQVE7SUFDekIsT0FBTywyQkFBMkIsR0FBRyxFQUFFLENBQUM7QUFDMUMsQ0FBQztBQUVELGtEQUFrRDtBQUNsRCxTQUFTLFdBQVcsQ0FBQyxHQUFRO0lBQzNCLE1BQU0sU0FBUyxHQUFHLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQy9DLElBQUksU0FBUztRQUFFLE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXJDLElBQUksR0FBRyxZQUFZLElBQUk7UUFBRSxPQUFPLFNBQVMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUN6RCxJQUFJLEdBQUcsWUFBWSxNQUFNO1FBQUUsT0FBTyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFakQsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoQyxJQUFJLEdBQUc7UUFBRSxPQUFPLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUvQixNQUFNLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQztJQUVyQixVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUV4QixPQUFPLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN2QixDQUFDO0FBRU0sS0FBSyxVQUFVLGdCQUFnQixDQUFDLEdBQUcsSUFBVztJQUNuRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUV0RCxJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksR0FBRyxJQUFBLHdCQUFVLEVBQUMsUUFBUSxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMzQixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7QUFDSCxDQUFDIn0=