sliftutils 1.4.80 → 1.4.82

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/index.d.ts CHANGED
@@ -963,8 +963,11 @@ declare module "sliftutils/storage/BulkDatabase2/BulkDatabaseBase" {
963
963
  private storageFactory;
964
964
  private config;
965
965
  constructor(name: string, deps: ReactiveDeps, storageFactory: StorageFactory, config?: BulkDatabase2Config);
966
+ private _reader;
967
+ private get reader();
968
+ private activated;
969
+ private activate;
966
970
  private setupVisibilityMergeCheck;
967
- private reader;
968
971
  private subCaches;
969
972
  private pendingAppends;
970
973
  private flushTimer;
@@ -2258,6 +2261,11 @@ declare module "sliftutils/storage/backblaze" {
2258
2261
 
2259
2262
  }
2260
2263
 
2264
+ declare module "sliftutils/storage/embeddingBench" {
2265
+ export {};
2266
+
2267
+ }
2268
+
2261
2269
  declare module "sliftutils/storage/embeddingFormats" {
2262
2270
  export type EmbeddingFormat = "q8g8_2048" | "q8_g16_2048" | "q8_g16_1024" | "float32";
2263
2271
  export declare const EMBEDDING_FORMATS: EmbeddingFormat[];
@@ -2275,6 +2283,10 @@ declare module "sliftutils/storage/embeddingFormats" {
2275
2283
  data: Uint8Array;
2276
2284
  scales: Uint8Array;
2277
2285
  };
2286
+ export declare function embeddingLength(input: Float32Array | StoredEmbedding): number;
2287
+ export declare function releaseFloat32(buffer: Float32Array): void;
2288
+ export declare function embeddingToFloat32(input: Float32Array | StoredEmbedding, usePool?: boolean): Float32Array;
2289
+ export declare const getCloseness: (a: Float32Array | StoredEmbedding, b: Float32Array | StoredEmbedding) => number;
2278
2290
  export declare function encodeEmbedding(config: {
2279
2291
  input: Float32Array | StoredEmbedding;
2280
2292
  format: EmbeddingFormat;
@@ -2282,7 +2294,21 @@ declare module "sliftutils/storage/embeddingFormats" {
2282
2294
  }): StoredEmbedding;
2283
2295
  export declare function serializeStoredEmbedding(stored: StoredEmbedding): string;
2284
2296
  export declare function deserializeStoredEmbedding(base64: string): StoredEmbedding;
2285
- export declare const getCloseness: (embedding1: Float32Array | StoredEmbedding, embedding2: Float32Array | StoredEmbedding) => number;
2297
+ export declare function averageEmbeddings(embeddings: StoredEmbedding[], config: {
2298
+ format: EmbeddingFormat;
2299
+ model: string;
2300
+ }): StoredEmbedding;
2301
+ export declare function hashEmbedding(stored: StoredEmbedding): string;
2302
+
2303
+ }
2304
+
2305
+ declare module "sliftutils/storage/faceFramesData" {
2306
+ export declare function ensureFaceData(fileName: string, byteLength: number): Promise<string>;
2307
+
2308
+ }
2309
+
2310
+ declare module "sliftutils/storage/faceFramesServer" {
2311
+ export {};
2286
2312
 
2287
2313
  }
2288
2314
 
@@ -2311,16 +2337,82 @@ declare module "sliftutils/storage/proxydatabase/Database" {
2311
2337
 
2312
2338
  }
2313
2339
 
2340
+ declare module "sliftutils/storage/proxydatabase/inMemoryDatabase" {
2341
+ import { Database } from "./Database";
2342
+ export declare class InMemoryDatabase<Root> implements Database<Root> {
2343
+ readCalls: number;
2344
+ writeCalls: number;
2345
+ deleteCalls: number;
2346
+ bytesRead: number;
2347
+ bytesWritten: number;
2348
+ private root;
2349
+ constructor(initial: Root);
2350
+ readData<Value>(deref: (root: Root) => Value): Value | undefined;
2351
+ writeData<Value>(deref: (root: Root) => Value, newValue: Value): void;
2352
+ deleteData(deref: (root: Root) => unknown): void;
2353
+ }
2354
+
2355
+ }
2356
+
2357
+ declare module "sliftutils/storage/proxydatabase/ivfDbCheck" {
2358
+ export {};
2359
+
2360
+ }
2361
+
2362
+ declare module "sliftutils/storage/proxydatabase/ivfEmbeddingDatabase" {
2363
+ import { Database } from "./Database";
2364
+ import { TransactionSetStore } from "./transactionSet";
2365
+ import { StoredEmbedding, EmbeddingFormat } from "../embeddingFormats";
2366
+ export type IvfConfig = {
2367
+ model: string;
2368
+ format: EmbeddingFormat;
2369
+ cellTargetSize: number;
2370
+ };
2371
+ export type IvfEmbeddingRoot = {
2372
+ config: IvfConfig;
2373
+ count: number;
2374
+ flat: TransactionSetStore<StoredEmbedding>;
2375
+ steps: {
2376
+ [step: string]: boolean;
2377
+ };
2378
+ centroids: TransactionSetStore<StoredEmbedding>;
2379
+ cells: {
2380
+ [cellId: string]: TransactionSetStore<StoredEmbedding>;
2381
+ };
2382
+ };
2383
+ export type EmbeddingInput = {
2384
+ ref: string;
2385
+ embedding: StoredEmbedding;
2386
+ };
2387
+ export type SearchHit = {
2388
+ ref: string;
2389
+ closeness: number;
2390
+ };
2391
+ export declare function rebuildStructure(database: Database<IvfEmbeddingRoot>): void;
2392
+ export declare function searchEmbeddings(database: Database<IvfEmbeddingRoot>, query: StoredEmbedding, options: {
2393
+ probeBudget: number;
2394
+ resultCount: number;
2395
+ }): SearchHit[] | undefined;
2396
+ export declare function insertEmbeddings(database: Database<IvfEmbeddingRoot>, items: EmbeddingInput[]): undefined;
2397
+ export declare function removeEmbeddings(database: Database<IvfEmbeddingRoot>, items: EmbeddingInput[]): void;
2398
+
2399
+ }
2400
+
2314
2401
  declare module "sliftutils/storage/proxydatabase/transactionSet" {
2315
2402
  import { Database } from "./Database";
2316
- export type TransactionSetStore = {
2403
+ declare const valueTag: unique symbol;
2404
+ export type TransactionSetStore<Value> = {
2317
2405
  [fileNumber: string]: Uint8Array;
2406
+ [valueTag]?: Value;
2318
2407
  };
2319
- export declare function transactionRead<Value>(database: Database<TransactionSetStore>): Map<string, Value> | undefined;
2320
- export declare function transactionMutate<Value>(database: Database<TransactionSetStore>, transactions: {
2408
+ export declare function transactionRead<Value>(database: Database<TransactionSetStore<Value>>): Map<string, Value> | undefined;
2409
+ export declare function replayTransactionStore<Value>(store: TransactionSetStore<Value> | undefined): Map<string, Value>;
2410
+ export declare function transactionMutate<Value>(database: Database<TransactionSetStore<Value>>, transactions: {
2321
2411
  key: string;
2322
2412
  value: Value | undefined;
2323
- }[], compactAfterFiles?: number): true | undefined;
2413
+ }[], compactAfterFiles?: number): void;
2414
+ export declare function transactionDelete<Value>(database: Database<TransactionSetStore<Value>>): void;
2415
+ export {};
2324
2416
 
2325
2417
  }
2326
2418
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliftutils",
3
- "version": "1.4.80",
3
+ "version": "1.4.82",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "files": [
package/spec.txt CHANGED
@@ -40,3 +40,21 @@ unknown
40
40
 
41
41
  BUT... how do we update IVF
42
42
 
43
+
44
+
45
+
46
+ 1) Converting once is faster, so we should investigate if we can have a pool of memory. If we can reuse it, then the allocations are free.
47
+
48
+ 1) Fix embedding formats. It's really, really stupid. decodeToLength was just absolutely retarded.
49
+
50
+
51
+
52
+
53
+
54
+
55
+ 0) Make sure the AI stops trying to stop when a read didn't work because it doesn't fucking matter. I don't think there's a single place that's doing it where it actually matters.
56
+ - I mean, I guess there are a few places. Like when we're rebalancing, that's one place.
57
+ - I guess some of the returns are valid, but I guess we have to check all of them.
58
+
59
+ 1) Make sure the AI gets rid of all those four each's. I mean, what the fuck?
60
+ 1) Ensure the AI efficiently switches from the hard-coded stuff to the regular stuff and correctly regenerates the codebook.
@@ -35,8 +35,11 @@ export declare class BulkDatabaseBase<T extends {
35
35
  private storageFactory;
36
36
  private config;
37
37
  constructor(name: string, deps: ReactiveDeps, storageFactory: StorageFactory, config?: BulkDatabase2Config);
38
+ private _reader;
39
+ private get reader();
40
+ private activated;
41
+ private activate;
38
42
  private setupVisibilityMergeCheck;
39
- private reader;
40
43
  private subCaches;
41
44
  private pendingAppends;
42
45
  private flushTimer;
@@ -148,14 +148,31 @@ export class BulkDatabaseBase<T extends { key: string }> {
148
148
  protected deps: ReactiveDeps,
149
149
  private storageFactory: StorageFactory,
150
150
  private config: BulkDatabase2Config = {},
151
- ) {
152
- this.reader = new BulkDatabaseReader<T>({
153
- name,
154
- deps,
155
- maxTriggerThrottleMs: config.maxTriggerThrottleMs,
151
+ ) { }
152
+
153
+ // The reader (and the background machinery that rides along with it) must NOT be set up just
154
+ // because the collection was constructed. Many collections are constructed and never touched, and
155
+ // in Node a merge tick would poke the storage factory (e.g. indexedDB) and throw. We build it
156
+ // lazily on first access to `this.reader`: every read, write, and merge goes through the reader,
157
+ // while pure construction never touches it.
158
+ private _reader: BulkDatabaseReader<T> | undefined;
159
+ private get reader(): BulkDatabaseReader<T> {
160
+ if (this._reader) return this._reader;
161
+ const reader = new BulkDatabaseReader<T>({
162
+ name: this.name,
163
+ deps: this.deps,
164
+ maxTriggerThrottleMs: this.config.maxTriggerThrottleMs,
156
165
  });
157
- this.reader.setEnsureIndex(() => this.ensureIndex());
166
+ reader.setEnsureIndex(() => this.ensureIndex());
167
+ this._reader = reader;
168
+ this.activate();
169
+ return reader;
170
+ }
158
171
 
172
+ private activated = false;
173
+ private activate(): void {
174
+ if (this.activated) return;
175
+ this.activated = true;
159
176
  if (typeof window !== "undefined") {
160
177
  try {
161
178
  window.addEventListener("pagehide", () => void this.flushPending());
@@ -205,7 +222,6 @@ export class BulkDatabaseBase<T extends { key: string }> {
205
222
  } catch { /* not in a DOM context */ }
206
223
  }
207
224
 
208
- private reader: BulkDatabaseReader<T>;
209
225
  private subCaches: SubReaderCaches = { bulk: new Map(), stream: new Map() };
210
226
 
211
227
  private pendingAppends: { framed: Buffer; rows: number }[] = [];
@@ -0,0 +1,340 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
+ //exports.hashEmbedding = exports.averageEmbeddings = exports.deserializeStoredEmbedding = exports.serializeStoredEmbedding = exports.encodeEmbedding = exports.getCloseness = exports.embeddingToFloat32 = exports.releaseFloat32 = exports.embeddingLength = exports.DEFAULT_EMBEDDING_FORMAT = exports.EMBEDDING_FORMATS = void 0;
4
+ const measure_1 = require("socket-function/src/profiling/measure");
5
+ const buffers_1 = require("socket-function/src/buffers");
6
+ exports.EMBEDDING_FORMATS = ["q8g8_2048", "q8_g16_2048", "q8_g16_1024", "float32"];
7
+ exports.DEFAULT_EMBEDDING_FORMAT = "q8g8_2048";
8
+ const INT8_MAX = 127;
9
+ const FORMAT_CONFIGS = {
10
+ q8g8_2048: { truncation: 2048, quant: { type: "q8", groupSize: 8 } },
11
+ q8_g16_2048: { truncation: 2048, quant: { type: "q8", groupSize: 16 } },
12
+ q8_g16_1024: { truncation: 1024, quant: { type: "q8", groupSize: 16 } },
13
+ float32: {},
14
+ };
15
+ const Float16ArrayCtor = globalThis.Float16Array;
16
+ const f32Scratch = new Float32Array(1);
17
+ const i32Scratch = new Int32Array(f32Scratch.buffer);
18
+ function floatToHalf(value) {
19
+ f32Scratch[0] = value;
20
+ let bitsIn = i32Scratch[0];
21
+ let bits = (bitsIn >> 16) & 0x8000;
22
+ let mantissa = (bitsIn >> 12) & 0x07ff;
23
+ let exponent = (bitsIn >> 23) & 0xff;
24
+ if (exponent < 103)
25
+ return bits;
26
+ if (exponent > 142) {
27
+ bits |= 0x7c00;
28
+ if (exponent !== 255) {
29
+ bits |= (bitsIn & 0x007fffff);
30
+ }
31
+ return bits;
32
+ }
33
+ if (exponent < 113) {
34
+ mantissa |= 0x0800;
35
+ bits |= (mantissa >> (114 - exponent)) + ((mantissa >> (113 - exponent)) & 1);
36
+ return bits;
37
+ }
38
+ bits |= ((exponent - 112) << 10) | (mantissa >> 1);
39
+ bits += mantissa & 1;
40
+ return bits;
41
+ }
42
+ function halfToFloat(half) {
43
+ let sign = (half & 0x8000) >> 15;
44
+ let exponent = (half & 0x7c00) >> 10;
45
+ let fraction = half & 0x03ff;
46
+ let signMultiplier = sign && -1 || 1;
47
+ if (exponent === 0) {
48
+ return signMultiplier * Math.pow(2, -14) * (fraction / 1024);
49
+ }
50
+ if (exponent === 0x1f) {
51
+ if (fraction)
52
+ return NaN;
53
+ return signMultiplier * Infinity;
54
+ }
55
+ return signMultiplier * Math.pow(2, exponent - 15) * (1 + fraction / 1024);
56
+ }
57
+ function asInt8(bytes) {
58
+ return new Int8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
59
+ }
60
+ function encodeFloat16(values) {
61
+ if (Float16ArrayCtor) {
62
+ let half = new Float16ArrayCtor(values);
63
+ return new Uint8Array(half.buffer, half.byteOffset, half.byteLength);
64
+ }
65
+ let out = new Uint8Array(values.length * 2);
66
+ let view = new DataView(out.buffer);
67
+ for (let index = 0; index < values.length; index++) {
68
+ view.setUint16(index * 2, floatToHalf(values[index]), true);
69
+ }
70
+ return out;
71
+ }
72
+ function asFloat16Indexable(bytes) {
73
+ // Float16Array / Uint16Array views require 2-byte alignment; copy when the stored bytes aren't.
74
+ if (bytes.byteOffset % 2 !== 0) {
75
+ bytes = new Uint8Array(bytes);
76
+ }
77
+ let count = Math.floor(bytes.byteLength / 2);
78
+ if (Float16ArrayCtor) {
79
+ return new Float16ArrayCtor(bytes.buffer, bytes.byteOffset, count);
80
+ }
81
+ let halves = new Uint16Array(bytes.buffer, bytes.byteOffset, count);
82
+ let out = new Float32Array(count);
83
+ for (let index = 0; index < count; index++) {
84
+ out[index] = halfToFloat(halves[index]);
85
+ }
86
+ return out;
87
+ }
88
+ function embeddingLength(input) {
89
+ if (input instanceof Float32Array)
90
+ return input.length;
91
+ if (input.kind === "float32")
92
+ return input.values.length;
93
+ return input.data.length;
94
+ }
95
+ exports.embeddingLength = embeddingLength;
96
+ // A pool of reusable Float32 buffers keyed by length. Most embeddings share a size, so internal hot paths
97
+ // borrow a buffer (embeddingToFloat32 with usePool) and return it (releaseFloat32) to avoid per-op
98
+ // allocations and GC thrashing. A borrowed buffer holds stale data; whoever borrows it overwrites it fully.
99
+ //
100
+ // Each free buffer records when it was last released; an hourly sweep drops any that have sat idle for over
101
+ // an hour, so the runtime can free buffers a burst of work allocated but isn't actually reusing anymore.
102
+ const POOL_MAX_IDLE_MS = 60 * 60 * 1000;
103
+ const float32Pool = new Map();
104
+ function acquireFloat32(length) {
105
+ let free = float32Pool.get(length);
106
+ if (free && free.length) {
107
+ return free.pop().buffer;
108
+ }
109
+ return new Float32Array(length);
110
+ }
111
+ function releaseFloat32(buffer) {
112
+ let free = float32Pool.get(buffer.length);
113
+ if (!free) {
114
+ free = [];
115
+ float32Pool.set(buffer.length, free);
116
+ }
117
+ free.push({ buffer, releasedAt: Date.now() });
118
+ }
119
+ exports.releaseFloat32 = releaseFloat32;
120
+ function sweepFloat32Pool() {
121
+ let cutoff = Date.now() - POOL_MAX_IDLE_MS;
122
+ for (let free of float32Pool.values()) {
123
+ let writeIndex = 0;
124
+ for (let readIndex = 0; readIndex < free.length; readIndex++) {
125
+ if (free[readIndex].releasedAt > cutoff) {
126
+ free[writeIndex++] = free[readIndex];
127
+ }
128
+ }
129
+ free.length = writeIndex;
130
+ }
131
+ }
132
+ const poolSweepTimer = setInterval(sweepFloat32Pool, POOL_MAX_IDLE_MS);
133
+ if (typeof poolSweepTimer.unref === "function") {
134
+ poolSweepTimer.unref();
135
+ }
136
+ // Decode to a Float32Array (full length). Stored values are already unit-normalized (encodeEmbedding does
137
+ // that), so this only de-quantizes. By default it allocates a fresh array (a float input is returned as-is,
138
+ // no copy). With usePool it borrows a pooled buffer the caller must releaseFloat32 — used by hot internal
139
+ // paths so repeated decodes don't allocate.
140
+ function embeddingToFloat32(input, usePool = false) {
141
+ if (input instanceof Float32Array) {
142
+ if (!usePool)
143
+ return input;
144
+ let out = acquireFloat32(input.length);
145
+ out.set(input);
146
+ return out;
147
+ }
148
+ if (input.kind === "float32") {
149
+ if (!usePool)
150
+ return input.values;
151
+ let out = acquireFloat32(input.values.length);
152
+ out.set(input.values);
153
+ return out;
154
+ }
155
+ let int8 = asInt8(input.data);
156
+ let scales = asFloat16Indexable(input.scales);
157
+ let groupSize = input.groupSize;
158
+ let length = int8.length;
159
+ let out = usePool ? acquireFloat32(length) : new Float32Array(length);
160
+ let group = 0;
161
+ for (let start = 0; start < length; start += groupSize) {
162
+ let scale = scales[group++];
163
+ let end = Math.min(start + groupSize, length);
164
+ for (let index = start; index < end; index++) {
165
+ out[index] = int8[index] * scale;
166
+ }
167
+ }
168
+ return out;
169
+ }
170
+ exports.embeddingToFloat32 = embeddingToFloat32;
171
+ function closenessFromDot(dot) {
172
+ // Inputs are unit vectors, so euclidean^2 = 2 - 2*dot; clamp away tiny negatives from float error.
173
+ return 1 - Math.sqrt(Math.max(0, 2 - 2 * dot));
174
+ }
175
+ function dotFloat32(a, b) {
176
+ let length = Math.min(a.length, b.length);
177
+ let dot = 0;
178
+ for (let index = 0; index < length; index++) {
179
+ dot += a[index] * b[index];
180
+ }
181
+ return dot;
182
+ }
183
+ // Closeness = 1 - euclidean distance of two unit vectors. Always decode both to (pooled) float32 and dot:
184
+ // simple, and once the decodes are pooled it's the fastest per-call path. Batch callers (k-means) decode
185
+ // every vector once themselves instead of going through here.
186
+ exports.getCloseness = (0, measure_1.measureWrap)(function getCloseness(a, b) {
187
+ let va = embeddingToFloat32(a, true);
188
+ let vb = embeddingToFloat32(b, true);
189
+ let result = closenessFromDot(dotFloat32(va, vb));
190
+ releaseFloat32(va);
191
+ releaseFloat32(vb);
192
+ return result;
193
+ });
194
+ // Encode a vector (or re-encode an embedding) into the requested format. This is THE place we normalize:
195
+ // the (truncated) vector is made unit length here, so anything that's been encoded is reliably normalized
196
+ // and the comparison/decoding paths never have to re-normalize.
197
+ function encodeEmbedding(config) {
198
+ let { input, format, model } = config;
199
+ let formatConfig = FORMAT_CONFIGS[format];
200
+ let decoded = embeddingToFloat32(input, true);
201
+ let length = decoded.length;
202
+ if (formatConfig.truncation !== undefined && formatConfig.truncation < length) {
203
+ length = formatConfig.truncation;
204
+ }
205
+ let norm = 0;
206
+ for (let index = 0; index < length; index++) {
207
+ norm += decoded[index] * decoded[index];
208
+ }
209
+ let magnitude = Math.sqrt(norm) || 1;
210
+ for (let index = 0; index < length; index++) {
211
+ decoded[index] /= magnitude;
212
+ }
213
+ let result;
214
+ if (!formatConfig.quant) {
215
+ result = { kind: "float32", model, values: new Float32Array(decoded.subarray(0, length)) };
216
+ }
217
+ else {
218
+ let { type, groupSize } = formatConfig.quant;
219
+ let groupCount = Math.ceil(length / groupSize);
220
+ let int8 = new Int8Array(length);
221
+ let scales = new Float32Array(groupCount);
222
+ for (let group = 0; group < groupCount; group++) {
223
+ let start = group * groupSize;
224
+ let end = Math.min(start + groupSize, length);
225
+ let maxAbs = 0;
226
+ for (let index = start; index < end; index++) {
227
+ let absValue = Math.abs(decoded[index]);
228
+ if (absValue > maxAbs)
229
+ maxAbs = absValue;
230
+ }
231
+ let scale = maxAbs / INT8_MAX;
232
+ scales[group] = scale;
233
+ if (!scale)
234
+ continue;
235
+ for (let index = start; index < end; index++) {
236
+ let quantized = Math.round(decoded[index] / scale);
237
+ if (quantized > INT8_MAX)
238
+ quantized = INT8_MAX;
239
+ if (quantized < -INT8_MAX)
240
+ quantized = -INT8_MAX;
241
+ int8[index] = quantized;
242
+ }
243
+ }
244
+ result = {
245
+ kind: "quant",
246
+ model,
247
+ type,
248
+ groupSize,
249
+ data: new Uint8Array(int8.buffer, int8.byteOffset, int8.byteLength),
250
+ scales: encodeFloat16(scales),
251
+ };
252
+ }
253
+ releaseFloat32(decoded);
254
+ return result;
255
+ }
256
+ exports.encodeEmbedding = encodeEmbedding;
257
+ // Serialize to base64 so a StoredEmbedding can travel through the (string) API call result. Layout:
258
+ // [4-byte little-endian header length][JSON header][raw typed-array payload(s)].
259
+ function serializeStoredEmbedding(stored) {
260
+ let header;
261
+ let payload;
262
+ if (stored.kind === "float32") {
263
+ header = { kind: "float32", model: stored.model };
264
+ payload = [new Uint8Array(stored.values.buffer, stored.values.byteOffset, stored.values.byteLength)];
265
+ }
266
+ else {
267
+ header = { kind: "quant", model: stored.model, type: stored.type, groupSize: stored.groupSize, dataBytes: stored.data.byteLength };
268
+ payload = [stored.data, stored.scales];
269
+ }
270
+ let headerBytes = Buffer.from(JSON.stringify(header), "utf8");
271
+ let headerLength = Buffer.alloc(4);
272
+ headerLength.writeUInt32LE(headerBytes.length, 0);
273
+ return Buffer.concat([headerLength, headerBytes, ...payload.map(buffers_1.asBuffer)]).toString("base64");
274
+ }
275
+ exports.serializeStoredEmbedding = serializeStoredEmbedding;
276
+ function deserializeStoredEmbedding(base64) {
277
+ let buffer = Buffer.from(base64, "base64");
278
+ if (buffer.length < 4) {
279
+ throw new Error(`Serialized embedding is too short (${buffer.length} bytes): ${base64.slice(0, 200)}`);
280
+ }
281
+ let headerLength = buffer.readUInt32LE(0);
282
+ let headerEnd = 4 + headerLength;
283
+ if (headerLength <= 0 || headerEnd > buffer.length) {
284
+ throw new Error(`Serialized embedding header length ${headerLength} is invalid for ${buffer.length} bytes: ${base64.slice(0, 200)}`);
285
+ }
286
+ let header = JSON.parse(buffer.toString("utf8", 4, headerEnd));
287
+ let payload = buffer.subarray(headerEnd);
288
+ if (header.kind === "float32") {
289
+ return { kind: "float32", model: header.model, values: (0, buffers_1.asFloat32)((0, buffers_1.asBuffer)(Uint8Array.from(payload))) };
290
+ }
291
+ return {
292
+ kind: "quant",
293
+ model: header.model,
294
+ type: header.type,
295
+ groupSize: header.groupSize,
296
+ data: Uint8Array.from(payload.subarray(0, header.dataBytes)),
297
+ scales: Uint8Array.from(payload.subarray(header.dataBytes)),
298
+ };
299
+ }
300
+ exports.deserializeStoredEmbedding = deserializeStoredEmbedding;
301
+ // Mean of several embeddings (encodeEmbedding normalizes the result to a unit centroid). Borrows a pooled
302
+ // accumulator.
303
+ function averageEmbeddings(embeddings, config) {
304
+ let length = Infinity;
305
+ for (let embedding of embeddings) {
306
+ length = Math.min(length, embeddingLength(embedding));
307
+ }
308
+ let sum = acquireFloat32(length);
309
+ sum.fill(0);
310
+ for (let embedding of embeddings) {
311
+ let vector = embeddingToFloat32(embedding, true);
312
+ for (let dimension = 0; dimension < length; dimension++) {
313
+ sum[dimension] += vector[dimension];
314
+ }
315
+ releaseFloat32(vector);
316
+ }
317
+ let result = encodeEmbedding({ input: sum.subarray(0, length), format: config.format, model: config.model });
318
+ releaseFloat32(sum);
319
+ return result;
320
+ }
321
+ exports.averageEmbeddings = averageEmbeddings;
322
+ // A stable 16-byte (base64) content hash of an embedding's values, for use as a cell id derived from its
323
+ // centroid. Iterates via the accessor (the value bits are hashed, so any format hashes consistently).
324
+ function hashEmbedding(stored) {
325
+ let vector = embeddingToFloat32(stored, true);
326
+ let length = vector.length;
327
+ let lanes = new Uint32Array([2166136261, 2654435761, 40503, 3266489917]);
328
+ for (let index = 0; index < length; index++) {
329
+ f32Scratch[0] = vector[index];
330
+ let bits = i32Scratch[0];
331
+ for (let lane = 0; lane < lanes.length; lane++) {
332
+ lanes[lane] = Math.imul(lanes[lane] ^ (bits + lane * 131 + index), 16777619);
333
+ }
334
+ }
335
+ releaseFloat32(vector);
336
+ return Buffer.from(lanes.buffer).toString("base64");
337
+ }
338
+ exports.hashEmbedding = hashEmbedding;
339
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1iZWRkaW5nRm9ybWF0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImVtYmVkZGluZ0Zvcm1hdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUVBQW9FO0FBQ3BFLHlEQUFrRTtBQU9yRCxRQUFBLGlCQUFpQixHQUFzQixDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQzlGLFFBQUEsd0JBQXdCLEdBQW9CLFdBQVcsQ0FBQztBQUtyRSxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUM7QUFRckIsTUFBTSxjQUFjLEdBQWtEO0lBQ2xFLFNBQVMsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDcEUsV0FBVyxFQUFFLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsRUFBRTtJQUN2RSxXQUFXLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFO0lBQ3ZFLE9BQU8sRUFBRSxFQUFFO0NBQ2QsQ0FBQztBQWlDRixNQUFNLGdCQUFnQixHQUFJLFVBQXlELENBQUMsWUFBWSxDQUFDO0FBRWpHLE1BQU0sVUFBVSxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNyRCxTQUFTLFdBQVcsQ0FBQyxLQUFhO0lBQzlCLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDdEIsSUFBSSxNQUFNLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FB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Q0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNqRixDQUFDO0lBQ0wsQ0FBQztJQUNELGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN2QixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUN4RCxDQUFDO0FBYkQsc0NBYUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBtZWFzdXJlV3JhcCB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL3Byb2ZpbGluZy9tZWFzdXJlXCI7XG5pbXBvcnQgeyBhc0J1ZmZlciwgYXNGbG9hdDMyIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvYnVmZmVyc1wiO1xuXG4vLyBUaGUgZm9ybWF0cyBhbiBlbWJlZGRpbmcgY2FuIGJlIHN0b3JlZCAmIGNvbXBhcmVkIGluLiBUaGUgdHJhaWxpbmcgbnVtYmVyIGlzIHRoZSBNYXRyeW9zaGthXG4vLyB0cnVuY2F0aW9uIGxlbmd0aCAodGhlIGNvdW50IG9mIGxlYWRpbmcgZGltZW5zaW9ucyBrZXB0KS4gXCJxOGdOXCIgbWVhbnMgc2lnbmVkIGludDggdmFsdWVzIHdpdGhcbi8vIG9uZSBzY2FsZSBzaGFyZWQgYWNyb3NzIGV2ZXJ5IE4gZGltZW5zaW9ucy4gXCJmbG9hdDMyXCIga2VlcHMgdGhlIHJhdyAodHJ1bmNhdGVkKSB2ZWN0b3IuXG5leHBvcnQgdHlwZSBFbWJlZGRpbmdGb3JtYXQgPSBcInE4ZzhfMjA0OFwiIHwgXCJxOF9nMTZfMjA0OFwiIHwgXCJxOF9nMTZfMTAyNFwiIHwgXCJmbG9hdDMyXCI7XG5cbmV4cG9ydCBjb25zdCBFTUJFRERJTkdfRk9STUFUUzogRW1iZWRkaW5nRm9ybWF0W10gPSBbXCJxOGc4XzIwNDhcIiwgXCJxOF9nMTZfMjA0OFwiLCBcInE4X2cxNl8xMDI0XCIsIFwiZmxvYXQzMlwiXTtcbmV4cG9ydCBjb25zdCBERUZBVUxUX0VNQkVERElOR19GT1JNQVQ6IEVtYmVkZGluZ0Zvcm1hdCA9IFwicThnOF8yMDQ4XCI7XG5cbi8vIFRoZSBvbmx5IGVsZW1lbnQgcXVhbnRpemF0aW9uIHdlIHN1cHBvcnQgcmlnaHQgbm93IChzaWduZWQgaW50OCwgdmFsdWVzIGluIFstMTI3LCAxMjddKS5cbmV4cG9ydCB0eXBlIFF1YW50VHlwZSA9IFwicThcIjtcblxuY29uc3QgSU5UOF9NQVggPSAxMjc7XG5cbnR5cGUgRm9ybWF0Q29uZmlnID0ge1xuICAgIC8vIExlYWRpbmcgZGltZW5zaW9ucyBrZXB0LiB1bmRlZmluZWQga2VlcHMgdGhlIGZ1bGwgdmVjdG9yLlxuICAgIHRydW5jYXRpb24/OiBudW1iZXI7XG4gICAgLy8gaW50OCBncm91cCBxdWFudGl6YXRpb24gcGFyYW1ldGVycy4gdW5kZWZpbmVkIHN0b3JlcyB0aGUgcmF3IGZsb2F0MzIgdmVjdG9yLlxuICAgIHF1YW50PzogeyB0eXBlOiBRdWFudFR5cGU7IGdyb3VwU2l6ZTogbnVtYmVyIH07XG59O1xuY29uc3QgRk9STUFUX0NPTkZJR1M6IHsgW2Zvcm1hdCBpbiBFbWJlZGRpbmdGb3JtYXRdOiBGb3JtYXRDb25maWcgfSA9IHtcbiAgICBxOGc4XzIwNDg6IHsgdHJ1bmNhdGlvbjogMjA0OCwgcXVhbnQ6IHsgdHlwZTogXCJxOFwiLCBncm91cFNpemU6IDggfSB9LFxuICAgIHE4X2cxNl8yMDQ4OiB7IHRydW5jYXRpb246IDIwNDgsIHF1YW50OiB7IHR5cGU6IFwicThcIiwgZ3JvdXBTaXplOiAxNiB9IH0sXG4gICAgcThfZzE2XzEwMjQ6IHsgdHJ1bmNhdGlvbjogMTAyNCwgcXVhbnQ6IHsgdHlwZTogXCJxOFwiLCBncm91cFNpemU6IDE2IH0gfSxcbiAgICBmbG9hdDMyOiB7fSxcbn07XG5cbmV4cG9ydCB0eXBlIFN0b3JlZEVtYmVkZGluZyA9IHtcbiAgICBraW5kOiBcImZsb2F0MzJcIjtcbiAgICBtb2RlbDogc3RyaW5nO1xuICAgIHZhbHVlczogRmxvYXQzMkFycmF5O1xufSB8IHtcbiAgICBraW5kOiBcInF1YW50XCI7XG4gICAgbW9kZWw6IHN0cmluZztcbiAgICAvLyBFbGVtZW50IHF1YW50aXphdGlvbi4gXCJxOFwiIGlzIHNpZ25lZCBpbnQ4ICh2YWx1ZXMgaW4gWy0xMjcsIDEyN10pLlxuICAgIHR5cGU6IFF1YW50VHlwZTtcbiAgICAvLyBOdW1iZXIgb2YgY29uc2VjdXRpdmUgZGltZW5zaW9ucyBzaGFyaW5nIG9uZSBzY2FsZS5cbiAgICBncm91cFNpemU6IG51bWJlcjtcbiAgICAvLyBpbnQ4IHZhbHVlcyAob25lIHBlciBrZXB0IGRpbWVuc2lvbiksIHJlaW50ZXJwcmV0ZWQgYXMgcmF3IGJ5dGVzLlxuICAgIGRhdGE6IFVpbnQ4QXJyYXk7XG4gICAgLy8gZmxvYXQxNiBzY2FsZXMgKG9uZSBwZXIgZ3JvdXApLCByZWludGVycHJldGVkIGFzIHJhdyBieXRlcy5cbiAgICBzY2FsZXM6IFVpbnQ4QXJyYXk7XG59O1xuXG4vLyBGbG9hdDE2QXJyYXkgaXNuJ3QgaW4gb3VyIFR5cGVTY3JpcHQgbGliIGFuZCBpc24ndCBndWFyYW50ZWVkIGF0IHJ1bnRpbWUsIHNvIHdlIHJlYWQgaXQgb2ZmXG4vLyBnbG9iYWxUaGlzIGFuZCBmYWxsIGJhY2sgdG8gYSBtYW51YWwgaGFsZjwtPmZsb2F0IGNvbnZlcnNpb24gd2hlbiBpdCdzIG1pc3NpbmcuXG5pbnRlcmZhY2UgRmxvYXQxNkFycmF5TGlrZSB7XG4gICAgcmVhZG9ubHkgbGVuZ3RoOiBudW1iZXI7XG4gICAgW2luZGV4OiBudW1iZXJdOiBudW1iZXI7XG4gICAgcmVhZG9ubHkgYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2U7XG4gICAgcmVhZG9ubHkgYnl0ZU9mZnNldDogbnVtYmVyO1xuICAgIHJlYWRvbmx5IGJ5dGVMZW5ndGg6IG51bWJlcjtcbn1cbmludGVyZmFjZSBGbG9hdDE2QXJyYXlDb25zdHJ1Y3RvciB7XG4gICAgbmV3KGxlbmd0aDogbnVtYmVyKTogRmxvYXQxNkFycmF5TGlrZTtcbiAgICBuZXcoZWxlbWVudHM6IEFycmF5TGlrZTxudW1iZXI+KTogRmxvYXQxNkFycmF5TGlrZTtcbiAgICBuZXcoYnVmZmVyOiBBcnJheUJ1ZmZlckxpa2UsIGJ5dGVPZmZzZXQ/OiBudW1iZXIsIGxlbmd0aD86IG51bWJlcik6IEZsb2F0MTZBcnJheUxpa2U7XG59XG5jb25zdCBGbG9hdDE2QXJyYXlDdG9yID0gKGdsb2JhbFRoaXMgYXMgeyBGbG9hdDE2QXJyYXk/OiBGbG9hdDE2QXJyYXlDb25zdHJ1Y3RvciB9KS5GbG9hdDE2QXJyYXk7XG5cbmNvbnN0IGYzMlNjcmF0Y2ggPSBuZXcgRmxvYXQzMkFycmF5KDEpO1xuY29uc3QgaTMyU2NyYXRjaCA9IG5ldyBJbnQzMkFycmF5KGYzMlNjcmF0Y2guYnVmZmVyKTtcbmZ1bmN0aW9uIGZsb2F0VG9IYWxmKHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGYzMlNjcmF0Y2hbMF0gPSB2YWx1ZTtcbiAgICBsZXQgYml0c0luID0gaTMyU2NyYXRjaFswXTtcbiAgICBsZXQgYml0cyA9IChiaXRzSW4gPj4gMTYpICYgMHg4MDAwO1xuICAgIGxldCBtYW50aXNzYSA9IChiaXRzSW4gPj4gMTIpICYgMHgwN2ZmO1xuICAgIGxldCBleHBvbmVudCA9IChiaXRzSW4gPj4gMjMpICYgMHhmZjtcbiAgICBpZiAoZXhwb25lbnQgPCAxMDMpIHJldHVybiBiaXRzO1xuICAgIGlmIChleHBvbmVudCA+IDE0Mikge1xuICAgICAgICBiaXRzIHw9IDB4N2MwMDtcbiAgICAgICAgaWYgKGV4cG9uZW50ICE9PSAyNTUpIHtcbiAgICAgICAgICAgIGJpdHMgfD0gKGJpdHNJbiAmIDB4MDA3ZmZmZmYpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiaXRzO1xuICAgIH1cbiAgICBpZiAoZXhwb25lbnQgPCAxMTMpIHtcbiAgICAgICAgbWFudGlzc2EgfD0gMHgwODAwO1xuICAgICAgICBiaXRzIHw9IChtYW50aXNzYSA+PiAoMTE0IC0gZXhwb25lbnQpKSArICgobWFudGlzc2EgPj4gKDExMyAtIGV4cG9uZW50KSkgJiAxKTtcbiAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgfVxuICAgIGJpdHMgfD0gKChleHBvbmVudCAtIDExMikgPDwgMTApIHwgKG1hbnRpc3NhID4+IDEpO1xuICAgIGJpdHMgKz0gbWFudGlzc2EgJiAxO1xuICAgIHJldHVybiBiaXRzO1xufVxuZnVuY3Rpb24gaGFsZlRvRmxvYXQoaGFsZjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgc2lnbiA9IChoYWxmICYgMHg4MDAwKSA+PiAxNTtcbiAgICBsZXQgZXhwb25lbnQgPSAoaGFsZiAmIDB4N2MwMCkgPj4gMTA7XG4gICAgbGV0IGZyYWN0aW9uID0gaGFsZiAmIDB4MDNmZjtcbiAgICBsZXQgc2lnbk11bHRpcGxpZXIgPSBzaWduICYmIC0xIHx8IDE7XG4gICAgaWYgKGV4cG9uZW50ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBzaWduTXVsdGlwbGllciAqIE1hdGgucG93KDIsIC0xNCkgKiAoZnJhY3Rpb24gLyAxMDI0KTtcbiAgICB9XG4gICAgaWYgKGV4cG9uZW50ID09PSAweDFmKSB7XG4gICAgICAgIGlmIChmcmFjdGlvbikgcmV0dXJuIE5hTjtcbiAgICAgICAgcmV0dXJuIHNpZ25NdWx0aXBsaWVyICogSW5maW5pdHk7XG4gICAgfVxuICAgIHJldHVybiBzaWduTXVsdGlwbGllciAqIE1hdGgucG93KDIsIGV4cG9uZW50IC0gMTUpICogKDEgKyBmcmFjdGlvbiAvIDEwMjQpO1xufVxuXG5mdW5jdGlvbiBhc0ludDgoYnl0ZXM6IFVpbnQ4QXJyYXkpOiBJbnQ4QXJyYXkge1xuICAgIHJldHVybiBuZXcgSW50OEFycmF5KGJ5dGVzLmJ1ZmZlciwgYnl0ZXMuYnl0ZU9mZnNldCwgYnl0ZXMuYnl0ZUxlbmd0aCk7XG59XG5mdW5jdGlvbiBlbmNvZGVGbG9hdDE2KHZhbHVlczogRmxvYXQzMkFycmF5KTogVWludDhBcnJheSB7XG4gICAgaWYgKEZsb2F0MTZBcnJheUN0b3IpIHtcbiAgICAgICAgbGV0IGhhbGYgPSBuZXcgRmxvYXQxNkFycmF5Q3Rvcih2YWx1ZXMpO1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoaGFsZi5idWZmZXIsIGhhbGYuYnl0ZU9mZnNldCwgaGFsZi5ieXRlTGVuZ3RoKTtcbiAgICB9XG4gICAgbGV0IG91dCA9IG5ldyBVaW50OEFycmF5KHZhbHVlcy5sZW5ndGggKiAyKTtcbiAgICBsZXQgdmlldyA9IG5ldyBEYXRhVmlldyhvdXQuYnVmZmVyKTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdmFsdWVzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICB2aWV3LnNldFVpbnQxNihpbmRleCAqIDIsIGZsb2F0VG9IYWxmKHZhbHVlc1tpbmRleF0pLCB0cnVlKTtcbiAgICB9XG4gICAgcmV0dXJuIG91dDtcbn1cbmZ1bmN0aW9uIGFzRmxvYXQxNkluZGV4YWJsZShieXRlczogVWludDhBcnJheSk6IHsgcmVhZG9ubHkgbGVuZ3RoOiBudW1iZXI7W2luZGV4OiBudW1iZXJdOiBudW1iZXIgfSB7XG4gICAgLy8gRmxvYXQxNkFycmF5IC8gVWludDE2QXJyYXkgdmlld3MgcmVxdWlyZSAyLWJ5dGUgYWxpZ25tZW50OyBjb3B5IHdoZW4gdGhlIHN0b3JlZCBieXRlcyBhcmVuJ3QuXG4gICAgaWYgKGJ5dGVzLmJ5dGVPZmZzZXQgJSAyICE9PSAwKSB7XG4gICAgICAgIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMpO1xuICAgIH1cbiAgICBsZXQgY291bnQgPSBNYXRoLmZsb29yKGJ5dGVzLmJ5dGVMZW5ndGggLyAyKTtcbiAgICBpZiAoRmxvYXQxNkFycmF5Q3Rvcikge1xuICAgICAgICByZXR1cm4gbmV3IEZsb2F0MTZBcnJheUN0b3IoYnl0ZXMuYnVmZmVyLCBieXRlcy5ieXRlT2Zmc2V0LCBjb3VudCk7XG4gICAgfVxuICAgIGxldCBoYWx2ZXMgPSBuZXcgVWludDE2QXJyYXkoYnl0ZXMuYnVmZmVyLCBieXRlcy5ieXRlT2Zmc2V0LCBjb3VudCk7XG4gICAgbGV0IG91dCA9IG5ldyBGbG9hdDMyQXJyYXkoY291bnQpO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjb3VudDsgaW5kZXgrKykge1xuICAgICAgICBvdXRbaW5kZXhdID0gaGFsZlRvRmxvYXQoaGFsdmVzW2luZGV4XSk7XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbWJlZGRpbmdMZW5ndGgoaW5wdXQ6IEZsb2F0MzJBcnJheSB8IFN0b3JlZEVtYmVkZGluZyk6IG51bWJlciB7XG4gICAgaWYgKGlucHV0IGluc3RhbmNlb2YgRmxvYXQzMkFycmF5KSByZXR1cm4gaW5wdXQubGVuZ3RoO1xuICAgIGlmIChpbnB1dC5raW5kID09PSBcImZsb2F0MzJcIikgcmV0dXJuIGlucHV0LnZhbHVlcy5sZW5ndGg7XG4gICAgcmV0dXJuIGlucHV0LmRhdGEubGVuZ3RoO1xufVxuXG4vLyBBIHBvb2wgb2YgcmV1c2FibGUgRmxvYXQzMiBidWZmZXJzIGtleWVkIGJ5IGxlbmd0aC4gTW9zdCBlbWJlZGRpbmdzIHNoYXJlIGEgc2l6ZSwgc28gaW50ZXJuYWwgaG90IHBhdGhzXG4vLyBib3Jyb3cgYSBidWZmZXIgKGVtYmVkZGluZ1RvRmxvYXQzMiB3aXRoIHVzZVBvb2wpIGFuZCByZXR1cm4gaXQgKHJlbGVhc2VGbG9hdDMyKSB0byBhdm9pZCBwZXItb3Bcbi8vIGFsbG9jYXRpb25zIGFuZCBHQyB0aHJhc2hpbmcuIEEgYm9ycm93ZWQgYnVmZmVyIGhvbGRzIHN0YWxlIGRhdGE7IHdob2V2ZXIgYm9ycm93cyBpdCBvdmVyd3JpdGVzIGl0IGZ1bGx5LlxuLy9cbi8vIEVhY2ggZnJlZSBidWZmZXIgcmVjb3JkcyB3aGVuIGl0IHdhcyBsYXN0IHJlbGVhc2VkOyBhbiBob3VybHkgc3dlZXAgZHJvcHMgYW55IHRoYXQgaGF2ZSBzYXQgaWRsZSBmb3Igb3ZlclxuLy8gYW4gaG91ciwgc28gdGhlIHJ1bnRpbWUgY2FuIGZyZWUgYnVmZmVycyBhIGJ1cnN0IG9mIHdvcmsgYWxsb2NhdGVkIGJ1dCBpc24ndCBhY3R1YWxseSByZXVzaW5nIGFueW1vcmUuXG5jb25zdCBQT09MX01BWF9JRExFX01TID0gNjAgKiA2MCAqIDEwMDA7XG50eXBlIFBvb2xlZEZsb2F0MzIgPSB7IGJ1ZmZlcjogRmxvYXQzMkFycmF5OyByZWxlYXNlZEF0OiBudW1iZXIgfTtcbmNvbnN0IGZsb2F0MzJQb29sID0gbmV3IE1hcDxudW1iZXIsIFBvb2xlZEZsb2F0MzJbXT4oKTtcbmZ1bmN0aW9uIGFjcXVpcmVGbG9hdDMyKGxlbmd0aDogbnVtYmVyKTogRmxvYXQzMkFycmF5IHtcbiAgICBsZXQgZnJlZSA9IGZsb2F0MzJQb29sLmdldChsZW5ndGgpO1xuICAgIGlmIChmcmVlICYmIGZyZWUubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmcmVlLnBvcCgpIS5idWZmZXI7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7XG59XG5leHBvcnQgZnVuY3Rpb24gcmVsZWFzZUZsb2F0MzIoYnVmZmVyOiBGbG9hdDMyQXJyYXkpOiB2b2lkIHtcbiAgICBsZXQgZnJlZSA9IGZsb2F0MzJQb29sLmdldChidWZmZXIubGVuZ3RoKTtcbiAgICBpZiAoIWZyZWUpIHtcbiAgICAgICAgZnJlZSA9IFtdO1xuICAgICAgICBmbG9hdDMyUG9vbC5zZXQoYnVmZmVyLmxlbmd0aCwgZnJlZSk7XG4gICAgfVxuICAgIGZyZWUucHVzaCh7IGJ1ZmZlciwgcmVsZWFzZWRBdDogRGF0ZS5ub3coKSB9KTtcbn1cbmZ1bmN0aW9uIHN3ZWVwRmxvYXQzMlBvb2woKTogdm9pZCB7XG4gICAgbGV0IGN1dG9mZiA9IERhdGUubm93KCkgLSBQT09MX01BWF9JRExFX01TO1xuICAgIGZvciAobGV0IGZyZWUgb2YgZmxvYXQzMlBvb2wudmFsdWVzKCkpIHtcbiAgICAgICAgbGV0IHdyaXRlSW5kZXggPSAwO1xuICAgICAgICBmb3IgKGxldCByZWFkSW5kZXggPSAwOyByZWFkSW5kZXggPCBmcmVlLmxlbmd0aDsgcmVhZEluZGV4KyspIHtcbiAgICAgICAgICAgIGlmIChmcmVlW3JlYWRJbmRleF0ucmVsZWFzZWRBdCA+IGN1dG9mZikge1xuICAgICAgICAgICAgICAgIGZyZWVbd3JpdGVJbmRleCsrXSA9IGZyZWVbcmVhZEluZGV4XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmcmVlLmxlbmd0aCA9IHdyaXRlSW5kZXg7XG4gICAgfVxufVxuY29uc3QgcG9vbFN3ZWVwVGltZXIgPSBzZXRJbnRlcnZhbChzd2VlcEZsb2F0MzJQb29sLCBQT09MX01BWF9JRExFX01TKSBhcyB1bmtub3duIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH07XG5pZiAodHlwZW9mIHBvb2xTd2VlcFRpbWVyLnVucmVmID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICBwb29sU3dlZXBUaW1lci51bnJlZigpO1xufVxuXG4vLyBEZWNvZGUgdG8gYSBGbG9hdDMyQXJyYXkgKGZ1bGwgbGVuZ3RoKS4gU3RvcmVkIHZhbHVlcyBhcmUgYWxyZWFkeSB1bml0LW5vcm1hbGl6ZWQgKGVuY29kZUVtYmVkZGluZyBkb2VzXG4vLyB0aGF0KSwgc28gdGhpcyBvbmx5IGRlLXF1YW50aXplcy4gQnkgZGVmYXVsdCBpdCBhbGxvY2F0ZXMgYSBmcmVzaCBhcnJheSAoYSBmbG9hdCBpbnB1dCBpcyByZXR1cm5lZCBhcy1pcyxcbi8vIG5vIGNvcHkpLiBXaXRoIHVzZVBvb2wgaXQgYm9ycm93cyBhIHBvb2xlZCBidWZmZXIgdGhlIGNhbGxlciBtdXN0IHJlbGVhc2VGbG9hdDMyIOKAlCB1c2VkIGJ5IGhvdCBpbnRlcm5hbFxuLy8gcGF0aHMgc28gcmVwZWF0ZWQgZGVjb2RlcyBkb24ndCBhbGxvY2F0ZS5cbmV4cG9ydCBmdW5jdGlvbiBlbWJlZGRpbmdUb0Zsb2F0MzIoaW5wdXQ6IEZsb2F0MzJBcnJheSB8IFN0b3JlZEVtYmVkZGluZywgdXNlUG9vbCA9IGZhbHNlKTogRmxvYXQzMkFycmF5IHtcbiAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkpIHtcbiAgICAgICAgaWYgKCF1c2VQb29sKSByZXR1cm4gaW5wdXQ7XG4gICAgICAgIGxldCBvdXQgPSBhY3F1aXJlRmxvYXQzMihpbnB1dC5sZW5ndGgpO1xuICAgICAgICBvdXQuc2V0KGlucHV0KTtcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG4gICAgaWYgKGlucHV0LmtpbmQgPT09IFwiZmxvYXQzMlwiKSB7XG4gICAgICAgIGlmICghdXNlUG9vbCkgcmV0dXJuIGlucHV0LnZhbHVlcztcbiAgICAgICAgbGV0IG91dCA9IGFjcXVpcmVGbG9hdDMyKGlucHV0LnZhbHVlcy5sZW5ndGgpO1xuICAgICAgICBvdXQuc2V0KGlucHV0LnZhbHVlcyk7XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuICAgIGxldCBpbnQ4ID0gYXNJbnQ4KGlucHV0LmRhdGEpO1xuICAgIGxldCBzY2FsZXMgPSBhc0Zsb2F0MTZJbmRleGFibGUoaW5wdXQuc2NhbGVzKTtcbiAgICBsZXQgZ3JvdXBTaXplID0gaW5wdXQuZ3JvdXBTaXplO1xuICAgIGxldCBsZW5ndGggPSBpbnQ4Lmxlbmd0aDtcbiAgICBsZXQgb3V0ID0gdXNlUG9vbCA/IGFjcXVpcmVGbG9hdDMyKGxlbmd0aCkgOiBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7XG4gICAgbGV0IGdyb3VwID0gMDtcbiAgICBmb3IgKGxldCBzdGFydCA9IDA7IHN0YXJ0IDwgbGVuZ3RoOyBzdGFydCArPSBncm91cFNpemUpIHtcbiAgICAgICAgbGV0IHNjYWxlID0gc2NhbGVzW2dyb3VwKytdO1xuICAgICAgICBsZXQgZW5kID0gTWF0aC5taW4oc3RhcnQgKyBncm91cFNpemUsIGxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gc3RhcnQ7IGluZGV4IDwgZW5kOyBpbmRleCsrKSB7XG4gICAgICAgICAgICBvdXRbaW5kZXhdID0gaW50OFtpbmRleF0gKiBzY2FsZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb3V0O1xufVxuXG5mdW5jdGlvbiBjbG9zZW5lc3NGcm9tRG90KGRvdDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAvLyBJbnB1dHMgYXJlIHVuaXQgdmVjdG9ycywgc28gZXVjbGlkZWFuXjIgPSAyIC0gMipkb3Q7IGNsYW1wIGF3YXkgdGlueSBuZWdhdGl2ZXMgZnJvbSBmbG9hdCBlcnJvci5cbiAgICByZXR1cm4gMSAtIE1hdGguc3FydChNYXRoLm1heCgwLCAyIC0gMiAqIGRvdCkpO1xufVxuXG5mdW5jdGlvbiBkb3RGbG9hdDMyKGE6IEZsb2F0MzJBcnJheSwgYjogRmxvYXQzMkFycmF5KTogbnVtYmVyIHtcbiAgICBsZXQgbGVuZ3RoID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKTtcbiAgICBsZXQgZG90ID0gMDtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIGRvdCArPSBhW2luZGV4XSAqIGJbaW5kZXhdO1xuICAgIH1cbiAgICByZXR1cm4gZG90O1xufVxuXG4vLyBDbG9zZW5lc3MgPSAxIC0gZXVjbGlkZWFuIGRpc3RhbmNlIG9mIHR3byB1bml0IHZlY3RvcnMuIEFsd2F5cyBkZWNvZGUgYm90aCB0byAocG9vbGVkKSBmbG9hdDMyIGFuZCBkb3Q6XG4vLyBzaW1wbGUsIGFuZCBvbmNlIHRoZSBkZWNvZGVzIGFyZSBwb29sZWQgaXQncyB0aGUgZmFzdGVzdCBwZXItY2FsbCBwYXRoLiBCYXRjaCBjYWxsZXJzIChrLW1lYW5zKSBkZWNvZGVcbi8vIGV2ZXJ5IHZlY3RvciBvbmNlIHRoZW1zZWx2ZXMgaW5zdGVhZCBvZiBnb2luZyB0aHJvdWdoIGhlcmUuXG5leHBvcnQgY29uc3QgZ2V0Q2xvc2VuZXNzID0gbWVhc3VyZVdyYXAoZnVuY3Rpb24gZ2V0Q2xvc2VuZXNzKGE6IEZsb2F0MzJBcnJheSB8IFN0b3JlZEVtYmVkZGluZywgYjogRmxvYXQzMkFycmF5IHwgU3RvcmVkRW1iZWRkaW5nKTogbnVtYmVyIHtcbiAgICBsZXQgdmEgPSBlbWJlZGRpbmdUb0Zsb2F0MzIoYSwgdHJ1ZSk7XG4gICAgbGV0IHZiID0gZW1iZWRkaW5nVG9GbG9hdDMyKGIsIHRydWUpO1xuICAgIGxldCByZXN1bHQgPSBjbG9zZW5lc3NGcm9tRG90KGRvdEZsb2F0MzIodmEsIHZiKSk7XG4gICAgcmVsZWFzZUZsb2F0MzIodmEpO1xuICAgIHJlbGVhc2VGbG9hdDMyKHZiKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufSk7XG5cbi8vIEVuY29kZSBhIHZlY3RvciAob3IgcmUtZW5jb2RlIGFuIGVtYmVkZGluZykgaW50byB0aGUgcmVxdWVzdGVkIGZvcm1hdC4gVGhpcyBpcyBUSEUgcGxhY2Ugd2Ugbm9ybWFsaXplOlxuLy8gdGhlICh0cnVuY2F0ZWQpIHZlY3RvciBpcyBtYWRlIHVuaXQgbGVuZ3RoIGhlcmUsIHNvIGFueXRoaW5nIHRoYXQncyBiZWVuIGVuY29kZWQgaXMgcmVsaWFibHkgbm9ybWFsaXplZFxuLy8gYW5kIHRoZSBjb21wYXJpc29uL2RlY29kaW5nIHBhdGhzIG5ldmVyIGhhdmUgdG8gcmUtbm9ybWFsaXplLlxuZXhwb3J0IGZ1bmN0aW9uIGVuY29kZUVtYmVkZGluZyhjb25maWc6IHtcbiAgICBpbnB1dDogRmxvYXQzMkFycmF5IHwgU3RvcmVkRW1iZWRkaW5nO1xuICAgIGZvcm1hdDogRW1iZWRkaW5nRm9ybWF0O1xuICAgIG1vZGVsOiBzdHJpbmc7XG59KTogU3RvcmVkRW1iZWRkaW5nIHtcbiAgICBsZXQgeyBpbnB1dCwgZm9ybWF0LCBtb2RlbCB9ID0gY29uZmlnO1xuICAgIGxldCBmb3JtYXRDb25maWcgPSBGT1JNQVRfQ09ORklHU1tmb3JtYXRdO1xuICAgIGxldCBkZWNvZGVkID0gZW1iZWRkaW5nVG9GbG9hdDMyKGlucHV0LCB0cnVlKTtcbiAgICBsZXQgbGVuZ3RoID0gZGVjb2RlZC5sZW5ndGg7XG4gICAgaWYgKGZvcm1hdENvbmZpZy50cnVuY2F0aW9uICE9PSB1bmRlZmluZWQgJiYgZm9ybWF0Q29uZmlnLnRydW5jYXRpb24gPCBsZW5ndGgpIHtcbiAgICAgICAgbGVuZ3RoID0gZm9ybWF0Q29uZmlnLnRydW5jYXRpb247XG4gICAgfVxuICAgIGxldCBub3JtID0gMDtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIG5vcm0gKz0gZGVjb2RlZFtpbmRleF0gKiBkZWNvZGVkW2luZGV4XTtcbiAgICB9XG4gICAgbGV0IG1hZ25pdHVkZSA9IE1hdGguc3FydChub3JtKSB8fCAxO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgZGVjb2RlZFtpbmRleF0gLz0gbWFnbml0dWRlO1xuICAgIH1cblxuICAgIGxldCByZXN1bHQ6IFN0b3JlZEVtYmVkZGluZztcbiAgICBpZiAoIWZvcm1hdENvbmZpZy5xdWFudCkge1xuICAgICAgICByZXN1bHQgPSB7IGtpbmQ6IFwiZmxvYXQzMlwiLCBtb2RlbCwgdmFsdWVzOiBuZXcgRmxvYXQzMkFycmF5KGRlY29kZWQuc3ViYXJyYXkoMCwgbGVuZ3RoKSkgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgeyB0eXBlLCBncm91cFNpemUgfSA9IGZvcm1hdENvbmZpZy5xdWFudDtcbiAgICAgICAgbGV0IGdyb3VwQ291bnQgPSBNYXRoLmNlaWwobGVuZ3RoIC8gZ3JvdXBTaXplKTtcbiAgICAgICAgbGV0IGludDggPSBuZXcgSW50OEFycmF5KGxlbmd0aCk7XG4gICAgICAgIGxldCBzY2FsZXMgPSBuZXcgRmxvYXQzMkFycmF5KGdyb3VwQ291bnQpO1xuICAgICAgICBmb3IgKGxldCBncm91cCA9IDA7IGdyb3VwIDwgZ3JvdXBDb3VudDsgZ3JvdXArKykge1xuICAgICAgICAgICAgbGV0IHN0YXJ0ID0gZ3JvdXAgKiBncm91cFNpemU7XG4gICAgICAgICAgICBsZXQgZW5kID0gTWF0aC5taW4oc3RhcnQgKyBncm91cFNpemUsIGxlbmd0aCk7XG4gICAgICAgICAgICBsZXQgbWF4QWJzID0gMDtcbiAgICAgICAgICAgIGZvciAobGV0IGluZGV4ID0gc3RhcnQ7IGluZGV4IDwgZW5kOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IGFic1ZhbHVlID0gTWF0aC5hYnMoZGVjb2RlZFtpbmRleF0pO1xuICAgICAgICAgICAgICAgIGlmIChhYnNWYWx1ZSA+IG1heEFicykgbWF4QWJzID0gYWJzVmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgc2NhbGUgPSBtYXhBYnMgLyBJTlQ4X01BWDtcbiAgICAgICAgICAgIHNjYWxlc1tncm91cF0gPSBzY2FsZTtcbiAgICAgICAgICAgIGlmICghc2NhbGUpIGNvbnRpbnVlO1xuICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSBzdGFydDsgaW5kZXggPCBlbmQ7IGluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBsZXQgcXVhbnRpemVkID0gTWF0aC5yb3VuZChkZWNvZGVkW2luZGV4XSAvIHNjYWxlKTtcbiAgICAgICAgICAgICAgICBpZiAocXVhbnRpemVkID4gSU5UOF9NQVgpIHF1YW50aXplZCA9IElOVDhfTUFYO1xuICAgICAgICAgICAgICAgIGlmIChxdWFudGl6ZWQgPCAtSU5UOF9NQVgpIHF1YW50aXplZCA9IC1JTlQ4X01BWDtcbiAgICAgICAgICAgICAgICBpbnQ4W2luZGV4XSA9IHF1YW50aXplZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXN1bHQgPSB7XG4gICAgICAgICAgICBraW5kOiBcInF1YW50XCIsXG4gICAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICBncm91cFNpemUsXG4gICAgICAgICAgICBkYXRhOiBuZXcgVWludDhBcnJheShpbnQ4LmJ1ZmZlciwgaW50OC5ieXRlT2Zmc2V0LCBpbnQ4LmJ5dGVMZW5ndGgpLFxuICAgICAgICAgICAgc2NhbGVzOiBlbmNvZGVGbG9hdDE2KHNjYWxlcyksXG4gICAgICAgIH07XG4gICAgfVxuICAgIHJlbGVhc2VGbG9hdDMyKGRlY29kZWQpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbnR5cGUgU2VyaWFsaXplZEhlYWRlciA9XG4gICAgfCB7IGtpbmQ6IFwiZmxvYXQzMlwiOyBtb2RlbDogc3RyaW5nIH1cbiAgICB8IHsga2luZDogXCJxdWFudFwiOyBtb2RlbDogc3RyaW5nOyB0eXBlOiBRdWFudFR5cGU7IGdyb3VwU2l6ZTogbnVtYmVyOyBkYXRhQnl0ZXM6IG51bWJlciB9O1xuXG4vLyBTZXJpYWxpemUgdG8gYmFzZTY0IHNvIGEgU3RvcmVkRW1iZWRkaW5nIGNhbiB0cmF2ZWwgdGhyb3VnaCB0aGUgKHN0cmluZykgQVBJIGNhbGwgcmVzdWx0LiBMYXlvdXQ6XG4vLyBbNC1ieXRlIGxpdHRsZS1lbmRpYW4gaGVhZGVyIGxlbmd0aF1bSlNPTiBoZWFkZXJdW3JhdyB0eXBlZC1hcnJheSBwYXlsb2FkKHMpXS5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVTdG9yZWRFbWJlZGRpbmcoc3RvcmVkOiBTdG9yZWRFbWJlZGRpbmcpOiBzdHJpbmcge1xuICAgIGxldCBoZWFkZXI6IFNlcmlhbGl6ZWRIZWFkZXI7XG4gICAgbGV0IHBheWxvYWQ6IFVpbnQ4QXJyYXlbXTtcbiAgICBpZiAoc3RvcmVkLmtpbmQgPT09IFwiZmxvYXQzMlwiKSB7XG4gICAgICAgIGhlYWRlciA9IHsga2luZDogXCJmbG9hdDMyXCIsIG1vZGVsOiBzdG9yZWQubW9kZWwgfTtcbiAgICAgICAgcGF5bG9hZCA9IFtuZXcgVWludDhBcnJheShzdG9yZWQudmFsdWVzLmJ1ZmZlciwgc3RvcmVkLnZhbHVlcy5ieXRlT2Zmc2V0LCBzdG9yZWQudmFsdWVzLmJ5dGVMZW5ndGgpXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBoZWFkZXIgPSB7IGtpbmQ6IFwicXVhbnRcIiwgbW9kZWw6IHN0b3JlZC5tb2RlbCwgdHlwZTogc3RvcmVkLnR5cGUsIGdyb3VwU2l6ZTogc3RvcmVkLmdyb3VwU2l6ZSwgZGF0YUJ5dGVzOiBzdG9yZWQuZGF0YS5ieXRlTGVuZ3RoIH07XG4gICAgICAgIHBheWxvYWQgPSBbc3RvcmVkLmRhdGEsIHN0b3JlZC5zY2FsZXNdO1xuICAgIH1cbiAgICBsZXQgaGVhZGVyQnl0ZXMgPSBCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShoZWFkZXIpLCBcInV0ZjhcIik7XG4gICAgbGV0IGhlYWRlckxlbmd0aCA9IEJ1ZmZlci5hbGxvYyg0KTtcbiAgICBoZWFkZXJMZW5ndGgud3JpdGVVSW50MzJMRShoZWFkZXJCeXRlcy5sZW5ndGgsIDApO1xuICAgIHJldHVybiBCdWZmZXIuY29uY2F0KFtoZWFkZXJMZW5ndGgsIGhlYWRlckJ5dGVzLCAuLi5wYXlsb2FkLm1hcChhc0J1ZmZlcildKS50b1N0cmluZyhcImJhc2U2NFwiKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBkZXNlcmlhbGl6ZVN0b3JlZEVtYmVkZGluZyhiYXNlNjQ6IHN0cmluZyk6IFN0b3JlZEVtYmVkZGluZyB7XG4gICAgbGV0IGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGJhc2U2NCwgXCJiYXNlNjRcIik7XG4gICAgaWYgKGJ1ZmZlci5sZW5ndGggPCA0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgU2VyaWFsaXplZCBlbWJlZGRpbmcgaXMgdG9vIHNob3J0ICgke2J1ZmZlci5sZW5ndGh9IGJ5dGVzKTogJHtiYXNlNjQuc2xpY2UoMCwgMjAwKX1gKTtcbiAgICB9XG4gICAgbGV0IGhlYWRlckxlbmd0aCA9IGJ1ZmZlci5yZWFkVUludDMyTEUoMCk7XG4gICAgbGV0IGhlYWRlckVuZCA9IDQgKyBoZWFkZXJMZW5ndGg7XG4gICAgaWYgKGhlYWRlckxlbmd0aCA8PSAwIHx8IGhlYWRlckVuZCA+IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZXJpYWxpemVkIGVtYmVkZGluZyBoZWFkZXIgbGVuZ3RoICR7aGVhZGVyTGVuZ3RofSBpcyBpbnZhbGlkIGZvciAke2J1ZmZlci5sZW5ndGh9IGJ5dGVzOiAke2Jhc2U2NC5zbGljZSgwLCAyMDApfWApO1xuICAgIH1cbiAgICBsZXQgaGVhZGVyID0gSlNPTi5wYXJzZShidWZmZXIudG9TdHJpbmcoXCJ1dGY4XCIsIDQsIGhlYWRlckVuZCkpIGFzIFNlcmlhbGl6ZWRIZWFkZXI7XG4gICAgbGV0IHBheWxvYWQgPSBidWZmZXIuc3ViYXJyYXkoaGVhZGVyRW5kKTtcbiAgICBpZiAoaGVhZGVyLmtpbmQgPT09IFwiZmxvYXQzMlwiKSB7XG4gICAgICAgIHJldHVybiB7IGtpbmQ6IFwiZmxvYXQzMlwiLCBtb2RlbDogaGVhZGVyLm1vZGVsLCB2YWx1ZXM6IGFzRmxvYXQzMihhc0J1ZmZlcihVaW50OEFycmF5LmZyb20ocGF5bG9hZCkpKSB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBraW5kOiBcInF1YW50XCIsXG4gICAgICAgIG1vZGVsOiBoZWFkZXIubW9kZWwsXG4gICAgICAgIHR5cGU6IGhlYWRlci50eXBlLFxuICAgICAgICBncm91cFNpemU6IGhlYWRlci5ncm91cFNpemUsXG4gICAgICAgIGRhdGE6IFVpbnQ4QXJyYXkuZnJvbShwYXlsb2FkLnN1YmFycmF5KDAsIGhlYWRlci5kYXRhQnl0ZXMpKSxcbiAgICAgICAgc2NhbGVzOiBVaW50OEFycmF5LmZyb20ocGF5bG9hZC5zdWJhcnJheShoZWFkZXIuZGF0YUJ5dGVzKSksXG4gICAgfTtcbn1cblxuLy8gTWVhbiBvZiBzZXZlcmFsIGVtYmVkZGluZ3MgKGVuY29kZUVtYmVkZGluZyBub3JtYWxpemVzIHRoZSByZXN1bHQgdG8gYSB1bml0IGNlbnRyb2lkKS4gQm9ycm93cyBhIHBvb2xlZFxuLy8gYWNjdW11bGF0b3IuXG5leHBvcnQgZnVuY3Rpb24gYXZlcmFnZUVtYmVkZGluZ3MoZW1iZWRkaW5nczogU3RvcmVkRW1iZWRkaW5nW10sIGNvbmZpZzogeyBmb3JtYXQ6IEVtYmVkZGluZ0Zvcm1hdDsgbW9kZWw6IHN0cmluZyB9KTogU3RvcmVkRW1iZWRkaW5nIHtcbiAgICBsZXQgbGVuZ3RoID0gSW5maW5pdHk7XG4gICAgZm9yIChsZXQgZW1iZWRkaW5nIG9mIGVtYmVkZGluZ3MpIHtcbiAgICAgICAgbGVuZ3RoID0gTWF0aC5taW4obGVuZ3RoLCBlbWJlZGRpbmdMZW5ndGgoZW1iZWRkaW5nKSk7XG4gICAgfVxuICAgIGxldCBzdW0gPSBhY3F1aXJlRmxvYXQzMihsZW5ndGgpO1xuICAgIHN1bS5maWxsKDApO1xuICAgIGZvciAobGV0IGVtYmVkZGluZyBvZiBlbWJlZGRpbmdzKSB7XG4gICAgICAgIGxldCB2ZWN0b3IgPSBlbWJlZGRpbmdUb0Zsb2F0MzIoZW1iZWRkaW5nLCB0cnVlKTtcbiAgICAgICAgZm9yIChsZXQgZGltZW5zaW9uID0gMDsgZGltZW5zaW9uIDwgbGVuZ3RoOyBkaW1lbnNpb24rKykge1xuICAgICAgICAgICAgc3VtW2RpbWVuc2lvbl0gKz0gdmVjdG9yW2RpbWVuc2lvbl07XG4gICAgICAgIH1cbiAgICAgICAgcmVsZWFzZUZsb2F0MzIodmVjdG9yKTtcbiAgICB9XG4gICAgbGV0IHJlc3VsdCA9IGVuY29kZUVtYmVkZGluZyh7IGlucHV0OiBzdW0uc3ViYXJyYXkoMCwgbGVuZ3RoKSwgZm9ybWF0OiBjb25maWcuZm9ybWF0LCBtb2RlbDogY29uZmlnLm1vZGVsIH0pO1xuICAgIHJlbGVhc2VGbG9hdDMyKHN1bSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLy8gQSBzdGFibGUgMTYtYnl0ZSAoYmFzZTY0KSBjb250ZW50IGhhc2ggb2YgYW4gZW1iZWRkaW5nJ3MgdmFsdWVzLCBmb3IgdXNlIGFzIGEgY2VsbCBpZCBkZXJpdmVkIGZyb20gaXRzXG4vLyBjZW50cm9pZC4gSXRlcmF0ZXMgdmlhIHRoZSBhY2Nlc3NvciAodGhlIHZhbHVlIGJpdHMgYXJlIGhhc2hlZCwgc28gYW55IGZvcm1hdCBoYXNoZXMgY29uc2lzdGVudGx5KS5cbmV4cG9ydCBmdW5jdGlvbiBoYXNoRW1iZWRkaW5nKHN0b3JlZDogU3RvcmVkRW1iZWRkaW5nKTogc3RyaW5nIHtcbiAgICBsZXQgdmVjdG9yID0gZW1iZWRkaW5nVG9GbG9hdDMyKHN0b3JlZCwgdHJ1ZSk7XG4gICAgbGV0IGxlbmd0aCA9IHZlY3Rvci5sZW5ndGg7XG4gICAgbGV0IGxhbmVzID0gbmV3IFVpbnQzMkFycmF5KFsyMTY2MTM2MjYxLCAyNjU0NDM1NzYxLCA0MDUwMywgMzI2NjQ4OTkxN10pO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgZjMyU2NyYXRjaFswXSA9IHZlY3RvcltpbmRleF07XG4gICAgICAgIGxldCBiaXRzID0gaTMyU2NyYXRjaFswXTtcbiAgICAgICAgZm9yIChsZXQgbGFuZSA9IDA7IGxhbmUgPCBsYW5lcy5sZW5ndGg7IGxhbmUrKykge1xuICAgICAgICAgICAgbGFuZXNbbGFuZV0gPSBNYXRoLmltdWwobGFuZXNbbGFuZV0gXiAoYml0cyArIGxhbmUgKiAxMzEgKyBpbmRleCksIDE2Nzc3NjE5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZWxlYXNlRmxvYXQzMih2ZWN0b3IpO1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShsYW5lcy5idWZmZXIpLnRvU3RyaW5nKFwiYmFzZTY0XCIpO1xufVxuIl19
340
+ /* _JS_SOURCE_HASH = "252bf7f8cc3cfd27bebc9b3e1ddee9aa39631ffeffa137c02456c63deb496996"; */