sliftutils 1.7.12 → 1.7.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.claude/settings.local.json +2 -1
  2. package/index.d.ts +95 -39
  3. package/misc/dist/yaml.ts.cache +2 -2
  4. package/misc/dist/yamlBase.ts.cache +2 -2
  5. package/misc/https/hostServer.d.ts +7 -0
  6. package/misc/https/hostServer.ts +89 -20
  7. package/misc/openrouter.ts +17 -14
  8. package/package.json +2 -2
  9. package/storage/ArchivesDisk.d.ts +1 -1
  10. package/storage/ArchivesDisk.ts +2 -1
  11. package/storage/IArchives.d.ts +5 -1
  12. package/storage/IArchives.ts +5 -1
  13. package/storage/backblaze.d.ts +1 -1
  14. package/storage/backblaze.ts +9 -6
  15. package/storage/dist/embeddingFormats.ts.cache +2 -2
  16. package/storage/proxydatabase/dist/Database.ts.cache +2 -2
  17. package/storage/proxydatabase/dist/ivfEmbeddingDatabase.ts.cache +123 -61
  18. package/storage/proxydatabase/dist/transactionSet.ts.cache +16 -4
  19. package/storage/remoteStorage/ArchivesRemote.d.ts +1 -1
  20. package/storage/remoteStorage/ArchivesRemote.ts +2 -1
  21. package/storage/remoteStorage/ArchivesUrl.d.ts +1 -1
  22. package/storage/remoteStorage/ArchivesUrl.ts +13 -9
  23. package/storage/remoteStorage/blobStore.d.ts +6 -2
  24. package/storage/remoteStorage/blobStore.ts +46 -6
  25. package/storage/remoteStorage/createArchives.d.ts +26 -11
  26. package/storage/remoteStorage/createArchives.ts +104 -28
  27. package/storage/remoteStorage/deployTakeover.d.ts +24 -0
  28. package/storage/remoteStorage/deployTakeover.ts +373 -0
  29. package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +16 -11
  30. package/storage/remoteStorage/dist/blobStore.ts.cache +39 -4
  31. package/storage/remoteStorage/dist/createArchives.ts.cache +91 -9
  32. package/storage/remoteStorage/dist/deployTakeover.ts.cache +371 -0
  33. package/storage/remoteStorage/dist/remoteConfig.ts.cache +9 -3
  34. package/storage/remoteStorage/dist/sourceWrapper.ts.cache +3 -3
  35. package/storage/remoteStorage/dist/storageController.ts.cache +11 -12
  36. package/storage/remoteStorage/dist/storageServerState.ts.cache +120 -19
  37. package/storage/remoteStorage/remoteConfig.d.ts +1 -0
  38. package/storage/remoteStorage/remoteConfig.ts +6 -0
  39. package/storage/remoteStorage/storageController.d.ts +2 -0
  40. package/storage/remoteStorage/storageController.ts +9 -9
  41. package/storage/remoteStorage/storageServer.ts +14 -1
  42. package/storage/remoteStorage/storageServerState.d.ts +16 -1
  43. package/storage/remoteStorage/storageServerState.ts +118 -16
  44. package/yarn.lock +4 -4
  45. package/storage/dist/faceFramesData.ts.cache +0 -55
  46. package/storage/embeddingBench.d.ts +0 -1
  47. package/storage/embeddingBench.ts +0 -152
  48. package/storage/faceFramesData.d.ts +0 -1
  49. package/storage/faceFramesData.ts +0 -49
  50. package/storage/faceFramesServer.d.ts +0 -1
  51. package/storage/faceFramesServer.ts +0 -56
  52. package/storage/proxydatabase/ivfDbCheck.d.ts +0 -1
  53. package/storage/proxydatabase/ivfDbCheck.ts +0 -85
@@ -6,6 +6,13 @@ export type HostServerConfig = {
6
6
  setDNSRecord?: boolean;
7
7
  publicIp?: string;
8
8
  allowHostnames?: string[];
9
+ /** Deploy takeover: when the port is busy (the previous version still holds it), mount on a random alternate port instead, and keep trying to take the real port - once it frees, a raw TCP relay on the real port forwards to our listener (SocketFunction can only mount once per process). Only pass this when a deploy timeline actually exists; without it a busy port is a real misconfiguration and must throw. */
10
+ portFallback?: {
11
+ /** Delay until the next main-port acquisition attempt (tightened around the predecessor's scheduled death) */
12
+ getAcquireDelay: () => number;
13
+ /** Reports every port we become reachable on (the alternate at mount, the main port once relayed) */
14
+ onListening: (port: number, isMainPort: boolean) => void;
15
+ };
9
16
  };
10
17
  /** Hosts a SocketFunction server on a real domain, with an automatically created and renewed Let's Encrypt HTTPS certificate (cached in the home folder, shared between processes on the machine). Expose your controllers (and any RequireController setup) before calling this. Returns the mounted nodeId. */
11
18
  export declare function hostServer(config: HostServerConfig): Promise<string>;
@@ -1,5 +1,6 @@
1
1
  import os from "os";
2
2
  import fs from "fs";
3
+ import net from "net";
3
4
  import { SocketFunction } from "socket-function/SocketFunction";
4
5
  import { timeInMinute } from "socket-function/src/misc";
5
6
  import { delay } from "socket-function/src/batching";
@@ -13,6 +14,10 @@ import { setRecord } from "./dns";
13
14
  const RENEW_THRESHOLD_MIN = 0.4;
14
15
  const RENEW_THRESHOLD_MAX = 0.6;
15
16
  const CERT_CHECK_INTERVAL = timeInMinute * 15;
17
+ // Alternate ports (deploy takeover) are picked randomly from [port + OFFSET, port + OFFSET + RANGE)
18
+ const ALT_PORT_OFFSET = 1000;
19
+ const ALT_PORT_RANGE = 1000;
20
+ const ALT_PORT_ATTEMPTS = 10;
16
21
 
17
22
  // One threshold per process, so a process is consistently early or late relative to its siblings
18
23
  const renewThreshold = RENEW_THRESHOLD_MIN + Math.random() * (RENEW_THRESHOLD_MAX - RENEW_THRESHOLD_MIN);
@@ -27,6 +32,13 @@ export type HostServerConfig = {
27
32
  setDNSRecord?: boolean;
28
33
  publicIp?: string;
29
34
  allowHostnames?: string[];
35
+ /** Deploy takeover: when the port is busy (the previous version still holds it), mount on a random alternate port instead, and keep trying to take the real port - once it frees, a raw TCP relay on the real port forwards to our listener (SocketFunction can only mount once per process). Only pass this when a deploy timeline actually exists; without it a busy port is a real misconfiguration and must throw. */
36
+ portFallback?: {
37
+ /** Delay until the next main-port acquisition attempt (tightened around the predecessor's scheduled death) */
38
+ getAcquireDelay: () => number;
39
+ /** Reports every port we become reachable on (the alternate at mount, the main port once relayed) */
40
+ onListening: (port: number, isMainPort: boolean) => void;
41
+ };
30
42
  };
31
43
 
32
44
  /** Hosts a SocketFunction server on a real domain, with an automatically created and renewed Let's Encrypt HTTPS certificate (cached in the home folder, shared between processes on the machine). Expose your controllers (and any RequireController setup) before calling this. Returns the mounted nodeId. */
@@ -50,30 +62,87 @@ export async function hostServer(config: HostServerConfig): Promise<string> {
50
62
  }
51
63
  });
52
64
 
53
- let nodeId = await SocketFunction.mount({
54
- public: true,
55
- autoForwardPort: true,
56
- port,
57
- ...getThreadKeyCert(rootDomain),
58
- SNICerts: {
59
- [domain]: callback => {
60
- callback(keyCert);
61
- certListeners.push(callback);
65
+ let mountOn = async (mountPort: number) => {
66
+ return await SocketFunction.mount({
67
+ public: true,
68
+ autoForwardPort: true,
69
+ port: mountPort,
70
+ ...getThreadKeyCert(rootDomain),
71
+ SNICerts: {
72
+ [domain]: callback => {
73
+ callback(keyCert);
74
+ certListeners.push(callback);
75
+ },
76
+ [getOwnMachineId(rootDomain) + "." + rootDomain]: async callback => {
77
+ let threadCert = await getThreadKeyCert(rootDomain);
78
+ callback({
79
+ key: threadCert.key,
80
+ cert: threadCert.cert,
81
+ });
82
+ },
62
83
  },
63
- [getOwnMachineId(rootDomain) + "." + rootDomain]: async callback => {
64
- let threadCert = await getThreadKeyCert(rootDomain);
65
- callback({
66
- key: threadCert.key,
67
- cert: threadCert.cert,
68
- });
69
- },
70
- },
71
- allowHostnames: config.allowHostnames,
72
- });
73
- console.log(magenta(`Hosting https://${domain}:${port} (nodeId ${nodeId})`));
84
+ allowHostnames: config.allowHostnames,
85
+ });
86
+ };
87
+
88
+ let servingPort = port;
89
+ let nodeId: string;
90
+ try {
91
+ nodeId = await mountOn(port);
92
+ } catch (e) {
93
+ let fallback = config.portFallback;
94
+ if (!fallback || !String((e as Error).stack ?? e).includes("EADDRINUSE")) throw e;
95
+ // Deploy takeover: the previous version still holds the port. Serve on an alternate port,
96
+ // and relay the real port to ourselves once the predecessor dies and frees it.
97
+ let mounted: string | undefined;
98
+ for (let attempt = 0; attempt < ALT_PORT_ATTEMPTS && !mounted; attempt++) {
99
+ let altPort = port + ALT_PORT_OFFSET + Math.floor(Math.random() * ALT_PORT_RANGE);
100
+ try {
101
+ mounted = await mountOn(altPort);
102
+ servingPort = altPort;
103
+ } catch (e2) {
104
+ if (!String((e2 as Error).stack ?? e2).includes("EADDRINUSE")) throw e2;
105
+ }
106
+ }
107
+ if (!mounted) throw e;
108
+ nodeId = mounted;
109
+ console.log(magenta(`Port ${port} is held by our predecessor; serving on alternate port ${servingPort} until it frees`));
110
+ void runMainPortAcquireLoop(domain, port, servingPort, fallback);
111
+ }
112
+ config.portFallback?.onListening(servingPort, servingPort === port);
113
+ console.log(magenta(`Hosting https://${domain}:${servingPort} (nodeId ${nodeId})`));
74
114
  return nodeId;
75
115
  }
76
116
 
117
+ // SocketFunction can only mount once per process, so "taking over" the main port is a raw TCP
118
+ // relay forwarding to our real listener - TLS/SNI passes straight through, and clients address
119
+ // servers by ip domain (wildcard negotiation), so the extra hop is invisible.
120
+ async function runMainPortAcquireLoop(domain: string, mainPort: number, servingPort: number, fallback: NonNullable<HostServerConfig["portFallback"]>): Promise<void> {
121
+ while (true) {
122
+ await delay(fallback.getAcquireDelay());
123
+ let acquired = await new Promise<boolean>(resolve => {
124
+ let relay = net.createServer(client => {
125
+ let upstream = net.connect({ host: "127.0.0.1", port: servingPort });
126
+ client.pipe(upstream);
127
+ upstream.pipe(client);
128
+ let cleanup = () => {
129
+ client.destroy();
130
+ upstream.destroy();
131
+ };
132
+ client.on("error", cleanup);
133
+ upstream.on("error", cleanup);
134
+ });
135
+ relay.once("error", () => resolve(false));
136
+ relay.listen(mainPort, () => resolve(true));
137
+ });
138
+ if (acquired) {
139
+ console.log(magenta(`Acquired main port ${mainPort} for https://${domain} (relaying to our listener on ${servingPort})`));
140
+ fallback.onListening(mainPort, true);
141
+ return;
142
+ }
143
+ }
144
+ }
145
+
77
146
  function getCertDiskPath(domain: string) {
78
147
  return os.homedir() + `/httpscert_${domain}.json`;
79
148
  }
@@ -1,5 +1,6 @@
1
1
  import { parseYAML } from "./yaml";
2
2
  import { retryFunctional } from "socket-function/src/batching";
3
+ import { httpsRequest } from "socket-function/src/https";
3
4
 
4
5
  const CANNOT_RETRY = "(CANNOT RETRY)";
5
6
  import { formatNumber } from "socket-function/src/formatting/format";
@@ -110,13 +111,11 @@ export async function openRouterCallBase(config: {
110
111
 
111
112
  try {
112
113
  return await retryFunctional(async () => {
113
- let response = await fetch("https://openrouter.ai/api/v1/chat/completions", {
114
- method: "POST",
115
- headers: {
116
- "Authorization": `Bearer ${openrouterKey}`,
117
- "Content-Type": "application/json",
118
- },
119
- body: JSON.stringify({
114
+ // httpsRequest routes through socket-function's DNS cache and throws on any non-2xx (with the
115
+ // response body in the message), which retryFunctional then retries.
116
+ let responseBody = await httpsRequest(
117
+ "https://openrouter.ai/api/v1/chat/completions",
118
+ Buffer.from(JSON.stringify({
120
119
  model,
121
120
  messages,
122
121
  provider: {
@@ -124,14 +123,18 @@ export async function openRouterCallBase(config: {
124
123
  },
125
124
  usage: { include: true },
126
125
  ...options,
127
- }),
128
- });
126
+ })),
127
+ "POST",
128
+ false,
129
+ {
130
+ headers: {
131
+ "Authorization": `Bearer ${openrouterKey}`,
132
+ "Content-Type": "application/json",
133
+ },
134
+ }
135
+ );
129
136
 
130
- if (response.status !== 200) {
131
- let responseText = await response.text();
132
- throw new Error(`Failed to call OpenRouter: ${response.status} ${response.statusText} ${responseText}`);
133
- }
134
- let responseObj = await response.json() as {
137
+ let responseObj = JSON.parse(responseBody.toString()) as {
135
138
  usage: {
136
139
  cost: number;
137
140
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliftutils",
3
- "version": "1.7.12",
3
+ "version": "1.7.14",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -57,7 +57,7 @@
57
57
  "node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6",
58
58
  "preact-old-types": "^10.28.1",
59
59
  "shell-quote": "^1.8.3",
60
- "socket-function": "^1.2.16",
60
+ "socket-function": "^1.2.20",
61
61
  "typenode": "^6.6.1",
62
62
  "typesafecss": "*",
63
63
  "ws": "^8.18.3",
@@ -20,7 +20,7 @@ export declare class ArchivesDisk implements IArchives {
20
20
  private filePath;
21
21
  set(key: string, data: Buffer, config?: {
22
22
  lastModified?: number;
23
- }): Promise<void>;
23
+ }): Promise<string>;
24
24
  del(key: string): Promise<void>;
25
25
  get(key: string, config?: {
26
26
  range?: {
@@ -144,7 +144,7 @@ export class ArchivesDisk implements IArchives {
144
144
  return result;
145
145
  }
146
146
 
147
- public async set(key: string, data: Buffer, config?: { lastModified?: number }): Promise<void> {
147
+ public async set(key: string, data: Buffer, config?: { lastModified?: number }): Promise<string> {
148
148
  await this.init();
149
149
  let lastModified = config?.lastModified;
150
150
  if (lastModified) {
@@ -165,6 +165,7 @@ export class ArchivesDisk implements IArchives {
165
165
  await handle.utimes(new Date(lastModified), new Date(lastModified));
166
166
  }
167
167
  });
168
+ return key;
168
169
  }
169
170
 
170
171
  public async del(key: string): Promise<void> {
@@ -126,10 +126,14 @@ export interface IArchives {
126
126
  * lastModified stamps the write with that last-write time instead of now. If it is OLDER than
127
127
  * the file's current last-write time the write no-ops (so delayed / synchronized writes can
128
128
  * never clobber newer data). Times more than 15 minutes in the future are rejected.
129
+ *
130
+ * Returns the full key actually written - identical to fileName, EXCEPT for keys containing
131
+ * VARIABLE_SHARD, where the shard value is materialized into the key (picked by shard latency,
132
+ * see ArchivesChain) and the caller needs the returned key to ever read the value back.
129
133
  */
130
134
  set(fileName: string, data: Buffer, config?: {
131
135
  lastModified?: number;
132
- }): Promise<void>;
136
+ }): Promise<string>;
133
137
  del(fileName: string): Promise<void>;
134
138
  /** Streams a file too large to hold in memory. getNextData returns undefined when done. */
135
139
  setLargeFile(config: {
@@ -197,8 +197,12 @@ export interface IArchives {
197
197
  * lastModified stamps the write with that last-write time instead of now. If it is OLDER than
198
198
  * the file's current last-write time the write no-ops (so delayed / synchronized writes can
199
199
  * never clobber newer data). Times more than 15 minutes in the future are rejected.
200
+ *
201
+ * Returns the full key actually written - identical to fileName, EXCEPT for keys containing
202
+ * VARIABLE_SHARD, where the shard value is materialized into the key (picked by shard latency,
203
+ * see ArchivesChain) and the caller needs the returned key to ever read the value back.
200
204
  */
201
- set(fileName: string, data: Buffer, config?: { lastModified?: number }): Promise<void>;
205
+ set(fileName: string, data: Buffer, config?: { lastModified?: number }): Promise<string>;
202
206
  del(fileName: string): Promise<void>;
203
207
  /** Streams a file too large to hold in memory. getNextData returns undefined when done. */
204
208
  setLargeFile(config: { path: string; getNextData(): Promise<Buffer | undefined> }): Promise<void>;
@@ -41,7 +41,7 @@ export declare class ArchivesBackblaze implements IArchives {
41
41
  hasWriteAccess(): Promise<boolean>;
42
42
  set(fileName: string, data: Buffer, config?: {
43
43
  lastModified?: number;
44
- }): Promise<void>;
44
+ }): Promise<string>;
45
45
  del(fileName: string): Promise<void>;
46
46
  setLargeFile(config: {
47
47
  path: string;
@@ -661,13 +661,13 @@ export class ArchivesBackblaze implements IArchives {
661
661
  return false;
662
662
  }
663
663
  }
664
- public async set(fileName: string, data: Buffer, config?: { lastModified?: number }): Promise<void> {
664
+ public async set(fileName: string, data: Buffer, config?: { lastModified?: number }): Promise<string> {
665
665
  if (config?.lastModified) {
666
666
  assertValidLastModified(config.lastModified);
667
667
  let existing = await this.getInfo(fileName);
668
668
  // An older write never overwrites a newer one (see IArchives.set). B2 stamps its own
669
669
  // upload time, so the exact lastModified is not preserved on the stored file.
670
- if (existing && config.lastModified < existing.writeTime) return;
670
+ if (existing && config.lastModified < existing.writeTime) return fileName;
671
671
  }
672
672
  this.log(`backblaze upload (${formatNumber(data.length)}B) ${fileName}`);
673
673
  let f = fileName;
@@ -685,7 +685,7 @@ export class ArchivesBackblaze implements IArchives {
685
685
  let exists = await this.getInfo(fileName);
686
686
  console.warn(`File ${fileName}/${f} was uploaded, but could not be found afterwards. Hopefully it was just deleted, very quickly? If backblaze is taking too long for files to propagate, then we might run into issues with the database atomicity.`);
687
687
  }
688
-
688
+ return fileName;
689
689
  }
690
690
  public async del(fileName: string): Promise<void> {
691
691
  this.log(`backblaze delete ${fileName}`);
@@ -743,17 +743,20 @@ export class ArchivesBackblaze implements IArchives {
743
743
  if (!data?.length) return;
744
744
  // Backblaze disallows overly small files
745
745
  if (data.length < MIN_CHUNK_SIZE) {
746
- return await this.set(fileName, data);
746
+ await this.set(fileName, data);
747
+ return;
747
748
  }
748
749
  // Backblaze disallows less than 2 chunks
749
750
  let secondData = await getNextData();
750
751
  if (!secondData?.length) {
751
- return await this.set(fileName, data);
752
+ await this.set(fileName, data);
753
+ return;
752
754
  }
753
755
  // ALSO, if there are two chunks, but one is too small, combine it. This helps allow us never
754
756
  // send small chunks.
755
757
  if (secondData.length < MIN_CHUNK_SIZE) {
756
- return await this.set(fileName, Buffer.concat([data, secondData]));
758
+ await this.set(fileName, Buffer.concat([data, secondData]));
759
+ return;
757
760
  }
758
761
  this.log(`Uploading large file ${config.path}`);
759
762
  dataQueue.unshift(data, secondData);
@@ -1,4 +1,4 @@
1
- "use strict";
1
+ "use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
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
4
  const measure_1 = require("socket-function/src/profiling/measure");
@@ -337,4 +337,4 @@ function hashEmbedding(stored) {
337
337
  }
338
338
  exports.hashEmbedding = hashEmbedding;
339
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"; */
340
+ /* _JS_SOURCE_HASH = "667dde839f46c7c3f10ea92a2c74c5c2c98824118f56e021de748b660953952e"; */
@@ -1,4 +1,4 @@
1
- "use strict";
1
+ "use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
3
  //exports.namespaceDatabase = void 0;
4
4
  function namespaceDatabase(database, into) {
@@ -10,4 +10,4 @@ function namespaceDatabase(database, into) {
10
10
  }
11
11
  exports.namespaceDatabase = namespaceDatabase;
12
12
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJEYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFPQSxTQUFnQixpQkFBaUIsQ0FDN0IsUUFBd0IsRUFDeEIsSUFBeUI7SUFFekIsT0FBTztRQUNILFFBQVEsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNqRSxTQUFTLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQztRQUN2RixVQUFVLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7S0FDeEUsQ0FBQztBQUNOLENBQUM7QUFURCw4Q0FTQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHVuZGVmaW5lZCBmcm9tIGEgcmVhZCBtZWFucyBcIm5vdCBzeW5jZWQgeWV0XCIsIE5PVCBcImFic2VudFwiIOKAlCBzdG9yYWdlIGluaXRpYWxpemVzIG9uIGl0cyBvd24uIFNvIHJlYWQgZXZlcnl0aGluZyBhIHN0YWdlIG5lZWRzIGluIG9uZSByZWFkRGF0YSBhbmQgYmFpbCBpZiB0aGUgd2hvbGUgcmVzdWx0IGlzIHVuZGVmaW5lZDsgdGhlIGRhdGFiYXNlIG5ldmVyIHJldHVybnMgYW4gaW5kaXZpZHVhbCB1bnN5bmNlZCB2YWx1ZSBpbnNpZGUgYW4gb3RoZXJ3aXNlLXN1Y2Nlc3NmdWwgcmVhZC5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YWJhc2U8Um9vdD4ge1xuICAgIHJlYWREYXRhOiA8VmFsdWU+KGRlcmVmOiAocm9vdDogUm9vdCkgPT4gVmFsdWUpID0+IFZhbHVlIHwgdW5kZWZpbmVkO1xuICAgIHdyaXRlRGF0YTogPFZhbHVlPihkZXJlZjogKHJvb3Q6IFJvb3QpID0+IFZhbHVlLCBuZXdWYWx1ZTogVmFsdWUpID0+IHZvaWQ7XG4gICAgZGVsZXRlRGF0YTogKGRlcmVmOiAocm9vdDogUm9vdCkgPT4gdW5rbm93bikgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5hbWVzcGFjZURhdGFiYXNlPFJvb3QsIFN1Yj4oXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPFJvb3Q+LFxuICAgIGludG86IChyb290OiBSb290KSA9PiBTdWIsXG4pOiBEYXRhYmFzZTxTdWI+IHtcbiAgICByZXR1cm4ge1xuICAgICAgICByZWFkRGF0YTogKGRlcmVmKSA9PiBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IGRlcmVmKGludG8ocm9vdCkpKSxcbiAgICAgICAgd3JpdGVEYXRhOiAoZGVyZWYsIG5ld1ZhbHVlKSA9PiBkYXRhYmFzZS53cml0ZURhdGEocm9vdCA9PiBkZXJlZihpbnRvKHJvb3QpKSwgbmV3VmFsdWUpLFxuICAgICAgICBkZWxldGVEYXRhOiAoZGVyZWYpID0+IGRhdGFiYXNlLmRlbGV0ZURhdGEocm9vdCA9PiBkZXJlZihpbnRvKHJvb3QpKSksXG4gICAgfTtcbn1cbiJdfQ==
13
- /* _JS_SOURCE_HASH = "93a620d26b6a59665b5f7dab689d9739693a4990e1c4781abcddc6cda24bda11"; */
13
+ /* _JS_SOURCE_HASH = "a66e8405ab4b7b49928062632c915e26904e833e3d97a1f7e7f635613bb15809"; */