@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.
- package/dist/use-cache.d.ts +7 -35
- package/dist/use-cache.js +51 -82
- package/package.json +5 -4
- package/dist/utils.d.ts +0 -1
- package/dist/utils.js +0 -47
package/dist/use-cache.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
*
|
|
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
|
-
*
|
|
55
|
+
* await revalidateTag('user:123');
|
|
85
56
|
* ```
|
|
86
57
|
*/
|
|
87
|
-
export declare function
|
|
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.
|
|
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
|
-
|
|
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
|
|
44
|
-
|
|
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 ??
|
|
64
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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.
|
|
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
|
-
*
|
|
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
|
-
*
|
|
162
|
+
* await revalidateTag('user:123');
|
|
202
163
|
* ```
|
|
203
164
|
*/
|
|
204
|
-
async function
|
|
165
|
+
async function revalidateTag(tag) {
|
|
205
166
|
const provider = (0, cache_plugin_1.getCacheProvider)();
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
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,
|
|
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.
|
|
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
|
-
"
|
|
31
|
-
"
|
|
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=
|