sliftutils 1.7.18 → 1.7.20

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.
@@ -77,7 +77,20 @@ class SourceWrapper {
77
77
  return wrapper;
78
78
  }
79
79
  getDebugName() {
80
- return `source/${this.config.url}`;
80
+ // The same URL can appear as multiple sources (different routes / valid windows), so the
81
+ // distinguishing slice is part of the name
82
+ let parts = [];
83
+ let route = this.config.route;
84
+ if (route) {
85
+ parts.push(`route [${route[0]}, ${route[1]})`);
86
+ }
87
+ let [start, end] = this.config.validWindow;
88
+ if (start !== 0 || end !== Number.MAX_SAFE_INTEGER) {
89
+ let startText = start === 0 && "0" || new Date(start).toISOString();
90
+ let endText = end === Number.MAX_SAFE_INTEGER && "forever" || new Date(end).toISOString();
91
+ parts.push(`validWindow [${startText}, ${endText}]`);
92
+ }
93
+ return `source/${this.config.url}${parts.length && ` (${parts.join(", ")})` || ""}`;
81
94
  }
82
95
  isConnected() {
83
96
  if (!this.remote)
@@ -91,7 +104,7 @@ class SourceWrapper {
91
104
  return;
92
105
  if (this.isConnected())
93
106
  return;
94
- console.error(`Cannot connect to storage source ${this.config.url}`);
107
+ console.error(`Cannot connect to storage ${this.getDebugName()}`);
95
108
  this.reconnectRunning = true;
96
109
  void this.reconnectLoop();
97
110
  }
@@ -115,12 +128,12 @@ class SourceWrapper {
115
128
  // Even a failing call (e.g. access denied) proves the connection is back
116
129
  if (this.isConnected())
117
130
  break;
118
- console.warn(`Cannot connect to storage source ${this.config.url}, retrying in ${Math.round(retryDelay / 1000)}s. ${(_b = e.stack) !== null && _b !== void 0 ? _b : e}`);
131
+ console.warn(`Cannot connect to storage ${this.getDebugName()}, retrying in ${Math.round(retryDelay / 1000)}s. ${(_b = e.stack) !== null && _b !== void 0 ? _b : e}`);
119
132
  }
120
133
  retryDelay = Math.min(exports.RETRY_MAX_DELAY, retryDelay * exports.RETRY_GROWTH);
121
134
  }
122
135
  this.reconnectRunning = false;
123
- console.log(`Reconnected to storage source ${this.config.url}`);
136
+ console.log(`Reconnected to storage ${this.getDebugName()}`);
124
137
  }
125
138
  // For hosted sources: cached access check, so reads know whether to use the API or the public
126
139
  // URL form. Access, once seen, is assumed to stick; no-access is re-checked periodically (the
@@ -178,7 +191,7 @@ class SourceWrapper {
178
191
  }
179
192
  if (!this.loggedConnected) {
180
193
  this.loggedConnected = true;
181
- console.log(`Connected to storage source ${this.config.url} (${Date.now() - start}ms)`);
194
+ console.log(`Connected to storage ${this.getDebugName()} (${Date.now() - start}ms)`);
182
195
  }
183
196
  this.pings.push(Date.now() - start);
184
197
  if (this.pings.length > PING_HISTORY) {
@@ -191,6 +204,14 @@ class SourceWrapper {
191
204
  }, PING_INTERVAL);
192
205
  (_b = (_a = this.pingTimer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
193
206
  }
207
+ /** Seeds the latency estimate before the first ping lands (e.g. from the initial routing
208
+ * fetch), so variable-shard picking has something immediately. Real pings take over from the
209
+ * first measurement on. */
210
+ seedLatency(ms) {
211
+ if (this.pings.length)
212
+ return;
213
+ this.pings.push(ms);
214
+ }
194
215
  /** Median of the recent pings. Sources that can't be pinged sort last (Infinity), except our
195
216
  * own in-process server, which is the best possible target (0). */
196
217
  getLatency() {
@@ -227,5 +248,5 @@ class SourceWrapper {
227
248
  }
228
249
  }
229
250
  exports.SourceWrapper = SourceWrapper;
230
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlV3JhcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNvdXJjZVdyYXBwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsTUFBTSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFFMUIsbURBQXdEO0FBQ3hELDJEQUFxRDtBQUNyRCxvREFBaUQ7QUFFakQsaURBQW1HO0FBQ25HLHFEQUFrRDtBQUNsRCwrQ0FBNEM7QUFDNUMsNENBQWlEO0FBQ2pELDZEQUF3RjtBQUUzRSxRQUFBLGlCQUFpQixHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDN0IsUUFBQSxlQUFlLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDaEMsUUFBQSxZQUFZLEdBQUcsR0FBRyxDQUFDO0FBQ2hDLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUMxQyxNQUFNLGFBQWEsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQztBQUV4QixLQUFLLFVBQVUsaUJBQWlCO0lBQzVCLElBQUksQ0FBQyxJQUFBLGFBQU0sR0FBRTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzVCLElBQUksQ0FBQztRQUNELE1BQU0sSUFBQSxxQkFBUyxFQUFDLGlDQUFpQyxDQUFDLENBQUM7UUFDbkQsTUFBTSxJQUFBLHFCQUFTLEVBQUMsK0JBQStCLENBQUMsQ0FBQztRQUNqRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBQUMsV0FBTSxDQUFDO1FBQ0wsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztBQUNMLENBQUM7QUFFRCxtR0FBbUc7QUFDbkcsbUdBQW1HO0FBQ25HLGtHQUFrRztBQUNsRyw2RkFBNkY7QUFDN0YsOEZBQThGO0FBQzlGLDZGQUE2RjtBQUM3RixNQUFhLGFBQWE7SUFTdEIsWUFDVyxNQUFzQztJQUM3QyxvRkFBb0Y7SUFDNUUsVUFBbUI7UUFGcEIsV0FBTSxHQUFOLE1BQU0sQ0FBZ0M7UUFFckMsZUFBVSxHQUFWLFVBQVUsQ0FBUztRQVB2QixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQXdIekIsVUFBSyxHQUFhLEVBQUUsQ0FBQztRQUVyQixvQkFBZSxHQUFHLEtBQUssQ0FBQztJQW5INUIsQ0FBQztJQUVFLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQXNDLEVBQUUsT0FBa0M7UUFDakcsSUFBSSxPQUFPLEdBQUcsSUFBSSxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFVBQVUsTUFBSyxLQUFLLENBQUMsQ0FBQztRQUN2RSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDOUIsSUFBSSxNQUFNLGlCQUFpQixFQUFFLEVBQUUsQ0FBQztnQkFDNUIsT0FBTyxDQUFDLEdBQUcsR0FBRyxJQUFJLDZCQUFpQixDQUFDLEVBQUUsVUFBVSxFQUFFLElBQUEsZ0NBQWlCLEVBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7WUFDdEosQ0FBQztpQkFBTSxJQUFJLElBQUEsYUFBTSxHQUFFLEVBQUUsQ0FBQztnQkFDbEIsT0FBTyxDQUFDLFlBQVksR0FBRyxnQ0FBZ0MsTUFBTSxDQUFDLEdBQUcsaUhBQWlILENBQUM7WUFDdkwsQ0FBQztpQkFBTSxDQUFDO2dCQUNKLE9BQU8sQ0FBQyxZQUFZLEdBQUcsOENBQThDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUN2RixDQUFDO1lBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxLQUFLLEVBQUUsQ0FBQztnQkFDMUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxJQUFJLHlCQUFXLENBQUMsSUFBQSwrQkFBZ0IsRUFBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNoRSxDQUFDO1lBQ0QsT0FBTyxPQUFPLENBQUM7UUFDbkIsQ0FBQztRQUNELElBQUksTUFBTSxHQUFHLElBQUEsNkJBQWMsRUFBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEMsSUFBSSxNQUFNLEdBQUcsSUFBQSxhQUFNLEdBQUUsSUFBSSxJQUFBLG1EQUE4QixHQUFFLElBQUksU0FBUyxDQUFDO1FBQ3ZFLElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssTUFBTSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM1RSxvRkFBb0Y7WUFDcEYsT0FBTyxDQUFDLEdBQUcsR0FBRyxJQUFBLHFDQUFnQixFQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2xFLE9BQU8sT0FBTyxDQUFDO1FBQ25CLENBQUM7UUFDRCxPQUFPLENBQUMsTUFBTSxHQUFHLElBQUksK0JBQWMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2hILE9BQU8sQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUM3QixJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDMUIsT0FBTyxDQUFDLEdBQUcsR0FBRyxJQUFJLHlCQUFXLENBQUMsSUFBQSwrQkFBZ0IsRUFBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNoRSxDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDbkIsQ0FBQztJQUVNLFlBQVk7UUFDZixPQUFPLFVBQVUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN2QyxDQUFDO0lBRU0sV0FBVztRQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzlCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7eUZBQ3FGO0lBQzlFLFdBQVc7UUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxnQkFBZ0I7WUFBRSxPQUFPO1FBQ3ZFLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUFFLE9BQU87UUFDL0IsT0FBTyxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3JFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsS0FBSyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVPLEtBQUssQ0FBQyxhQUFhOztRQUN2QixJQUFJLFVBQVUsR0FBRyx5QkFBaUIsQ0FBQztRQUNuQyxPQUFPLElBQUksRUFBRSxDQUFDO1lBQ1YsTUFBTSxJQUFBLGdCQUFLLEVBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEIsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2hCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7Z0JBQzlCLE9BQU87WUFDWCxDQUFDO1lBQ0QsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUFFLE1BQU07WUFDOUIsSUFBSSxDQUFDO2dCQUNELG1FQUFtRTtnQkFDbkUsTUFBTSxDQUFBLE1BQUEsSUFBSSxDQUFDLE1BQU0sMENBQUUsT0FBTyxDQUFDLDJCQUFZLENBQUMsQ0FBQSxDQUFDO2dCQUN6QyxNQUFNO1lBQ1YsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1QseUVBQXlFO2dCQUN6RSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7b0JBQUUsTUFBTTtnQkFDOUIsT0FBTyxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLGlCQUFpQixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxNQUFDLENBQVcsQ0FBQyxLQUFLLG1DQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDbkosQ0FBQztZQUNELFVBQVUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLHVCQUFlLEVBQUUsVUFBVSxHQUFHLG9CQUFZLENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBQ0QsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztRQUM5QixPQUFPLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVELDhGQUE4RjtJQUM5Riw4RkFBOEY7SUFDOUYsbUZBQW1GO0lBQzNFLEtBQUssQ0FBQyxXQUFXO1FBQ3JCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDekIsSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQy9CLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDOUIsSUFBSSxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxHQUFHLHVCQUF1QixDQUFDLEVBQUUsQ0FBQztZQUNyRixPQUFPLE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFDNUIsQ0FBQztRQUNELElBQUksT0FBTyxHQUFHLE1BQU0sTUFBTSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDOUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7UUFDN0QsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNWLE9BQU8sQ0FBQyxJQUFJLENBQUMsb0NBQW9DLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxpQkFBaUIsT0FBTyxDQUFDLFNBQVMsUUFBUSxPQUFPLENBQUMsRUFBRSxzRUFBc0UsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDOU0sQ0FBQztRQUNELE9BQU8sQ0FBQyxPQUFPLENBQUM7SUFDcEIsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJLENBQUksR0FBd0M7UUFDekQsSUFBSSxJQUFJLENBQUMsR0FBRyxJQUFJLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7WUFDdkMsT0FBTyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1gsT0FBTyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1gsdUZBQXVGO1lBQ3ZGLG1DQUFtQztZQUNuQyxPQUFPLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQixDQUFDO1FBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRywyREFBMkQsQ0FBQyxDQUFDO0lBQzFHLENBQUM7SUFFTSxLQUFLLENBQUMsY0FBYztRQUN2QixJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ2pELE9BQU8sTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFNRDs2RkFDeUY7SUFDbEYsWUFBWTs7UUFDZixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzNCLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDdkQsSUFBSSxPQUFPLEdBQUcsS0FBSyxJQUFJLEVBQUU7WUFDckIsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQztnQkFDRCxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN4QixDQUFDO1lBQUMsV0FBTSxDQUFDO2dCQUNMLG9EQUFvRDtnQkFDcEQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNuQixPQUFPO1lBQ1gsQ0FBQztZQUNELElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO2dCQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLCtCQUErQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxLQUFLLENBQUMsQ0FBQztZQUM1RixDQUFDO1lBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDO1lBQ3BDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsWUFBWSxFQUFFLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdkIsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUNGLEtBQUssT0FBTyxFQUFFLENBQUM7UUFDZixJQUFJLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUU7WUFDOUIsS0FBSyxPQUFPLEVBQUUsQ0FBQztRQUNuQixDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDbEIsTUFBQSxNQUFDLElBQUksQ0FBQyxTQUFvQyxFQUFDLEtBQUssa0RBQUksQ0FBQztJQUN6RCxDQUFDO0lBRUQ7d0VBQ29FO0lBQzdELFVBQVU7UUFDYixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2YsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLEdBQUc7Z0JBQUUsT0FBTyxDQUFDLENBQUM7WUFDeEQsT0FBTyxRQUFRLENBQUM7UUFDcEIsQ0FBQztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU07WUFBRSxPQUFPLFFBQVEsQ0FBQztRQUN4QyxJQUFJLE1BQU0sR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdCLElBQUEsV0FBSSxFQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRDsyRUFDdUU7SUFDaEUsS0FBSyxDQUFDLEtBQUssQ0FBSSxHQUF3QztRQUMxRCxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUNuQixJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDUCxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLGdEQUFnRCxDQUFDLENBQUM7UUFDL0YsQ0FBQztRQUNELElBQUksTUFBTSxHQUFHLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzVCLElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUN6RCxPQUFPLE1BQU0sQ0FBQztJQUNsQixDQUFDO0lBRU0sT0FBTztRQUNWLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEMsQ0FBQztJQUNMLENBQUM7Q0FDSjtBQWxNRCxzQ0FrTUMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuYWxsb3djbGllbnQgPSB0cnVlO1xuXG5pbXBvcnQgeyBpc05vZGUsIHNvcnQgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9taXNjXCI7XG5pbXBvcnQgeyBkZWxheSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2JhdGNoaW5nXCI7XG5pbXBvcnQgeyBnZXRTZWNyZXQgfSBmcm9tIFwiLi4vLi4vbWlzYy9nZXRTZWNyZXRcIjtcbmltcG9ydCB7IElBcmNoaXZlcywgSG9zdGVkQ29uZmlnLCBCYWNrYmxhemVDb25maWcgfSBmcm9tIFwiLi4vSUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBST1VUSU5HX0ZJTEUsIGdldEJ1Y2tldEJhc2VVcmwsIHBhcnNlSG9zdGVkVXJsLCBwYXJzZUJhY2tibGF6ZVVybCB9IGZyb20gXCIuL3JlbW90ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgQXJjaGl2ZXNSZW1vdGUgfSBmcm9tIFwiLi9BcmNoaXZlc1JlbW90ZVwiO1xuaW1wb3J0IHsgQXJjaGl2ZXNVcmwgfSBmcm9tIFwiLi9BcmNoaXZlc1VybFwiO1xuaW1wb3J0IHsgQXJjaGl2ZXNCYWNrYmxhemUgfSBmcm9tIFwiLi4vYmFja2JsYXplXCI7XG5pbXBvcnQgeyBnZXRTdG9yYWdlU2VydmVyQ29uZmlnT3B0aW9uYWwsIGdldExvY2FsQXJjaGl2ZXMgfSBmcm9tIFwiLi9zdG9yYWdlU2VydmVyU3RhdGVcIjtcblxuZXhwb3J0IGNvbnN0IFJFVFJZX1NUQVJUX0RFTEFZID0gMiAqIDEwMDA7XG5leHBvcnQgY29uc3QgUkVUUllfTUFYX0RFTEFZID0gNSAqIDYwICogMTAwMDtcbmV4cG9ydCBjb25zdCBSRVRSWV9HUk9XVEggPSAxLjU7XG5jb25zdCBBQ0NFU1NfUkVDSEVDS19JTlRFUlZBTCA9IDYwICogMTAwMDtcbmNvbnN0IFBJTkdfSU5URVJWQUwgPSA2MCAqIDEwMDA7XG5jb25zdCBQSU5HX0hJU1RPUlkgPSAxMDtcblxuYXN5bmMgZnVuY3Rpb24gaGFzQmFja2JsYXplQ3JlZHMoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKCFpc05vZGUoKSkgcmV0dXJuIGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGdldFNlY3JldChcImJhY2tibGF6ZS5qc29uLmFwcGxpY2F0aW9uS2V5SWRcIik7XG4gICAgICAgIGF3YWl0IGdldFNlY3JldChcImJhY2tibGF6ZS5qc29uLmFwcGxpY2F0aW9uS2V5XCIpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuLy8gT25lIHNvdXJjZSBvZiBhIFJlbW90ZUNvbmZpZywgYXMgYSB1c2FibGUgSUFyY2hpdmVzLiBSZWFkcyBmYWxsIGJhY2sgdG8gdGhlIHB1YmxpYy1VUkwgZm9ybSB3aGVuXG4vLyB3ZSBkb24ndCBoYXZlIEFQSSBhY2Nlc3M7IHdyaXRlcyBhbHdheXMgYXR0ZW1wdCB0aGUgQVBJIChzbyBhY2Nlc3MgZ3JhbnRlZCBsYXRlciBpcyBwaWNrZWQgdXAgb25cbi8vIHRoZSBuZXh0IHdyaXRlKS4gV2hlbiBhIGNhbGwgZmFpbHMgd2hpbGUgdGhlIFdlYlNvY2tldCBpcyBkb3duLCBub3RlRmFpbHVyZSBzdGFydHMgYSBiYWNrZ3JvdW5kXG4vLyByZWNvbm5lY3QgbG9vcCB3aXRoIGEgcmFtcGluZyBkZWxheSAtIGl0IG5ldmVyIGJsb2NrcyBjYWxsZXJzLCBpdCBqdXN0IGtlZXBzIHRyeWluZyBzbyB0aGVcbi8vIGNvbm5lY3Rpb24gZXZlbnR1YWxseSBjb21lcyBiYWNrLiBTb3VyY2VzIHdpdGhvdXQgYSBXZWJTb2NrZXQgKGJhY2tibGF6ZSwgVVJMLWZvcm0sIG91ciBvd25cbi8vIGxvY2FsIHNlcnZlcikgcmVwb3J0IGFsd2F5cy1jb25uZWN0ZWQ6IHRoZXkncmUgbGFzdC1yZXNvcnQgc291cmNlcyB3aGVyZSB0aHJvd2luZyBpcyBmaW5lLlxuZXhwb3J0IGNsYXNzIFNvdXJjZVdyYXBwZXIge1xuICAgIHB1YmxpYyBhcGk/OiBJQXJjaGl2ZXM7XG4gICAgcHVibGljIHVybD86IEFyY2hpdmVzVXJsO1xuICAgIHB1YmxpYyB3cml0ZUJsb2NrZWQ/OiBzdHJpbmc7XG4gICAgcHJpdmF0ZSByZW1vdGU/OiBBcmNoaXZlc1JlbW90ZTtcbiAgICBwcml2YXRlIGRpc3Bvc2VkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSByZWNvbm5lY3RSdW5uaW5nID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBhY2Nlc3NDYWNoZT86IHsgaGFzQWNjZXNzOiBib29sZWFuOyB0aW1lOiBudW1iZXIgfTtcblxuICAgIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgICAgIHB1YmxpYyBjb25maWc6IEhvc3RlZENvbmZpZyB8IEJhY2tibGF6ZUNvbmZpZyxcbiAgICAgICAgLy8gZmFsc2UgZm9yIHNob3J0LWxpdmVkIHByb2JlIGluc3RhbmNlcywgd2hpY2ggbXVzdCBuZXZlciBsZWF2ZSBhIHJldHJ5IGxvb3AgYmVoaW5kXG4gICAgICAgIHByaXZhdGUgYmFja2dyb3VuZDogYm9vbGVhbixcbiAgICApIHsgfVxuXG4gICAgcHVibGljIHN0YXRpYyBhc3luYyBjcmVhdGUoY29uZmlnOiBIb3N0ZWRDb25maWcgfCBCYWNrYmxhemVDb25maWcsIG9wdGlvbnM/OiB7IGJhY2tncm91bmQ/OiBib29sZWFuIH0pOiBQcm9taXNlPFNvdXJjZVdyYXBwZXI+IHtcbiAgICAgICAgbGV0IHdyYXBwZXIgPSBuZXcgU291cmNlV3JhcHBlcihjb25maWcsIG9wdGlvbnM/LmJhY2tncm91bmQgIT09IGZhbHNlKTtcbiAgICAgICAgaWYgKGNvbmZpZy50eXBlID09PSBcImJhY2tibGF6ZVwiKSB7XG4gICAgICAgICAgICBpZiAoYXdhaXQgaGFzQmFja2JsYXplQ3JlZHMoKSkge1xuICAgICAgICAgICAgICAgIHdyYXBwZXIuYXBpID0gbmV3IEFyY2hpdmVzQmFja2JsYXplKHsgYnVja2V0TmFtZTogcGFyc2VCYWNrYmxhemVVcmwoY29uZmlnLnVybCkuYnVja2V0TmFtZSwgcHVibGljOiBjb25maWcucHVibGljLCBpbW11dGFibGU6IGNvbmZpZy5pbW11dGFibGUgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzTm9kZSgpKSB7XG4gICAgICAgICAgICAgICAgd3JhcHBlci53cml0ZUJsb2NrZWQgPSBgTm8gYmFja2JsYXplIGNyZWRlbnRpYWxzIGZvciAke2NvbmZpZy51cmx9LiBQcm92aWRlIGJhY2tibGF6ZS5qc29uLmFwcGxpY2F0aW9uS2V5SWQgYW5kIGJhY2tibGF6ZS5qc29uLmFwcGxpY2F0aW9uS2V5IHZpYSBnZXRTZWNyZXQgdG8gZW5hYmxlIEFQSSBhY2Nlc3MuYDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgd3JhcHBlci53cml0ZUJsb2NrZWQgPSBgQnJvd3NlcnMgY2Fubm90IHdyaXRlIHRvIGJhY2tibGF6ZSAoYnVja2V0ICR7Y29uZmlnLnVybH0pYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghd3JhcHBlci5hcGkgJiYgY29uZmlnLnB1YmxpYyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICB3cmFwcGVyLnVybCA9IG5ldyBBcmNoaXZlc1VybChnZXRCdWNrZXRCYXNlVXJsKGNvbmZpZy51cmwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwYXJzZWQgPSBwYXJzZUhvc3RlZFVybChjb25maWcudXJsKTtcbiAgICAgICAgbGV0IHNlcnZlciA9IGlzTm9kZSgpICYmIGdldFN0b3JhZ2VTZXJ2ZXJDb25maWdPcHRpb25hbCgpIHx8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHNlcnZlciAmJiBwYXJzZWQuYWRkcmVzcyA9PT0gc2VydmVyLmRvbWFpbiAmJiBwYXJzZWQucG9ydCA9PT0gc2VydmVyLnBvcnQpIHtcbiAgICAgICAgICAgIC8vIEEgYnVja2V0IGhvc3RlZCBieSBvdXIgb3duIHByb2Nlc3MgLSB1c2UgaXQgZGlyZWN0bHkgaW5zdGVhZCBvZiBjYWxsaW5nIG91cnNlbHZlc1xuICAgICAgICAgICAgd3JhcHBlci5hcGkgPSBnZXRMb2NhbEFyY2hpdmVzKHBhcnNlZC5hY2NvdW50LCBwYXJzZWQuYnVja2V0TmFtZSk7XG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlcjtcbiAgICAgICAgfVxuICAgICAgICB3cmFwcGVyLnJlbW90ZSA9IG5ldyBBcmNoaXZlc1JlbW90ZSh7IHVybDogY29uZmlnLnVybCwgYWNjb3VudE5hbWU6IGNvbmZpZy5hY2NvdW50TmFtZSwgd2FpdEZvckFjY2VzczogZmFsc2UgfSk7XG4gICAgICAgIHdyYXBwZXIuYXBpID0gd3JhcHBlci5yZW1vdGU7XG4gICAgICAgIGlmIChjb25maWcucHVibGljICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgd3JhcHBlci51cmwgPSBuZXcgQXJjaGl2ZXNVcmwoZ2V0QnVja2V0QmFzZVVybChjb25maWcudXJsKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGdldERlYnVnTmFtZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYHNvdXJjZS8ke3RoaXMuY29uZmlnLnVybH1gO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzLnJlbW90ZS5pc0Nvbm5lY3RlZCgpO1xuICAgIH1cblxuICAgIC8qKiBDYWxsIGFmdGVyIGEgcmVxdWVzdCBmYWlsZWQgd2hpbGUgaXNDb25uZWN0ZWQoKSB3YXMgZmFsc2U6IHN0YXJ0cyAoaWYgbm90IGFscmVhZHkgcnVubmluZylcbiAgICAgKiAgdGhlIGJhY2tncm91bmQgcmVjb25uZWN0IGxvb3AuIE5ldmVyIGJsb2NrcyAtIHRoZSBmYWlsZWQgcmVxdWVzdCBzdGlsbCB0aHJvd3MuICovXG4gICAgcHVibGljIG5vdGVGYWlsdXJlKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuYmFja2dyb3VuZCB8fCB0aGlzLmRpc3Bvc2VkIHx8IHRoaXMucmVjb25uZWN0UnVubmluZykgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSByZXR1cm47XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYENhbm5vdCBjb25uZWN0IHRvIHN0b3JhZ2Ugc291cmNlICR7dGhpcy5jb25maWcudXJsfWApO1xuICAgICAgICB0aGlzLnJlY29ubmVjdFJ1bm5pbmcgPSB0cnVlO1xuICAgICAgICB2b2lkIHRoaXMucmVjb25uZWN0TG9vcCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVjb25uZWN0TG9vcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IHJldHJ5RGVsYXkgPSBSRVRSWV9TVEFSVF9ERUxBWTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGF3YWl0IGRlbGF5KHJldHJ5RGVsYXkpO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdFJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSBicmVhaztcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gQW55IGNhbGwgcmUtZXN0YWJsaXNoZXMgdGhlIFdlYlNvY2tldDsgdGhlIHJlc3VsdCBkb2Vzbid0IG1hdHRlclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVtb3RlPy5nZXRJbmZvKFJPVVRJTkdfRklMRSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gRXZlbiBhIGZhaWxpbmcgY2FsbCAoZS5nLiBhY2Nlc3MgZGVuaWVkKSBwcm92ZXMgdGhlIGNvbm5lY3Rpb24gaXMgYmFja1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGVkKCkpIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgQ2Fubm90IGNvbm5lY3QgdG8gc3RvcmFnZSBzb3VyY2UgJHt0aGlzLmNvbmZpZy51cmx9LCByZXRyeWluZyBpbiAke01hdGgucm91bmQocmV0cnlEZWxheSAvIDEwMDApfXMuICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXRyeURlbGF5ID0gTWF0aC5taW4oUkVUUllfTUFYX0RFTEFZLCByZXRyeURlbGF5ICogUkVUUllfR1JPV1RIKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlY29ubmVjdFJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgY29uc29sZS5sb2coYFJlY29ubmVjdGVkIHRvIHN0b3JhZ2Ugc291cmNlICR7dGhpcy5jb25maWcudXJsfWApO1xuICAgIH1cblxuICAgIC8vIEZvciBob3N0ZWQgc291cmNlczogY2FjaGVkIGFjY2VzcyBjaGVjaywgc28gcmVhZHMga25vdyB3aGV0aGVyIHRvIHVzZSB0aGUgQVBJIG9yIHRoZSBwdWJsaWNcbiAgICAvLyBVUkwgZm9ybS4gQWNjZXNzLCBvbmNlIHNlZW4sIGlzIGFzc3VtZWQgdG8gc3RpY2s7IG5vLWFjY2VzcyBpcyByZS1jaGVja2VkIHBlcmlvZGljYWxseSAodGhlXG4gICAgLy8gY2hlY2sgYWxzbyByZWdpc3RlcnMgb3VyIGFjY2VzcyByZXF1ZXN0IHNlcnZlci1zaWRlLCB3aGljaCBsb2dzIHRoZSBncmFudCBsaW5rKS5cbiAgICBwcml2YXRlIGFzeW5jIGNoZWNrQWNjZXNzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBsZXQgcmVtb3RlID0gdGhpcy5yZW1vdGU7XG4gICAgICAgIGlmICghcmVtb3RlKSByZXR1cm4gISF0aGlzLmFwaTtcbiAgICAgICAgbGV0IGNhY2hlZCA9IHRoaXMuYWNjZXNzQ2FjaGU7XG4gICAgICAgIGlmIChjYWNoZWQgJiYgKGNhY2hlZC5oYXNBY2Nlc3MgfHwgRGF0ZS5ub3coKSAtIGNhY2hlZC50aW1lIDwgQUNDRVNTX1JFQ0hFQ0tfSU5URVJWQUwpKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkLmhhc0FjY2VzcztcbiAgICAgICAgfVxuICAgICAgICBsZXQgd2FpdGluZyA9IGF3YWl0IHJlbW90ZS53YWl0aW5nRm9yQWNjZXNzKCk7XG4gICAgICAgIHRoaXMuYWNjZXNzQ2FjaGUgPSB7IGhhc0FjY2VzczogIXdhaXRpbmcsIHRpbWU6IERhdGUubm93KCkgfTtcbiAgICAgICAgaWYgKHdhaXRpbmcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgTm8gYWNjZXNzIHRvIHN0b3JhZ2UgYWNjb3VudCBmb3IgJHt0aGlzLmNvbmZpZy51cmx9IChvdXIgbWFjaGluZSAke3dhaXRpbmcubWFjaGluZUlkfSwgaXAgJHt3YWl0aW5nLmlwfSkuIFJlYWRpbmcgdmlhIHRoZSBwdWJsaWMgVVJMIGZvcm0gd2hlcmUgcG9zc2libGUuIEdyYW50IGFjY2VzcyBhdCAke3dhaXRpbmcubGlua31gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gIXdhaXRpbmc7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJlYWQ8VD4ocnVuOiAoYXJjaGl2ZXM6IElBcmNoaXZlcykgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgICAgICBpZiAodGhpcy5hcGkgJiYgYXdhaXQgdGhpcy5jaGVja0FjY2VzcygpKSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgcnVuKHRoaXMuYXBpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51cmwpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBydW4odGhpcy51cmwpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFwaSkge1xuICAgICAgICAgICAgLy8gTm8gcHVibGljIFVSTCBmb3JtIC0gbGV0IHRoZSBBUEkgY2FsbCB0aHJvdyBpdHMgb3duIGVycm9yICh3aGljaCBpbmNsdWRlcyB0aGUgYWNjZXNzXG4gICAgICAgICAgICAvLyBpbnN0cnVjdGlvbnMgZm9yIGhvc3RlZCBzb3VyY2VzKVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHJ1bih0aGlzLmFwaSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTb3VyY2UgJHt0aGlzLmNvbmZpZy51cmx9IGhhcyBubyBBUEkgYWNjZXNzIGFuZCBubyBwdWJsaWMgVVJMIGZvcm0gKHB1YmxpYzogZmFsc2UpYCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGhhc1dyaXRlQWNjZXNzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBpZiAodGhpcy53cml0ZUJsb2NrZWQgfHwgIXRoaXMuYXBpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmFwaS5oYXNXcml0ZUFjY2VzcygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcGluZ3M6IG51bWJlcltdID0gW107XG4gICAgcHJpdmF0ZSBwaW5nVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPiB8IHVuZGVmaW5lZDtcbiAgICBwcml2YXRlIGxvZ2dlZENvbm5lY3RlZCA9IGZhbHNlO1xuXG4gICAgLyoqIFN0YXJ0cyBtZWFzdXJpbmcgdGhpcyBzb3VyY2UncyBsYXRlbmN5IChmb3IgdmFyaWFibGUtc2hhcmQgdGFyZ2V0IHByZWZlcmVuY2UpLiBPbmx5IGhvc3RlZFxuICAgICAqICByZW1vdGVzIGFyZSBwaW5nZWQ7IG91ciBvd24gbG9jYWwgc2VydmVyIGNvdW50cyBhcyAwLCBldmVyeXRoaW5nIGVsc2UgYXMgSW5maW5pdHkuICovXG4gICAgcHVibGljIHN0YXJ0UGluZ2luZygpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcmVtb3RlID0gdGhpcy5yZW1vdGU7XG4gICAgICAgIGlmICghcmVtb3RlIHx8IHRoaXMucGluZ1RpbWVyIHx8IHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgbGV0IG1lYXN1cmUgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW1vdGUucGluZygpO1xuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgLy8gQSBmYWlsZWQgcGluZyBpcyBhbHNvIG91ciBlYXJsaWVzdCBkb3duLWRldGVjdGlvblxuICAgICAgICAgICAgICAgIHRoaXMubm90ZUZhaWx1cmUoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMubG9nZ2VkQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZWRDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDb25uZWN0ZWQgdG8gc3RvcmFnZSBzb3VyY2UgJHt0aGlzLmNvbmZpZy51cmx9ICgke0RhdGUubm93KCkgLSBzdGFydH1tcylgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucGluZ3MucHVzaChEYXRlLm5vdygpIC0gc3RhcnQpO1xuICAgICAgICAgICAgaWYgKHRoaXMucGluZ3MubGVuZ3RoID4gUElOR19ISVNUT1JZKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5waW5ncy5zaGlmdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB2b2lkIG1lYXN1cmUoKTtcbiAgICAgICAgdGhpcy5waW5nVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICB2b2lkIG1lYXN1cmUoKTtcbiAgICAgICAgfSwgUElOR19JTlRFUlZBTCk7XG4gICAgICAgICh0aGlzLnBpbmdUaW1lciBhcyB7IHVucmVmPzogKCkgPT4gdm9pZCB9KS51bnJlZj8uKCk7XG4gICAgfVxuXG4gICAgLyoqIE1lZGlhbiBvZiB0aGUgcmVjZW50IHBpbmdzLiBTb3VyY2VzIHRoYXQgY2FuJ3QgYmUgcGluZ2VkIHNvcnQgbGFzdCAoSW5maW5pdHkpLCBleGNlcHQgb3VyXG4gICAgICogIG93biBpbi1wcm9jZXNzIHNlcnZlciwgd2hpY2ggaXMgdGhlIGJlc3QgcG9zc2libGUgdGFyZ2V0ICgwKS4gKi9cbiAgICBwdWJsaWMgZ2V0TGF0ZW5jeSgpOiBudW1iZXIge1xuICAgICAgICBpZiAoIXRoaXMucmVtb3RlKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25maWcudHlwZSA9PT0gXCJyZW1vdGVcIiAmJiB0aGlzLmFwaSkgcmV0dXJuIDA7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnBpbmdzLmxlbmd0aCkgcmV0dXJuIEluZmluaXR5O1xuICAgICAgICBsZXQgc29ydGVkID0gWy4uLnRoaXMucGluZ3NdO1xuICAgICAgICBzb3J0KHNvcnRlZCwgeCA9PiB4KTtcbiAgICAgICAgcmV0dXJuIHNvcnRlZFtNYXRoLmZsb29yKHNvcnRlZC5sZW5ndGggLyAyKV07XG4gICAgfVxuXG4gICAgLyoqIFdyaXRlcyBhbHdheXMgZ28gdGhyb3VnaCB0aGUgQVBJLCBzbyBhIHBlcm1pc3Npb24gZXJyb3IgdGhyb3dzIHRvIHRoZSBjYWxsZXIgb24gZXZlcnkgd3JpdGVcbiAgICAgKiAgKGFuZCBhY2Nlc3MgZ3JhbnRlZCBpbiB0aGUgbWVhbnRpbWUgaXMgcGlja2VkIHVwIGF1dG9tYXRpY2FsbHkpLiAqL1xuICAgIHB1YmxpYyBhc3luYyB3cml0ZTxUPihydW46IChhcmNoaXZlczogSUFyY2hpdmVzKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIGlmICh0aGlzLndyaXRlQmxvY2tlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMud3JpdGVCbG9ja2VkKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYXBpID0gdGhpcy5hcGk7XG4gICAgICAgIGlmICghYXBpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNvdXJjZSAke3RoaXMuY29uZmlnLnVybH0gaGFzIG5vIEFQSSBhY2Nlc3MsIHNvIGl0IGNhbm5vdCBhY2NlcHQgd3JpdGVzYCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHJ1bihhcGkpO1xuICAgICAgICB0aGlzLmFjY2Vzc0NhY2hlID0geyBoYXNBY2Nlc3M6IHRydWUsIHRpbWU6IERhdGUubm93KCkgfTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNwb3NlZCA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLnBpbmdUaW1lcikge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnBpbmdUaW1lcik7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=
231
- /* _JS_SOURCE_HASH = "53f9ac041dc89756cc30d98e2196f886861b780f1b4cf4115214d64c4ceaf38c"; */
251
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlV3JhcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNvdXJjZVdyYXBwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsTUFBTSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFFMUIsbURBQXdEO0FBQ3hELDJEQUFxRDtBQUNyRCxvREFBaUQ7QUFFakQsaURBQW1HO0FBQ25HLHFEQUFrRDtBQUNsRCwrQ0FBNEM7QUFDNUMsNENBQWlEO0FBQ2pELDZEQUF3RjtBQUUzRSxRQUFBLGlCQUFpQixHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDN0IsUUFBQSxlQUFlLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDaEMsUUFBQSxZQUFZLEdBQUcsR0FBRyxDQUFDO0FBQ2hDLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUMxQyxNQUFNLGFBQWEsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQztBQUV4QixLQUFLLFVBQVUsaUJBQWlCO0lBQzVCLElBQUksQ0FBQyxJQUFBLGFBQU0sR0FBRTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzVCLElBQUksQ0FBQztRQUNELE1BQU0sSUFBQSxxQkFBUyxFQUFDLGlDQUFpQyxDQUFDLENBQUM7UUFDbkQsTUFBTSxJQUFBLHFCQUFTLEVBQUMsK0JBQStCLENBQUMsQ0FBQztRQUNqRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBQUMsV0FBTSxDQUFDO1FBQ0wsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztBQUNMLENBQUM7QUFFRCxtR0FBbUc7QUFDbkcsbUdBQW1HO0FBQ25HLGtHQUFrRztBQUNsRyw2RkFBNkY7QUFDN0YsOEZBQThGO0FBQzlGLDZGQUE2RjtBQUM3RixNQUFhLGFBQWE7SUFTdEIsWUFDVyxNQUFzQztJQUM3QyxvRkFBb0Y7SUFDNUUsVUFBbUI7UUFGcEIsV0FB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QUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7SUFDTCxDQUFDO0NBQ0o7QUF2TkQsc0NBdU5DIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmFsbG93Y2xpZW50ID0gdHJ1ZTtcblxuaW1wb3J0IHsgaXNOb2RlLCBzb3J0IH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgZGVsYXkgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9iYXRjaGluZ1wiO1xuaW1wb3J0IHsgZ2V0U2VjcmV0IH0gZnJvbSBcIi4uLy4uL21pc2MvZ2V0U2VjcmV0XCI7XG5pbXBvcnQgeyBJQXJjaGl2ZXMsIEhvc3RlZENvbmZpZywgQmFja2JsYXplQ29uZmlnIH0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHsgUk9VVElOR19GSUxFLCBnZXRCdWNrZXRCYXNlVXJsLCBwYXJzZUhvc3RlZFVybCwgcGFyc2VCYWNrYmxhemVVcmwgfSBmcm9tIFwiLi9yZW1vdGVDb25maWdcIjtcbmltcG9ydCB7IEFyY2hpdmVzUmVtb3RlIH0gZnJvbSBcIi4vQXJjaGl2ZXNSZW1vdGVcIjtcbmltcG9ydCB7IEFyY2hpdmVzVXJsIH0gZnJvbSBcIi4vQXJjaGl2ZXNVcmxcIjtcbmltcG9ydCB7IEFyY2hpdmVzQmFja2JsYXplIH0gZnJvbSBcIi4uL2JhY2tibGF6ZVwiO1xuaW1wb3J0IHsgZ2V0U3RvcmFnZVNlcnZlckNvbmZpZ09wdGlvbmFsLCBnZXRMb2NhbEFyY2hpdmVzIH0gZnJvbSBcIi4vc3RvcmFnZVNlcnZlclN0YXRlXCI7XG5cbmV4cG9ydCBjb25zdCBSRVRSWV9TVEFSVF9ERUxBWSA9IDIgKiAxMDAwO1xuZXhwb3J0IGNvbnN0IFJFVFJZX01BWF9ERUxBWSA9IDUgKiA2MCAqIDEwMDA7XG5leHBvcnQgY29uc3QgUkVUUllfR1JPV1RIID0gMS41O1xuY29uc3QgQUNDRVNTX1JFQ0hFQ0tfSU5URVJWQUwgPSA2MCAqIDEwMDA7XG5jb25zdCBQSU5HX0lOVEVSVkFMID0gNjAgKiAxMDAwO1xuY29uc3QgUElOR19ISVNUT1JZID0gMTA7XG5cbmFzeW5jIGZ1bmN0aW9uIGhhc0JhY2tibGF6ZUNyZWRzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICghaXNOb2RlKCkpIHJldHVybiBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCBnZXRTZWNyZXQoXCJiYWNrYmxhemUuanNvbi5hcHBsaWNhdGlvbktleUlkXCIpO1xuICAgICAgICBhd2FpdCBnZXRTZWNyZXQoXCJiYWNrYmxhemUuanNvbi5hcHBsaWNhdGlvbktleVwiKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbi8vIE9uZSBzb3VyY2Ugb2YgYSBSZW1vdGVDb25maWcsIGFzIGEgdXNhYmxlIElBcmNoaXZlcy4gUmVhZHMgZmFsbCBiYWNrIHRvIHRoZSBwdWJsaWMtVVJMIGZvcm0gd2hlblxuLy8gd2UgZG9uJ3QgaGF2ZSBBUEkgYWNjZXNzOyB3cml0ZXMgYWx3YXlzIGF0dGVtcHQgdGhlIEFQSSAoc28gYWNjZXNzIGdyYW50ZWQgbGF0ZXIgaXMgcGlja2VkIHVwIG9uXG4vLyB0aGUgbmV4dCB3cml0ZSkuIFdoZW4gYSBjYWxsIGZhaWxzIHdoaWxlIHRoZSBXZWJTb2NrZXQgaXMgZG93biwgbm90ZUZhaWx1cmUgc3RhcnRzIGEgYmFja2dyb3VuZFxuLy8gcmVjb25uZWN0IGxvb3Agd2l0aCBhIHJhbXBpbmcgZGVsYXkgLSBpdCBuZXZlciBibG9ja3MgY2FsbGVycywgaXQganVzdCBrZWVwcyB0cnlpbmcgc28gdGhlXG4vLyBjb25uZWN0aW9uIGV2ZW50dWFsbHkgY29tZXMgYmFjay4gU291cmNlcyB3aXRob3V0IGEgV2ViU29ja2V0IChiYWNrYmxhemUsIFVSTC1mb3JtLCBvdXIgb3duXG4vLyBsb2NhbCBzZXJ2ZXIpIHJlcG9ydCBhbHdheXMtY29ubmVjdGVkOiB0aGV5J3JlIGxhc3QtcmVzb3J0IHNvdXJjZXMgd2hlcmUgdGhyb3dpbmcgaXMgZmluZS5cbmV4cG9ydCBjbGFzcyBTb3VyY2VXcmFwcGVyIHtcbiAgICBwdWJsaWMgYXBpPzogSUFyY2hpdmVzO1xuICAgIHB1YmxpYyB1cmw/OiBBcmNoaXZlc1VybDtcbiAgICBwdWJsaWMgd3JpdGVCbG9ja2VkPzogc3RyaW5nO1xuICAgIHByaXZhdGUgcmVtb3RlPzogQXJjaGl2ZXNSZW1vdGU7XG4gICAgcHJpdmF0ZSBkaXNwb3NlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgcmVjb25uZWN0UnVubmluZyA9IGZhbHNlO1xuICAgIHByaXZhdGUgYWNjZXNzQ2FjaGU/OiB7IGhhc0FjY2VzczogYm9vbGVhbjsgdGltZTogbnVtYmVyIH07XG5cbiAgICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgICAgICBwdWJsaWMgY29uZmlnOiBIb3N0ZWRDb25maWcgfCBCYWNrYmxhemVDb25maWcsXG4gICAgICAgIC8vIGZhbHNlIGZvciBzaG9ydC1saXZlZCBwcm9iZSBpbnN0YW5jZXMsIHdoaWNoIG11c3QgbmV2ZXIgbGVhdmUgYSByZXRyeSBsb29wIGJlaGluZFxuICAgICAgICBwcml2YXRlIGJhY2tncm91bmQ6IGJvb2xlYW4sXG4gICAgKSB7IH1cblxuICAgIHB1YmxpYyBzdGF0aWMgYXN5bmMgY3JlYXRlKGNvbmZpZzogSG9zdGVkQ29uZmlnIHwgQmFja2JsYXplQ29uZmlnLCBvcHRpb25zPzogeyBiYWNrZ3JvdW5kPzogYm9vbGVhbiB9KTogUHJvbWlzZTxTb3VyY2VXcmFwcGVyPiB7XG4gICAgICAgIGxldCB3cmFwcGVyID0gbmV3IFNvdXJjZVdyYXBwZXIoY29uZmlnLCBvcHRpb25zPy5iYWNrZ3JvdW5kICE9PSBmYWxzZSk7XG4gICAgICAgIGlmIChjb25maWcudHlwZSA9PT0gXCJiYWNrYmxhemVcIikge1xuICAgICAgICAgICAgaWYgKGF3YWl0IGhhc0JhY2tibGF6ZUNyZWRzKCkpIHtcbiAgICAgICAgICAgICAgICB3cmFwcGVyLmFwaSA9IG5ldyBBcmNoaXZlc0JhY2tibGF6ZSh7IGJ1Y2tldE5hbWU6IHBhcnNlQmFja2JsYXplVXJsKGNvbmZpZy51cmwpLmJ1Y2tldE5hbWUsIHB1YmxpYzogY29uZmlnLnB1YmxpYywgaW1tdXRhYmxlOiBjb25maWcuaW1tdXRhYmxlIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc05vZGUoKSkge1xuICAgICAgICAgICAgICAgIHdyYXBwZXIud3JpdGVCbG9ja2VkID0gYE5vIGJhY2tibGF6ZSBjcmVkZW50aWFscyBmb3IgJHtjb25maWcudXJsfS4gUHJvdmlkZSBiYWNrYmxhemUuanNvbi5hcHBsaWNhdGlvbktleUlkIGFuZCBiYWNrYmxhemUuanNvbi5hcHBsaWNhdGlvbktleSB2aWEgZ2V0U2VjcmV0IHRvIGVuYWJsZSBBUEkgYWNjZXNzLmA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHdyYXBwZXIud3JpdGVCbG9ja2VkID0gYEJyb3dzZXJzIGNhbm5vdCB3cml0ZSB0byBiYWNrYmxhemUgKGJ1Y2tldCAke2NvbmZpZy51cmx9KWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXdyYXBwZXIuYXBpICYmIGNvbmZpZy5wdWJsaWMgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgd3JhcHBlci51cmwgPSBuZXcgQXJjaGl2ZXNVcmwoZ2V0QnVja2V0QmFzZVVybChjb25maWcudXJsKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlcjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcGFyc2VkID0gcGFyc2VIb3N0ZWRVcmwoY29uZmlnLnVybCk7XG4gICAgICAgIGxldCBzZXJ2ZXIgPSBpc05vZGUoKSAmJiBnZXRTdG9yYWdlU2VydmVyQ29uZmlnT3B0aW9uYWwoKSB8fCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChzZXJ2ZXIgJiYgcGFyc2VkLmFkZHJlc3MgPT09IHNlcnZlci5kb21haW4gJiYgcGFyc2VkLnBvcnQgPT09IHNlcnZlci5wb3J0KSB7XG4gICAgICAgICAgICAvLyBBIGJ1Y2tldCBob3N0ZWQgYnkgb3VyIG93biBwcm9jZXNzIC0gdXNlIGl0IGRpcmVjdGx5IGluc3RlYWQgb2YgY2FsbGluZyBvdXJzZWx2ZXNcbiAgICAgICAgICAgIHdyYXBwZXIuYXBpID0gZ2V0TG9jYWxBcmNoaXZlcyhwYXJzZWQuYWNjb3VudCwgcGFyc2VkLmJ1Y2tldE5hbWUpO1xuICAgICAgICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgICAgIH1cbiAgICAgICAgd3JhcHBlci5yZW1vdGUgPSBuZXcgQXJjaGl2ZXNSZW1vdGUoeyB1cmw6IGNvbmZpZy51cmwsIGFjY291bnROYW1lOiBjb25maWcuYWNjb3VudE5hbWUsIHdhaXRGb3JBY2Nlc3M6IGZhbHNlIH0pO1xuICAgICAgICB3cmFwcGVyLmFwaSA9IHdyYXBwZXIucmVtb3RlO1xuICAgICAgICBpZiAoY29uZmlnLnB1YmxpYyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHdyYXBwZXIudXJsID0gbmV3IEFyY2hpdmVzVXJsKGdldEJ1Y2tldEJhc2VVcmwoY29uZmlnLnVybCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXREZWJ1Z05hbWUoKTogc3RyaW5nIHtcbiAgICAgICAgLy8gVGhlIHNhbWUgVVJMIGNhbiBhcHBlYXIgYXMgbXVsdGlwbGUgc291cmNlcyAoZGlmZmVyZW50IHJvdXRlcyAvIHZhbGlkIHdpbmRvd3MpLCBzbyB0aGVcbiAgICAgICAgLy8gZGlzdGluZ3Vpc2hpbmcgc2xpY2UgaXMgcGFydCBvZiB0aGUgbmFtZVxuICAgICAgICBsZXQgcGFydHM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGxldCByb3V0ZSA9IHRoaXMuY29uZmlnLnJvdXRlO1xuICAgICAgICBpZiAocm91dGUpIHtcbiAgICAgICAgICAgIHBhcnRzLnB1c2goYHJvdXRlIFske3JvdXRlWzBdfSwgJHtyb3V0ZVsxXX0pYCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IFtzdGFydCwgZW5kXSA9IHRoaXMuY29uZmlnLnZhbGlkV2luZG93O1xuICAgICAgICBpZiAoc3RhcnQgIT09IDAgfHwgZW5kICE9PSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUikge1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGV4dCA9IHN0YXJ0ID09PSAwICYmIFwiMFwiIHx8IG5ldyBEYXRlKHN0YXJ0KS50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgbGV0IGVuZFRleHQgPSBlbmQgPT09IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSICYmIFwiZm9yZXZlclwiIHx8IG5ldyBEYXRlKGVuZCkudG9JU09TdHJpbmcoKTtcbiAgICAgICAgICAgIHBhcnRzLnB1c2goYHZhbGlkV2luZG93IFske3N0YXJ0VGV4dH0sICR7ZW5kVGV4dH1dYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGBzb3VyY2UvJHt0aGlzLmNvbmZpZy51cmx9JHtwYXJ0cy5sZW5ndGggJiYgYCAoJHtwYXJ0cy5qb2luKFwiLCBcIil9KWAgfHwgXCJcIn1gO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzLnJlbW90ZS5pc0Nvbm5lY3RlZCgpO1xuICAgIH1cblxuICAgIC8qKiBDYWxsIGFmdGVyIGEgcmVxdWVzdCBmYWlsZWQgd2hpbGUgaXNDb25uZWN0ZWQoKSB3YXMgZmFsc2U6IHN0YXJ0cyAoaWYgbm90IGFscmVhZHkgcnVubmluZylcbiAgICAgKiAgdGhlIGJhY2tncm91bmQgcmVjb25uZWN0IGxvb3AuIE5ldmVyIGJsb2NrcyAtIHRoZSBmYWlsZWQgcmVxdWVzdCBzdGlsbCB0aHJvd3MuICovXG4gICAgcHVibGljIG5vdGVGYWlsdXJlKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuYmFja2dyb3VuZCB8fCB0aGlzLmRpc3Bvc2VkIHx8IHRoaXMucmVjb25uZWN0UnVubmluZykgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSByZXR1cm47XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYENhbm5vdCBjb25uZWN0IHRvIHN0b3JhZ2UgJHt0aGlzLmdldERlYnVnTmFtZSgpfWApO1xuICAgICAgICB0aGlzLnJlY29ubmVjdFJ1bm5pbmcgPSB0cnVlO1xuICAgICAgICB2b2lkIHRoaXMucmVjb25uZWN0TG9vcCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVjb25uZWN0TG9vcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IHJldHJ5RGVsYXkgPSBSRVRSWV9TVEFSVF9ERUxBWTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGF3YWl0IGRlbGF5KHJldHJ5RGVsYXkpO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdFJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSBicmVhaztcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gQW55IGNhbGwgcmUtZXN0YWJsaXNoZXMgdGhlIFdlYlNvY2tldDsgdGhlIHJlc3VsdCBkb2Vzbid0IG1hdHRlclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVtb3RlPy5nZXRJbmZvKFJPVVRJTkdfRklMRSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gRXZlbiBhIGZhaWxpbmcgY2FsbCAoZS5nLiBhY2Nlc3MgZGVuaWVkKSBwcm92ZXMgdGhlIGNvbm5lY3Rpb24gaXMgYmFja1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGVkKCkpIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgQ2Fubm90IGNvbm5lY3QgdG8gc3RvcmFnZSAke3RoaXMuZ2V0RGVidWdOYW1lKCl9LCByZXRyeWluZyBpbiAke01hdGgucm91bmQocmV0cnlEZWxheSAvIDEwMDApfXMuICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXRyeURlbGF5ID0gTWF0aC5taW4oUkVUUllfTUFYX0RFTEFZLCByZXRyeURlbGF5ICogUkVUUllfR1JPV1RIKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlY29ubmVjdFJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgY29uc29sZS5sb2coYFJlY29ubmVjdGVkIHRvIHN0b3JhZ2UgJHt0aGlzLmdldERlYnVnTmFtZSgpfWApO1xuICAgIH1cblxuICAgIC8vIEZvciBob3N0ZWQgc291cmNlczogY2FjaGVkIGFjY2VzcyBjaGVjaywgc28gcmVhZHMga25vdyB3aGV0aGVyIHRvIHVzZSB0aGUgQVBJIG9yIHRoZSBwdWJsaWNcbiAgICAvLyBVUkwgZm9ybS4gQWNjZXNzLCBvbmNlIHNlZW4sIGlzIGFzc3VtZWQgdG8gc3RpY2s7IG5vLWFjY2VzcyBpcyByZS1jaGVja2VkIHBlcmlvZGljYWxseSAodGhlXG4gICAgLy8gY2hlY2sgYWxzbyByZWdpc3RlcnMgb3VyIGFjY2VzcyByZXF1ZXN0IHNlcnZlci1zaWRlLCB3aGljaCBsb2dzIHRoZSBncmFudCBsaW5rKS5cbiAgICBwcml2YXRlIGFzeW5jIGNoZWNrQWNjZXNzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBsZXQgcmVtb3RlID0gdGhpcy5yZW1vdGU7XG4gICAgICAgIGlmICghcmVtb3RlKSByZXR1cm4gISF0aGlzLmFwaTtcbiAgICAgICAgbGV0IGNhY2hlZCA9IHRoaXMuYWNjZXNzQ2FjaGU7XG4gICAgICAgIGlmIChjYWNoZWQgJiYgKGNhY2hlZC5oYXNBY2Nlc3MgfHwgRGF0ZS5ub3coKSAtIGNhY2hlZC50aW1lIDwgQUNDRVNTX1JFQ0hFQ0tfSU5URVJWQUwpKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkLmhhc0FjY2VzcztcbiAgICAgICAgfVxuICAgICAgICBsZXQgd2FpdGluZyA9IGF3YWl0IHJlbW90ZS53YWl0aW5nRm9yQWNjZXNzKCk7XG4gICAgICAgIHRoaXMuYWNjZXNzQ2FjaGUgPSB7IGhhc0FjY2VzczogIXdhaXRpbmcsIHRpbWU6IERhdGUubm93KCkgfTtcbiAgICAgICAgaWYgKHdhaXRpbmcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgTm8gYWNjZXNzIHRvIHN0b3JhZ2UgYWNjb3VudCBmb3IgJHt0aGlzLmNvbmZpZy51cmx9IChvdXIgbWFjaGluZSAke3dhaXRpbmcubWFjaGluZUlkfSwgaXAgJHt3YWl0aW5nLmlwfSkuIFJlYWRpbmcgdmlhIHRoZSBwdWJsaWMgVVJMIGZvcm0gd2hlcmUgcG9zc2libGUuIEdyYW50IGFjY2VzcyBhdCAke3dhaXRpbmcubGlua31gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gIXdhaXRpbmc7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJlYWQ8VD4ocnVuOiAoYXJjaGl2ZXM6IElBcmNoaXZlcykgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgICAgICBpZiAodGhpcy5hcGkgJiYgYXdhaXQgdGhpcy5jaGVja0FjY2VzcygpKSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgcnVuKHRoaXMuYXBpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51cmwpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBydW4odGhpcy51cmwpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFwaSkge1xuICAgICAgICAgICAgLy8gTm8gcHVibGljIFVSTCBmb3JtIC0gbGV0IHRoZSBBUEkgY2FsbCB0aHJvdyBpdHMgb3duIGVycm9yICh3aGljaCBpbmNsdWRlcyB0aGUgYWNjZXNzXG4gICAgICAgICAgICAvLyBpbnN0cnVjdGlvbnMgZm9yIGhvc3RlZCBzb3VyY2VzKVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHJ1bih0aGlzLmFwaSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTb3VyY2UgJHt0aGlzLmNvbmZpZy51cmx9IGhhcyBubyBBUEkgYWNjZXNzIGFuZCBubyBwdWJsaWMgVVJMIGZvcm0gKHB1YmxpYzogZmFsc2UpYCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGhhc1dyaXRlQWNjZXNzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBpZiAodGhpcy53cml0ZUJsb2NrZWQgfHwgIXRoaXMuYXBpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmFwaS5oYXNXcml0ZUFjY2VzcygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcGluZ3M6IG51bWJlcltdID0gW107XG4gICAgcHJpdmF0ZSBwaW5nVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPiB8IHVuZGVmaW5lZDtcbiAgICBwcml2YXRlIGxvZ2dlZENvbm5lY3RlZCA9IGZhbHNlO1xuXG4gICAgLyoqIFN0YXJ0cyBtZWFzdXJpbmcgdGhpcyBzb3VyY2UncyBsYXRlbmN5IChmb3IgdmFyaWFibGUtc2hhcmQgdGFyZ2V0IHByZWZlcmVuY2UpLiBPbmx5IGhvc3RlZFxuICAgICAqICByZW1vdGVzIGFyZSBwaW5nZWQ7IG91ciBvd24gbG9jYWwgc2VydmVyIGNvdW50cyBhcyAwLCBldmVyeXRoaW5nIGVsc2UgYXMgSW5maW5pdHkuICovXG4gICAgcHVibGljIHN0YXJ0UGluZ2luZygpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcmVtb3RlID0gdGhpcy5yZW1vdGU7XG4gICAgICAgIGlmICghcmVtb3RlIHx8IHRoaXMucGluZ1RpbWVyIHx8IHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgbGV0IG1lYXN1cmUgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW1vdGUucGluZygpO1xuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgLy8gQSBmYWlsZWQgcGluZyBpcyBhbHNvIG91ciBlYXJsaWVzdCBkb3duLWRldGVjdGlvblxuICAgICAgICAgICAgICAgIHRoaXMubm90ZUZhaWx1cmUoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMubG9nZ2VkQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZWRDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDb25uZWN0ZWQgdG8gc3RvcmFnZSAke3RoaXMuZ2V0RGVidWdOYW1lKCl9ICgke0RhdGUubm93KCkgLSBzdGFydH1tcylgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucGluZ3MucHVzaChEYXRlLm5vdygpIC0gc3RhcnQpO1xuICAgICAgICAgICAgaWYgKHRoaXMucGluZ3MubGVuZ3RoID4gUElOR19ISVNUT1JZKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5waW5ncy5zaGlmdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB2b2lkIG1lYXN1cmUoKTtcbiAgICAgICAgdGhpcy5waW5nVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICB2b2lkIG1lYXN1cmUoKTtcbiAgICAgICAgfSwgUElOR19JTlRFUlZBTCk7XG4gICAgICAgICh0aGlzLnBpbmdUaW1lciBhcyB7IHVucmVmPzogKCkgPT4gdm9pZCB9KS51bnJlZj8uKCk7XG4gICAgfVxuXG4gICAgLyoqIFNlZWRzIHRoZSBsYXRlbmN5IGVzdGltYXRlIGJlZm9yZSB0aGUgZmlyc3QgcGluZyBsYW5kcyAoZS5nLiBmcm9tIHRoZSBpbml0aWFsIHJvdXRpbmdcbiAgICAgKiAgZmV0Y2gpLCBzbyB2YXJpYWJsZS1zaGFyZCBwaWNraW5nIGhhcyBzb21ldGhpbmcgaW1tZWRpYXRlbHkuIFJlYWwgcGluZ3MgdGFrZSBvdmVyIGZyb20gdGhlXG4gICAgICogIGZpcnN0IG1lYXN1cmVtZW50IG9uLiAqL1xuICAgIHB1YmxpYyBzZWVkTGF0ZW5jeShtczogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnBpbmdzLmxlbmd0aCkgcmV0dXJuO1xuICAgICAgICB0aGlzLnBpbmdzLnB1c2gobXMpO1xuICAgIH1cblxuICAgIC8qKiBNZWRpYW4gb2YgdGhlIHJlY2VudCBwaW5ncy4gU291cmNlcyB0aGF0IGNhbid0IGJlIHBpbmdlZCBzb3J0IGxhc3QgKEluZmluaXR5KSwgZXhjZXB0IG91clxuICAgICAqICBvd24gaW4tcHJvY2VzcyBzZXJ2ZXIsIHdoaWNoIGlzIHRoZSBiZXN0IHBvc3NpYmxlIHRhcmdldCAoMCkuICovXG4gICAgcHVibGljIGdldExhdGVuY3koKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLnR5cGUgPT09IFwicmVtb3RlXCIgJiYgdGhpcy5hcGkpIHJldHVybiAwO1xuICAgICAgICAgICAgcmV0dXJuIEluZmluaXR5O1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5waW5ncy5sZW5ndGgpIHJldHVybiBJbmZpbml0eTtcbiAgICAgICAgbGV0IHNvcnRlZCA9IFsuLi50aGlzLnBpbmdzXTtcbiAgICAgICAgc29ydChzb3J0ZWQsIHggPT4geCk7XG4gICAgICAgIHJldHVybiBzb3J0ZWRbTWF0aC5mbG9vcihzb3J0ZWQubGVuZ3RoIC8gMildO1xuICAgIH1cblxuICAgIC8qKiBXcml0ZXMgYWx3YXlzIGdvIHRocm91Z2ggdGhlIEFQSSwgc28gYSBwZXJtaXNzaW9uIGVycm9yIHRocm93cyB0byB0aGUgY2FsbGVyIG9uIGV2ZXJ5IHdyaXRlXG4gICAgICogIChhbmQgYWNjZXNzIGdyYW50ZWQgaW4gdGhlIG1lYW50aW1lIGlzIHBpY2tlZCB1cCBhdXRvbWF0aWNhbGx5KS4gKi9cbiAgICBwdWJsaWMgYXN5bmMgd3JpdGU8VD4ocnVuOiAoYXJjaGl2ZXM6IElBcmNoaXZlcykgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgICAgICBpZiAodGhpcy53cml0ZUJsb2NrZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcih0aGlzLndyaXRlQmxvY2tlZCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGFwaSA9IHRoaXMuYXBpO1xuICAgICAgICBpZiAoIWFwaSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTb3VyY2UgJHt0aGlzLmNvbmZpZy51cmx9IGhhcyBubyBBUEkgYWNjZXNzLCBzbyBpdCBjYW5ub3QgYWNjZXB0IHdyaXRlc2ApO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBydW4oYXBpKTtcbiAgICAgICAgdGhpcy5hY2Nlc3NDYWNoZSA9IHsgaGFzQWNjZXNzOiB0cnVlLCB0aW1lOiBEYXRlLm5vdygpIH07XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcHVibGljIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGlzcG9zZWQgPSB0cnVlO1xuICAgICAgICBpZiAodGhpcy5waW5nVGltZXIpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5waW5nVGltZXIpO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19
252
+ /* _JS_SOURCE_HASH = "ba8d9cbc371a1988ca790de602bce14e06c48e99af667c040858bea920a18e39"; */
@@ -32,6 +32,10 @@ export declare class SourceWrapper {
32
32
  /** Starts measuring this source's latency (for variable-shard target preference). Only hosted
33
33
  * remotes are pinged; our own local server counts as 0, everything else as Infinity. */
34
34
  startPinging(): void;
35
+ /** Seeds the latency estimate before the first ping lands (e.g. from the initial routing
36
+ * fetch), so variable-shard picking has something immediately. Real pings take over from the
37
+ * first measurement on. */
38
+ seedLatency(ms: number): void;
35
39
  /** Median of the recent pings. Sources that can't be pinged sort last (Infinity), except our
36
40
  * own in-process server, which is the best possible target (0). */
37
41
  getLatency(): number;
@@ -80,7 +80,20 @@ export class SourceWrapper {
80
80
  }
81
81
 
82
82
  public getDebugName(): string {
83
- return `source/${this.config.url}`;
83
+ // The same URL can appear as multiple sources (different routes / valid windows), so the
84
+ // distinguishing slice is part of the name
85
+ let parts: string[] = [];
86
+ let route = this.config.route;
87
+ if (route) {
88
+ parts.push(`route [${route[0]}, ${route[1]})`);
89
+ }
90
+ let [start, end] = this.config.validWindow;
91
+ if (start !== 0 || end !== Number.MAX_SAFE_INTEGER) {
92
+ let startText = start === 0 && "0" || new Date(start).toISOString();
93
+ let endText = end === Number.MAX_SAFE_INTEGER && "forever" || new Date(end).toISOString();
94
+ parts.push(`validWindow [${startText}, ${endText}]`);
95
+ }
96
+ return `source/${this.config.url}${parts.length && ` (${parts.join(", ")})` || ""}`;
84
97
  }
85
98
 
86
99
  public isConnected(): boolean {
@@ -93,7 +106,7 @@ export class SourceWrapper {
93
106
  public noteFailure(): void {
94
107
  if (!this.background || this.disposed || this.reconnectRunning) return;
95
108
  if (this.isConnected()) return;
96
- console.error(`Cannot connect to storage source ${this.config.url}`);
109
+ console.error(`Cannot connect to storage ${this.getDebugName()}`);
97
110
  this.reconnectRunning = true;
98
111
  void this.reconnectLoop();
99
112
  }
@@ -114,12 +127,12 @@ export class SourceWrapper {
114
127
  } catch (e) {
115
128
  // Even a failing call (e.g. access denied) proves the connection is back
116
129
  if (this.isConnected()) break;
117
- console.warn(`Cannot connect to storage source ${this.config.url}, retrying in ${Math.round(retryDelay / 1000)}s. ${(e as Error).stack ?? e}`);
130
+ console.warn(`Cannot connect to storage ${this.getDebugName()}, retrying in ${Math.round(retryDelay / 1000)}s. ${(e as Error).stack ?? e}`);
118
131
  }
119
132
  retryDelay = Math.min(RETRY_MAX_DELAY, retryDelay * RETRY_GROWTH);
120
133
  }
121
134
  this.reconnectRunning = false;
122
- console.log(`Reconnected to storage source ${this.config.url}`);
135
+ console.log(`Reconnected to storage ${this.getDebugName()}`);
123
136
  }
124
137
 
125
138
  // For hosted sources: cached access check, so reads know whether to use the API or the public
@@ -180,7 +193,7 @@ export class SourceWrapper {
180
193
  }
181
194
  if (!this.loggedConnected) {
182
195
  this.loggedConnected = true;
183
- console.log(`Connected to storage source ${this.config.url} (${Date.now() - start}ms)`);
196
+ console.log(`Connected to storage ${this.getDebugName()} (${Date.now() - start}ms)`);
184
197
  }
185
198
  this.pings.push(Date.now() - start);
186
199
  if (this.pings.length > PING_HISTORY) {
@@ -194,6 +207,14 @@ export class SourceWrapper {
194
207
  (this.pingTimer as { unref?: () => void }).unref?.();
195
208
  }
196
209
 
210
+ /** Seeds the latency estimate before the first ping lands (e.g. from the initial routing
211
+ * fetch), so variable-shard picking has something immediately. Real pings take over from the
212
+ * first measurement on. */
213
+ public seedLatency(ms: number): void {
214
+ if (this.pings.length) return;
215
+ this.pings.push(ms);
216
+ }
217
+
197
218
  /** Median of the recent pings. Sources that can't be pinged sort last (Infinity), except our
198
219
  * own in-process server, which is the best possible target (0). */
199
220
  public getLatency(): number {
@@ -223,7 +223,7 @@ function scheduleWindowBoundaryRebuild(loaded: LoadedBucket): void {
223
223
  scheduleWindowBoundaryRebuild(loaded);
224
224
  return;
225
225
  }
226
- await scheduleRoutingReload(loaded.account, loaded.bucketName, { force: true });
226
+ await scheduleRoutingReload(loaded.account, loaded.bucketName, { force: true, reason: "a valid window boundary passed" });
227
227
  })();
228
228
  }, Math.min(nextBoundary - now + REBUILD_BOUNDARY_BUFFER, MAX_REBUILD_TIMER_DELAY));
229
229
  (timer as { unref?: () => void }).unref?.();
@@ -322,16 +322,16 @@ export function getLoadedBucket(account: string, bucketName: string): Promise<Lo
322
322
  // Routing reloads are serialized per bucket, so concurrent writes/syncs can't rebuild the same
323
323
  // store twice in parallel
324
324
  const routingReloads = new Map<string, Promise<void>>();
325
- function scheduleRoutingReload(account: string, bucketName: string, config?: { force?: boolean }): Promise<void> {
325
+ function scheduleRoutingReload(account: string, bucketName: string, config?: { force?: boolean; reason?: string }): Promise<void> {
326
326
  let key = `${account}/${bucketName}`;
327
327
  let next = (routingReloads.get(key) || Promise.resolve())
328
- .then(() => checkRoutingChanged(account, bucketName, config?.force))
328
+ .then(() => checkRoutingChanged(account, bucketName, config))
329
329
  .catch(e => console.error(`Reloading routing config for bucket ${key} failed:`, e));
330
330
  routingReloads.set(key, next);
331
331
  return next;
332
332
  }
333
333
 
334
- async function checkRoutingChanged(account: string, bucketName: string, force?: boolean): Promise<void> {
334
+ async function checkRoutingChanged(account: string, bucketName: string, config?: { force?: boolean; reason?: string }): Promise<void> {
335
335
  let key = `${account}/${bucketName}`;
336
336
  let loaded = await buckets.get(key);
337
337
  if (!loaded) return;
@@ -340,9 +340,9 @@ async function checkRoutingChanged(account: string, bucketName: string, force?:
340
340
  let data = await loaded.store.get(ROUTING_FILE);
341
341
  if (!data) return;
342
342
  let routing = parseRoutingData(data);
343
- if (!force && JSON.stringify(routing) === loaded.routingJSON) return;
344
- if (force) {
345
- console.log(`Rebuilding the store for bucket ${key} (a valid window boundary passed)`);
343
+ if (!config?.force && JSON.stringify(routing) === loaded.routingJSON) return;
344
+ if (config?.force) {
345
+ console.log(`Rebuilding the store for bucket ${key} (${config.reason || "forced"})`);
346
346
  } else {
347
347
  console.log(`Routing config changed for bucket ${key}, rebuilding its store`);
348
348
  }
@@ -368,6 +368,16 @@ export async function assertMutable(bucket: LoadedBucket, filePath: string, writ
368
368
  }
369
369
  }
370
370
 
371
+ // Wrong-target rejections are rare and important (they ARE the switchover handoff), but a burst of
372
+ // racing writes at a boundary must not flood the log - so at most one line a minute
373
+ const WRONG_TARGET_LOG_THROTTLE = 60 * 1000;
374
+ let lastWrongTargetLog = 0;
375
+ function logWrongTargetRejection(message: string): void {
376
+ if (Date.now() - lastWrongTargetLog < WRONG_TARGET_LOG_THROTTLE) return;
377
+ lastWrongTargetLog = Date.now();
378
+ console.log(message);
379
+ }
380
+
371
381
  // Routing writes are serialized per bucket, so two concurrent creates can't both build a store
372
382
  // (the loser's store would leak with its sync loops running forever)
373
383
  const routingWrites = new Map<string, Promise<void>>();
@@ -421,9 +431,11 @@ export async function writeBucketFile(account: string, bucketName: string, fileP
421
431
  if (!config?.lastModified && loaded.selfEntries.length) {
422
432
  let timeValid = loaded.selfEntries.filter(x => writeTime >= x.validWindow[0] - WRITE_PAST_WINDOW_GRACE && writeTime <= x.validWindow[1] + WRITE_PAST_WINDOW_GRACE);
423
433
  if (!timeValid.length) {
434
+ logWrongTargetRejection(`Rejecting fresh write of ${JSON.stringify(filePath)} to bucket ${account}/${bucketName}: outside our valid windows (a switchover moved the write target)`);
424
435
  throw new Error(`${STORAGE_WRONG_VALID_WINDOW} This server is not a valid write target at ${writeTime} for bucket ${account}/${bucketName} (our valid windows: ${JSON.stringify(loaded.selfEntries.map(x => x.validWindow))}). Re-resolve the currently valid source and retry.`);
425
436
  }
426
437
  if (!timeValid.some(x => routeContains(x.route, route))) {
438
+ logWrongTargetRejection(`Rejecting fresh write of ${JSON.stringify(filePath)} to bucket ${account}/${bucketName}: route ${route} is not ours (the client's shard config is stale)`);
427
439
  throw new Error(`${STORAGE_WRONG_ROUTE} This server does not handle route ${route} (key ${JSON.stringify(filePath)}) for bucket ${account}/${bucketName} (our routes at this time: ${JSON.stringify(timeValid.map(x => x.route || FULL_ROUTE))}). Re-resolve the source for this key and retry.`);
428
440
  }
429
441
  }
@@ -448,11 +460,12 @@ export function getBucketConfig(bucket: LoadedBucket): ArchivesConfig {
448
460
  export async function rebuildAllLoadedBuckets(): Promise<void> {
449
461
  for (let key of [...buckets.keys()]) {
450
462
  let slash = key.indexOf("/");
451
- await scheduleRoutingReload(key.slice(0, slash), key.slice(slash + 1), { force: true });
463
+ await scheduleRoutingReload(key.slice(0, slash), key.slice(slash + 1), { force: true, reason: "deploy takeover state changed" });
452
464
  }
453
465
  }
454
466
 
455
467
  export async function rescanAllLoadedBucketDisks(): Promise<void> {
468
+ console.log(`Deploy switchover disk rescan starting (${buckets.size} loaded buckets) - catching files the other process wrote`);
456
469
  for (let loadedPromise of [...buckets.values()]) {
457
470
  let loaded = await loadedPromise.catch(() => undefined);
458
471
  if (!loaded) continue;
package/yarn.lock CHANGED
@@ -1944,10 +1944,10 @@ slash@^3.0.0:
1944
1944
  resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
1945
1945
  integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
1946
1946
 
1947
- socket-function@^1.2.24:
1948
- version "1.2.24"
1949
- resolved "https://registry.yarnpkg.com/socket-function/-/socket-function-1.2.24.tgz#3683e93f0fe84a8b3076fd9cd18b45baef941286"
1950
- integrity sha512-Y6da2A16MUPc2E/yJ4tJJAWXszIxgYaA/sVz0gKdZCb5nADCZeUAXE15bfkhX9HWn0zQv8AzXXkKHs78vhQVwQ==
1947
+ socket-function@^1.2.25:
1948
+ version "1.2.25"
1949
+ resolved "https://registry.yarnpkg.com/socket-function/-/socket-function-1.2.25.tgz#4f715d96354596e781d9619fe8725d7ab243a878"
1950
+ integrity sha512-4jalIocImnTG5cw7IJ5XtMwVN3fySTKN+Kyixl6I/R6IYXzPP8HspXi0c1D18SRcFwZZuG06+2FWv5xB+ny/mw==
1951
1951
  dependencies:
1952
1952
  "@types/pako" "^2.0.3"
1953
1953
  "@types/ws" "^8.5.3"