sliftutils 1.4.81 → 1.4.83

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.
@@ -0,0 +1,334 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
+ //exports.removeEmbeddings = exports.insertEmbeddings = exports.searchEmbeddings = exports.rebuildStructure = void 0;
4
+ const Database_1 = require("./Database");
5
+ const transactionSet_1 = require("./transactionSet");
6
+ const embeddingFormats_1 = require("../embeddingFormats");
7
+ // Below this many embeddings we skip the IVF entirely (flat store). 1024 = a clean power of two.
8
+ const FLAT_LIMIT = 1024;
9
+ // Force a from-scratch rebuild once at each of these (multiples of 4 above FLAT_LIMIT, up to ~16k), gated by a step flag so each runs at most once ever.
10
+ const REGENERATE_AT = [4096, 16384];
11
+ const STEP_IVF = "ivf";
12
+ // On delete, the member's exact cell plus this many nearby cells are checked, in case a rebuild left it non-optimal.
13
+ const DELETE_FALLBACK_CELLS = 10;
14
+ const REBALANCE_ITERATIONS = 4;
15
+ function flatStore(database) {
16
+ return (0, Database_1.namespaceDatabase)(database, root => root.flat);
17
+ }
18
+ function centroidStore(database) {
19
+ return (0, Database_1.namespaceDatabase)(database, root => root.centroids);
20
+ }
21
+ function cellStore(database, cellId) {
22
+ return (0, Database_1.namespaceDatabase)(database, root => root.cells[cellId]);
23
+ }
24
+ function readSteps(database) {
25
+ var _a;
26
+ return (_a = database.readData(root => root.steps)) !== null && _a !== void 0 ? _a : {};
27
+ }
28
+ function readCount(database) {
29
+ var _a;
30
+ return (_a = database.readData(root => root.count)) !== null && _a !== void 0 ? _a : 0;
31
+ }
32
+ function rankCellsByCloseness(embedding, centroids) {
33
+ const ranked = [];
34
+ for (const cellId of centroids.keys()) {
35
+ ranked.push({ cellId, closeness: (0, embeddingFormats_1.getCloseness)(embedding, centroids.get(cellId)) });
36
+ }
37
+ ranked.sort((left, right) => right.closeness - left.closeness);
38
+ return ranked.map(entry => entry.cellId);
39
+ }
40
+ // Per-write chance of a full rebuild. Zero at/under the target size, then rises (cubically) past it so cells
41
+ // stay roughly between target and ~2x target.
42
+ function rebalanceProbability(fillRatio) {
43
+ if (fillRatio <= 1) {
44
+ return 0;
45
+ }
46
+ const over = fillRatio - 1;
47
+ return Math.min(1, over * over * over * 0.25);
48
+ }
49
+ // k-means. Decodes every member to a pooled float32 buffer ONCE, then assigns with a plain internal float
50
+ // dot (no getCloseness call — comparing two float vectors is trivial) and keeps centroids as float means,
51
+ // encoding them to StoredEmbedding only at the end. Releases the borrowed buffers when done.
52
+ function clusterMembers(members, clusterCount, config) {
53
+ const memberFloats = [];
54
+ for (const member of members) {
55
+ memberFloats.push((0, embeddingFormats_1.embeddingToFloat32)(member.embedding, true));
56
+ }
57
+ const length = memberFloats.length ? memberFloats[0].length : 0;
58
+ let centroids = [];
59
+ const seedStep = members.length / clusterCount;
60
+ for (let clusterIndex = 0; clusterIndex < clusterCount; clusterIndex++) {
61
+ centroids.push(new Float32Array(memberFloats[Math.floor(clusterIndex * seedStep)]));
62
+ }
63
+ let groups = [];
64
+ for (let iteration = 0; iteration < REBALANCE_ITERATIONS; iteration++) {
65
+ groups = [];
66
+ for (let clusterIndex = 0; clusterIndex < centroids.length; clusterIndex++) {
67
+ groups.push([]);
68
+ }
69
+ for (let memberIndex = 0; memberIndex < memberFloats.length; memberIndex++) {
70
+ const memberFloat = memberFloats[memberIndex];
71
+ let bestIndex = 0;
72
+ let bestDot = -Infinity;
73
+ for (let centroidIndex = 0; centroidIndex < centroids.length; centroidIndex++) {
74
+ const centroidFloat = centroids[centroidIndex];
75
+ let dot = 0;
76
+ for (let dim = 0; dim < length; dim++) {
77
+ dot += memberFloat[dim] * centroidFloat[dim];
78
+ }
79
+ if (dot > bestDot) {
80
+ bestDot = dot;
81
+ bestIndex = centroidIndex;
82
+ }
83
+ }
84
+ groups[bestIndex].push(memberIndex);
85
+ }
86
+ const nextCentroids = [];
87
+ const nextGroups = [];
88
+ for (const group of groups) {
89
+ if (!group.length) {
90
+ continue;
91
+ }
92
+ const mean = new Float32Array(length);
93
+ for (const memberIndex of group) {
94
+ const memberFloat = memberFloats[memberIndex];
95
+ for (let dim = 0; dim < length; dim++) {
96
+ mean[dim] += memberFloat[dim];
97
+ }
98
+ }
99
+ let norm = 0;
100
+ for (let dim = 0; dim < length; dim++) {
101
+ norm += mean[dim] * mean[dim];
102
+ }
103
+ const magnitude = Math.sqrt(norm) || 1;
104
+ for (let dim = 0; dim < length; dim++) {
105
+ mean[dim] /= magnitude;
106
+ }
107
+ nextCentroids.push(mean);
108
+ nextGroups.push(group);
109
+ }
110
+ centroids = nextCentroids;
111
+ groups = nextGroups;
112
+ }
113
+ const result = [];
114
+ for (let clusterIndex = 0; clusterIndex < centroids.length; clusterIndex++) {
115
+ const centroid = (0, embeddingFormats_1.encodeEmbedding)({ input: centroids[clusterIndex], format: config.format, model: config.model });
116
+ const cellMembers = [];
117
+ for (const memberIndex of groups[clusterIndex]) {
118
+ cellMembers.push(members[memberIndex]);
119
+ }
120
+ result.push({ centroid, members: cellMembers });
121
+ }
122
+ for (const memberFloat of memberFloats) {
123
+ (0, embeddingFormats_1.releaseFloat32)(memberFloat);
124
+ }
125
+ return result;
126
+ }
127
+ // Re-cluster EVERY embedding (flat tier + all cells) into a fresh IVF, clear the flat tier, and mark IVF
128
+ // mode. This is the rearranger: run probabilistically as the set grows, once at each regenerate threshold,
129
+ // and once to upgrade from flat. Reads everything it uses, so it bails (does nothing) if anything isn't
130
+ // synced and the caller's retry re-runs it; no caller cares about its result.
131
+ function rebuildStructure(database) {
132
+ const config = database.readData(root => root.config);
133
+ if (!config)
134
+ return;
135
+ const allMembers = [];
136
+ const flat = (0, transactionSet_1.transactionRead)(flatStore(database));
137
+ if (!flat)
138
+ return;
139
+ for (const ref of flat.keys()) {
140
+ allMembers.push({ ref, embedding: flat.get(ref) });
141
+ }
142
+ const centroids = (0, transactionSet_1.transactionRead)(centroidStore(database));
143
+ if (!centroids)
144
+ return;
145
+ const oldCellIds = Array.from(centroids.keys());
146
+ const cellStores = database.readData(root => oldCellIds.map(cellId => root.cells[cellId]));
147
+ if (!cellStores)
148
+ return;
149
+ for (const store of cellStores) {
150
+ const members = (0, transactionSet_1.replayTransactionStore)(store);
151
+ for (const ref of members.keys()) {
152
+ allMembers.push({ ref, embedding: members.get(ref) });
153
+ }
154
+ }
155
+ if (!allMembers.length)
156
+ return;
157
+ const clusterCount = Math.max(1, Math.round(allMembers.length / config.cellTargetSize));
158
+ const clusters = clusterMembers(allMembers, clusterCount, config);
159
+ const newCellIds = new Set();
160
+ const centroidWrites = [];
161
+ for (const cluster of clusters) {
162
+ const cellId = (0, embeddingFormats_1.hashEmbedding)(cluster.centroid);
163
+ newCellIds.add(cellId);
164
+ centroidWrites.push({ key: cellId, value: cluster.centroid });
165
+ const memberWrites = cluster.members.map(member => ({ key: member.ref, value: member.embedding }));
166
+ (0, transactionSet_1.transactionMutate)(cellStore(database, cellId), memberWrites);
167
+ }
168
+ for (const oldCellId of oldCellIds) {
169
+ if (newCellIds.has(oldCellId)) {
170
+ continue;
171
+ }
172
+ centroidWrites.push({ key: oldCellId, value: undefined });
173
+ database.deleteData(root => root.cells[oldCellId]);
174
+ }
175
+ (0, transactionSet_1.transactionMutate)(centroidStore(database), centroidWrites);
176
+ database.deleteData(root => root.flat);
177
+ database.writeData(root => root.count, allMembers.length);
178
+ database.writeData(root => root.steps[STEP_IVF], true);
179
+ }
180
+ exports.rebuildStructure = rebuildStructure;
181
+ function searchEmbeddings(database, query, options) {
182
+ const config = database.readData(root => root.config);
183
+ if (!config)
184
+ return undefined;
185
+ const steps = readSteps(database);
186
+ const hits = [];
187
+ if (!steps[STEP_IVF]) {
188
+ const flat = (0, transactionSet_1.transactionRead)(flatStore(database));
189
+ if (!flat)
190
+ return undefined;
191
+ for (const ref of flat.keys()) {
192
+ hits.push({ ref, closeness: (0, embeddingFormats_1.getCloseness)(query, flat.get(ref)) });
193
+ }
194
+ hits.sort((left, right) => right.closeness - left.closeness);
195
+ return hits.slice(0, options.resultCount);
196
+ }
197
+ const centroids = (0, transactionSet_1.transactionRead)(centroidStore(database));
198
+ if (!centroids)
199
+ return undefined;
200
+ if (!centroids.size)
201
+ return [];
202
+ const probeCellCount = Math.max(1, Math.ceil(options.probeBudget / config.cellTargetSize));
203
+ const probeCellIds = rankCellsByCloseness(query, centroids).slice(0, probeCellCount);
204
+ const stores = database.readData(root => probeCellIds.map(cellId => root.cells[cellId]));
205
+ if (!stores)
206
+ return undefined;
207
+ for (const store of stores) {
208
+ const members = (0, transactionSet_1.replayTransactionStore)(store);
209
+ for (const ref of members.keys()) {
210
+ hits.push({ ref, closeness: (0, embeddingFormats_1.getCloseness)(query, members.get(ref)) });
211
+ }
212
+ }
213
+ hits.sort((left, right) => right.closeness - left.closeness);
214
+ return hits.slice(0, options.resultCount);
215
+ }
216
+ exports.searchEmbeddings = searchEmbeddings;
217
+ function insertEmbeddings(database, items) {
218
+ if (!items.length)
219
+ return true;
220
+ const config = database.readData(root => root.config);
221
+ if (!config)
222
+ return undefined;
223
+ const steps = readSteps(database);
224
+ const newCount = readCount(database) + items.length;
225
+ if (!steps[STEP_IVF]) {
226
+ const flatWrites = items.map(item => ({ key: item.ref, value: item.embedding }));
227
+ (0, transactionSet_1.transactionMutate)(flatStore(database), flatWrites);
228
+ database.writeData(root => root.count, newCount);
229
+ if (newCount > FLAT_LIMIT) {
230
+ rebuildStructure(database);
231
+ }
232
+ return true;
233
+ }
234
+ const centroids = (0, transactionSet_1.transactionRead)(centroidStore(database));
235
+ if (!centroids)
236
+ return undefined;
237
+ const itemsByCell = new Map();
238
+ for (const item of items) {
239
+ const cellId = rankCellsByCloseness(item.embedding, centroids)[0];
240
+ let group = itemsByCell.get(cellId);
241
+ if (!group) {
242
+ group = [];
243
+ itemsByCell.set(cellId, group);
244
+ }
245
+ group.push(item);
246
+ }
247
+ for (const cellId of itemsByCell.keys()) {
248
+ const group = itemsByCell.get(cellId);
249
+ const memberWrites = group.map(item => ({ key: item.ref, value: item.embedding }));
250
+ (0, transactionSet_1.transactionMutate)(cellStore(database, cellId), memberWrites);
251
+ }
252
+ database.writeData(root => root.count, newCount);
253
+ let regenerated = false;
254
+ for (const threshold of REGENERATE_AT) {
255
+ const stepName = "regen" + threshold;
256
+ if (!steps[stepName] && newCount > threshold) {
257
+ rebuildStructure(database);
258
+ database.writeData(root => root.steps[stepName], true);
259
+ regenerated = true;
260
+ }
261
+ }
262
+ if (!regenerated) {
263
+ const averageFill = newCount / Math.max(1, centroids.size) / config.cellTargetSize;
264
+ if (Math.random() < rebalanceProbability(averageFill)) {
265
+ rebuildStructure(database);
266
+ }
267
+ }
268
+ return true;
269
+ }
270
+ exports.insertEmbeddings = insertEmbeddings;
271
+ function removeEmbeddings(database, items) {
272
+ if (!items.length)
273
+ return true;
274
+ const steps = readSteps(database);
275
+ const count = readCount(database);
276
+ if (!steps[STEP_IVF]) {
277
+ const flatDeletes = items.map(item => ({ key: item.ref, value: undefined }));
278
+ (0, transactionSet_1.transactionMutate)(flatStore(database), flatDeletes);
279
+ database.writeData(root => root.count, Math.max(0, count - items.length));
280
+ return true;
281
+ }
282
+ const centroids = (0, transactionSet_1.transactionRead)(centroidStore(database));
283
+ if (!centroids)
284
+ return undefined;
285
+ if (!centroids.size)
286
+ return true;
287
+ const candidatesByItem = [];
288
+ const candidateSet = new Set();
289
+ for (const item of items) {
290
+ const cellIds = rankCellsByCloseness(item.embedding, centroids).slice(0, 1 + DELETE_FALLBACK_CELLS);
291
+ candidatesByItem.push({ ref: item.ref, cellIds });
292
+ for (const cellId of cellIds) {
293
+ candidateSet.add(cellId);
294
+ }
295
+ }
296
+ const candidateCellIds = Array.from(candidateSet);
297
+ const stores = database.readData(root => candidateCellIds.map(cellId => root.cells[cellId]));
298
+ if (!stores)
299
+ return undefined;
300
+ const membersByCell = new Map();
301
+ for (let index = 0; index < candidateCellIds.length; index++) {
302
+ membersByCell.set(candidateCellIds[index], (0, transactionSet_1.replayTransactionStore)(stores[index]));
303
+ }
304
+ const deletesByCell = new Map();
305
+ for (const candidate of candidatesByItem) {
306
+ for (const cellId of candidate.cellIds) {
307
+ const members = membersByCell.get(cellId);
308
+ if (!members || !members.has(candidate.ref)) {
309
+ continue;
310
+ }
311
+ let refs = deletesByCell.get(cellId);
312
+ if (!refs) {
313
+ refs = [];
314
+ deletesByCell.set(cellId, refs);
315
+ }
316
+ refs.push(candidate.ref);
317
+ break;
318
+ }
319
+ }
320
+ let deletedCount = 0;
321
+ for (const cellId of deletesByCell.keys()) {
322
+ const refs = deletesByCell.get(cellId);
323
+ deletedCount += refs.length;
324
+ const memberDeletes = refs.map(ref => ({ key: ref, value: undefined }));
325
+ (0, transactionSet_1.transactionMutate)(cellStore(database, cellId), memberDeletes);
326
+ }
327
+ if (deletedCount) {
328
+ database.writeData(root => root.count, Math.max(0, count - deletedCount));
329
+ }
330
+ return true;
331
+ }
332
+ exports.removeEmbeddings = removeEmbeddings;
333
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXZmRW1iZWRkaW5nRGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpdmZFbWJlZGRpbmdEYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FBeUQ7QUFDekQscURBQW1IO0FBQ25ILDBEQUF5SjtBQTBCekosaUdBQWlHO0FBQ2pHLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQztBQUN4Qix5SkFBeUo7QUFDekosTUFBTSxhQUFhLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDcEMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDO0FBQ3ZCLHFIQUFxSDtBQUNySCxNQUFNLHFCQUFxQixHQUFHLEVBQUUsQ0FBQztBQUNqQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQUUvQixTQUFTLFNBQVMsQ0FBQyxRQUFvQztJQUNuRCxPQUFPLElBQUEsNEJBQWlCLEVBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzFELENBQUM7QUFDRCxTQUFTLGFBQWEsQ0FBQyxRQUFvQztJQUN2RCxPQUFPLElBQUEsNEJBQWlCLEVBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFDRCxTQUFTLFNBQVMsQ0FBQyxRQUFvQyxFQUFFLE1BQWM7SUFDbkUsT0FBTyxJQUFBLDRCQUFpQixFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUNuRSxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsUUFBb0M7O0lBQ25ELE9BQU8sTUFBQSxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQ0FBSSxFQUFFLENBQUM7QUFDdkQsQ0FBQztB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QUFZLENBQUMsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNoQixDQUFDO0FBakVELDRDQWlFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGFiYXNlLCBuYW1lc3BhY2VEYXRhYmFzZSB9IGZyb20gXCIuL0RhdGFiYXNlXCI7XG5pbXBvcnQgeyBUcmFuc2FjdGlvblNldFN0b3JlLCB0cmFuc2FjdGlvblJlYWQsIHRyYW5zYWN0aW9uTXV0YXRlLCByZXBsYXlUcmFuc2FjdGlvblN0b3JlIH0gZnJvbSBcIi4vdHJhbnNhY3Rpb25TZXRcIjtcbmltcG9ydCB7IFN0b3JlZEVtYmVkZGluZywgRW1iZWRkaW5nRm9ybWF0LCBnZXRDbG9zZW5lc3MsIGVtYmVkZGluZ1RvRmxvYXQzMiwgcmVsZWFzZUZsb2F0MzIsIGVuY29kZUVtYmVkZGluZywgaGFzaEVtYmVkZGluZyB9IGZyb20gXCIuLi9lbWJlZGRpbmdGb3JtYXRzXCI7XG5cbmV4cG9ydCB0eXBlIEl2ZkNvbmZpZyA9IHtcbiAgICBtb2RlbDogc3RyaW5nO1xuICAgIGZvcm1hdDogRW1iZWRkaW5nRm9ybWF0O1xuICAgIC8vIFRhcmdldCBudW1iZXIgb2YgZW1iZWRkaW5ncyBwZXIgY2VsbC5cbiAgICBjZWxsVGFyZ2V0U2l6ZTogbnVtYmVyO1xufTtcblxuLy8gVGllcmVkIHN0b3JhZ2UuIEJlbG93IEZMQVRfTElNSVQgZW1iZWRkaW5ncyB0aGUgd2hvbGUgc2V0IGxpdmVzIGluIG9uZSBmbGF0IHRyYW5zYWN0aW9uIHNldCAobm8gSVZGKTtcbi8vIG9uY2UgaXQgZ3Jvd3MgcGFzdCB0aGF0IHdlIGJ1aWxkIHRoZSBJVkYgKGNlbnRyb2lkcyArIHBlci1jZWxsIHNldHMpIGFuZCBzdGF5IHRoZXJlIGZvcmV2ZXIuIGBjb3VudGAgaXNcbi8vIHRoZSBsaXZlIGVtYmVkZGluZyBjb3VudCAocmUtZGVyaXZlZCBleGFjdGx5IG9uIGEgcmVidWlsZCkuIGBzdGVwc2AgcmVjb3JkcyBvbmUtdGltZSB1cGdyYWRlcyB0aGF0IG11c3Rcbi8vIG5ldmVyIHJlLXJ1biBldmVuIGlmIHRoZSBzZXQgbGF0ZXIgc2hyaW5rcyBhbmQgcmVncm93cy5cbmV4cG9ydCB0eXBlIEl2ZkVtYmVkZGluZ1Jvb3QgPSB7XG4gICAgY29uZmlnOiBJdmZDb25maWc7XG4gICAgY291bnQ6IG51bWJlcjtcbiAgICBmbGF0OiBUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz47XG4gICAgc3RlcHM6IHsgW3N0ZXA6IHN0cmluZ106IGJvb2xlYW4gfTtcbiAgICBjZW50cm9pZHM6IFRyYW5zYWN0aW9uU2V0U3RvcmU8U3RvcmVkRW1iZWRkaW5nPjtcbiAgICBjZWxsczogeyBbY2VsbElkOiBzdHJpbmddOiBUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz4gfTtcbn07XG5cbmV4cG9ydCB0eXBlIEVtYmVkZGluZ0lucHV0ID0geyByZWY6IHN0cmluZzsgZW1iZWRkaW5nOiBTdG9yZWRFbWJlZGRpbmcgfTtcbmV4cG9ydCB0eXBlIFNlYXJjaEhpdCA9IHsgcmVmOiBzdHJpbmc7IGNsb3NlbmVzczogbnVtYmVyIH07XG50eXBlIENlbGxFbnRyeSA9IHsgcmVmOiBzdHJpbmc7IGVtYmVkZGluZzogU3RvcmVkRW1iZWRkaW5nIH07XG5cbi8vIEJlbG93IHRoaXMgbWFueSBlbWJlZGRpbmdzIHdlIHNraXAgdGhlIElWRiBlbnRpcmVseSAoZmxhdCBzdG9yZSkuIDEwMjQgPSBhIGNsZWFuIHBvd2VyIG9mIHR3by5cbmNvbnN0IEZMQVRfTElNSVQgPSAxMDI0O1xuLy8gRm9yY2UgYSBmcm9tLXNjcmF0Y2ggcmVidWlsZCBvbmNlIGF0IGVhY2ggb2YgdGhlc2UgKG11bHRpcGxlcyBvZiA0IGFib3ZlIEZMQVRfTElNSVQsIHVwIHRvIH4xNmspLCBnYXRlZCBieSBhIHN0ZXAgZmxhZyBzbyBlYWNoIHJ1bnMgYXQgbW9zdCBvbmNlIGV2ZXIuXG5jb25zdCBSRUdFTkVSQVRFX0FUID0gWzQwOTYsIDE2Mzg0XTtcbmNvbnN0IFNURVBfSVZGID0gXCJpdmZcIjtcbi8vIE9uIGRlbGV0ZSwgdGhlIG1lbWJlcidzIGV4YWN0IGNlbGwgcGx1cyB0aGlzIG1hbnkgbmVhcmJ5IGNlbGxzIGFyZSBjaGVja2VkLCBpbiBjYXNlIGEgcmVidWlsZCBsZWZ0IGl0IG5vbi1vcHRpbWFsLlxuY29uc3QgREVMRVRFX0ZBTExCQUNLX0NFTExTID0gMTA7XG5jb25zdCBSRUJBTEFOQ0VfSVRFUkFUSU9OUyA9IDQ7XG5cbmZ1bmN0aW9uIGZsYXRTdG9yZShkYXRhYmFzZTogRGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4pOiBEYXRhYmFzZTxUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz4+IHtcbiAgICByZXR1cm4gbmFtZXNwYWNlRGF0YWJhc2UoZGF0YWJhc2UsIHJvb3QgPT4gcm9vdC5mbGF0KTtcbn1cbmZ1bmN0aW9uIGNlbnRyb2lkU3RvcmUoZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+KTogRGF0YWJhc2U8VHJhbnNhY3Rpb25TZXRTdG9yZTxTdG9yZWRFbWJlZGRpbmc+PiB7XG4gICAgcmV0dXJuIG5hbWVzcGFjZURhdGFiYXNlKGRhdGFiYXNlLCByb290ID0+IHJvb3QuY2VudHJvaWRzKTtcbn1cbmZ1bmN0aW9uIGNlbGxTdG9yZShkYXRhYmFzZTogRGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4sIGNlbGxJZDogc3RyaW5nKTogRGF0YWJhc2U8VHJhbnNhY3Rpb25TZXRTdG9yZTxTdG9yZWRFbWJlZGRpbmc+PiB7XG4gICAgcmV0dXJuIG5hbWVzcGFjZURhdGFiYXNlKGRhdGFiYXNlLCByb290ID0+IHJvb3QuY2VsbHNbY2VsbElkXSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRTdGVwcyhkYXRhYmFzZTogRGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4pOiB7IFtzdGVwOiBzdHJpbmddOiBib29sZWFuIH0ge1xuICAgIHJldHVybiBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3Quc3RlcHMpID8/IHt9O1xufVxuZnVuY3Rpb24gcmVhZENvdW50KGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290Pik6IG51bWJlciB7XG4gICAgcmV0dXJuIGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5jb3VudCkgPz8gMDtcbn1cblxuZnVuY3Rpb24gcmFua0NlbGxzQnlDbG9zZW5lc3MoZW1iZWRkaW5nOiBTdG9yZWRFbWJlZGRpbmcsIGNlbnRyb2lkczogTWFwPHN0cmluZywgU3RvcmVkRW1iZWRkaW5nPik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCByYW5rZWQ6IHsgY2VsbElkOiBzdHJpbmc7IGNsb3NlbmVzczogbnVtYmVyIH1bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY2VsbElkIG9mIGNlbnRyb2lkcy5rZXlzKCkpIHtcbiAgICAgICAgcmFua2VkLnB1c2goeyBjZWxsSWQsIGNsb3NlbmVzczogZ2V0Q2xvc2VuZXNzKGVtYmVkZGluZywgY2VudHJvaWRzLmdldChjZWxsSWQpISkgfSk7XG4gICAgfVxuICAgIHJhbmtlZC5zb3J0KChsZWZ0LCByaWdodCkgPT4gcmlnaHQuY2xvc2VuZXNzIC0gbGVmdC5jbG9zZW5lc3MpO1xuICAgIHJldHVybiByYW5rZWQubWFwKGVudHJ5ID0+IGVudHJ5LmNlbGxJZCk7XG59XG5cbi8vIFBlci13cml0ZSBjaGFuY2Ugb2YgYSBmdWxsIHJlYnVpbGQuIFplcm8gYXQvdW5kZXIgdGhlIHRhcmdldCBzaXplLCB0aGVuIHJpc2VzIChjdWJpY2FsbHkpIHBhc3QgaXQgc28gY2VsbHNcbi8vIHN0YXkgcm91Z2hseSBiZXR3ZWVuIHRhcmdldCBhbmQgfjJ4IHRhcmdldC5cbmZ1bmN0aW9uIHJlYmFsYW5jZVByb2JhYmlsaXR5KGZpbGxSYXRpbzogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoZmlsbFJhdGlvIDw9IDEpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNvbnN0IG92ZXIgPSBmaWxsUmF0aW8gLSAxO1xuICAgIHJldHVybiBNYXRoLm1pbigxLCBvdmVyICogb3ZlciAqIG92ZXIgKiAwLjI1KTtcbn1cblxuLy8gay1tZWFucy4gRGVjb2RlcyBldmVyeSBtZW1iZXIgdG8gYSBwb29sZWQgZmxvYXQzMiBidWZmZXIgT05DRSwgdGhlbiBhc3NpZ25zIHdpdGggYSBwbGFpbiBpbnRlcm5hbCBmbG9hdFxuLy8gZG90IChubyBnZXRDbG9zZW5lc3MgY2FsbCDigJQgY29tcGFyaW5nIHR3byBmbG9hdCB2ZWN0b3JzIGlzIHRyaXZpYWwpIGFuZCBrZWVwcyBjZW50cm9pZHMgYXMgZmxvYXQgbWVhbnMsXG4vLyBlbmNvZGluZyB0aGVtIHRvIFN0b3JlZEVtYmVkZGluZyBvbmx5IGF0IHRoZSBlbmQuIFJlbGVhc2VzIHRoZSBib3Jyb3dlZCBidWZmZXJzIHdoZW4gZG9uZS5cbmZ1bmN0aW9uIGNsdXN0ZXJNZW1iZXJzKG1lbWJlcnM6IENlbGxFbnRyeVtdLCBjbHVzdGVyQ291bnQ6IG51bWJlciwgY29uZmlnOiBJdmZDb25maWcpOiB7IGNlbnRyb2lkOiBTdG9yZWRFbWJlZGRpbmc7IG1lbWJlcnM6IENlbGxFbnRyeVtdIH1bXSB7XG4gICAgY29uc3QgbWVtYmVyRmxvYXRzOiBGbG9hdDMyQXJyYXlbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgbWVtYmVyIG9mIG1lbWJlcnMpIHtcbiAgICAgICAgbWVtYmVyRmxvYXRzLnB1c2goZW1iZWRkaW5nVG9GbG9hdDMyKG1lbWJlci5lbWJlZGRpbmcsIHRydWUpKTtcbiAgICB9XG4gICAgY29uc3QgbGVuZ3RoID0gbWVtYmVyRmxvYXRzLmxlbmd0aCA/IG1lbWJlckZsb2F0c1swXS5sZW5ndGggOiAwO1xuICAgIGxldCBjZW50cm9pZHM6IEZsb2F0MzJBcnJheVtdID0gW107XG4gICAgY29uc3Qgc2VlZFN0ZXAgPSBtZW1iZXJzLmxlbmd0aCAvIGNsdXN0ZXJDb3VudDtcbiAgICBmb3IgKGxldCBjbHVzdGVySW5kZXggPSAwOyBjbHVzdGVySW5kZXggPCBjbHVzdGVyQ291bnQ7IGNsdXN0ZXJJbmRleCsrKSB7XG4gICAgICAgIGNlbnRyb2lkcy5wdXNoKG5ldyBGbG9hdDMyQXJyYXkobWVtYmVyRmxvYXRzW01hdGguZmxvb3IoY2x1c3RlckluZGV4ICogc2VlZFN0ZXApXSkpO1xuICAgIH1cbiAgICBsZXQgZ3JvdXBzOiBudW1iZXJbXVtdID0gW107XG4gICAgZm9yIChsZXQgaXRlcmF0aW9uID0gMDsgaXRlcmF0aW9uIDwgUkVCQUxBTkNFX0lURVJBVElPTlM7IGl0ZXJhdGlvbisrKSB7XG4gICAgICAgIGdyb3VwcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBjbHVzdGVySW5kZXggPSAwOyBjbHVzdGVySW5kZXggPCBjZW50cm9pZHMubGVuZ3RoOyBjbHVzdGVySW5kZXgrKykge1xuICAgICAgICAgICAgZ3JvdXBzLnB1c2goW10pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IG1lbWJlckluZGV4ID0gMDsgbWVtYmVySW5kZXggPCBtZW1iZXJGbG9hdHMubGVuZ3RoOyBtZW1iZXJJbmRleCsrKSB7XG4gICAgICAgICAgICBjb25zdCBtZW1iZXJGbG9hdCA9IG1lbWJlckZsb2F0c1ttZW1iZXJJbmRleF07XG4gICAgICAgICAgICBsZXQgYmVzdEluZGV4ID0gMDtcbiAgICAgICAgICAgIGxldCBiZXN0RG90ID0gLUluZmluaXR5O1xuICAgICAgICAgICAgZm9yIChsZXQgY2VudHJvaWRJbmRleCA9IDA7IGNlbnRyb2lkSW5kZXggPCBjZW50cm9pZHMubGVuZ3RoOyBjZW50cm9pZEluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjZW50cm9pZEZsb2F0ID0gY2VudHJvaWRzW2NlbnRyb2lkSW5kZXhdO1xuICAgICAgICAgICAgICAgIGxldCBkb3QgPSAwO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGxlbmd0aDsgZGltKyspIHtcbiAgICAgICAgICAgICAgICAgICAgZG90ICs9IG1lbWJlckZsb2F0W2RpbV0gKiBjZW50cm9pZEZsb2F0W2RpbV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkb3QgPiBiZXN0RG90KSB7XG4gICAgICAgICAgICAgICAgICAgIGJlc3REb3QgPSBkb3Q7XG4gICAgICAgICAgICAgICAgICAgIGJlc3RJbmRleCA9IGNlbnRyb2lkSW5kZXg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ3JvdXBzW2Jlc3RJbmRleF0ucHVzaChtZW1iZXJJbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV4dENlbnRyb2lkczogRmxvYXQzMkFycmF5W10gPSBbXTtcbiAgICAgICAgY29uc3QgbmV4dEdyb3VwczogbnVtYmVyW11bXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGdyb3VwIG9mIGdyb3Vwcykge1xuICAgICAgICAgICAgaWYgKCFncm91cC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG1lYW4gPSBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG1lbWJlckluZGV4IG9mIGdyb3VwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWVtYmVyRmxvYXQgPSBtZW1iZXJGbG9hdHNbbWVtYmVySW5kZXhdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGxlbmd0aDsgZGltKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbWVhbltkaW1dICs9IG1lbWJlckZsb2F0W2RpbV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IG5vcm0gPSAwO1xuICAgICAgICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgbGVuZ3RoOyBkaW0rKykge1xuICAgICAgICAgICAgICAgIG5vcm0gKz0gbWVhbltkaW1dICogbWVhbltkaW1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWFnbml0dWRlID0gTWF0aC5zcXJ0KG5vcm0pIHx8IDE7XG4gICAgICAgICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBsZW5ndGg7IGRpbSsrKSB7XG4gICAgICAgICAgICAgICAgbWVhbltkaW1dIC89IG1hZ25pdHVkZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5leHRDZW50cm9pZHMucHVzaChtZWFuKTtcbiAgICAgICAgICAgIG5leHRHcm91cHMucHVzaChncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgY2VudHJvaWRzID0gbmV4dENlbnRyb2lkcztcbiAgICAgICAgZ3JvdXBzID0gbmV4dEdyb3VwcztcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0OiB7IGNlbnRyb2lkOiBTdG9yZWRFbWJlZGRpbmc7IG1lbWJlcnM6IENlbGxFbnRyeVtdIH1bXSA9IFtdO1xuICAgIGZvciAobGV0IGNsdXN0ZXJJbmRleCA9IDA7IGNsdXN0ZXJJbmRleCA8IGNlbnRyb2lkcy5sZW5ndGg7IGNsdXN0ZXJJbmRleCsrKSB7XG4gICAgICAgIGNvbnN0IGNlbnRyb2lkID0gZW5jb2RlRW1iZWRkaW5nKHsgaW5wdXQ6IGNlbnRyb2lkc1tjbHVzdGVySW5kZXhdLCBmb3JtYXQ6IGNvbmZpZy5mb3JtYXQsIG1vZGVsOiBjb25maWcubW9kZWwgfSk7XG4gICAgICAgIGNvbnN0IGNlbGxNZW1iZXJzOiBDZWxsRW50cnlbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IG1lbWJlckluZGV4IG9mIGdyb3Vwc1tjbHVzdGVySW5kZXhdKSB7XG4gICAgICAgICAgICBjZWxsTWVtYmVycy5wdXNoKG1lbWJlcnNbbWVtYmVySW5kZXhdKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQucHVzaCh7IGNlbnRyb2lkLCBtZW1iZXJzOiBjZWxsTWVtYmVycyB9KTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBtZW1iZXJGbG9hdCBvZiBtZW1iZXJGbG9hdHMpIHtcbiAgICAgICAgcmVsZWFzZUZsb2F0MzIobWVtYmVyRmxvYXQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG4vLyBSZS1jbHVzdGVyIEVWRVJZIGVtYmVkZGluZyAoZmxhdCB0aWVyICsgYWxsIGNlbGxzKSBpbnRvIGEgZnJlc2ggSVZGLCBjbGVhciB0aGUgZmxhdCB0aWVyLCBhbmQgbWFyayBJVkZcbi8vIG1vZGUuIFRoaXMgaXMgdGhlIHJlYXJyYW5nZXI6IHJ1biBwcm9iYWJpbGlzdGljYWxseSBhcyB0aGUgc2V0IGdyb3dzLCBvbmNlIGF0IGVhY2ggcmVnZW5lcmF0ZSB0aHJlc2hvbGQsXG4vLyBhbmQgb25jZSB0byB1cGdyYWRlIGZyb20gZmxhdC4gUmVhZHMgZXZlcnl0aGluZyBpdCB1c2VzLCBzbyBpdCBiYWlscyAoZG9lcyBub3RoaW5nKSBpZiBhbnl0aGluZyBpc24ndFxuLy8gc3luY2VkIGFuZCB0aGUgY2FsbGVyJ3MgcmV0cnkgcmUtcnVucyBpdDsgbm8gY2FsbGVyIGNhcmVzIGFib3V0IGl0cyByZXN1bHQuXG5leHBvcnQgZnVuY3Rpb24gcmVidWlsZFN0cnVjdHVyZShkYXRhYmFzZTogRGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4pOiB2b2lkIHtcbiAgICBjb25zdCBjb25maWcgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3QuY29uZmlnKTtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuO1xuXG4gICAgY29uc3QgYWxsTWVtYmVyczogQ2VsbEVudHJ5W10gPSBbXTtcbiAgICBjb25zdCBmbGF0ID0gdHJhbnNhY3Rpb25SZWFkKGZsYXRTdG9yZShkYXRhYmFzZSkpO1xuICAgIGlmICghZmxhdCkgcmV0dXJuO1xuICAgIGZvciAoY29uc3QgcmVmIG9mIGZsYXQua2V5cygpKSB7XG4gICAgICAgIGFsbE1lbWJlcnMucHVzaCh7IHJlZiwgZW1iZWRkaW5nOiBmbGF0LmdldChyZWYpISB9KTtcbiAgICB9XG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuO1xuICAgIGNvbnN0IG9sZENlbGxJZHMgPSBBcnJheS5mcm9tKGNlbnRyb2lkcy5rZXlzKCkpO1xuICAgIGNvbnN0IGNlbGxTdG9yZXMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IG9sZENlbGxJZHMubWFwKGNlbGxJZCA9PiByb290LmNlbGxzW2NlbGxJZF0pKTtcbiAgICBpZiAoIWNlbGxTdG9yZXMpIHJldHVybjtcbiAgICBmb3IgKGNvbnN0IHN0b3JlIG9mIGNlbGxTdG9yZXMpIHtcbiAgICAgICAgY29uc3QgbWVtYmVycyA9IHJlcGxheVRyYW5zYWN0aW9uU3RvcmU8U3RvcmVkRW1iZWRkaW5nPihzdG9yZSk7XG4gICAgICAgIGZvciAoY29uc3QgcmVmIG9mIG1lbWJlcnMua2V5cygpKSB7XG4gICAgICAgICAgICBhbGxNZW1iZXJzLnB1c2goeyByZWYsIGVtYmVkZGluZzogbWVtYmVycy5nZXQocmVmKSEgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFhbGxNZW1iZXJzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgY29uc3QgY2x1c3RlckNvdW50ID0gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChhbGxNZW1iZXJzLmxlbmd0aCAvIGNvbmZpZy5jZWxsVGFyZ2V0U2l6ZSkpO1xuICAgIGNvbnN0IGNsdXN0ZXJzID0gY2x1c3Rlck1lbWJlcnMoYWxsTWVtYmVycywgY2x1c3RlckNvdW50LCBjb25maWcpO1xuXG4gICAgY29uc3QgbmV3Q2VsbElkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGNlbnRyb2lkV3JpdGVzOiB7IGtleTogc3RyaW5nOyB2YWx1ZTogU3RvcmVkRW1iZWRkaW5nIHwgdW5kZWZpbmVkIH1bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY2x1c3RlciBvZiBjbHVzdGVycykge1xuICAgICAgICBjb25zdCBjZWxsSWQgPSBoYXNoRW1iZWRkaW5nKGNsdXN0ZXIuY2VudHJvaWQpO1xuICAgICAgICBuZXdDZWxsSWRzLmFkZChjZWxsSWQpO1xuICAgICAgICBjZW50cm9pZFdyaXRlcy5wdXNoKHsga2V5OiBjZWxsSWQsIHZhbHVlOiBjbHVzdGVyLmNlbnRyb2lkIH0pO1xuICAgICAgICBjb25zdCBtZW1iZXJXcml0ZXMgPSBjbHVzdGVyLm1lbWJlcnMubWFwKG1lbWJlciA9PiAoeyBrZXk6IG1lbWJlci5yZWYsIHZhbHVlOiBtZW1iZXIuZW1iZWRkaW5nIH0pKTtcbiAgICAgICAgdHJhbnNhY3Rpb25NdXRhdGUoY2VsbFN0b3JlKGRhdGFiYXNlLCBjZWxsSWQpLCBtZW1iZXJXcml0ZXMpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG9sZENlbGxJZCBvZiBvbGRDZWxsSWRzKSB7XG4gICAgICAgIGlmIChuZXdDZWxsSWRzLmhhcyhvbGRDZWxsSWQpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjZW50cm9pZFdyaXRlcy5wdXNoKHsga2V5OiBvbGRDZWxsSWQsIHZhbHVlOiB1bmRlZmluZWQgfSk7XG4gICAgICAgIGRhdGFiYXNlLmRlbGV0ZURhdGEocm9vdCA9PiByb290LmNlbGxzW29sZENlbGxJZF0pO1xuICAgIH1cbiAgICB0cmFuc2FjdGlvbk11dGF0ZShjZW50cm9pZFN0b3JlKGRhdGFiYXNlKSwgY2VudHJvaWRXcml0ZXMpO1xuICAgIGRhdGFiYXNlLmRlbGV0ZURhdGEocm9vdCA9PiByb290LmZsYXQpO1xuICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIGFsbE1lbWJlcnMubGVuZ3RoKTtcbiAgICBkYXRhYmFzZS53cml0ZURhdGEocm9vdCA9PiByb290LnN0ZXBzW1NURVBfSVZGXSwgdHJ1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZWFyY2hFbWJlZGRpbmdzKFxuICAgIGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290PixcbiAgICBxdWVyeTogU3RvcmVkRW1iZWRkaW5nLFxuICAgIG9wdGlvbnM6IHsgcHJvYmVCdWRnZXQ6IG51bWJlcjsgcmVzdWx0Q291bnQ6IG51bWJlciB9LFxuKTogU2VhcmNoSGl0W10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5jb25maWcpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IHN0ZXBzID0gcmVhZFN0ZXBzKGRhdGFiYXNlKTtcblxuICAgIGNvbnN0IGhpdHM6IFNlYXJjaEhpdFtdID0gW107XG4gICAgaWYgKCFzdGVwc1tTVEVQX0lWRl0pIHtcbiAgICAgICAgY29uc3QgZmxhdCA9IHRyYW5zYWN0aW9uUmVhZChmbGF0U3RvcmUoZGF0YWJhc2UpKTtcbiAgICAgICAgaWYgKCFmbGF0KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICBmb3IgKGNvbnN0IHJlZiBvZiBmbGF0LmtleXMoKSkge1xuICAgICAgICAgICAgaGl0cy5wdXNoKHsgcmVmLCBjbG9zZW5lc3M6IGdldENsb3NlbmVzcyhxdWVyeSwgZmxhdC5nZXQocmVmKSEpIH0pO1xuICAgICAgICB9XG4gICAgICAgIGhpdHMuc29ydCgobGVmdCwgcmlnaHQpID0+IHJpZ2h0LmNsb3NlbmVzcyAtIGxlZnQuY2xvc2VuZXNzKTtcbiAgICAgICAgcmV0dXJuIGhpdHMuc2xpY2UoMCwgb3B0aW9ucy5yZXN1bHRDb3VudCk7XG4gICAgfVxuXG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAoIWNlbnRyb2lkcy5zaXplKSByZXR1cm4gW107XG4gICAgY29uc3QgcHJvYmVDZWxsQ291bnQgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwob3B0aW9ucy5wcm9iZUJ1ZGdldCAvIGNvbmZpZy5jZWxsVGFyZ2V0U2l6ZSkpO1xuICAgIGNvbnN0IHByb2JlQ2VsbElkcyA9IHJhbmtDZWxsc0J5Q2xvc2VuZXNzKHF1ZXJ5LCBjZW50cm9pZHMpLnNsaWNlKDAsIHByb2JlQ2VsbENvdW50KTtcbiAgICBjb25zdCBzdG9yZXMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHByb2JlQ2VsbElkcy5tYXAoY2VsbElkID0+IHJvb3QuY2VsbHNbY2VsbElkXSkpO1xuICAgIGlmICghc3RvcmVzKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGZvciAoY29uc3Qgc3RvcmUgb2Ygc3RvcmVzKSB7XG4gICAgICAgIGNvbnN0IG1lbWJlcnMgPSByZXBsYXlUcmFuc2FjdGlvblN0b3JlPFN0b3JlZEVtYmVkZGluZz4oc3RvcmUpO1xuICAgICAgICBmb3IgKGNvbnN0IHJlZiBvZiBtZW1iZXJzLmtleXMoKSkge1xuICAgICAgICAgICAgaGl0cy5wdXNoKHsgcmVmLCBjbG9zZW5lc3M6IGdldENsb3NlbmVzcyhxdWVyeSwgbWVtYmVycy5nZXQocmVmKSEpIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGhpdHMuc29ydCgobGVmdCwgcmlnaHQpID0+IHJpZ2h0LmNsb3NlbmVzcyAtIGxlZnQuY2xvc2VuZXNzKTtcbiAgICByZXR1cm4gaGl0cy5zbGljZSgwLCBvcHRpb25zLnJlc3VsdENvdW50KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydEVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIGl0ZW1zOiBFbWJlZGRpbmdJbnB1dFtdLFxuKTogdHJ1ZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFpdGVtcy5sZW5ndGgpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IGNvbmZpZyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5jb25maWcpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IHN0ZXBzID0gcmVhZFN0ZXBzKGRhdGFiYXNlKTtcbiAgICBjb25zdCBuZXdDb3VudCA9IHJlYWRDb3VudChkYXRhYmFzZSkgKyBpdGVtcy5sZW5ndGg7XG5cbiAgICBpZiAoIXN0ZXBzW1NURVBfSVZGXSkge1xuICAgICAgICBjb25zdCBmbGF0V3JpdGVzID0gaXRlbXMubWFwKGl0ZW0gPT4gKHsga2V5OiBpdGVtLnJlZiwgdmFsdWU6IGl0ZW0uZW1iZWRkaW5nIH0pKTtcbiAgICAgICAgdHJhbnNhY3Rpb25NdXRhdGUoZmxhdFN0b3JlKGRhdGFiYXNlKSwgZmxhdFdyaXRlcyk7XG4gICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIG5ld0NvdW50KTtcbiAgICAgICAgaWYgKG5ld0NvdW50ID4gRkxBVF9MSU1JVCkge1xuICAgICAgICAgICAgcmVidWlsZFN0cnVjdHVyZShkYXRhYmFzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCBpdGVtc0J5Q2VsbCA9IG5ldyBNYXA8c3RyaW5nLCBFbWJlZGRpbmdJbnB1dFtdPigpO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBjb25zdCBjZWxsSWQgPSByYW5rQ2VsbHNCeUNsb3NlbmVzcyhpdGVtLmVtYmVkZGluZywgY2VudHJvaWRzKVswXTtcbiAgICAgICAgbGV0IGdyb3VwID0gaXRlbXNCeUNlbGwuZ2V0KGNlbGxJZCk7XG4gICAgICAgIGlmICghZ3JvdXApIHtcbiAgICAgICAgICAgIGdyb3VwID0gW107XG4gICAgICAgICAgICBpdGVtc0J5Q2VsbC5zZXQoY2VsbElkLCBncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgZ3JvdXAucHVzaChpdGVtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBjZWxsSWQgb2YgaXRlbXNCeUNlbGwua2V5cygpKSB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gaXRlbXNCeUNlbGwuZ2V0KGNlbGxJZCkhO1xuICAgICAgICBjb25zdCBtZW1iZXJXcml0ZXMgPSBncm91cC5tYXAoaXRlbSA9PiAoeyBrZXk6IGl0ZW0ucmVmLCB2YWx1ZTogaXRlbS5lbWJlZGRpbmcgfSkpO1xuICAgICAgICB0cmFuc2FjdGlvbk11dGF0ZShjZWxsU3RvcmUoZGF0YWJhc2UsIGNlbGxJZCksIG1lbWJlcldyaXRlcyk7XG4gICAgfVxuICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIG5ld0NvdW50KTtcblxuICAgIGxldCByZWdlbmVyYXRlZCA9IGZhbHNlO1xuICAgIGZvciAoY29uc3QgdGhyZXNob2xkIG9mIFJFR0VORVJBVEVfQVQpIHtcbiAgICAgICAgY29uc3Qgc3RlcE5hbWUgPSBcInJlZ2VuXCIgKyB0aHJlc2hvbGQ7XG4gICAgICAgIGlmICghc3RlcHNbc3RlcE5hbWVdICYmIG5ld0NvdW50ID4gdGhyZXNob2xkKSB7XG4gICAgICAgICAgICByZWJ1aWxkU3RydWN0dXJlKGRhdGFiYXNlKTtcbiAgICAgICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3Quc3RlcHNbc3RlcE5hbWVdLCB0cnVlKTtcbiAgICAgICAgICAgIHJlZ2VuZXJhdGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXJlZ2VuZXJhdGVkKSB7XG4gICAgICAgIGNvbnN0IGF2ZXJhZ2VGaWxsID0gbmV3Q291bnQgLyBNYXRoLm1heCgxLCBjZW50cm9pZHMuc2l6ZSkgLyBjb25maWcuY2VsbFRhcmdldFNpemU7XG4gICAgICAgIGlmIChNYXRoLnJhbmRvbSgpIDwgcmViYWxhbmNlUHJvYmFiaWxpdHkoYXZlcmFnZUZpbGwpKSB7XG4gICAgICAgICAgICByZWJ1aWxkU3RydWN0dXJlKGRhdGFiYXNlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIGl0ZW1zOiBFbWJlZGRpbmdJbnB1dFtdLFxuKTogdHJ1ZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFpdGVtcy5sZW5ndGgpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IHN0ZXBzID0gcmVhZFN0ZXBzKGRhdGFiYXNlKTtcbiAgICBjb25zdCBjb3VudCA9IHJlYWRDb3VudChkYXRhYmFzZSk7XG5cbiAgICBpZiAoIXN0ZXBzW1NURVBfSVZGXSkge1xuICAgICAgICBjb25zdCBmbGF0RGVsZXRlcyA9IGl0ZW1zLm1hcChpdGVtID0+ICh7IGtleTogaXRlbS5yZWYsIHZhbHVlOiB1bmRlZmluZWQgfSkpO1xuICAgICAgICB0cmFuc2FjdGlvbk11dGF0ZShmbGF0U3RvcmUoZGF0YWJhc2UpLCBmbGF0RGVsZXRlcyk7XG4gICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIE1hdGgubWF4KDAsIGNvdW50IC0gaXRlbXMubGVuZ3RoKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGNlbnRyb2lkcyA9IHRyYW5zYWN0aW9uUmVhZChjZW50cm9pZFN0b3JlKGRhdGFiYXNlKSk7XG4gICAgaWYgKCFjZW50cm9pZHMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKCFjZW50cm9pZHMuc2l6ZSkgcmV0dXJuIHRydWU7XG5cbiAgICBjb25zdCBjYW5kaWRhdGVzQnlJdGVtOiB7IHJlZjogc3RyaW5nOyBjZWxsSWRzOiBzdHJpbmdbXSB9W10gPSBbXTtcbiAgICBjb25zdCBjYW5kaWRhdGVTZXQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgY29uc3QgY2VsbElkcyA9IHJhbmtDZWxsc0J5Q2xvc2VuZXNzKGl0ZW0uZW1iZWRkaW5nLCBjZW50cm9pZHMpLnNsaWNlKDAsIDEgKyBERUxFVEVfRkFMTEJBQ0tfQ0VMTFMpO1xuICAgICAgICBjYW5kaWRhdGVzQnlJdGVtLnB1c2goeyByZWY6IGl0ZW0ucmVmLCBjZWxsSWRzIH0pO1xuICAgICAgICBmb3IgKGNvbnN0IGNlbGxJZCBvZiBjZWxsSWRzKSB7XG4gICAgICAgICAgICBjYW5kaWRhdGVTZXQuYWRkKGNlbGxJZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjYW5kaWRhdGVDZWxsSWRzID0gQXJyYXkuZnJvbShjYW5kaWRhdGVTZXQpO1xuICAgIGNvbnN0IHN0b3JlcyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gY2FuZGlkYXRlQ2VsbElkcy5tYXAoY2VsbElkID0+IHJvb3QuY2VsbHNbY2VsbElkXSkpO1xuICAgIGlmICghc3RvcmVzKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IG1lbWJlcnNCeUNlbGwgPSBuZXcgTWFwPHN0cmluZywgTWFwPHN0cmluZywgU3RvcmVkRW1iZWRkaW5nPj4oKTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgY2FuZGlkYXRlQ2VsbElkcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgbWVtYmVyc0J5Q2VsbC5zZXQoY2FuZGlkYXRlQ2VsbElkc1tpbmRleF0sIHJlcGxheVRyYW5zYWN0aW9uU3RvcmUoc3RvcmVzW2luZGV4XSkpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlbGV0ZXNCeUNlbGwgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nW10+KCk7XG4gICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2YgY2FuZGlkYXRlc0J5SXRlbSkge1xuICAgICAgICBmb3IgKGNvbnN0IGNlbGxJZCBvZiBjYW5kaWRhdGUuY2VsbElkcykge1xuICAgICAgICAgICAgY29uc3QgbWVtYmVycyA9IG1lbWJlcnNCeUNlbGwuZ2V0KGNlbGxJZCk7XG4gICAgICAgICAgICBpZiAoIW1lbWJlcnMgfHwgIW1lbWJlcnMuaGFzKGNhbmRpZGF0ZS5yZWYpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgcmVmcyA9IGRlbGV0ZXNCeUNlbGwuZ2V0KGNlbGxJZCk7XG4gICAgICAgICAgICBpZiAoIXJlZnMpIHtcbiAgICAgICAgICAgICAgICByZWZzID0gW107XG4gICAgICAgICAgICAgICAgZGVsZXRlc0J5Q2VsbC5zZXQoY2VsbElkLCByZWZzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlZnMucHVzaChjYW5kaWRhdGUucmVmKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGRlbGV0ZWRDb3VudCA9IDA7XG4gICAgZm9yIChjb25zdCBjZWxsSWQgb2YgZGVsZXRlc0J5Q2VsbC5rZXlzKCkpIHtcbiAgICAgICAgY29uc3QgcmVmcyA9IGRlbGV0ZXNCeUNlbGwuZ2V0KGNlbGxJZCkhO1xuICAgICAgICBkZWxldGVkQ291bnQgKz0gcmVmcy5sZW5ndGg7XG4gICAgICAgIGNvbnN0IG1lbWJlckRlbGV0ZXMgPSByZWZzLm1hcChyZWYgPT4gKHsga2V5OiByZWYsIHZhbHVlOiB1bmRlZmluZWQgfSkpO1xuICAgICAgICB0cmFuc2FjdGlvbk11dGF0ZShjZWxsU3RvcmUoZGF0YWJhc2UsIGNlbGxJZCksIG1lbWJlckRlbGV0ZXMpO1xuICAgIH1cbiAgICBpZiAoZGVsZXRlZENvdW50KSB7XG4gICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIE1hdGgubWF4KDAsIGNvdW50IC0gZGVsZXRlZENvdW50KSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuIl19
334
+ /* _JS_SOURCE_HASH = "6bb25c321db29d41be7eec5ac48ec8aad9563a1f8c7710e6700a8deb6ed719c9"; */
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
6
+ //exports.transactionMutate = exports.replayTransactionStore = exports.transactionRead = void 0;
7
+ const cbor_x_1 = __importDefault(require("cbor-x"));
8
+ // structuredClone keeps typed arrays / Maps / undefined intact through the round-trip.
9
+ const transactionCbor = new cbor_x_1.default.Encoder({ structuredClone: true });
10
+ const DEFAULT_COMPACT_AFTER_FILES = 16;
11
+ function maxNumber(values, fallback) {
12
+ let result = fallback;
13
+ for (const value of values) {
14
+ if (value > result) {
15
+ result = value;
16
+ }
17
+ }
18
+ return result;
19
+ }
20
+ function decodeBuffers(buffers) {
21
+ const transactions = [];
22
+ for (const buffer of buffers) {
23
+ const decoded = transactionCbor.decode(buffer);
24
+ for (const transaction of decoded) {
25
+ transactions.push(transaction);
26
+ }
27
+ }
28
+ return transactions;
29
+ }
30
+ function readTransactionFiles(database) {
31
+ const snapshot = database.readData(store => {
32
+ // A never-written / deleted set reads as empty (vs the whole readData being undefined = not synced).
33
+ const present = store;
34
+ if (!present)
35
+ return { fileKeys: [], buffers: [] };
36
+ return { fileKeys: Object.keys(present), buffers: Object.values(present) };
37
+ });
38
+ if (!snapshot)
39
+ return undefined;
40
+ return { fileKeys: snapshot.fileKeys, transactions: decodeBuffers(snapshot.buffers) };
41
+ }
42
+ function replay(transactions) {
43
+ const ordered = transactions.slice().sort((left, right) => left.sequence - right.sequence);
44
+ const state = new Map();
45
+ for (const transaction of ordered) {
46
+ // undefined (not falsy) is the delete marker, so 0 / "" / false stay real values.
47
+ if (transaction.value === undefined) {
48
+ state.delete(transaction.key);
49
+ }
50
+ else {
51
+ state.set(transaction.key, transaction.value);
52
+ }
53
+ }
54
+ return state;
55
+ }
56
+ // Deletes old files by their ORIGINAL string key, so a stray non-numeric key still gets removed.
57
+ function compactTransactions(database, allTransactions, oldFileKeys, newFileNumber) {
58
+ const finalState = replay(allTransactions);
59
+ const merged = [];
60
+ for (const key of finalState.keys()) {
61
+ merged.push({ sequence: merged.length, key, value: finalState.get(key) });
62
+ }
63
+ const encoded = transactionCbor.encode(merged);
64
+ database.writeData(store => store[String(newFileNumber)], encoded);
65
+ for (const fileKey of oldFileKeys) {
66
+ database.deleteData(store => store[fileKey]);
67
+ }
68
+ }
69
+ function transactionRead(database) {
70
+ const files = readTransactionFiles(database);
71
+ if (!files)
72
+ return undefined;
73
+ return replay(files.transactions);
74
+ }
75
+ exports.transactionRead = transactionRead;
76
+ // Replay an already-read store (no read of its own), so a caller can fetch many sets in one batched read and materialize each.
77
+ function replayTransactionStore(store) {
78
+ if (!store)
79
+ return new Map();
80
+ return replay(decodeBuffers(Object.values(store)));
81
+ }
82
+ exports.replayTransactionStore = replayTransactionStore;
83
+ // Fire-and-forget: no caller should care whether this "succeeded". If the set isn't synced for reading
84
+ // yet it simply does nothing this pass and the caller's retry wrapper re-runs the whole operation later.
85
+ function transactionMutate(database, transactions, compactAfterFiles = DEFAULT_COMPACT_AFTER_FILES) {
86
+ if (!transactions.length)
87
+ return;
88
+ const files = readTransactionFiles(database);
89
+ if (!files)
90
+ return;
91
+ const baseSequence = maxNumber(files.transactions.map(transaction => transaction.sequence), -1) + 1;
92
+ const incoming = transactions.map((transaction, index) => ({
93
+ sequence: baseSequence + index,
94
+ key: transaction.key,
95
+ value: transaction.value,
96
+ }));
97
+ const nextFileNumber = maxNumber(files.fileKeys.map(fileKey => Number(fileKey)), -1) + 1;
98
+ if (files.fileKeys.length + 1 >= compactAfterFiles) {
99
+ compactTransactions(database, files.transactions.concat(incoming), files.fileKeys, nextFileNumber);
100
+ }
101
+ else {
102
+ const encoded = transactionCbor.encode(incoming);
103
+ database.writeData(store => store[String(nextFileNumber)], encoded);
104
+ }
105
+ }
106
+ exports.transactionMutate = transactionMutate;
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25TZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0cmFuc2FjdGlvblNldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBMkI7QUFHM0IsdUZBQXVGO0FBQ3ZGLE1BQU0sZUFBZSxHQUFHLElBQUksZ0JBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQVdyRSxNQUFNLDJCQUEyQixHQUFHLEVBQUUsQ0FBQztBQUV2QyxTQUFTLFNBQVMsQ0FBQyxNQUFnQixFQUFFLFFBQWdCO0lBQ2pELElBQUksTUFBTSxHQUFHLFFBQVEsQ0FBQztJQUN0QixLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ3pCLElBQUksS0FBSyxHQUFHLE1BQU0sRUFBRSxDQUFDO1lBQ2pCLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDbkIsQ0FBQztJQUNMLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNsQixDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsT0FBcUI7SUFDeEMsTUFBTSxZQUFZLEdBQWtCLEVBQUUsQ0FBQztJQUN2QyxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzNCLE1BQU0sT0FBTyxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFrQixDQUFDO1FBQ2hFLEtBQUssTUFBTSxXQUFXLElBQUksT0FBTyxFQUFFLENBQUM7WUFDaEMsWUFBWSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNuQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE9BQU8sWUFBWSxDQUFDO0FBQ3hCLENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUN6QixRQUE4QztJQUU5QyxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFO1FBQ3ZDLHFHQUFxRztRQUNyRyxNQUFNLE9BQU8sR0FBRyxLQUErQyxDQUFD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RSxLQUFLLENBQUMsUUFBUSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ3ZHLENBQUM7U0FBTSxDQUFDO1FBQ0osTUFBTSxPQUFPLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQWUsQ0FBQztRQUMvRCxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3hFLENBQUM7QUFDTCxDQUFDO0FBckJELDhDQXFCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjYm9yeCBmcm9tIFwiY2Jvci14XCI7XG5pbXBvcnQgeyBEYXRhYmFzZSB9IGZyb20gXCIuL0RhdGFiYXNlXCI7XG5cbi8vIHN0cnVjdHVyZWRDbG9uZSBrZWVwcyB0eXBlZCBhcnJheXMgLyBNYXBzIC8gdW5kZWZpbmVkIGludGFjdCB0aHJvdWdoIHRoZSByb3VuZC10cmlwLlxuY29uc3QgdHJhbnNhY3Rpb25DYm9yID0gbmV3IGNib3J4LkVuY29kZXIoeyBzdHJ1Y3R1cmVkQ2xvbmU6IHRydWUgfSk7XG5cbi8vIE9uIHRoZSBzdG9yZTogZmlsZXMga2V5ZWQgYnkgYSBtb25vdG9uaWMgbnVtYmVyLCBlYWNoIGEgQ0JPUiBhcnJheSBvZiB0cmFuc2FjdGlvbnM7IGEgdHJhbnNhY3Rpb24gc2V0cyBvbmUga2V5ICh2YWx1ZSB1bmRlZmluZWQgPSBkZWxldGUpIGFuZCBjYXJyaWVzIGEgZ2xvYmFsIHNlcXVlbmNlIG51bWJlci4gUmVwbGF5aW5nIGV2ZXJ5IHRyYW5zYWN0aW9uIGluIHNlcXVlbmNlIG9yZGVyIChsYXN0IHdyaXRlIHdpbnMpIGdpdmVzIHRoZSBjdXJyZW50IG1hcC4gTXV0YXRpb25zIGFwcGVuZCBhIGZpbGUsIHRoZW4gZm9sZCB0aGUgd2hvbGUgc2V0IGludG8gb25lIG9uY2UgZW5vdWdoIGFjY3VtdWxhdGUuIFZhbHVlIGlzIHBoYW50b20g4oCUIGl0IG9ubHkgcmVjb3JkcyB3aGF0IHRoZSBlbmNvZGVkIHZhbHVlcyBkZXNlcmlhbGl6ZSB0by5cbmRlY2xhcmUgY29uc3QgdmFsdWVUYWc6IHVuaXF1ZSBzeW1ib2w7XG5leHBvcnQgdHlwZSBUcmFuc2FjdGlvblNldFN0b3JlPFZhbHVlPiA9IHtcbiAgICBbZmlsZU51bWJlcjogc3RyaW5nXTogVWludDhBcnJheTtcbiAgICBbdmFsdWVUYWddPzogVmFsdWU7XG59O1xuXG50eXBlIFRyYW5zYWN0aW9uID0geyBzZXF1ZW5jZTogbnVtYmVyOyBrZXk6IHN0cmluZzsgdmFsdWU6IHVua25vd24gfTtcblxuY29uc3QgREVGQVVMVF9DT01QQUNUX0FGVEVSX0ZJTEVTID0gMTY7XG5cbmZ1bmN0aW9uIG1heE51bWJlcih2YWx1ZXM6IG51bWJlcltdLCBmYWxsYmFjazogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgcmVzdWx0ID0gZmFsbGJhY2s7XG4gICAgZm9yIChjb25zdCB2YWx1ZSBvZiB2YWx1ZXMpIHtcbiAgICAgICAgaWYgKHZhbHVlID4gcmVzdWx0KSB7XG4gICAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBkZWNvZGVCdWZmZXJzKGJ1ZmZlcnM6IFVpbnQ4QXJyYXlbXSk6IFRyYW5zYWN0aW9uW10ge1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uczogVHJhbnNhY3Rpb25bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgYnVmZmVyIG9mIGJ1ZmZlcnMpIHtcbiAgICAgICAgY29uc3QgZGVjb2RlZCA9IHRyYW5zYWN0aW9uQ2Jvci5kZWNvZGUoYnVmZmVyKSBhcyBUcmFuc2FjdGlvbltdO1xuICAgICAgICBmb3IgKGNvbnN0IHRyYW5zYWN0aW9uIG9mIGRlY29kZWQpIHtcbiAgICAgICAgICAgIHRyYW5zYWN0aW9ucy5wdXNoKHRyYW5zYWN0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJhbnNhY3Rpb25zO1xufVxuXG5mdW5jdGlvbiByZWFkVHJhbnNhY3Rpb25GaWxlczxWYWx1ZT4oXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPFRyYW5zYWN0aW9uU2V0U3RvcmU8VmFsdWU+Pixcbik6IHsgZmlsZUtleXM6IHN0cmluZ1tdOyB0cmFuc2FjdGlvbnM6IFRyYW5zYWN0aW9uW10gfSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgc25hcHNob3QgPSBkYXRhYmFzZS5yZWFkRGF0YShzdG9yZSA9PiB7XG4gICAgICAgIC8vIEEgbmV2ZXItd3JpdHRlbiAvIGRlbGV0ZWQgc2V0IHJlYWRzIGFzIGVtcHR5ICh2cyB0aGUgd2hvbGUgcmVhZERhdGEgYmVpbmcgdW5kZWZpbmVkID0gbm90IHN5bmNlZCkuXG4gICAgICAgIGNvbnN0IHByZXNlbnQgPSBzdG9yZSBhcyBUcmFuc2FjdGlvblNldFN0b3JlPFZhbHVlPiB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCFwcmVzZW50KSByZXR1cm4geyBmaWxlS2V5czogW10gYXMgc3RyaW5nW10sIGJ1ZmZlcnM6IFtdIGFzIFVpbnQ4QXJyYXlbXSB9O1xuICAgICAgICByZXR1cm4geyBmaWxlS2V5czogT2JqZWN0LmtleXMocHJlc2VudCksIGJ1ZmZlcnM6IE9iamVjdC52YWx1ZXMocHJlc2VudCkgfTtcbiAgICB9KTtcbiAgICBpZiAoIXNuYXBzaG90KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHJldHVybiB7IGZpbGVLZXlzOiBzbmFwc2hvdC5maWxlS2V5cywgdHJhbnNhY3Rpb25zOiBkZWNvZGVCdWZmZXJzKHNuYXBzaG90LmJ1ZmZlcnMpIH07XG59XG5cbmZ1bmN0aW9uIHJlcGxheSh0cmFuc2FjdGlvbnM6IFRyYW5zYWN0aW9uW10pOiBNYXA8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgY29uc3Qgb3JkZXJlZCA9IHRyYW5zYWN0aW9ucy5zbGljZSgpLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiBsZWZ0LnNlcXVlbmNlIC0gcmlnaHQuc2VxdWVuY2UpO1xuICAgIGNvbnN0IHN0YXRlID0gbmV3IE1hcDxzdHJpbmcsIHVua25vd24+KCk7XG4gICAgZm9yIChjb25zdCB0cmFuc2FjdGlvbiBvZiBvcmRlcmVkKSB7XG4gICAgICAgIC8vIHVuZGVmaW5lZCAobm90IGZhbHN5KSBpcyB0aGUgZGVsZXRlIG1hcmtlciwgc28gMCAvIFwiXCIgLyBmYWxzZSBzdGF5IHJlYWwgdmFsdWVzLlxuICAgICAgICBpZiAodHJhbnNhY3Rpb24udmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc3RhdGUuZGVsZXRlKHRyYW5zYWN0aW9uLmtleSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdGF0ZS5zZXQodHJhbnNhY3Rpb24ua2V5LCB0cmFuc2FjdGlvbi52YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0YXRlO1xufVxuXG4vLyBEZWxldGVzIG9sZCBmaWxlcyBieSB0aGVpciBPUklHSU5BTCBzdHJpbmcga2V5LCBzbyBhIHN0cmF5IG5vbi1udW1lcmljIGtleSBzdGlsbCBnZXRzIHJlbW92ZWQuXG5mdW5jdGlvbiBjb21wYWN0VHJhbnNhY3Rpb25zPFZhbHVlPihcbiAgICBkYXRhYmFzZTogRGF0YWJhc2U8VHJhbnNhY3Rpb25TZXRTdG9yZTxWYWx1ZT4+LFxuICAgIGFsbFRyYW5zYWN0aW9uczogVHJhbnNhY3Rpb25bXSxcbiAgICBvbGRGaWxlS2V5czogc3RyaW5nW10sXG4gICAgbmV3RmlsZU51bWJlcjogbnVtYmVyLFxuKTogdm9pZCB7XG4gICAgY29uc3QgZmluYWxTdGF0ZSA9IHJlcGxheShhbGxUcmFuc2FjdGlvbnMpO1xuICAgIGNvbnN0IG1lcmdlZDogVHJhbnNhY3Rpb25bXSA9IFtdO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGZpbmFsU3RhdGUua2V5cygpKSB7XG4gICAgICAgIG1lcmdlZC5wdXNoKHsgc2VxdWVuY2U6IG1lcmdlZC5sZW5ndGgsIGtleSwgdmFsdWU6IGZpbmFsU3RhdGUuZ2V0KGtleSkgfSk7XG4gICAgfVxuICAgIGNvbnN0IGVuY29kZWQgPSB0cmFuc2FjdGlvbkNib3IuZW5jb2RlKG1lcmdlZCkgYXMgVWludDhBcnJheTtcbiAgICBkYXRhYmFzZS53cml0ZURhdGEoc3RvcmUgPT4gc3RvcmVbU3RyaW5nKG5ld0ZpbGVOdW1iZXIpXSwgZW5jb2RlZCk7XG4gICAgZm9yIChjb25zdCBmaWxlS2V5IG9mIG9sZEZpbGVLZXlzKSB7XG4gICAgICAgIGRhdGFiYXNlLmRlbGV0ZURhdGEoc3RvcmUgPT4gc3RvcmVbZmlsZUtleV0pO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zYWN0aW9uUmVhZDxWYWx1ZT4oXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPFRyYW5zYWN0aW9uU2V0U3RvcmU8VmFsdWU+Pixcbik6IE1hcDxzdHJpbmcsIFZhbHVlPiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZmlsZXMgPSByZWFkVHJhbnNhY3Rpb25GaWxlcyhkYXRhYmFzZSk7XG4gICAgaWYgKCFmaWxlcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICByZXR1cm4gcmVwbGF5KGZpbGVzLnRyYW5zYWN0aW9ucykgYXMgTWFwPHN0cmluZywgVmFsdWU+O1xufVxuXG4vLyBSZXBsYXkgYW4gYWxyZWFkeS1yZWFkIHN0b3JlIChubyByZWFkIG9mIGl0cyBvd24pLCBzbyBhIGNhbGxlciBjYW4gZmV0Y2ggbWFueSBzZXRzIGluIG9uZSBiYXRjaGVkIHJlYWQgYW5kIG1hdGVyaWFsaXplIGVhY2guXG5leHBvcnQgZnVuY3Rpb24gcmVwbGF5VHJhbnNhY3Rpb25TdG9yZTxWYWx1ZT4oc3RvcmU6IFRyYW5zYWN0aW9uU2V0U3RvcmU8VmFsdWU+IHwgdW5kZWZpbmVkKTogTWFwPHN0cmluZywgVmFsdWU+IHtcbiAgICBpZiAoIXN0b3JlKSByZXR1cm4gbmV3IE1hcCgpO1xuICAgIHJldHVybiByZXBsYXkoZGVjb2RlQnVmZmVycyhPYmplY3QudmFsdWVzKHN0b3JlKSkpIGFzIE1hcDxzdHJpbmcsIFZhbHVlPjtcbn1cblxuLy8gRmlyZS1hbmQtZm9yZ2V0OiBubyBjYWxsZXIgc2hvdWxkIGNhcmUgd2hldGhlciB0aGlzIFwic3VjY2VlZGVkXCIuIElmIHRoZSBzZXQgaXNuJ3Qgc3luY2VkIGZvciByZWFkaW5nXG4vLyB5ZXQgaXQgc2ltcGx5IGRvZXMgbm90aGluZyB0aGlzIHBhc3MgYW5kIHRoZSBjYWxsZXIncyByZXRyeSB3cmFwcGVyIHJlLXJ1bnMgdGhlIHdob2xlIG9wZXJhdGlvbiBsYXRlci5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2FjdGlvbk11dGF0ZTxWYWx1ZT4oXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPFRyYW5zYWN0aW9uU2V0U3RvcmU8VmFsdWU+PixcbiAgICB0cmFuc2FjdGlvbnM6IHsga2V5OiBzdHJpbmc7IHZhbHVlOiBWYWx1ZSB8IHVuZGVmaW5lZCB9W10sXG4gICAgY29tcGFjdEFmdGVyRmlsZXM6IG51bWJlciA9IERFRkFVTFRfQ09NUEFDVF9BRlRFUl9GSUxFUyxcbik6IHZvaWQge1xuICAgIGlmICghdHJhbnNhY3Rpb25zLmxlbmd0aCkgcmV0dXJuO1xuICAgIGNvbnN0IGZpbGVzID0gcmVhZFRyYW5zYWN0aW9uRmlsZXMoZGF0YWJhc2UpO1xuICAgIGlmICghZmlsZXMpIHJldHVybjtcbiAgICBjb25zdCBiYXNlU2VxdWVuY2UgPSBtYXhOdW1iZXIoZmlsZXMudHJhbnNhY3Rpb25zLm1hcCh0cmFuc2FjdGlvbiA9PiB0cmFuc2FjdGlvbi5zZXF1ZW5jZSksIC0xKSArIDE7XG4gICAgY29uc3QgaW5jb21pbmc6IFRyYW5zYWN0aW9uW10gPSB0cmFuc2FjdGlvbnMubWFwKCh0cmFuc2FjdGlvbiwgaW5kZXgpID0+ICh7XG4gICAgICAgIHNlcXVlbmNlOiBiYXNlU2VxdWVuY2UgKyBpbmRleCxcbiAgICAgICAga2V5OiB0cmFuc2FjdGlvbi5rZXksXG4gICAgICAgIHZhbHVlOiB0cmFuc2FjdGlvbi52YWx1ZSxcbiAgICB9KSk7XG4gICAgY29uc3QgbmV4dEZpbGVOdW1iZXIgPSBtYXhOdW1iZXIoZmlsZXMuZmlsZUtleXMubWFwKGZpbGVLZXkgPT4gTnVtYmVyKGZpbGVLZXkpKSwgLTEpICsgMTtcbiAgICBpZiAoZmlsZXMuZmlsZUtleXMubGVuZ3RoICsgMSA+PSBjb21wYWN0QWZ0ZXJGaWxlcykge1xuICAgICAgICBjb21wYWN0VHJhbnNhY3Rpb25zKGRhdGFiYXNlLCBmaWxlcy50cmFuc2FjdGlvbnMuY29uY2F0KGluY29taW5nKSwgZmlsZXMuZmlsZUtleXMsIG5leHRGaWxlTnVtYmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBlbmNvZGVkID0gdHJhbnNhY3Rpb25DYm9yLmVuY29kZShpbmNvbWluZykgYXMgVWludDhBcnJheTtcbiAgICAgICAgZGF0YWJhc2Uud3JpdGVEYXRhKHN0b3JlID0+IHN0b3JlW1N0cmluZyhuZXh0RmlsZU51bWJlcildLCBlbmNvZGVkKTtcbiAgICB9XG59XG4iXX0=
108
+ /* _JS_SOURCE_HASH = "5c22d95f86091992a5fc7263774f46e9f486d5f3cb56788139eecadc876b9f16"; */
@@ -0,0 +1,13 @@
1
+ import { Database } from "./Database";
2
+ export declare class InMemoryDatabase<Root> implements Database<Root> {
3
+ readCalls: number;
4
+ writeCalls: number;
5
+ deleteCalls: number;
6
+ bytesRead: number;
7
+ bytesWritten: number;
8
+ private root;
9
+ constructor(initial: Root);
10
+ readData<Value>(deref: (root: Root) => Value): Value | undefined;
11
+ writeData<Value>(deref: (root: Root) => Value, newValue: Value): void;
12
+ deleteData(deref: (root: Root) => unknown): void;
13
+ }