sliftutils 1.7.18 → 1.7.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +5 -0
- package/package.json +1 -1
- package/storage/remoteStorage/blobStore.d.ts +1 -0
- package/storage/remoteStorage/blobStore.ts +12 -0
- package/storage/remoteStorage/createArchives.ts +22 -3
- package/storage/remoteStorage/deployTakeover.ts +77 -38
- package/storage/remoteStorage/dist/createArchives.ts.cache +13 -4
- package/storage/remoteStorage/dist/sourceWrapper.ts.cache +28 -7
- package/storage/remoteStorage/sourceWrapper.d.ts +4 -0
- package/storage/remoteStorage/sourceWrapper.ts +26 -5
- package/storage/remoteStorage/storageServerState.ts +21 -8
package/index.d.ts
CHANGED
|
@@ -3155,6 +3155,7 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
|
|
|
3155
3155
|
cancelLargeUpload(id: string): Promise<void>;
|
|
3156
3156
|
private flushOverlay;
|
|
3157
3157
|
private evicting;
|
|
3158
|
+
private loggedFlushDeadline;
|
|
3158
3159
|
private enforceDiskLimit;
|
|
3159
3160
|
private cleanupTombstones;
|
|
3160
3161
|
}
|
|
@@ -3377,6 +3378,10 @@ declare module "sliftutils/storage/remoteStorage/sourceWrapper" {
|
|
|
3377
3378
|
/** Starts measuring this source's latency (for variable-shard target preference). Only hosted
|
|
3378
3379
|
* remotes are pinged; our own local server counts as 0, everything else as Infinity. */
|
|
3379
3380
|
startPinging(): void;
|
|
3381
|
+
/** Seeds the latency estimate before the first ping lands (e.g. from the initial routing
|
|
3382
|
+
* fetch), so variable-shard picking has something immediately. Real pings take over from the
|
|
3383
|
+
* first measurement on. */
|
|
3384
|
+
seedLatency(ms: number): void;
|
|
3380
3385
|
/** Median of the recent pings. Sources that can't be pinged sort last (Infinity), except our
|
|
3381
3386
|
* own in-process server, which is the best possible target (0). */
|
|
3382
3387
|
getLatency(): number;
|
package/package.json
CHANGED
|
@@ -169,6 +169,7 @@ export declare class BlobStore implements IBucketStore {
|
|
|
169
169
|
cancelLargeUpload(id: string): Promise<void>;
|
|
170
170
|
private flushOverlay;
|
|
171
171
|
private evicting;
|
|
172
|
+
private loggedFlushDeadline;
|
|
172
173
|
private enforceDiskLimit;
|
|
173
174
|
private cleanupTombstones;
|
|
174
175
|
}
|
|
@@ -674,6 +674,10 @@ export class BlobStore implements IBucketStore {
|
|
|
674
674
|
let deadline = this.config?.getFlushDeadline?.();
|
|
675
675
|
if (deadline !== undefined) {
|
|
676
676
|
if (Date.now() >= deadline) {
|
|
677
|
+
if (!this.loggedFlushDeadline) {
|
|
678
|
+
this.loggedFlushDeadline = true;
|
|
679
|
+
console.log(`Deploy switchover flush deadline passed (store ${this.folder}): fast writes now write through immediately`);
|
|
680
|
+
}
|
|
677
681
|
this.overlay.delete(key);
|
|
678
682
|
await this.writeToSources(key, data, writeTime);
|
|
679
683
|
return key;
|
|
@@ -854,11 +858,14 @@ export class BlobStore implements IBucketStore {
|
|
|
854
858
|
// holds a same-or-newer copy (the only copy of a file is never deleted), and the index entry
|
|
855
859
|
// repoints to that source so reads keep working (re-caching on the next read).
|
|
856
860
|
private evicting = false;
|
|
861
|
+
private loggedFlushDeadline = false;
|
|
857
862
|
private async enforceDiskLimit(): Promise<void> {
|
|
858
863
|
let limit = this.config?.readerDiskLimit;
|
|
859
864
|
if (!limit || this.evicting) return;
|
|
860
865
|
if (this.sourceByteCounts[0] <= limit) return;
|
|
861
866
|
this.evicting = true;
|
|
867
|
+
let evictedFiles = 0;
|
|
868
|
+
let evictedBytes = 0;
|
|
862
869
|
try {
|
|
863
870
|
let candidates: { key: string; entry: IndexEntry }[] = [];
|
|
864
871
|
for (let [key, entry] of this.mem) {
|
|
@@ -885,9 +892,14 @@ export class BlobStore implements IBucketStore {
|
|
|
885
892
|
if (holder === undefined) continue;
|
|
886
893
|
await this.sources[0].source.del(key);
|
|
887
894
|
this.setIndexEntry(key, { writeTime: entry.writeTime, size: entry.size, source: holder });
|
|
895
|
+
evictedFiles++;
|
|
896
|
+
evictedBytes += entry.size;
|
|
888
897
|
}
|
|
889
898
|
} finally {
|
|
890
899
|
this.evicting = false;
|
|
900
|
+
if (evictedFiles) {
|
|
901
|
+
console.log(`Disk cache over readerDiskLimit (store ${this.folder}): evicted ${evictedFiles} least-recently-used files (${formatNumber(evictedBytes)}B), now at ${formatNumber(this.sourceByteCounts[0])}B/${formatNumber(this.config?.readerDiskLimit || 0)}B`);
|
|
902
|
+
}
|
|
891
903
|
}
|
|
892
904
|
}
|
|
893
905
|
|
|
@@ -133,11 +133,12 @@ export class ArchivesChain implements IArchives {
|
|
|
133
133
|
// that answered (the first up source is authoritative).
|
|
134
134
|
let fetches = await Promise.all(configs.map(async sourceConfig => {
|
|
135
135
|
let probe = await SourceWrapper.create(sourceConfig, { background: false });
|
|
136
|
+
let start = Date.now();
|
|
136
137
|
try {
|
|
137
138
|
let data = await probe.read(archives => archives.get(ROUTING_FILE));
|
|
138
|
-
return { probe, sourceConfig, responded: true, existing: data && parseRoutingData(data) || undefined, error: "" };
|
|
139
|
+
return { probe, sourceConfig, responded: true, latency: Date.now() - start, existing: data && parseRoutingData(data) || undefined, error: "" };
|
|
139
140
|
} catch (e) {
|
|
140
|
-
return { probe, sourceConfig, responded: false, existing: undefined, error: `${sourceConfig.url}: ${(e as Error).stack ?? e}` };
|
|
141
|
+
return { probe, sourceConfig, responded: false, latency: 0, existing: undefined, error: `${sourceConfig.url}: ${(e as Error).stack ?? e}` };
|
|
141
142
|
}
|
|
142
143
|
}));
|
|
143
144
|
try {
|
|
@@ -222,6 +223,14 @@ export class ArchivesChain implements IArchives {
|
|
|
222
223
|
}
|
|
223
224
|
}
|
|
224
225
|
}
|
|
226
|
+
// The routing fetches double as our first latency measurements: variable-shard picking
|
|
227
|
+
// works immediately, instead of waiting for the first ping pass to land
|
|
228
|
+
for (let source of sources) {
|
|
229
|
+
let fetch = fetches.find(x => x.responded && x.sourceConfig.url === source.config.url);
|
|
230
|
+
if (fetch) {
|
|
231
|
+
source.seedLatency(fetch.latency);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
225
234
|
this.activeConfig = active;
|
|
226
235
|
this.startConfigPoll();
|
|
227
236
|
return { config: active, sources };
|
|
@@ -295,7 +304,13 @@ export class ArchivesChain implements IArchives {
|
|
|
295
304
|
|
|
296
305
|
private async adoptNewConfig(state: ChainState, latest: RemoteConfig): Promise<void> {
|
|
297
306
|
if (JSON.stringify(latest) === JSON.stringify(state.config)) return;
|
|
298
|
-
|
|
307
|
+
// Same version but different content is a deploy switchover remap (an in-memory window
|
|
308
|
+
// split pointing at a successor's port), not an actual configuration change
|
|
309
|
+
if (getConfigVersion(latest) === getConfigVersion(state.config)) {
|
|
310
|
+
console.log(`Storage routing reinterpreted at version ${getConfigVersion(latest)} for ${this.getDebugName()} (deploy switchover in progress), rebuilding sources. Sources: ${JSON.stringify(latest.sources)}`);
|
|
311
|
+
} else {
|
|
312
|
+
console.log(`Storage routing config changed for ${this.getDebugName()} (version ${getConfigVersion(state.config)} -> ${getConfigVersion(latest)}), rebuilding sources`);
|
|
313
|
+
}
|
|
299
314
|
let oldByConfig = new Map(state.sources.map(source => [JSON.stringify(source.config), source]));
|
|
300
315
|
let sources: SourceWrapper[] = [];
|
|
301
316
|
for (let sourceConfig of latest.sources.map(normalizeSource)) {
|
|
@@ -342,6 +357,7 @@ export class ArchivesChain implements IArchives {
|
|
|
342
357
|
// Init is failing; its own retry loop handles that
|
|
343
358
|
return;
|
|
344
359
|
}
|
|
360
|
+
console.log(`Every storage source failed for ${this.getDebugName()}; re-contacting all ${state.sources.length} sources (routing re-read + connection re-attempt)`);
|
|
345
361
|
let results = await Promise.all(state.sources.map(async source => {
|
|
346
362
|
try {
|
|
347
363
|
let data = await source.read(archives => archives.get(ROUTING_FILE));
|
|
@@ -456,12 +472,14 @@ export class ArchivesChain implements IArchives {
|
|
|
456
472
|
let now = Date.now();
|
|
457
473
|
let nearBoundary = state.sources.some(source => source.config.validWindow.some(t => t > 0 && t < Number.MAX_SAFE_INTEGER && Math.abs(t - now) <= WRONG_TARGET_BOUNDARY_WINDOW));
|
|
458
474
|
if (nearBoundary) {
|
|
475
|
+
console.log(`Write rejected by ${this.getDebugName()}: raced a valid window boundary; waiting ${WRONG_TARGET_BOUNDARY_RETRY_DELAY / 1000}s and retrying`);
|
|
459
476
|
await delay(WRONG_TARGET_BOUNDARY_RETRY_DELAY);
|
|
460
477
|
return;
|
|
461
478
|
}
|
|
462
479
|
}
|
|
463
480
|
if (Date.now() - this.lastConfigRefresh < CONFIG_REFRESH_THROTTLE) return;
|
|
464
481
|
this.lastConfigRefresh = Date.now();
|
|
482
|
+
console.log(`Write rejected by ${this.getDebugName()} (wrong ${kind}): our config is stale (likely a deploy switchover); refreshing it and retrying`);
|
|
465
483
|
await this.refreshActiveConfig();
|
|
466
484
|
}
|
|
467
485
|
|
|
@@ -665,6 +683,7 @@ export class ArchivesChain implements IArchives {
|
|
|
665
683
|
// NOTE: If we run into cases when transport level errors happen, but we are still connected, then we might want to add additional checking here, additional errors in which we will retry the other targets. However, ideally, checking if the WebSocket connection is still connected will handle all those cases. Distinguishing between application errors (which we can't retry) and transport errors.
|
|
666
684
|
if (target.isConnected()) throw e;
|
|
667
685
|
target.noteFailure();
|
|
686
|
+
console.log(`Variable-shard write target ${target.getDebugName()} is down; moving to the next-lowest-latency shard`);
|
|
668
687
|
errors.push(String((e as Error).stack ?? e));
|
|
669
688
|
}
|
|
670
689
|
}
|
|
@@ -20,7 +20,6 @@ import { parseHostedUrl, replaceHostedUrlPort } from "./remoteConfig";
|
|
|
20
20
|
// any point during a switchover.
|
|
21
21
|
|
|
22
22
|
const PARAMETERS_TIMELINE_FILE_REGEX = /^(\d+)-parameters\.json$/;
|
|
23
|
-
const ALIVE_WINDOW_FOREVER = Number.MAX_SAFE_INTEGER;
|
|
24
23
|
const TIMELINE_POLL_INTERVAL = 60 * 1000;
|
|
25
24
|
// Processes listening on an alternate port register it here (sibling of the storage folder), keyed
|
|
26
25
|
// by their actual pid; content includes their ancestor pids so the timeline entry pid (a shell
|
|
@@ -42,8 +41,10 @@ const REMAP_EXPIRE_FRACTION = 2;
|
|
|
42
41
|
|
|
43
42
|
type TimelineEntry = {
|
|
44
43
|
pid?: number;
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
// releaseTime + overlapTime define everything: the newer entry's releaseTime is when it
|
|
45
|
+
// starts, and releaseTime + overlapTime is when the older one is killed (freeing the port).
|
|
46
|
+
// The files also carry an aliveWindow, which is deliberately ignored.
|
|
47
|
+
parameters: { releaseTime?: number; overlapTime?: number };
|
|
47
48
|
};
|
|
48
49
|
|
|
49
50
|
type TakeoverComputed = {
|
|
@@ -67,6 +68,8 @@ let current: TakeoverComputed = {};
|
|
|
67
68
|
let currentKey = JSON.stringify(current);
|
|
68
69
|
let eventListeners: ((event: TakeoverEvent) => void)[] = [];
|
|
69
70
|
let eventTimers: ReturnType<typeof setTimeout>[] = [];
|
|
71
|
+
let loggedNoMatch = false;
|
|
72
|
+
let loggedIdentity = false;
|
|
70
73
|
|
|
71
74
|
function execText(command: string): Promise<string> {
|
|
72
75
|
return new Promise((resolve, reject) => {
|
|
@@ -103,20 +106,10 @@ async function getAncestorPids(): Promise<Set<number>> {
|
|
|
103
106
|
return pids;
|
|
104
107
|
}
|
|
105
108
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
files = await fs.promises.readdir(dir);
|
|
112
|
-
} catch { }
|
|
113
|
-
if (files.some(file => PARAMETERS_TIMELINE_FILE_REGEX.test(file))) {
|
|
114
|
-
return dir.replaceAll("\\", "/") + "/";
|
|
115
|
-
}
|
|
116
|
-
let parent = path.dirname(dir);
|
|
117
|
-
if (parent === dir) return undefined;
|
|
118
|
-
dir = parent;
|
|
119
|
-
}
|
|
109
|
+
// The instance folder is ALWAYS the parent of our cwd (services run in <instance>/git/) - never
|
|
110
|
+
// search for it, a walk could latch onto the wrong folder
|
|
111
|
+
function getTimelineFolder(): string {
|
|
112
|
+
return path.dirname(process.cwd()).replaceAll("\\", "/") + "/";
|
|
120
113
|
}
|
|
121
114
|
|
|
122
115
|
function pidAlive(pid: number): boolean {
|
|
@@ -211,8 +204,11 @@ function scheduleEvents(): void {
|
|
|
211
204
|
};
|
|
212
205
|
let remap = current.remap;
|
|
213
206
|
if (remap) {
|
|
207
|
+
let altPort = remap.altPort;
|
|
214
208
|
schedule(remap.boundaryA - SWITCH_SCAN_LEAD, () => emit("diskScan"));
|
|
209
|
+
schedule(remap.boundaryA, () => console.log(`Deploy switchover write handoff boundary passed: fresh writes now belong to the alternate-port side (port ${altPort})`));
|
|
215
210
|
schedule(remap.boundaryA + SWITCH_SCAN_LEAD, () => emit("diskScan"));
|
|
211
|
+
schedule(remap.boundaryB, () => console.log(`Deploy switchover second boundary passed: fresh writes return to the main port`));
|
|
216
212
|
schedule(remap.expire, () => void recompute().catch((e: Error) => console.error(`Deploy takeover recompute failed: ${e.stack ?? e}`)));
|
|
217
213
|
}
|
|
218
214
|
}
|
|
@@ -228,26 +224,42 @@ async function recompute(): Promise<void> {
|
|
|
228
224
|
us = entry;
|
|
229
225
|
}
|
|
230
226
|
}
|
|
227
|
+
// Matching failures must be loud, or takeover detection fails silently forever
|
|
228
|
+
if (!us && entries.length && !loggedNoMatch) {
|
|
229
|
+
loggedNoMatch = true;
|
|
230
|
+
console.warn(`No deploy timeline entry matches our pid chain (${[...ancestorPids].join(", ")}) - takeover detection cannot work. Entries: ${entries.map(x => `pid=${x.pid ?? "none"} releaseTime=${x.parameters.releaseTime}`).join(" | ")}`);
|
|
231
|
+
}
|
|
232
|
+
if (us && !loggedIdentity) {
|
|
233
|
+
loggedIdentity = true;
|
|
234
|
+
console.log(`Deploy timeline entry matched: we are pid=${us.pid}, releaseTime=${us.parameters.releaseTime !== undefined && iso(us.parameters.releaseTime) || "unknown"}, ${entries.length} entries total`);
|
|
235
|
+
}
|
|
231
236
|
let computed: TakeoverComputed = {};
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
237
|
+
let usRelease = us?.parameters.releaseTime;
|
|
238
|
+
if (us && usRelease !== undefined) {
|
|
239
|
+
// The newer entry's releaseTime is when it starts; releaseTime + overlapTime is when the
|
|
240
|
+
// older one is killed. That's the whole timeline.
|
|
241
|
+
let next: { entry: TimelineEntry; release: number } | undefined;
|
|
242
|
+
let prev: { entry: TimelineEntry; release: number } | undefined;
|
|
236
243
|
for (let entry of entries) {
|
|
237
244
|
if (entry === us) continue;
|
|
238
|
-
|
|
239
|
-
|
|
245
|
+
let release = entry.parameters.releaseTime;
|
|
246
|
+
if (release === undefined) continue;
|
|
247
|
+
if (release > usRelease && (!next || release < next.release)) {
|
|
248
|
+
next = { entry, release };
|
|
240
249
|
}
|
|
241
|
-
if (
|
|
242
|
-
prev = entry;
|
|
250
|
+
if (release < usRelease && (!prev || release > prev.release)) {
|
|
251
|
+
prev = { entry, release };
|
|
243
252
|
}
|
|
244
253
|
}
|
|
245
|
-
if (next
|
|
246
|
-
let
|
|
247
|
-
let
|
|
254
|
+
if (next) {
|
|
255
|
+
let successorStart = next.release;
|
|
256
|
+
let overlap = next.entry.parameters.overlapTime || us.parameters.overlapTime || 0;
|
|
257
|
+
// Even a ZERO-overlap deploy needs the dying behaviors - draining fast-write flushes
|
|
258
|
+
// by the release and writing through after it, or acknowledged data dies with us.
|
|
259
|
+
// Only the remap (the alternate-port middle window) needs an actual overlap.
|
|
260
|
+
computed.dying = { successorStart, overlap };
|
|
248
261
|
if (overlap > 0 && now < successorStart + overlap * REMAP_EXPIRE_FRACTION) {
|
|
249
|
-
|
|
250
|
-
const successorPid = next.pid;
|
|
262
|
+
const successorPid = next.entry.pid;
|
|
251
263
|
if (successorPid) {
|
|
252
264
|
let successorEntry = registry.find(x => x.ancestorPids.includes(successorPid));
|
|
253
265
|
if (successorEntry) {
|
|
@@ -256,31 +268,58 @@ async function recompute(): Promise<void> {
|
|
|
256
268
|
}
|
|
257
269
|
}
|
|
258
270
|
}
|
|
259
|
-
if (prev
|
|
260
|
-
let overlap = prev.
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
271
|
+
if (prev) {
|
|
272
|
+
let overlap = us.parameters.overlapTime || prev.entry.parameters.overlapTime || 0;
|
|
273
|
+
// The predecessor holds the main port until OUR release + the overlap
|
|
274
|
+
computed.predecessorEnd = usRelease + overlap;
|
|
275
|
+
if (overlap > 0 && ourAltPort && now < usRelease + overlap * REMAP_EXPIRE_FRACTION && !computed.remap) {
|
|
276
|
+
computed.remap = makeRemap(usRelease, overlap, ourAltPort);
|
|
264
277
|
}
|
|
265
278
|
}
|
|
266
279
|
}
|
|
267
280
|
let key = JSON.stringify(computed);
|
|
268
281
|
if (key === currentKey) return;
|
|
282
|
+
logTransitions(current, computed);
|
|
269
283
|
current = computed;
|
|
270
284
|
currentKey = key;
|
|
271
|
-
console.log(`Deploy takeover state changed: ${key}`);
|
|
272
285
|
scheduleEvents();
|
|
273
286
|
emit("remapChanged");
|
|
274
287
|
}
|
|
275
288
|
|
|
289
|
+
function iso(time: number): string {
|
|
290
|
+
return new Date(time).toISOString();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// The switchover lifecycle is rare and important, so every stage gets a clear line
|
|
294
|
+
function logTransitions(prev: TakeoverComputed, next: TakeoverComputed): void {
|
|
295
|
+
if (!prev.dying && next.dying) {
|
|
296
|
+
let { successorStart, overlap } = next.dying;
|
|
297
|
+
console.log(`Deploy switchover scheduled: our successor starts at ${iso(successorStart)}; fast-write flushes drain by ${iso(successorStart + overlap * FLUSH_DEADLINE_FRACTION)}, fresh writes hand off at ${iso(successorStart + overlap * BOUNDARY_A_FRACTION)}, and we are killed at ${iso(successorStart + overlap)}`);
|
|
298
|
+
}
|
|
299
|
+
if (!prev.predecessorEnd && next.predecessorEnd) {
|
|
300
|
+
console.log(`We are a deploy successor: our predecessor holds the main port until ${iso(next.predecessorEnd)}`);
|
|
301
|
+
}
|
|
302
|
+
if (!prev.remap && next.remap) {
|
|
303
|
+
console.log(`Deploy switchover remap active: sources pointing at us are split so [${iso(next.remap.boundaryA)} .. ${iso(next.remap.boundaryB)}] routes to alternate port ${next.remap.altPort} (remap expires at ${iso(next.remap.expire)})`);
|
|
304
|
+
}
|
|
305
|
+
if (prev.remap && !next.remap) {
|
|
306
|
+
console.log(`Deploy switchover remap ended; running on the plain stored routing config`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
276
310
|
/** Starts the takeover machinery. Port fallback (alternate port + registry + acquisition polling)
|
|
277
311
|
* works regardless; without a deploy timeline folder the switchover-specific parts (the remap,
|
|
278
312
|
* the flush deadline, the tighter acquisition pacing) simply stay inert. */
|
|
279
313
|
export async function initDeployTakeover(config: { domain: string; mainPort: number; storageFolder: string }): Promise<void> {
|
|
280
314
|
initialized = config;
|
|
281
315
|
ancestorPids = await getAncestorPids();
|
|
282
|
-
timelineFolder =
|
|
283
|
-
|
|
316
|
+
timelineFolder = getTimelineFolder();
|
|
317
|
+
let entries = await readTimelineEntries();
|
|
318
|
+
if (!entries.length) {
|
|
319
|
+
console.log(`No deploy timeline entries in ${timelineFolder}; deploy takeover inactive until they appear (port fallback still works)`);
|
|
320
|
+
} else {
|
|
321
|
+
console.log(`Deploy timeline found at ${timelineFolder} (${entries.length} entries); our pid chain: ${[...ancestorPids].join(" -> ")}`);
|
|
322
|
+
}
|
|
284
323
|
await recompute();
|
|
285
324
|
let poll = setInterval(() => {
|
|
286
325
|
void recompute().catch((e: Error) => console.error(`Deploy takeover recompute failed: ${e.stack ?? e}`));
|
|
@@ -117,12 +117,13 @@ class ArchivesChain {
|
|
|
117
117
|
let fetches = await Promise.all(configs.map(async (sourceConfig) => {
|
|
118
118
|
var _a;
|
|
119
119
|
let probe = await sourceWrapper_1.SourceWrapper.create(sourceConfig, { background: false });
|
|
120
|
+
let start = Date.now();
|
|
120
121
|
try {
|
|
121
122
|
let data = await probe.read(archives => archives.get(remoteConfig_1.ROUTING_FILE));
|
|
122
|
-
return { probe, sourceConfig, responded: true, existing: data && (0, remoteConfig_1.parseRoutingData)(data) || undefined, error: "" };
|
|
123
|
+
return { probe, sourceConfig, responded: true, latency: Date.now() - start, existing: data && (0, remoteConfig_1.parseRoutingData)(data) || undefined, error: "" };
|
|
123
124
|
}
|
|
124
125
|
catch (e) {
|
|
125
|
-
return { probe, sourceConfig, responded: false, existing: undefined, error: `${sourceConfig.url}: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}` };
|
|
126
|
+
return { probe, sourceConfig, responded: false, latency: 0, existing: undefined, error: `${sourceConfig.url}: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}` };
|
|
126
127
|
}
|
|
127
128
|
}));
|
|
128
129
|
try {
|
|
@@ -211,6 +212,14 @@ class ArchivesChain {
|
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
214
|
}
|
|
215
|
+
// The routing fetches double as our first latency measurements: variable-shard picking
|
|
216
|
+
// works immediately, instead of waiting for the first ping pass to land
|
|
217
|
+
for (let source of sources) {
|
|
218
|
+
let fetch = fetches.find(x => x.responded && x.sourceConfig.url === source.config.url);
|
|
219
|
+
if (fetch) {
|
|
220
|
+
source.seedLatency(fetch.latency);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
214
223
|
this.activeConfig = active;
|
|
215
224
|
this.startConfigPoll();
|
|
216
225
|
return { config: active, sources };
|
|
@@ -777,5 +786,5 @@ async function getBucketInfo(config) {
|
|
|
777
786
|
return await remote.getConfig();
|
|
778
787
|
}
|
|
779
788
|
exports.getBucketInfo = getBucketInfo;
|
|
780
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlQXJjaGl2ZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjcmVhdGVBcmNoaXZlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUUxQixtREFBd0Q7QUFDeEQsMkRBQXFEO0FBQ3JELDRDQUlzQjtBQUN0QixpREFJd0I7QUFDeEIsbUVBQWdFO0FBQ2hFLHFEQUF3RjtBQUN4Riw0Q0FBaUQ7QUFDakQsNkRBQTBHO0FBQzFHLDJEQUF5RjtBQUN6RixtREFBa0c7QUFFbEcsZ0dBQWdHO0FBQ2hHLG1HQUFtRztBQUNuRyxnR0FBZ0c7QUFDaEcsa0dBQWtHO0FBQ2xHLG1HQUFtRztBQUNuRyxtR0FBbUc7QUFDbkcsbUdBQW1HO0FBQ25HLG9GQUFvRjtBQUVwRixNQUFNLG9CQUFvQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQzNDLG1HQUFtRztBQUNuRyxpRUFBaUU7QUFDakUsTUFBTSw0QkFBNEIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQy9DLE1BQU0saUNBQWlDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUNwRCxrR0FBa0c7QUFDbEcsMkJBQTJCO0FBQzNCLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUMxQywyRkFBMkY7QUFDM0Ysb0RBQW9EO0FBQ3BELE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUUvQyxrR0FBa0c7QUFDbEcsa0dBQWtHO0FBQ2xHLGlHQUFpRztBQUNqRyxpR0FBaUc7QUFDakcsU0FBZ0IsaUJBQWlCLENBQUMsTUFBc0M7SUFDcEUsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQzlCLE9BQU8sSUFBSSw2QkFBaUIsQ0FBQyxFQUFFLFVBQVUsRUFBRSxJQUFBLGdDQUFpQixFQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxV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T0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3BGLElBQUksVUFBVSxHQUFHLDJDQUF1QixDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN2RCxJQUFJLENBQUM7UUFDRCxPQUFPLE1BQU0sVUFBVSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDVCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQUMsQ0FBVyxDQUFDLEtBQUssbUNBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLDZDQUF5QixDQUFDO1lBQUUsTUFBTSxDQUFDLENBQUM7UUFDbEYsTUFBTSxJQUFBLG9DQUFtQixFQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNsRixPQUFPLE1BQU0sVUFBVSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEQsQ0FBQztBQUNMLENBQUM7QUFaRCw4Q0FZQztBQUVEOztrR0FFa0c7QUFDM0YsS0FBSyxVQUFVLGFBQWEsQ0FBQyxNQUE2QztJQUM3RSxJQUFJLE1BQU0sR0FBRyxJQUFJLCtCQUFjLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUM1RyxPQUFPLE1BQU0sTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQ3BDLENBQUM7QUFIRCxzQ0FHQyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5hbGxvd2NsaWVudCA9IHRydWU7XG5cbmltcG9ydCB7IGlzTm9kZSwgc29ydCB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL21pc2NcIjtcbmltcG9ydCB7IGRlbGF5IH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvYmF0Y2hpbmdcIjtcbmltcG9ydCB7XG4gICAgSUFyY2hpdmVzLCBSZW1vdGVDb25maWcsIFJlbW90ZUNvbmZpZ0Jhc2UsIEhvc3RlZENvbmZpZywgQmFja2JsYXplQ29uZmlnLFxuICAgIEFyY2hpdmVGaWxlSW5mbywgQXJjaGl2ZXNDb25maWcsIEFyY2hpdmVzU3luY1N0YXR1cywgV1JJVEVfUEFTVF9XSU5ET1dfR1JBQ0UsIFNUT1JBR0VfV1JPTkdfVkFMSURfV0lORE9XLFxuICAgIFNUT1JBR0VfV1JPTkdfUk9VVEUsIEZVTExfUk9VVEUsIFZBUklBQkxFX1NIQVJELFxufSBmcm9tIFwiLi4vSUFyY2hpdmVzXCI7XG5pbXBvcnQge1xuICAgIFJPVVRJTkdfRklMRSwgZ2V0Q29uZmlnVmVyc2lvbiwgcGFyc2VIb3N0ZWRVcmwsIHBhcnNlQmFja2JsYXplVXJsLFxuICAgIG5vcm1hbGl6ZVJlbW90ZUNvbmZpZywgbm9ybWFsaXplU291cmNlLCBwYXJzZVJvdXRpbmdEYXRhLCBzZXJpYWxpemVSZW1vdGVDb25maWcsXG4gICAgZ2V0Um91dGUsIHJvdXRlQ29udGFpbnMsIHBhcnNlVmFyaWFibGVSb3V0ZSxcbn0gZnJvbSBcIi4vcmVtb3RlQ29uZmlnXCI7XG5pbXBvcnQgeyBTb2NrZXRGdW5jdGlvbiB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vU29ja2V0RnVuY3Rpb25cIjtcbmltcG9ydCB7IEFyY2hpdmVzUmVtb3RlLCBwYXJzZVN0b3JhZ2VVcmwsIGF1dGhlbnRpY2F0ZVN0b3JhZ2UgfSBmcm9tIFwiLi9BcmNoaXZlc1JlbW90ZVwiO1xuaW1wb3J0IHsgQXJjaGl2ZXNCYWNrYmxhemUgfSBmcm9tIFwiLi4vYmFja2JsYXplXCI7XG5pbXBvcnQgeyBnZXRTdG9yYWdlU2VydmVyQ29uZmlnT3B0aW9uYWwsIGdldExvY2FsQXJjaGl2ZXMsIFNlcnZlckJ1Y2tldEluZm8gfSBmcm9tIFwiLi9zdG9yYWdlU2VydmVyU3RhdGVcIjtcbmltcG9ydCB7IFJlbW90ZVN0b3JhZ2VDb250cm9sbGVyLCBTVE9SQUdFX05PVF9BVVRIRU5USUNBVEVEIH0gZnJvbSBcIi4vc3RvcmFnZUNvbnRyb2xsZXJcIjtcbmltcG9ydCB7IFNvdXJjZVdyYXBwZXIsIFJFVFJZX1NUQVJUX0RFTEFZLCBSRVRSWV9NQVhfREVMQVksIFJFVFJZX0dST1dUSCB9IGZyb20gXCIuL3NvdXJjZVdyYXBwZXJcIjtcblxuLy8gVHVybnMgYSBSZW1vdGVDb25maWcgaW50byBhIHVzYWJsZSBJQXJjaGl2ZXMgKGNyZWF0ZUFyY2hpdmVzKS4gSW5pdGlhbGl6YXRpb24gaXMgbGF6eTogb24gdGhlXG4vLyBmaXJzdCBjYWxsIHdlIHdhbGsgdGhlIHNvdXJjZXMgSU4gT1JERVIgYW5kIHRoZSBmaXJzdCBvbmUgdGhhdCBhbnN3ZXJzIGlzIGF1dGhvcml0YXRpdmUgKHNvdXJjZXNcbi8vIGFyZSBzeW5jaHJvbml6ZWQgY29waWVzIG9mIHRoZSBzYW1lIGJ1Y2tldCwgc28gd2UgbmV2ZXIgY29uc3VsdCB0aGUgcmVzdCkuIEl0cyBzdG9yZWQgcm91dGluZ1xuLy8gY29uZmlnIHdpbnMgb3ZlciB0aGUgaW4tbWVtb3J5IG9uZSAtIHVubGVzcyBvdXJzIGhhcyBhIHN0cmljdGx5IG5ld2VyIHZlcnNpb24sIGluIHdoaWNoIGNhc2Ugd2Vcbi8vIHdyaXRlIG91cnMgKGNyZWF0aW5nIHRoZSBidWNrZXQgd2hlbiBubyByb3V0aW5nIGV4aXN0cyBhdCBhbGwpLiBBIGZhaWxlZCBpbml0IChhbGwgc291cmNlcyBkb3duLFxuLy8gb3IgdGhlIHJvdXRpbmcgd3JpdGUgd2FzIHJlamVjdGVkKSBzdGF5cyBmYWlsZWQgZm9yIGNhbGxlcnMgYnV0IHJldHJpZXMgaXRzZWxmIGluIHRoZSBiYWNrZ3JvdW5kXG4vLyB3aXRoIGEgcmFtcGluZyBkZWxheS4gT25jZSBydW5uaW5nLCB3ZSByZS1yZWFkIHRoZSByb3V0aW5nIGNvbmZpZyBldmVyeSBDT05GSUdfUE9MTF9JTlRFUlZBTCBhbmRcbi8vIHJlYnVpbGQgdGhlIHNvdXJjZSBsaXN0IHdoZW4gaXQgY2hhbmdlZCAocmV1c2luZyB3cmFwcGVycyBmb3IgdW5jaGFuZ2VkIHNvdXJjZXMpLlxuXG5jb25zdCBDT05GSUdfUE9MTF9JTlRFUlZBTCA9IDUgKiA2MCAqIDEwMDA7XG4vLyBXcm9uZy12YWxpZC13aW5kb3cgcmVqZWN0aW9ucyB3aXRoaW4gdGhpcyBkaXN0YW5jZSBvZiBhIGtub3duIHdpbmRvdyBib3VuZGFyeSBhcmUganVzdCB1cyByYWNpbmdcbi8vIHRoZSBib3VuZGFyeSBpdHNlbGYgLSB3YWl0aW5nIGZpeGVzIHRoZW0sIG5vIG5ldyBjb25maWcgbmVlZGVkXG5jb25zdCBXUk9OR19UQVJHRVRfQk9VTkRBUllfV0lORE9XID0gMzAgKiAxMDAwO1xuY29uc3QgV1JPTkdfVEFSR0VUX0JPVU5EQVJZX1JFVFJZX0RFTEFZID0gMTUgKiAxMDAwO1xuLy8gT3RoZXJ3aXNlIG91ciBjb25maWcgaXMgc3RhbGU7IHJlLWZldGNoIGl0IGZyb20gdGhlIHNlcnZlciwgYXQgbW9zdCB0aGlzIG9mdGVuICh3aGVuIHRocm90dGxlZCxcbi8vIHJldHJ5IHdpdGggd2hhdCB3ZSBoYXZlKVxuY29uc3QgQ09ORklHX1JFRlJFU0hfVEhST1RUTEUgPSAzMCAqIDEwMDA7XG4vLyBXaGVuIGV2ZXJ5IHNvdXJjZSBsb29rcyBkb3duLCBhbGwgb2YgdGhlbSBhcmUgcmUtY29udGFjdGVkIChyb3V0aW5nIHJlLXJlYWQgKyBjb25uZWN0aW9uXG4vLyByZS1hdHRlbXB0KSBiZWZvcmUgZ2l2aW5nIHVwIC0gYXQgbW9zdCB0aGlzIG9mdGVuXG5jb25zdCBBVkFJTEFCSUxJVFlfUkVDSEVDS19USFJPVFRMRSA9IDUgKiAxMDAwO1xuXG4vLyBUaGUgZGlyZWN0IEFQSSBJQXJjaGl2ZXMgZm9yIG9uZSBzb3VyY2UsIHdpdGggbm8gVVJMLWZvcm0gZmFsbGJhY2sgYW5kIG5vIGNoYWluaW5nLiBVc2VkIGJ5IHRoZVxuLy8gc3RvcmFnZSBzZXJ2ZXIgZm9yIGl0cyBzeW5jaHJvbml6YXRpb24gc291cmNlcy4gRGVuaWVkIGNhbGxzIHRocm93IGltbWVkaWF0ZWx5IChyZWdpc3RlcmluZyB0aGVcbi8vIGFjY2VzcyByZXF1ZXN0IGluIHRoZSBiYWNrZ3JvdW5kKTogdGhlIHN5bmMgbG9vcHMgcmV0cnktYW5kLWxvZyB1bnRpbCBhY2Nlc3MgaXMgZ3JhbnRlZCwgd2hpbGVcbi8vIGV4cGxpY2l0IHdyaXRlcyBzdXJmYWNlIHRoZSBkZW5pYWwgKHdpdGggZ3JhbnQgaW5zdHJ1Y3Rpb25zKSB0byB0aGUgY2FsbGVyIGluc3RlYWQgb2YgaGFuZ2luZy5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBcGlBcmNoaXZlcyhzb3VyY2U6IEhvc3RlZENvbmZpZyB8IEJhY2tibGF6ZUNvbmZpZyk6IElBcmNoaXZlcyB7XG4gICAgaWYgKHNvdXJjZS50eXBlID09PSBcImJhY2tibGF6ZVwiKSB7XG4gICAgICAgIHJldHVybiBuZXcgQXJjaGl2ZXNCYWNrYmxhemUoeyBidWNrZXROYW1lOiBwYXJzZUJhY2tibGF6ZVVybChzb3VyY2UudXJsKS5idWNrZXROYW1lLCBwdWJsaWM6IHNvdXJjZS5wdWJsaWMsIGltbXV0YWJsZTogc291cmNlLmltbXV0YWJsZSB9KTtcbiAgICB9XG4gICAgbGV0IHBhcnNlZCA9IHBhcnNlSG9zdGVkVXJsKHNvdXJjZS51cmwpO1xuICAgIGxldCBzZXJ2ZXIgPSBpc05vZGUoKSAmJiBnZXRTdG9yYWdlU2VydmVyQ29uZmlnT3B0aW9uYWwoKSB8fCB1bmRlZmluZWQ7XG4gICAgaWYgKHNlcnZlciAmJiBwYXJzZWQuYWRkcmVzcyA9PT0gc2VydmVyLmRvbWFpbiAmJiBwYXJzZWQucG9ydCA9PT0gc2VydmVyLnBvcnQpIHtcbiAgICAgICAgLy8gVGhpcyBzb3VyY2UgaXMgYSBidWNrZXQgaG9zdGVkIGJ5IG91ciBvd24gcHJvY2VzcyAtIHVzZSBpdCBkaXJlY3RseSBpbnN0ZWFkIG9mIGNhbGxpbmdcbiAgICAgICAgLy8gb3Vyc2VsdmVzIG92ZXIgSFRUUFNcbiAgICAgICAgcmV0dXJuIGdldExvY2FsQXJjaGl2ZXMocGFyc2VkLmFjY291bnQsIHBhcnNlZC5idWNrZXROYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBBcmNoaXZlc1JlbW90ZSh7IHVybDogc291cmNlLnVybCwgYWNjb3VudE5hbWU6IHNvdXJjZS5hY2NvdW50TmFtZSwgd2FpdEZvckFjY2VzczogZmFsc2UgfSk7XG59XG5cbnR5cGUgQ2hhaW5TdGF0ZSA9IHtcbiAgICBjb25maWc6IFJlbW90ZUNvbmZpZztcbiAgICBzb3VyY2VzOiBTb3VyY2VXcmFwcGVyW107XG59O1xuXG5mdW5jdGlvbiBjb25maWdXaW5kb3dDdXJyZW50KGNvbmZpZzogSG9zdGVkQ29uZmlnIHwgQmFja2JsYXplQ29uZmlnKTogYm9vbGVhbiB7XG4gICAgbGV0IG5vdyA9IERhdGUubm93KCk7XG4gICAgbGV0IFtzdGFydCwgZW5kXSA9IGNvbmZpZy52YWxpZFdpbmRvdztcbiAgICByZXR1cm4gc3RhcnQgLSBXUklURV9QQVNUX1dJTkRPV19HUkFDRSA8PSBub3cgJiYgbm93IDw9IGVuZCArIFdSSVRFX1BBU1RfV0lORE9XX0dSQUNFO1xufVxuXG4vLyBDbGllbnQgd3JpdGVzIHRhcmdldCBvbmx5IHRoZSBDVVJSRU5UTFkgdmFsaWQgc291cmNlOiBhIGZ1dHVyZS13aW5kb3cgc291cmNlIHJlY2VpdmVzIGl0cyBkYXRhXG4vLyB0aHJvdWdoIHNlcnZlci1zaWRlIGRvd25zdHJlYW0gcHJvcGFnYXRpb24vYmFja2ZpbGwsIG5ldmVyIGRpcmVjdGx5IGZyb20gY2xpZW50c1xuZnVuY3Rpb24gY29uZmlnQWNjZXB0c1dyaXRlcyhjb25maWc6IEhvc3RlZENvbmZpZyB8IEJhY2tibGF6ZUNvbmZpZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBjb25maWdXaW5kb3dDdXJyZW50KGNvbmZpZyk7XG59XG5cbmV4cG9ydCBjbGFzcyBBcmNoaXZlc0NoYWluIGltcGxlbWVudHMgSUFyY2hpdmVzIHtcbiAgICBwcml2YXRlIGNvbmZpZ3VyZWQ6IFJlbW90ZUNvbmZpZztcbiAgICAvLyBUaGUgY29uZmlnIHdlIGFjdHVhbGx5IHJ1biBvbiAodGhlIGF1dGhvcml0YXRpdmUgc3RvcmVkIG9uZSBhZnRlciBpbml0KVxuICAgIHByaXZhdGUgYWN0aXZlQ29uZmlnOiBSZW1vdGVDb25maWc7XG4gICAgcHJpdmF0ZSBzdGF0ZVByb21pc2U6IFByb21pc2U8Q2hhaW5TdGF0ZT4gfCB1bmRlZmluZWQ7XG4gICAgcHJpdmF0ZSBpbml0UmV0cnlEZWxheSA9IFJFVFJZX1NUQVJUX0RFTEFZO1xuICAgIHByaXZhdGUgaW5pdFJldHJ5VGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkO1xuICAgIHByaXZhdGUgcG9sbFRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCB1bmRlZmluZWQ7XG4gICAgcHJpdmF0ZSBkaXNwb3NlZCA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnOiBSZW1vdGVDb25maWcgfCBSZW1vdGVDb25maWdCYXNlKSB7XG4gICAgICAgIHRoaXMuY29uZmlndXJlZCA9IG5vcm1hbGl6ZVJlbW90ZUNvbmZpZyhjb25maWcpO1xuICAgICAgICB0aGlzLmFjdGl2ZUNvbmZpZyA9IHRoaXMuY29uZmlndXJlZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0RGVidWdOYW1lKCkge1xuICAgICAgICBsZXQgdXJscyA9IHRoaXMuYWN0aXZlQ29uZmlnLnNvdXJjZXMubWFwKHggPT4gdHlwZW9mIHggPT09IFwic3RyaW5nXCIgJiYgeCB8fCAoeCBhcyBIb3N0ZWRDb25maWcgfCBCYWNrYmxhemVDb25maWcpLnVybCk7XG4gICAgICAgIHJldHVybiBgY2hhaW4vJHt1cmxzLmpvaW4oXCIsXCIpfWA7XG4gICAgfVxuXG4gICAgLy8gTGF6eSBpbml0IHRoYXQgcmV0aHJvd3MgaXRzIGVycm9yIHRvIGV2ZXJ5IGNhbGxlciwgd2hpbGUgYSBiYWNrZ3JvdW5kIHRpbWVyIHJlc2V0cyBhbmRcbiAgICAvLyByZXRyaWVzIGl0IHdpdGggYSByYW1waW5nIGRlbGF5IC0gc28gYSBjaGFpbiB0aGF0IGNvdWxkbid0IGluaXRpYWxpemUgZml4ZXMgaXRzZWxmIG9uY2UgYVxuICAgIC8vIHNvdXJjZSBjb21lcyBiYWNrLCB3aXRob3V0IGFueSBjYWxsZXIgaGF2aW5nIHRvIGRyaXZlIGl0LlxuICAgIHByaXZhdGUgZ2V0U3RhdGUoKTogUHJvbWlzZTxDaGFpblN0YXRlPiB7XG4gICAgICAgIGlmICh0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKGBBcmNoaXZlc0NoYWluICR7dGhpcy5nZXREZWJ1Z05hbWUoKX0gaGFzIGJlZW4gZGlzcG9zZWRgKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlUHJvbWlzZSkge1xuICAgICAgICAgICAgbGV0IHByb21pc2UgPSB0aGlzLmluaXQoKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdGVQcm9taXNlID0gcHJvbWlzZTtcbiAgICAgICAgICAgIHByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmV0cnlEZWxheSA9IFJFVFJZX1NUQVJUX0RFTEFZO1xuICAgICAgICAgICAgfSwgKGU6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQgfHwgdGhpcy5pbml0UmV0cnlUaW1lcikgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFN0b3JhZ2UgaW5pdCBmYWlsZWQgZm9yICR7dGhpcy5nZXREZWJ1Z05hbWUoKX0sIHJldHJ5aW5nIGluICR7TWF0aC5yb3VuZCh0aGlzLmluaXRSZXRyeURlbGF5IC8gMTAwMCl9cy4gJHtlLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmV0cnlUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRSZXRyeVRpbWVyID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZVByb21pc2UgPT09IHByb21pc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGVQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0U3RhdGUoKS5jYXRjaCgoKSA9PiB7IH0pO1xuICAgICAgICAgICAgICAgIH0sIHRoaXMuaW5pdFJldHJ5RGVsYXkpO1xuICAgICAgICAgICAgICAgICh0aGlzLmluaXRSZXRyeVRpbWVyIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRSZXRyeURlbGF5ID0gTWF0aC5taW4oUkVUUllfTUFYX0RFTEFZLCB0aGlzLmluaXRSZXRyeURlbGF5ICogUkVUUllfR1JPV1RIKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRlUHJvbWlzZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGluaXQoKTogUHJvbWlzZTxDaGFpblN0YXRlPiB7XG4gICAgICAgIGxldCBjb25maWdzID0gdGhpcy5jb25maWd1cmVkLnNvdXJjZXMubWFwKG5vcm1hbGl6ZVNvdXJjZSk7XG4gICAgICAgIC8vIEVWRVJZIHNvdXJjZSBpcyBjb250YWN0ZWQgZm9yIGl0cyBwaWN0dXJlIG9mIHRoZSByb3V0aW5nIGNvbmZpZyAocGVyIHRoZSBzcGVjOiB0aGUgY29uZmlnXG4gICAgICAgIC8vIGlzIGR1cGxpY2F0ZWQgaW50byBhbGwgb2YgdGhlbSkgLSB3aGljaCBhbHNvIGVzdGFibGlzaGVzIG91ciBjb25uZWN0aW9uIHRvIGV2ZXJ5IG5vZGUgdXBcbiAgICAgICAgLy8gZnJvbnQuIENvbnRhY3QgaXMgcGFyYWxsZWw7IEFET1BUSU9OIGlzIGRldGVybWluaXN0aWMgYnkgY29uZmlnIG9yZGVyIGFtb25nIHRoZSBzb3VyY2VzXG4gICAgICAgIC8vIHRoYXQgYW5zd2VyZWQgKHRoZSBmaXJzdCB1cCBzb3VyY2UgaXMgYXV0aG9yaXRhdGl2ZSkuXG4gICAgICAgIGxldCBmZXRjaGVzID0gYXdhaXQgUHJvbWlzZS5hbGwoY29uZmlncy5tYXAoYXN5bmMgc291cmNlQ29uZmlnID0+IHtcbiAgICAgICAgICAgIGxldCBwcm9iZSA9IGF3YWl0IFNvdXJjZVdyYXBwZXIuY3JlYXRlKHNvdXJjZUNvbmZpZywgeyBiYWNrZ3JvdW5kOiBmYWxzZSB9KTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IGRhdGEgPSBhd2FpdCBwcm9iZS5yZWFkKGFyY2hpdmVzID0+IGFyY2hpdmVzLmdldChST1VUSU5HX0ZJTEUpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBwcm9iZSwgc291cmNlQ29uZmlnLCByZXNwb25kZWQ6IHRydWUsIGV4aXN0aW5nOiBkYXRhICYmIHBhcnNlUm91dGluZ0RhdGEoZGF0YSkgfHwgdW5kZWZpbmVkLCBlcnJvcjogXCJcIiB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHByb2JlLCBzb3VyY2VDb25maWcsIHJlc3BvbmRlZDogZmFsc2UsIGV4aXN0aW5nOiB1bmRlZmluZWQsIGVycm9yOiBgJHtzb3VyY2VDb25maWcudXJsfTogJHsoZSBhcyBFcnJvcikuc3RhY2sgPz8gZX1gIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBmb3VuZCA9IGZldGNoZXMuZmluZCh4ID0+IHgucmVzcG9uZGVkKTtcbiAgICAgICAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBpbml0aWFsaXplIHN0b3JhZ2UgZm9yICR7dGhpcy5nZXREZWJ1Z05hbWUoKX06IG5vIHNvdXJjZSBhbnN3ZXJlZC4gJHtmZXRjaGVzLm1hcCh4ID0+IHguZXJyb3IpLmpvaW4oXCIgfCBcIil9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgZXhpc3RpbmcgPSBmb3VuZC5leGlzdGluZztcbiAgICAgICAgICAgIGxldCBhY3RpdmUgPSB0aGlzLmNvbmZpZ3VyZWQ7XG4gICAgICAgICAgICBsZXQgbmVlZHNXcml0ZSA9IHRydWU7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmcgJiYgZ2V0Q29uZmlnVmVyc2lvbihleGlzdGluZykgPj0gZ2V0Q29uZmlnVmVyc2lvbih0aGlzLmNvbmZpZ3VyZWQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGdldENvbmZpZ1ZlcnNpb24oZXhpc3RpbmcpID09PSBnZXRDb25maWdWZXJzaW9uKHRoaXMuY29uZmlndXJlZCkgJiYgSlNPTi5zdHJpbmdpZnkoZXhpc3RpbmcpICE9PSBKU09OLnN0cmluZ2lmeSh0aGlzLmNvbmZpZ3VyZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEFyY2hpdmVzIGNvbmZpZ3VyYXRpb24gdXBkYXRlZCB3aXRob3V0IHVwZGF0aW5nIHRoZSB2ZXJzaW9uLCBmb3IgJHtmb3VuZC5zb3VyY2VDb25maWcudXJsfS4gVXBkYXRlcyB3aWxsIGJlIGlnbm9yZWQgdW50aWwgeW91IGluY3JlYXNlIHRoZSB2ZXJzaW9uLiBVc2luZzogJHtKU09OLnN0cmluZ2lmeShleGlzdGluZyl9LCBpZ25vcmluZzogJHtKU09OLnN0cmluZ2lmeSh0aGlzLmNvbmZpZ3VyZWQpfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhY3RpdmUgPSBleGlzdGluZztcbiAgICAgICAgICAgICAgICBuZWVkc1dyaXRlID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobmVlZHNXcml0ZSkge1xuICAgICAgICAgICAgICAgIC8vIFdlIGRlY2lkZWQgdG8gd3JpdGUgKG91cnMgaXMgbmV3ZXIgdGhhbiB0aGUgYXV0aG9yaXRhdGl2ZSBmaXJzdC11cCBzb3VyY2Uncywgb3JcbiAgICAgICAgICAgICAgICAvLyBubyByb3V0aW5nIGV4aXN0cyB5ZXQpLiBUaGUgd3JpdGUgZ29lcyB0byBhbGwgc291cmNlcywgc28gaXQgaXMgcmVmdXNlZCB1bmxlc3NcbiAgICAgICAgICAgICAgICAvLyBvdXIgdmVyc2lvbiBpcyBzdHJpY3RseSBncmVhdGVyIHRoYW4gRVZFUlkgc291cmNlJ3Mgc3RvcmVkIHZlcnNpb24gKGFsbCBhbHJlYWR5XG4gICAgICAgICAgICAgICAgLy8gZmV0Y2hlZCBhYm92ZSkgLSBhIHNvdXJjZSBhdCAob3IgcGFzdCkgb3VyIHZlcnNpb24gbWVhbnMgdGhpcyB2ZXJzaW9uIG51bWJlciBpc1xuICAgICAgICAgICAgICAgIC8vIHRha2VuLCBhbmQgd3JpdGluZyBhbnl3YXkgd291bGQgbGVhdmUgc291cmNlcyBhdCB0aGUgc2FtZSB2ZXJzaW9uIHdpdGggZGlmZmVyZW50XG4gICAgICAgICAgICAgICAgLy8gY29udGVudCwgZWFjaCByZWplY3RpbmcgdGhlIG90aGVyJ3MgcHVzaGVzIGZvcmV2ZXIuIERvd24gc291cmNlcyBhcmUgc3RpbGxcbiAgICAgICAgICAgICAgICAvLyBwcm90ZWN0ZWQgYnkgdGhlIHNlcnZlci1zaWRlIHZlcnNpb24gZ3VhcmQgd2hlbiB0aGUgd3JpdGUgZXZlbnR1YWxseSByZWFjaGVzIHRoZW0uXG4gICAgICAgICAgICAgICAgbGV0IGJlc3Q6IFJlbW90ZUNvbmZpZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBsZXQgY29uZmxpY3RVcmw6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBmZXRjaCBvZiBmZXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBzdG9yZWQgPSBmZXRjaC5leGlzdGluZztcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdG9yZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWJlc3QgfHwgZ2V0Q29uZmlnVmVyc2lvbihzdG9yZWQpID4gZ2V0Q29uZmlnVmVyc2lvbihiZXN0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYmVzdCA9IHN0b3JlZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZ2V0Q29uZmlnVmVyc2lvbihzdG9yZWQpID09PSBnZXRDb25maWdWZXJzaW9uKHRoaXMuY29uZmlndXJlZCkgJiYgSlNPTi5zdHJpbmdpZnkoc3RvcmVkKSAhPT0gSlNPTi5zdHJpbmdpZnkodGhpcy5jb25maWd1cmVkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uZmxpY3RVcmwgPSBmZXRjaC5zb3VyY2VDb25maWcudXJsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChiZXN0ICYmIGdldENvbmZpZ1ZlcnNpb24oYmVzdCkgPj0gZ2V0Q29uZmlnVmVyc2lvbih0aGlzLmNvbmZpZ3VyZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb25mbGljdFVybCAmJiBnZXRDb25maWdWZXJzaW9uKGJlc3QpID09PSBnZXRDb25maWdWZXJzaW9uKHRoaXMuY29uZmlndXJlZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEFyY2hpdmVzIGNvbmZpZ3VyYXRpb24gdXBkYXRlZCB3aXRob3V0IHVwZGF0aW5nIHRoZSB2ZXJzaW9uLCBmb3IgJHtjb25mbGljdFVybH0uIFVwZGF0ZXMgd2lsbCBiZSBpZ25vcmVkIHVudGlsIHlvdSBpbmNyZWFzZSB0aGUgdmVyc2lvbi4gVXNpbmc6ICR7SlNPTi5zdHJpbmdpZnkoYmVzdCl9LCBpZ25vcmluZzogJHtKU09OLnN0cmluZ2lmeSh0aGlzLmNvbmZpZ3VyZWQpfWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZSA9IGJlc3Q7XG4gICAgICAgICAgICAgICAgICAgIG5lZWRzV3JpdGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgc291cmNlcyA9IGF3YWl0IHRoaXMuYnVpbGRTb3VyY2VzKGFjdGl2ZSk7XG4gICAgICAgICAgICBpZiAobmVlZHNXcml0ZSkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSB1cGRhdGUgb25seSBoYXBwZW5zIHdoZW4gRVZFUlkgc291cmNlIHdvdWxkIGFjY2VwdCBpdCAtIGEgcGFydGlhbCB1cGRhdGVcbiAgICAgICAgICAgICAgICAvLyB3b3VsZCBsZWF2ZSB0aGUgc291cmNlcyBvdXQgb2Ygc3luYywgYW5kIGEgY2xpZW50IHdpdGhvdXQgYWNjZXNzIHJldHJ5aW5nIHRoZVxuICAgICAgICAgICAgICAgIC8vIHdyaXRlIGZvcmV2ZXIgd291bGQgbmV2ZXIgaW5pdGlhbGl6ZS4gV2l0aG91dCBmdWxsIGFjY2VzcyB3ZSBydW4gb24gdGhlIHN0b3JlZFxuICAgICAgICAgICAgICAgIC8vIGNvbmZpZyAod2hlbiB0aGVyZSBpcyBvbmUpIGFuZCBsb2cgdGhlIHByb2JsZW0gaW5zdGVhZC5cbiAgICAgICAgICAgICAgICBsZXQgbWlzc2luZzogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBzb3VyY2Ugb2Ygc291cmNlcykge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhd2FpdCBzb3VyY2UuaGFzV3JpdGVBY2Nlc3MoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pc3NpbmcucHVzaChzb3VyY2UuY29uZmlnLnVybCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pc3NpbmcucHVzaChgJHtzb3VyY2UuY29uZmlnLnVybH0gKGNoZWNrIGZhaWxlZDogJHsoZSBhcyBFcnJvcikuc3RhY2sgPz8gZX0pYCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1pc3NpbmcubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYE5vdCB3cml0aW5nIHRoZSBzdG9yYWdlIHJvdXRpbmcgY29uZmlnIGZvciAke3RoaXMuZ2V0RGVidWdOYW1lKCl9ICh2ZXJzaW9uICR7Z2V0Q29uZmlnVmVyc2lvbih0aGlzLmNvbmZpZ3VyZWQpfSk6IG5vIHdyaXRlIGFjY2VzcyB0byAke21pc3Npbmcuam9pbihcIiwgXCIpfS4gJHtleGlzdGluZyAmJiBgUnVubmluZyBvbiB0aGUgc3RvcmVkIGNvbmZpZyAodmVyc2lvbiAke2dldENvbmZpZ1ZlcnNpb24oZXhpc3RpbmcpfSkgaW5zdGVhZC5gIHx8IGBObyBzdG9yZWQgY29uZmlnIGV4aXN0cywgc28gdGhlIGJ1Y2tldCBjYW5ub3QgYmUgY3JlYXRlZCB1bnRpbCB3cml0ZSBhY2Nlc3MgaXMgZ3JhbnRlZC5gfWApO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZSA9IGV4aXN0aW5nO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlcyA9IGF3YWl0IHRoaXMuYnVpbGRTb3VyY2VzKGFjdGl2ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSByZWplY3RlZCB3cml0ZSBmYWlscyBpbml0LCB3aGljaCByZXRyaWVzIGZyb20gc2NyYXRjaCAtIHJlLXJlYWRpbmcgdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyByb3V0aW5nLCBzbyBsb3NpbmcgYSBjcmVhdGUgcmFjZSB0byBhbm90aGVyIGNsaWVudCBqdXN0IGFkb3B0cyB0aGVpclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uZmlnIG9uIHRoZSBuZXh0IGF0dGVtcHQuXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBmb3VuZC5wcm9iZS53cml0ZShhcmNoaXZlcyA9PiBhcmNoaXZlcy5zZXQoUk9VVElOR19GSUxFLCBzZXJpYWxpemVSZW1vdGVDb25maWcodGhpcy5jb25maWd1cmVkKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBzb3VyY2Ugb2Ygc291cmNlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hY3RpdmVDb25maWcgPSBhY3RpdmU7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0Q29uZmlnUG9sbCgpO1xuICAgICAgICAgICAgcmV0dXJuIHsgY29uZmlnOiBhY3RpdmUsIHNvdXJjZXMgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGZvciAobGV0IGZldGNoIG9mIGZldGNoZXMpIHtcbiAgICAgICAgICAgICAgICBmZXRjaC5wcm9iZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGJ1aWxkU291cmNlcyhjb25maWc6IFJlbW90ZUNvbmZpZyk6IFByb21pc2U8U291cmNlV3JhcHBlcltdPiB7XG4gICAgICAgIGxldCBzb3VyY2VzOiBTb3VyY2VXcmFwcGVyW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgc291cmNlQ29uZmlnIG9mIGNvbmZpZy5zb3VyY2VzLm1hcChub3JtYWxpemVTb3VyY2UpKSB7XG4gICAgICAgICAgICBsZXQgc291cmNlID0gYXdhaXQgU291cmNlV3JhcHBlci5jcmVhdGUoc291cmNlQ29uZmlnKTtcbiAgICAgICAgICAgIC8vIExhdGVuY3kgKGZvciB2YXJpYWJsZS1zaGFyZCB0YXJnZXQgcHJlZmVyZW5jZSkgaXMgdHJhY2tlZCBmcm9tIGluaXRpYWxpemF0aW9uIG9uXG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnRQaW5naW5nKCk7XG4gICAgICAgICAgICBzb3VyY2VzLnB1c2goc291cmNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc291cmNlcztcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXJ0Q29uZmlnUG9sbCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMucG9sbFRpbWVyIHx8IHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgdGhpcy5wb2xsVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEFjdGl2ZUNvbmZpZygpLmNhdGNoKChlOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYENoZWNraW5nIGZvciBhIG5ldyBzdG9yYWdlIHJvdXRpbmcgY29uZmlnIGZhaWxlZCBmb3IgJHt0aGlzLmdldERlYnVnTmFtZSgpfTogJHtlLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgQ09ORklHX1BPTExfSU5URVJWQUwpO1xuICAgICAgICAodGhpcy5wb2xsVGltZXIgYXMgeyB1bnJlZj86ICgpID0+IHZvaWQgfSkudW5yZWY/LigpO1xuICAgIH1cblxuICAgIC8vIERlZHVwbGljYXRlcyBjb25jdXJyZW50IHJlZnJlc2hlcyAodGhlIHBvbGwgdGltZXIgYW5kIHdyb25nLXRhcmdldCB3cml0ZSByZXRyaWVzIHNoYXJlIHRoaXMpXG4gICAgcHJpdmF0ZSBjb25maWdSZWZyZXNoSW5GbGlnaHQ6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG4gICAgcHJpdmF0ZSByZWZyZXNoQWN0aXZlQ29uZmlnKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMuY29uZmlnUmVmcmVzaEluRmxpZ2h0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ1JlZnJlc2hJbkZsaWdodCA9IHRoaXMuY2hlY2tGb3JOZXdDb25maWcoKS5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1JlZnJlc2hJbkZsaWdodCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZ1JlZnJlc2hJbkZsaWdodDtcbiAgICB9XG5cbiAgICAvLyBUaGUgbGF0ZXN0IGNvbmZpZywgYXMgdGhlIHNlcnZlciBJTlRFUlBSRVRTIGl0OiBnZXRDb25maWcgY2FycmllcyBpbi1tZW1vcnkgb3ZlcmxheXMgKGRlcGxveVxuICAgIC8vIHRha2VvdmVyIHJlbWFwcykgdGhhdCBhcmUgZGVsaWJlcmF0ZWx5IG5ldmVyIHdyaXR0ZW4gaW50byB0aGUgcm91dGluZyBmaWxlLCBzbyBpdCdzXG4gICAgLy8gcHJlZmVycmVkIG92ZXIgcmVhZGluZyB0aGUgcmF3IGZpbGUuIFVSTC1vbmx5IGNoYWlucyBmYWxsIGJhY2sgdG8gdGhlIHJhdyBmaWxlLlxuICAgIHByaXZhdGUgYXN5bmMgZmV0Y2hMYXRlc3RDb25maWcoc3RhdGU6IENoYWluU3RhdGUpOiBQcm9taXNlPFJlbW90ZUNvbmZpZyB8IHVuZGVmaW5lZD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGNvbmZpZyA9IGF3YWl0IHRoaXMucnVuKHN0YXRlLCB7IGFwaU9ubHk6IHRydWUgfSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuZ2V0Q29uZmlnKCkpO1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5yZW1vdGVDb25maWcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplUmVtb3RlQ29uZmlnKGNvbmZpZy5yZW1vdGVDb25maWcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIHsgfVxuICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHRoaXMucnVuKHN0YXRlLCB7fSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuZ2V0KFJPVVRJTkdfRklMRSkpO1xuICAgICAgICBpZiAoIWRhdGEpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiBwYXJzZVJvdXRpbmdEYXRhKGRhdGEpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY2hlY2tGb3JOZXdDb25maWcoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmRpc3Bvc2VkIHx8ICF0aGlzLnN0YXRlUHJvbWlzZSkgcmV0dXJuO1xuICAgICAgICBsZXQgc3RhdGU6IENoYWluU3RhdGU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzdGF0ZSA9IGF3YWl0IHRoaXMuc3RhdGVQcm9taXNlO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIEluaXQgaXMgZmFpbGluZzsgaXRzIG93biByZXRyeSBsb29wIGhhbmRsZXMgdGhhdFxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBsYXRlc3QgPSBhd2FpdCB0aGlzLmZldGNoTGF0ZXN0Q29uZmlnKHN0YXRlKTtcbiAgICAgICAgaWYgKCFsYXRlc3QpIHJldHVybjtcbiAgICAgICAgYXdhaXQgdGhpcy5hZG9wdE5ld0NvbmZpZyhzdGF0ZSwgbGF0ZXN0KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGFkb3B0TmV3Q29uZmlnKHN0YXRlOiBDaGFpblN0YXRlLCBsYXRlc3Q6IFJlbW90ZUNvbmZpZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkobGF0ZXN0KSA9PT0gSlNPTi5zdHJpbmdpZnkoc3RhdGUuY29uZmlnKSkgcmV0dXJuO1xuICAgICAgICBjb25zb2xlLmxvZyhgU3RvcmFnZSByb3V0aW5nIGNvbmZpZyBjaGFuZ2VkIGZvciAke3RoaXMuZ2V0RGVidWdOYW1lKCl9LCByZWJ1aWxkaW5nIHNvdXJjZXNgKTtcbiAgICAgICAgbGV0IG9sZEJ5Q29uZmlnID0gbmV3IE1hcChzdGF0ZS5zb3VyY2VzLm1hcChzb3VyY2UgPT4gW0pTT04uc3RyaW5naWZ5KHNvdXJjZS5jb25maWcpLCBzb3VyY2VdKSk7XG4gICAgICAgIGxldCBzb3VyY2VzOiBTb3VyY2VXcmFwcGVyW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgc291cmNlQ29uZmlnIG9mIGxhdGVzdC5zb3VyY2VzLm1hcChub3JtYWxpemVTb3VyY2UpKSB7XG4gICAgICAgICAgICBsZXQga2V5ID0gSlNPTi5zdHJpbmdpZnkoc291cmNlQ29uZmlnKTtcbiAgICAgICAgICAgIGxldCBvbGQgPSBvbGRCeUNvbmZpZy5nZXQoa2V5KTtcbiAgICAgICAgICAgIGlmIChvbGQpIHtcbiAgICAgICAgICAgICAgICBvbGRCeUNvbmZpZy5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgICAgICBzb3VyY2VzLnB1c2gob2xkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHNvdXJjZSA9IGF3YWl0IFNvdXJjZVdyYXBwZXIuY3JlYXRlKHNvdXJjZUNvbmZpZyk7XG4gICAgICAgICAgICAgICAgc291cmNlLnN0YXJ0UGluZ2luZygpO1xuICAgICAgICAgICAgICAgIHNvdXJjZXMucHVzaChzb3VyY2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEluLWZsaWdodCByZXF1ZXN0cyBzdGlsbCBob2xkIHRoZSBvbGQgd3JhcHBlcnMgYW5kIGZpbmlzaCBmaW5lOyBkaXNwb3NlIGp1c3Qgc3RvcHMgYW55XG4gICAgICAgIC8vIGJhY2tncm91bmQgcmVjb25uZWN0L3BpbmcgbG9vcHNcbiAgICAgICAgZm9yIChsZXQgbGVmdG92ZXIgb2Ygb2xkQnlDb25maWcudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIGxlZnRvdmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFjdGl2ZUNvbmZpZyA9IGxhdGVzdDtcbiAgICAgICAgdGhpcy5zdGF0ZVByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoeyBjb25maWc6IGxhdGVzdCwgc291cmNlcyB9KTtcbiAgICB9XG5cbiAgICAvLyBXaGVuIGV2ZXJ5IHNvdXJjZSBsb29rcyBkb3duLCB0aGUgcm91dGluZyBjb25maWcgaXMgcmUtcmVhZCBmcm9tIEVWRVJZIHNvdXJjZSAtIHdoaWNoIGJvdGhcbiAgICAvLyByZS1hdHRlbXB0cyB0aGVpciBjb25uZWN0aW9ucyAob3VyIGxpdmVuZXNzIHJlLWNoZWNrKSBhbmQgZGlzY292ZXJzIGEgcm91dGluZyB1cGRhdGUgd2UgbWF5XG4gICAgLy8gaGF2ZSBtaXNzZWQgKGFkb3B0aW5nIGl0IHJlLWluaXRpYWxpemVzIHRoZSBzb3VyY2UgbGlzdCkuIENvbmN1cnJlbnQgY2FsbGVycyBzaGFyZSBvbmUgcGFzcy5cbiAgICBwcml2YXRlIGxhc3RBdmFpbGFiaWxpdHlSZWNoZWNrID0gMDtcbiAgICBwcml2YXRlIGF2YWlsYWJpbGl0eVJlY2hlY2tJbkZsaWdodDogUHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZDtcbiAgICBwcml2YXRlIHJlY2hlY2tBdmFpbGFiaWxpdHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmF2YWlsYWJpbGl0eVJlY2hlY2tJbkZsaWdodCkgcmV0dXJuIHRoaXMuYXZhaWxhYmlsaXR5UmVjaGVja0luRmxpZ2h0O1xuICAgICAgICBpZiAoRGF0ZS5ub3coKSAtIHRoaXMubGFzdEF2YWlsYWJpbGl0eVJlY2hlY2sgPCBBVkFJTEFCSUxJVFlfUkVDSEVDS19USFJPVFRMRSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB0aGlzLmxhc3RBdmFpbGFiaWxpdHlSZWNoZWNrID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdGhpcy5hdmFpbGFiaWxpdHlSZWNoZWNrSW5GbGlnaHQgPSB0aGlzLnJlY2hlY2tBdmFpbGFiaWxpdHlOb3coKS5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYXZhaWxhYmlsaXR5UmVjaGVja0luRmxpZ2h0ID0gdW5kZWZpbmVkO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXZhaWxhYmlsaXR5UmVjaGVja0luRmxpZ2h0O1xuICAgIH1cbiAgICBwcml2YXRlIGFzeW5jIHJlY2hlY2tBdmFpbGFiaWxpdHlOb3coKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmRpc3Bvc2VkIHx8ICF0aGlzLnN0YXRlUHJvbWlzZSkgcmV0dXJuO1xuICAgICAgICBsZXQgc3RhdGU6IENoYWluU3RhdGU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzdGF0ZSA9IGF3YWl0IHRoaXMuc3RhdGVQcm9taXNlO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIEluaXQgaXMgZmFpbGluZzsgaXRzIG93biByZXRyeSBsb29wIGhhbmRsZXMgdGhhdFxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoc3RhdGUuc291cmNlcy5tYXAoYXN5bmMgc291cmNlID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IGRhdGEgPSBhd2FpdCBzb3VyY2UucmVhZChhcmNoaXZlcyA9PiBhcmNoaXZlcy5nZXQoUk9VVElOR19GSUxFKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEgJiYgcGFyc2VSb3V0aW5nRGF0YShkYXRhKSB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG4gICAgICAgIGxldCBsYXRlc3QgPSByZXN1bHRzLmZpbmQoeCA9PiB4KTtcbiAgICAgICAgaWYgKCFsYXRlc3QpIHJldHVybjtcbiAgICAgICAgYXdhaXQgdGhpcy5hZG9wdE5ld0NvbmZpZyhzdGF0ZSwgbGF0ZXN0KTtcbiAgICB9XG5cbiAgICAvLyBSdW5zIGEgcmVxdWVzdCBhZ2FpbnN0IHRoZSBmaXJzdCBhdmFpbGFibGUgc291cmNlICh0aGF0IGNvdmVycyB0aGUga2V5J3Mgcm91dGUsIHdoZW4gb25lIGlzXG4gICAgLy8gZ2l2ZW4pLCBtb3ZpbmcgdG8gdGhlIG5leHQgb25lIE9OTFkgd2hlbiB0aGUgc291cmNlJ3MgV2ViU29ja2V0IGlzIGRvd24gKGNoZWNrZWQgZGlyZWN0bHkgLVxuICAgIC8vIG5ldmVyIGJ5IGluc3BlY3RpbmcgdGhlIGVycm9yLCB3aGljaCBpcyBhcmJpdHJhcnkgZGF0YSkuIEFuIGVycm9yIGZyb20gYSBjb25uZWN0ZWQgc291cmNlIGlzXG4gICAgLy8gYW4gYXBwbGljYXRpb24gZXJyb3IgYW5kIHRocm93cyBhcy1pcy4gQSBkb3duIHNvdXJjZSBnZXRzIGl0cyBiYWNrZ3JvdW5kIHJlY29ubmVjdCBraWNrZWQuXG4gICAgcHJpdmF0ZSBhc3luYyBydW48VD4oc3RhdGU6IENoYWluU3RhdGUsIGNvbmZpZzogeyBhcGlPbmx5PzogYm9vbGVhbjsgd3JpdGU/OiBib29sZWFuOyByb3V0ZT86IG51bWJlciB9LCBydW46IChhcmNoaXZlczogSUFyY2hpdmVzKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIGlmIChjb25maWcud3JpdGUpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJ1bldyaXRlKGNvbmZpZy5yb3V0ZSwgcnVuKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVjaGVja2VkQXZhaWxhYmlsaXR5ID0gZmFsc2U7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBsZXQgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgc291cmNlIG9mIHN0YXRlLnNvdXJjZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLnJvdXRlICE9PSB1bmRlZmluZWQgJiYgIXJvdXRlQ29udGFpbnMoc291cmNlLmNvbmZpZy5yb3V0ZSwgY29uZmlnLnJvdXRlKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgaWYgKCFjb25maWdXaW5kb3dDdXJyZW50KHNvdXJjZS5jb25maWcpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29uZmlnLmFwaU9ubHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBhcGkgPSBzb3VyY2UuYXBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhcGkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChgJHtzb3VyY2UuY29uZmlnLnVybH0gaGFzIFVSTC1vbmx5IGFjY2Vzcywgd2hpY2ggY2Fubm90IHNlcnZlIHRoaXMgb3BlcmF0aW9uYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgcnVuKGFwaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHNvdXJjZS5yZWFkKHJ1bik7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlLmlzQ29ubmVjdGVkKCkpIHRocm93IGU7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZS5ub3RlRmFpbHVyZSgpO1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChTdHJpbmcoKGUgYXMgRXJyb3IpLnN0YWNrID8/IGUpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBFdmVyeSBzb3VyY2UgZmFpbGVkOiByZS1jb250YWN0IGV2ZXJ5dGhpbmcgKHJvdXRpbmcgcmUtcmVhZCArIGNvbm5lY3Rpb24gcmUtYXR0ZW1wdCxcbiAgICAgICAgICAgIC8vIHBvc3NpYmx5IGFkb3B0aW5nIGEgcm91dGluZyB1cGRhdGUpIGFuZCB0cnkgb25jZSBtb3JlIGJlZm9yZSBnaXZpbmcgdXBcbiAgICAgICAgICAgIGlmICghcmVjaGVja2VkQXZhaWxhYmlsaXR5KSB7XG4gICAgICAgICAgICAgICAgcmVjaGVja2VkQXZhaWxhYmlsaXR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlY2hlY2tBdmFpbGFiaWxpdHkoKTtcbiAgICAgICAgICAgICAgICBzdGF0ZSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGUoKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQWxsIHNvdXJjZXMgZmFpbGVkIGZvciAke3RoaXMuZ2V0RGVidWdOYW1lKCl9JHtjb25maWcucm91dGUgIT09IHVuZGVmaW5lZCAmJiBgIChyb3V0ZSAke2NvbmZpZy5yb3V0ZX0pYCB8fCBcIlwifTogJHtlcnJvcnMuam9pbihcIiB8IFwiKSB8fCBcIm5vIHNvdXJjZXMgYXZhaWxhYmxlXCJ9YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBXcml0ZXMgYXJlIGNvbnNpc3RlbnQ6IHRoZXkgZ28gdG8gdGhlIGZpcnN0IGN1cnJlbnRseS12YWxpZCBzb3VyY2UgY292ZXJpbmcgdGhlIGtleSdzIHJvdXRlXG4gICAgLy8gYW5kIE5FVkVSIGZhaWwgb3ZlciB0byBhbm90aGVyIG5vZGUgLSBhIGNsaWVudCB3cm9uZ2x5IGRlY2lkaW5nIG5vZGVzIGFyZSBkb3duIG11c3Qgbm90XG4gICAgLy8gc2NhdHRlciBpdHMgd3JpdGVzIGFjcm9zcyB0aGUgY2hhaW4uIChSZWFkcyBmYWlsIG92ZXIgZnJlZWx5IGFib3ZlOiBzb3VyY2VzIGFyZSBzeW5jaHJvbml6ZWRcbiAgICAvLyBjb3BpZXMsIHNvIHJlYWRpbmcgZnJvbSBhbnkgb2YgdGhlbSBpcyBzYWZlLikgVGhlIG9uZSByZXRyeSBpcyBmb3IgYSB3aW5kb3cgYm91bmRhcnkgcGFzc2luZ1xuICAgIC8vIChvciBhIHJvdXRlIGRpc2FncmVlbWVudCkgbWlkLXdyaXRlLCB3aGljaCByZS1yZXNvbHZlcyB0aGUgdGFyZ2V0IHJhdGhlciB0aGFuIGZhbGxpbmcgYmFjay5cbiAgICBwcml2YXRlIGFzeW5jIHJ1bldyaXRlPFQ+KHJvdXRlOiBudW1iZXIgfCB1bmRlZmluZWQsIHJ1bjogKGFyY2hpdmVzOiBJQXJjaGl2ZXMpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAgICAgbGV0IHJldHJpZWRXcm9uZ1dpbmRvdyA9IGZhbHNlO1xuICAgICAgICBsZXQgcmV0cmllZFdyb25nUm91dGUgPSBmYWxzZTtcbiAgICAgICAgbGV0IHJlY2hlY2tlZEF2YWlsYWJpbGl0eSA9IGZhbHNlO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5nZXRTdGF0ZSgpO1xuICAgICAgICAgICAgbGV0IHRhcmdldCA9IHN0YXRlLnNvdXJjZXMuZmluZCh4ID0+IGNvbmZpZ0FjY2VwdHNXcml0ZXMoeC5jb25maWcpICYmIChyb3V0ZSA9PT0gdW5kZWZpbmVkIHx8IHJvdXRlQ29udGFpbnMoeC5jb25maWcucm91dGUsIHJvdXRlKSkpO1xuICAgICAgICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAvLyBCZWZvcmUgZ2l2aW5nIHVwLCByZS1jb250YWN0IGV2ZXJ5IHNvdXJjZSBvbmNlIChyb3V0aW5nIHJlLXJlYWQgKyBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgLy8gcmUtYXR0ZW1wdCwgcG9zc2libHkgYWRvcHRpbmcgYSByb3V0aW5nIHVwZGF0ZSB0aGF0IGZpeGVzIHRoZSB0YXJnZXQpXG4gICAgICAgICAgICAgICAgaWYgKCFyZWNoZWNrZWRBdmFpbGFiaWxpdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjaGVja2VkQXZhaWxhYmlsaXR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWNoZWNrQXZhaWxhYmlsaXR5KCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHNvdXJjZSBhY2NlcHRzIHdyaXRlcyBmb3IgJHt0aGlzLmdldERlYnVnTmFtZSgpfSR7cm91dGUgIT09IHVuZGVmaW5lZCAmJiBgIChyb3V0ZSAke3JvdXRlfSlgIHx8IFwiXCJ9IChldmVyeSBzb3VyY2UgaXMgb3V0c2lkZSBpdHMgdmFsaWQgd2luZG93IG9yIG91dHNpZGUgdGhlIGtleSdzIHJvdXRlKWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGFyZ2V0LndyaXRlKHJ1bik7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgbGV0IG1lc3NhZ2UgPSBTdHJpbmcoKGUgYXMgRXJyb3IpLnN0YWNrID8/IGUpO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFNUT1JBR0VfV1JPTkdfVkFMSURfV0lORE9XKSAmJiAhcmV0cmllZFdyb25nV2luZG93KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHJpZWRXcm9uZ1dpbmRvdyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucHJlcGFyZVdyb25nVGFyZ2V0UmV0cnkoc3RhdGUsIFwid2luZG93XCIpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoU1RPUkFHRV9XUk9OR19ST1VURSkgJiYgIXJldHJpZWRXcm9uZ1JvdXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHJpZWRXcm9uZ1JvdXRlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlV3JvbmdUYXJnZXRSZXRyeShzdGF0ZSwgXCJyb3V0ZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFRoZSBjb25uZWN0aW9uIGRpZWQgZHVyaW5nIChvciBiZWZvcmUpIHRoZSByZXF1ZXN0LiBPbmUgZnVsbCByZS1jb250YWN0IHBhc3MsXG4gICAgICAgICAgICAgICAgLy8gdGhlbiBvbmUgcmV0cnkgLSBzdGlsbCB0aGUgc2FtZSBjb25zaXN0ZW50IHRhcmdldCwgbmV2ZXIgYSBkaWZmZXJlbnQgbm9kZS5cbiAgICAgICAgICAgICAgICBpZiAoIXRhcmdldC5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5ub3RlRmFpbHVyZSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXJlY2hlY2tlZEF2YWlsYWJpbGl0eSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjaGVja2VkQXZhaWxhYmlsaXR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVjaGVja0F2YWlsYWJpbGl0eSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbGFzdENvbmZpZ1JlZnJlc2ggPSAwO1xuICAgIC8vIEEgd3JvbmctdGFyZ2V0IHJlamVjdGlvbiBtZWFucyBlaXRoZXIgd2UgcmFjZWQgYSB3aW5kb3cgYm91bmRhcnkgKHRpbWUgZml4ZXMgaXQpIG9yIG91clxuICAgIC8vIGNvbmZpZyBpcyBzdGFsZSAtIGUuZy4gYSBkZXBsb3ktdGFrZW92ZXIgcmVtYXAgdGhhdCBvbmx5IGV4aXN0cyBpbiB0aGUgc2VydmVyJ3MgbWVtb3J5XG4gICAgcHJpdmF0ZSBhc3luYyBwcmVwYXJlV3JvbmdUYXJnZXRSZXRyeShzdGF0ZTogQ2hhaW5TdGF0ZSwga2luZDogXCJ3aW5kb3dcIiB8IFwicm91dGVcIik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoa2luZCA9PT0gXCJ3aW5kb3dcIikge1xuICAgICAgICAgICAgbGV0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBsZXQgbmVhckJvdW5kYXJ5ID0gc3RhdGUuc291cmNlcy5zb21lKHNvdXJjZSA9PiBzb3VyY2UuY29uZmlnLnZhbGlkV2luZG93LnNvbWUodCA9PiB0ID4gMCAmJiB0IDwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgJiYgTWF0aC5hYnModCAtIG5vdykgPD0gV1JPTkdfVEFSR0VUX0JPVU5EQVJZX1dJTkRPVykpO1xuICAgICAgICAgICAgaWYgKG5lYXJCb3VuZGFyeSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IGRlbGF5KFdST05HX1RBUkdFVF9CT1VOREFSWV9SRVRSWV9ERUxBWSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChEYXRlLm5vdygpIC0gdGhpcy5sYXN0Q29uZmlnUmVmcmVzaCA8IENPTkZJR19SRUZSRVNIX1RIUk9UVExFKSByZXR1cm47XG4gICAgICAgIHRoaXMubGFzdENvbmZpZ1JlZnJlc2ggPSBEYXRlLm5vdygpO1xuICAgICAgICBhd2FpdCB0aGlzLnJlZnJlc2hBY3RpdmVDb25maWcoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlcXVlc3Q8VD4oY29uZmlnOiB7IGFwaU9ubHk/OiBib29sZWFuOyB3cml0ZT86IGJvb2xlYW47IHJvdXRlPzogbnVtYmVyIH0sIHJ1bjogKGFyY2hpdmVzOiBJQXJjaGl2ZXMpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5nZXRTdGF0ZSgpO1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW4oc3RhdGUsIGNvbmZpZywgcnVuKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgYWNjZXNzLXBhZ2UgbGluayAocGx1cyBvdXIgbWFjaGluZUlkL2lwLCBmb3IgdGhlIGFwcHJvdmVyIHRvIG1hdGNoIHRoZSByZXF1ZXN0KSBmb3IgdGhlXG4gICAgLy8gZmlyc3QgaG9zdGVkIHNvdXJjZSB0aGF0IGhhc24ndCBncmFudGVkIHVzIGFjY2Vzcy4gdW5kZWZpbmVkIHdoZW4gd2UgaGF2ZSBhY2Nlc3MgZXZlcnl3aGVyZVxuICAgIC8vIHdlIGNhbiBoYXZlIGl0LiBBbHNvIHJlZ2lzdGVycyB0aGUgYWNjZXNzIHJlcXVlc3Qgc2VydmVyLXNpZGUuXG4gICAgcHVibGljIGFzeW5jIHdhaXRpbmdGb3JBY2Nlc3MoKTogUHJvbWlzZTx7IGxpbms6IHN0cmluZzsgbWFjaGluZUlkOiBzdHJpbmc7IGlwOiBzdHJpbmcgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICBsZXQgc3RhdGUgPSBhd2FpdCB0aGlzLmdldFN0YXRlKCk7XG4gICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzdGF0ZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICBpZiAoc291cmNlLmFwaSBpbnN0YW5jZW9mIEFyY2hpdmVzUmVtb3RlKSB7XG4gICAgICAgICAgICAgICAgbGV0IHdhaXRpbmcgPSBhd2FpdCBzb3VyY2UuYXBpLndhaXRpbmdGb3JBY2Nlc3MoKTtcbiAgICAgICAgICAgICAgICBpZiAod2FpdGluZykgcmV0dXJuIHdhaXRpbmc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0KGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IHsgcmFuZ2U/OiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH0gfSk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLmdldDIoZmlsZU5hbWUsIGNvbmZpZyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgJiYgcmVzdWx0LmRhdGEgfHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0MihmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiB7IHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9IH0pOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVxdWVzdCh7IHJvdXRlOiBnZXRSb3V0ZShmaWxlTmFtZSkgfSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuZ2V0MihmaWxlTmFtZSwgY29uZmlnKSk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBnZXRJbmZvKGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlcXVlc3QoeyByb3V0ZTogZ2V0Um91dGUoZmlsZU5hbWUpIH0sIGFyY2hpdmVzID0+IGFyY2hpdmVzLmdldEluZm8oZmlsZU5hbWUpKTtcbiAgICB9XG5cbiAgICAvLyBBIG1pbmltYWwgc2V0IG9mIGNvbm5lY3RlZCwgY3VycmVudGx5LXZhbGlkIEFQSSBzb3VyY2VzIHdob3NlIHJvdXRlcyBjb3ZlciBbMCwgMSkgLSBsaXN0aW5nXG4gICAgLy8gb3BlcmF0aW9ucyBtdXN0IG1lcmdlIGV2ZXJ5IHNoYXJkLiBHcmVlZHkgc3dlZXA6IHJlcGVhdGVkbHkgdGFrZSB0aGUgc291cmNlIHRoYXQgZXh0ZW5kc1xuICAgIC8vIGNvdmVyYWdlIHRoZSBmdXJ0aGVzdC4gSW4gcHJhY3RpY2UgdGhpcyBpcyBvbmUgc291cmNlICh1bnNoYXJkZWQpLCBvciBvbmUgcGVyIHNoYXJkLlxuICAgIHByaXZhdGUgc2VsZWN0Q292ZXJpbmdTb3VyY2VzKHN0YXRlOiBDaGFpblN0YXRlLCBleGNsdWRlZDogU2V0PFNvdXJjZVdyYXBwZXI+KTogU291cmNlV3JhcHBlcltdIHtcbiAgICAgICAgbGV0IGNhbmRpZGF0ZXMgPSBzdGF0ZS5zb3VyY2VzLmZpbHRlcih4ID0+IGNvbmZpZ1dpbmRvd0N1cnJlbnQoeC5jb25maWcpICYmIHguYXBpICYmICFleGNsdWRlZC5oYXMoeCkpO1xuICAgICAgICBsZXQgY2hvc2VuOiBTb3VyY2VXcmFwcGVyW10gPSBbXTtcbiAgICAgICAgbGV0IGNvdmVyZWQgPSAwO1xuICAgICAgICB3aGlsZSAoY292ZXJlZCA8IDEpIHtcbiAgICAgICAgICAgIGxldCBiZXN0OiBTb3VyY2VXcmFwcGVyIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgbGV0IGJlc3RFbmQgPSBjb3ZlcmVkO1xuICAgICAgICAgICAgZm9yIChsZXQgc291cmNlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICAgICAgICBsZXQgW3N0YXJ0LCBlbmRdID0gc291cmNlLmNvbmZpZy5yb3V0ZSB8fCBGVUxMX1JPVVRFO1xuICAgICAgICAgICAgICAgIGlmIChzdGFydCA+IGNvdmVyZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGlmIChlbmQgPiBiZXN0RW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGJlc3RFbmQgPSBlbmQ7XG4gICAgICAgICAgICAgICAgICAgIGJlc3QgPSBzb3VyY2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFiZXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY292ZXIgdGhlIGZ1bGwgcm91dGUgc3BhY2UgZm9yICR7dGhpcy5nZXREZWJ1Z05hbWUoKX06IHRoZSBhdmFpbGFibGUgc291cmNlcyBvbmx5IGNvdmVyIHVwIHRvICR7Y292ZXJlZH0gKHNvbWUgc2hhcmRzIGFyZSBkb3duIG9yIFVSTC1vbmx5KWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2hvc2VuLnB1c2goYmVzdCk7XG4gICAgICAgICAgICBjb3ZlcmVkID0gYmVzdEVuZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2hvc2VuO1xuICAgIH1cblxuICAgIC8vIEZhbnMgb25lIGNhbGwgb3V0IG92ZXIgYSBjb3ZlcmluZyBzZXQgb2Ygc2hhcmRzLiBTb3VyY2VzIGFyZSBuZXZlciBwcmUtZmlsdGVyZWQgYnlcbiAgICAvLyBjb25uZWN0aXZpdHkgLSB0aGUgcmVxdWVzdCBpcyBhdHRlbXB0ZWQsIGFuZCBhIGZhaWx1cmUgd2l0aCB0aGUgc29ja2V0IGRvd24gYWZ0ZXJ3YXJkc1xuICAgIC8vIGV4Y2x1ZGVzIHRoYXQgc291cmNlIGFuZCByZS1zZWxlY3RzIHRoZSBjb3ZlcmluZyBzZXQgKGFuIGVycm9yIGZyb20gYSBsaXZlIHNvdXJjZSB0aHJvd3MpLlxuICAgIHByaXZhdGUgYXN5bmMgcnVuT25Db3ZlcmluZzxUPihydW46IChhcmNoaXZlczogSUFyY2hpdmVzKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUW10+IHtcbiAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5nZXRTdGF0ZSgpO1xuICAgICAgICBsZXQgZXhjbHVkZWQgPSBuZXcgU2V0PFNvdXJjZVdyYXBwZXI+KCk7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBsZXQgY292ZXJpbmcgPSB0aGlzLnNlbGVjdENvdmVyaW5nU291cmNlcyhzdGF0ZSwgZXhjbHVkZWQpO1xuICAgICAgICAgICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChjb3ZlcmluZy5tYXAoYXN5bmMgc291cmNlID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgYXBpID0gc291cmNlLmFwaTtcbiAgICAgICAgICAgICAgICBpZiAoIWFwaSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c291cmNlLmNvbmZpZy51cmx9IGhhcyBVUkwtb25seSBhY2Nlc3MsIHdoaWNoIGNhbm5vdCBzZXJ2ZSB0aGlzIG9wZXJhdGlvbmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogYXdhaXQgcnVuKGFwaSkgfTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuaXNDb25uZWN0ZWQoKSkgdGhyb3cgZTtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlLm5vdGVGYWlsdXJlKCk7XG4gICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGVkLmFkZChzb3VyY2UpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHRzLmV2ZXJ5KHggPT4geCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAoeCA9PiAoeCBhcyB7IHZhbHVlOiBUIH0pLnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBmaW5kKHByZWZpeDogc3RyaW5nLCBjb25maWc/OiB7IHNoYWxsb3c/OiBib29sZWFuOyB0eXBlOiBcImZpbGVzXCIgfCBcImZvbGRlcnNcIiB9KTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgICAgICByZXR1cm4gKGF3YWl0IHRoaXMuZmluZEluZm8ocHJlZml4LCBjb25maWcpKS5tYXAoeCA9PiB4LnBhdGgpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZmluZEluZm8ocHJlZml4OiBzdHJpbmcsIGNvbmZpZz86IHsgc2hhbGxvdz86IGJvb2xlYW47IHR5cGU6IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgdGhpcy5ydW5PbkNvdmVyaW5nKGFyY2hpdmVzID0+IGFyY2hpdmVzLmZpbmRJbmZvKHByZWZpeCwgY29uZmlnKSk7XG4gICAgICAgIC8vIE92ZXJsYXBwaW5nIHNoYXJkcyBjYW4gYm90aCByZXBvcnQgYSBwYXRoOyB0aGUgbmV3ZXN0IHdpbnNcbiAgICAgICAgbGV0IGJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBBcmNoaXZlRmlsZUluZm8+KCk7XG4gICAgICAgIGZvciAobGV0IGxpc3Qgb2YgcmVzdWx0cykge1xuICAgICAgICAgICAgZm9yIChsZXQgZmlsZSBvZiBsaXN0KSB7XG4gICAgICAgICAgICAgICAgbGV0IGV4aXN0aW5nID0gYnlQYXRoLmdldChmaWxlLnBhdGgpO1xuICAgICAgICAgICAgICAgIGlmICghZXhpc3RpbmcgfHwgZmlsZS5jcmVhdGVUaW1lID4gZXhpc3RpbmcuY3JlYXRlVGltZSkge1xuICAgICAgICAgICAgICAgICAgICBieVBhdGguc2V0KGZpbGUucGF0aCwgZmlsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBtZXJnZWQgPSBbLi4uYnlQYXRoLnZhbHVlcygpXTtcbiAgICAgICAgc29ydChtZXJnZWQsIHggPT4geC5wYXRoKTtcbiAgICAgICAgcmV0dXJuIG1lcmdlZDtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldENoYW5nZXNBZnRlcih0aW1lOiBudW1iZXIpOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgdGhpcy5ydW5PbkNvdmVyaW5nKGFzeW5jIGFyY2hpdmVzID0+IHtcbiAgICAgICAgICAgIGlmICghYXJjaGl2ZXMuZ2V0Q2hhbmdlc0FmdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2FyY2hpdmVzLmdldERlYnVnTmFtZSgpfSBkb2VzIG5vdCBzdXBwb3J0IGdldENoYW5nZXNBZnRlcmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGFyY2hpdmVzLmdldENoYW5nZXNBZnRlcih0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGxldCBieVBhdGggPSBuZXcgTWFwPHN0cmluZywgQXJjaGl2ZUZpbGVJbmZvPigpO1xuICAgICAgICBmb3IgKGxldCBsaXN0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGZpbGUgb2YgbGlzdCkge1xuICAgICAgICAgICAgICAgIGxldCBleGlzdGluZyA9IGJ5UGF0aC5nZXQoZmlsZS5wYXRoKTtcbiAgICAgICAgICAgICAgICBpZiAoIWV4aXN0aW5nIHx8IGZpbGUuY3JlYXRlVGltZSA+IGV4aXN0aW5nLmNyZWF0ZVRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgYnlQYXRoLnNldChmaWxlLnBhdGgsIGZpbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgbWVyZ2VkID0gWy4uLmJ5UGF0aC52YWx1ZXMoKV07XG4gICAgICAgIHNvcnQobWVyZ2VkLCB4ID0+IHgucGF0aCk7XG4gICAgICAgIHJldHVybiBtZXJnZWQ7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBnZXRTeW5jU3RhdHVzKCk6IFByb21pc2U8QXJjaGl2ZXNTeW5jU3RhdHVzPiB7XG4gICAgICAgIGxldCBzdGF0dXNlcyA9IGF3YWl0IHRoaXMucnVuT25Db3ZlcmluZyhhc3luYyBhcmNoaXZlcyA9PiB7XG4gICAgICAgICAgICBpZiAoIWFyY2hpdmVzLmdldFN5bmNTdGF0dXMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7YXJjaGl2ZXMuZ2V0RGVidWdOYW1lKCl9IGRvZXMgbm90IHN1cHBvcnQgZ2V0U3luY1N0YXR1c2ApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGFyY2hpdmVzLmdldFN5bmNTdGF0dXMoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhbGxTY2Fuc0NvbXBsZXRlOiBzdGF0dXNlcy5ldmVyeSh4ID0+IHguYWxsU2NhbnNDb21wbGV0ZSksXG4gICAgICAgICAgICBpbmRleFNpemU6IHN0YXR1c2VzLnJlZHVjZSgoc3VtLCB4KSA9PiBzdW0gKyB4LmluZGV4U2l6ZSwgMCksXG4gICAgICAgICAgICBzb3VyY2VzOiBzdGF0dXNlcy5mbGF0TWFwKHggPT4geC5zb3VyY2VzKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldENvbmZpZygpOiBQcm9taXNlPEFyY2hpdmVzQ29uZmlnPiB7XG4gICAgICAgIGxldCBzdGF0ZSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGUoKTtcbiAgICAgICAgaWYgKCFzdGF0ZS5zb3VyY2VzLnNvbWUoeCA9PiB4LmFwaSkpIHJldHVybiB7IHJlbW90ZUNvbmZpZzogc3RhdGUuY29uZmlnIH07XG4gICAgICAgIGxldCBjb25maWcgPSBhd2FpdCB0aGlzLnJ1bihzdGF0ZSwgeyBhcGlPbmx5OiB0cnVlIH0sIGFyY2hpdmVzID0+IGFyY2hpdmVzLmdldENvbmZpZygpKTtcbiAgICAgICAgcmV0dXJuIHsgLi4uY29uZmlnLCByZW1vdGVDb25maWc6IHN0YXRlLmNvbmZpZyB9O1xuICAgIH1cbiAgICAvKiogVHJ1ZSBvbmx5IHdoZW4gRVZFUlkgd3JpdGUtcmVjZWl2aW5nIHNvdXJjZSB3b3VsZCBhY2NlcHQgb3VyIHdyaXRlcyAocGFydGlhbCB3cml0ZSBhY2Nlc3NcbiAgICAgKiAgZGVzeW5jaHJvbml6ZXMgc291cmNlcywgc28gaXQgY291bnRzIGFzIG5vIGFjY2VzcykuICovXG4gICAgcHVibGljIGFzeW5jIGhhc1dyaXRlQWNjZXNzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBsZXQgc3RhdGUgPSBhd2FpdCB0aGlzLmdldFN0YXRlKCk7XG4gICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzdGF0ZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICBpZiAoIWNvbmZpZ0FjY2VwdHNXcml0ZXMoc291cmNlLmNvbmZpZykpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFhd2FpdCBzb3VyY2UuaGFzV3JpdGVBY2Nlc3MoKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKiBSZXR1cm5zIHRoZSBmdWxsIGtleSB3cml0dGVuLiBQbGFpbiBrZXlzIGNvbWUgYmFjayB1bmNoYW5nZWQ7IGtleXMgY29udGFpbmluZyBWQVJJQUJMRV9TSEFSRFxuICAgICAqICBhcmUgYXV0b21hdGljYWxseSBtYXRlcmlhbGl6ZWQgKGEgc2hhcmQgdmFsdWUgaXMgcGlja2VkIGFuZCBlbWJlZGRlZCwgc2VlIHNldFZhcmlhYmxlU2hhcmQpXG4gICAgICogIGFuZCB0aGUgY2FsbGVyIG5lZWRzIHRoZSByZXR1cm5lZCBrZXkgdG8gZXZlciByZWFkIHRoZSB2YWx1ZSBiYWNrLiAqL1xuICAgIHB1YmxpYyBhc3luYyBzZXQoZmlsZU5hbWU6IHN0cmluZywgZGF0YTogQnVmZmVyLCBjb25maWc/OiB7IGxhc3RNb2RpZmllZD86IG51bWJlciB9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgaWYgKGZpbGVOYW1lLmluY2x1ZGVzKFZBUklBQkxFX1NIQVJEKSAmJiBwYXJzZVZhcmlhYmxlUm91dGUoZmlsZU5hbWUpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNldFZhcmlhYmxlU2hhcmQoZmlsZU5hbWUsIGRhdGEsIGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5yZXF1ZXN0KHsgd3JpdGU6IHRydWUsIHJvdXRlOiBnZXRSb3V0ZShmaWxlTmFtZSkgfSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuc2V0KGZpbGVOYW1lLCBkYXRhLCBjb25maWcpKTtcbiAgICAgICAgcmV0dXJuIGZpbGVOYW1lO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZGVsKGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZXF1ZXN0KHsgd3JpdGU6IHRydWUsIHJvdXRlOiBnZXRSb3V0ZShmaWxlTmFtZSkgfSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuZGVsKGZpbGVOYW1lKSk7XG4gICAgfVxuXG4gICAgLy8gV3JpdGVzIGEgYmFyZSB2YXJpYWJsZS1zaGFyZCBrZXk6IHBpY2tzIHRoZSBsb3dlc3QtbGF0ZW5jeSB1cCB3cml0ZSBzaGFyZCwgbWF0ZXJpYWxpemVzIHRoZVxuICAgIC8vIGtleSB3aXRoIGEgcmFuZG9tIHZhbHVlIGluc2lkZSB0aGF0IHNoYXJkJ3Mgcm91dGUsIHdyaXRlcyBpdCwgYW5kIHJldHVybnMgdGhlIEZVTEwga2V5XG4gICAgLy8gYWN0dWFsbHkgd3JpdHRlbi4gVW5saWtlIG5vcm1hbCB3cml0ZXMgdGhpcyBDQU4gbW92ZSB0byBhbm90aGVyIHNoYXJkIHdoZW4gdGhlIHByZWZlcnJlZCBvbmVcbiAgICAvLyBpcyBkb3duIChlcnJvciArIHNvY2tldCBkb3duLCBzYW1lIHJ1bGUgYXMgcmVhZHMpIC0gZWFjaCBzaGFyZCByZWNlaXZlcyBhIGRpZmZlcmVudCBrZXksIHNvXG4gICAgLy8gd3JpdGUgY29uc2lzdGVuY3kgaXMgcHJlc2VydmVkLlxuICAgIHByaXZhdGUgYXN5bmMgc2V0VmFyaWFibGVTaGFyZChrZXk6IHN0cmluZywgZGF0YTogQnVmZmVyLCBjb25maWc/OiB7IGxhc3RNb2RpZmllZD86IG51bWJlciB9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgbGV0IHJlY2hlY2tlZEF2YWlsYWJpbGl0eSA9IGZhbHNlO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5nZXRTdGF0ZSgpO1xuICAgICAgICAgICAgLy8gUGVyLXNoYXJkIHdyaXRlIGNvbnNpc3RlbmN5IHN0aWxsIGhvbGRzOiB3aXRoaW4gYSByb3V0ZSwgb25seSB0aGUgRklSU1Qgc291cmNlIG1heVxuICAgICAgICAgICAgLy8gdGFrZSB3cml0ZXMgLSBsYXRlbmN5IG9ubHkgcGlja3MgV0hJQ0ggc2hhcmQgdGhlIGtleSBtYXRlcmlhbGl6ZXMgaW50b1xuICAgICAgICAgICAgbGV0IHRhcmdldHNCeVJvdXRlID0gbmV3IE1hcDxzdHJpbmcsIFNvdXJjZVdyYXBwZXI+KCk7XG4gICAgICAgICAgICBmb3IgKGxldCBzb3VyY2Ugb2Ygc3RhdGUuc291cmNlcykge1xuICAgICAgICAgICAgICAgIGlmICghY29uZmlnQWNjZXB0c1dyaXRlcyhzb3VyY2UuY29uZmlnKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgbGV0IHJvdXRlS2V5ID0gSlNPTi5zdHJpbmdpZnkoc291cmNlLmNvbmZpZy5yb3V0ZSB8fCBGVUxMX1JPVVRFKTtcbiAgICAgICAgICAgICAgICBpZiAoIXRhcmdldHNCeVJvdXRlLmhhcyhyb3V0ZUtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0c0J5Um91dGUuc2V0KHJvdXRlS2V5LCBzb3VyY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCB0YXJnZXRzID0gWy4uLnRhcmdldHNCeVJvdXRlLnZhbHVlcygpXTtcbiAgICAgICAgICAgIHNvcnQodGFyZ2V0cywgeCA9PiB4LmdldExhdGVuY3koKSk7XG4gICAgICAgICAgICBsZXQgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgdGFyZ2V0IG9mIHRhcmdldHMpIHtcbiAgICAgICAgICAgICAgICBsZXQgW3N0YXJ0LCBlbmRdID0gdGFyZ2V0LmNvbmZpZy5yb3V0ZSB8fCBGVUxMX1JPVVRFO1xuICAgICAgICAgICAgICAgIGxldCBmdWxsS2V5ID0ga2V5LnJlcGxhY2UoVkFSSUFCTEVfU0hBUkQsIFZBUklBQkxFX1NIQVJEICsgXCJfXCIgKyAoc3RhcnQgKyBNYXRoLnJhbmRvbSgpICogKGVuZCAtIHN0YXJ0KSkpO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRhcmdldC53cml0ZShhcmNoaXZlcyA9PiBhcmNoaXZlcy5zZXQoZnVsbEtleSwgZGF0YSwgY29uZmlnKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmdWxsS2V5O1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogSWYgd2UgcnVuIGludG8gY2FzZXMgd2hlbiB0cmFuc3BvcnQgbGV2ZWwgZXJyb3JzIGhhcHBlbiwgYnV0IHdlIGFyZSBzdGlsbCBjb25uZWN0ZWQsIHRoZW4gd2UgbWlnaHQgd2FudCB0byBhZGQgYWRkaXRpb25hbCBjaGVja2luZyBoZXJlLCBhZGRpdGlvbmFsIGVycm9ycyBpbiB3aGljaCB3ZSB3aWxsIHJldHJ5IHRoZSBvdGhlciB0YXJnZXRzLiBIb3dldmVyLCBpZGVhbGx5LCBjaGVja2luZyBpZiB0aGUgV2ViU29ja2V0IGNvbm5lY3Rpb24gaXMgc3RpbGwgY29ubmVjdGVkIHdpbGwgaGFuZGxlIGFsbCB0aG9zZSBjYXNlcy4gRGlzdGluZ3Vpc2hpbmcgYmV0d2VlbiBhcHBsaWNhdGlvbiBlcnJvcnMgKHdoaWNoIHdlIGNhbid0IHJldHJ5KSBhbmQgdHJhbnNwb3J0IGVycm9ycy5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldC5pc0Nvbm5lY3RlZCgpKSB0aHJvdyBlO1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQubm90ZUZhaWx1cmUoKTtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2goU3RyaW5nKChlIGFzIEVycm9yKS5zdGFjayA/PyBlKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRXZlcnkgc2hhcmQgZmFpbGVkOiByZS1jb250YWN0IGV2ZXJ5dGhpbmcgYW5kIHRyeSBvbmNlIG1vcmUgYmVmb3JlIGdpdmluZyB1cFxuICAgICAgICAgICAgaWYgKCFyZWNoZWNrZWRBdmFpbGFiaWxpdHkpIHtcbiAgICAgICAgICAgICAgICByZWNoZWNrZWRBdmFpbGFiaWxpdHkgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVjaGVja0F2YWlsYWJpbGl0eSgpO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFdmVyeSB2YXJpYWJsZS1zaGFyZCB3cml0ZSB0YXJnZXQgZmFpbGVkIGZvciAke3RoaXMuZ2V0RGVidWdOYW1lKCl9OiAke2Vycm9ycy5qb2luKFwiIHwgXCIpIHx8IFwibm8gc291cmNlcyBhY2NlcHQgd3JpdGVzXCJ9YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgc2V0TGFyZ2VGaWxlKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IGdldE5leHREYXRhKCk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChjb25maWcucGF0aC5pbmNsdWRlcyhWQVJJQUJMRV9TSEFSRCkgJiYgcGFyc2VWYXJpYWJsZVJvdXRlKGNvbmZpZy5wYXRoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHNldExhcmdlRmlsZSBkb2VzIG5vdCBzdXBwb3J0IFZBUklBQkxFX1NIQVJEIGtleXMgKHRoZXJlIGlzIG5vIHdheSB0byByZXR1cm4gdGhlIG1hdGVyaWFsaXplZCBrZXkpOyB3cml0ZSB0aGUgZmlsZSB3aXRoIHNldCwgb3IgbWF0ZXJpYWxpemUgdGhlIGtleSB5b3Vyc2VsZi4gS2V5OiAke0pTT04uc3RyaW5naWZ5KGNvbmZpZy5wYXRoKX1gKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcm91dGUgPSBnZXRSb3V0ZShjb25maWcucGF0aCk7XG4gICAgICAgIGxldCByZWNoZWNrZWRBdmFpbGFiaWxpdHkgPSBmYWxzZTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGxldCBzdGF0ZSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGUoKTtcbiAgICAgICAgICAgIC8vIFNhbWUgY29uc2lzdGVuY3kgcnVsZSBhcyBydW5Xcml0ZTogdGhlIGZpcnN0IGN1cnJlbnRseS12YWxpZCBzb3VyY2UgZm9yIHRoZSByb3V0ZSwgb3Igbm90aGluZ1xuICAgICAgICAgICAgbGV0IHRhcmdldCA9IHN0YXRlLnNvdXJjZXMuZmluZCh4ID0+IGNvbmZpZ0FjY2VwdHNXcml0ZXMoeC5jb25maWcpICYmIHJvdXRlQ29udGFpbnMoeC5jb25maWcucm91dGUsIHJvdXRlKSk7XG4gICAgICAgICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICAgICAgICAgIGlmICghcmVjaGVja2VkQXZhaWxhYmlsaXR5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY2hlY2tlZEF2YWlsYWJpbGl0eSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVjaGVja0F2YWlsYWJpbGl0eSgpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBzb3VyY2UgYWNjZXB0cyB3cml0ZXMgZm9yIHNldExhcmdlRmlsZSBvbiAke3RoaXMuZ2V0RGVidWdOYW1lKCl9IChyb3V0ZSAke3JvdXRlfSlgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGFyZ2V0LndyaXRlKGFyY2hpdmVzID0+IGFyY2hpdmVzLnNldExhcmdlRmlsZShjb25maWcpKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIGRhdGEgc3RyZWFtIGNhbm5vdCBiZSByZXdvdW5kLCBzbyBhIG1pZC11cGxvYWQgZGlzY29ubmVjdCBjYW5ub3QgYmUgcmV0cmllZFxuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Lm5vdGVGYWlsdXJlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0VVJMKHBhdGg6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGxldCBzdGF0ZSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGUoKTtcbiAgICAgICAgbGV0IHJvdXRlID0gZ2V0Um91dGUocGF0aCk7XG4gICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzdGF0ZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICBpZiAoc291cmNlLmNvbmZpZy5wdWJsaWMgPT09IGZhbHNlKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmICghcm91dGVDb250YWlucyhzb3VyY2UuY29uZmlnLnJvdXRlLCByb3V0ZSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHNvdXJjZS51cmwpIHJldHVybiBhd2FpdCBzb3VyY2UudXJsLmdldFVSTChwYXRoKTtcbiAgICAgICAgICAgIGlmIChzb3VyY2UuYXBpKSByZXR1cm4gYXdhaXQgc291cmNlLmFwaS5nZXRVUkwocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBwdWJsaWMgc291cmNlIGNvdmVyaW5nIHJvdXRlICR7cm91dGV9IHRvIGJ1aWxkIGEgVVJMIGZyb20gZm9yICR7dGhpcy5nZXREZWJ1Z05hbWUoKX1gKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNwb3NlZCA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLnBvbGxUaW1lcikge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnBvbGxUaW1lcik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaW5pdFJldHJ5VGltZXIpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmluaXRSZXRyeVRpbWVyKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc3RhdGVQcm9taXNlID0gdGhpcy5zdGF0ZVByb21pc2U7XG4gICAgICAgIGlmIChzdGF0ZVByb21pc2UpIHtcbiAgICAgICAgICAgIHZvaWQgc3RhdGVQcm9taXNlLnRoZW4oc3RhdGUgPT4ge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzdGF0ZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgKCkgPT4geyB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gVGhlIElBcmNoaXZlcyBmb3IgYSBSZW1vdGVDb25maWcgKG9yIGEgc2luZ2xlIHNvdXJjZSAtIGEgcm91dGluZyBVUkwgc3RyaW5nIHdvcmtzKS4gRnVsbHkgbGF6eTpcbi8vIG5vdGhpbmcgaXMgY29udGFjdGVkIHVudGlsIHRoZSBmaXJzdCBjYWxsLiBDYWxsIGRpc3Bvc2UoKSB3aGVuIGRvbmUgd2l0aCBpdCwgc28gaXRzIGJhY2tncm91bmRcbi8vIHJldHJ5L3BvbGwgbG9vcHMgc3RvcC5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBcmNoaXZlcyhjb25maWc6IFJlbW90ZUNvbmZpZyB8IFJlbW90ZUNvbmZpZ0Jhc2UpOiBBcmNoaXZlc0NoYWluIHtcbiAgICByZXR1cm4gbmV3IEFyY2hpdmVzQ2hhaW4oY29uZmlnKTtcbn1cblxuLyoqIEV2ZXJ5IGJ1Y2tldCBhbiBhY2NvdW50IGhhcyBvbiBvbmUgc3RvcmFnZSBzZXJ2ZXIgLSBhY3RpdmUgYW5kIGluYWN0aXZlIC0gd2l0aCBlYWNoIGJ1Y2tldCdzXG4gKiAgY29uZmlndXJhdGlvbi4gT25lIGF1dGhlbnRpY2F0ZWQgY2FsbCAodGhlIG5vcm1hbCB0cnVzdCBzeXN0ZW0gYXBwbGllcyk6IG5vIEFyY2hpdmVzQ2hhaW4sIG5vXG4gKiAgc3luY2hyb25pemF0aW9uLCBhbmQgaW5hY3RpdmUgYnVja2V0cyBvbiB0aGUgc2VydmVyIHN0YXkgaW5hY3RpdmUuIEFueSBVUkwgYWRkcmVzc2luZyB0aGVcbiAqICBzZXJ2ZXIgd29ya3MgKGEgYnVja2V0IHJvdXRpbmcgVVJMLCBvciBqdXN0IGh0dHBzOi8vaG9zdDpwb3J0KS4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsaXN0U2VydmVyQnVja2V0cyhjb25maWc6IHsgdXJsOiBzdHJpbmc7IGFjY291bnQ6IHN0cmluZyB9KTogUHJvbWlzZTxTZXJ2ZXJCdWNrZXRJbmZvW10+IHtcbiAgICBTb2NrZXRGdW5jdGlvbi5FTkFCTEVfQ0xJRU5UX01PREUgPSB0cnVlO1xuICAgIGxldCBwYXJzZWQgPSBwYXJzZVN0b3JhZ2VVcmwoY29uZmlnLnVybCk7XG4gICAgbGV0IG5vZGVJZCA9IFNvY2tldEZ1bmN0aW9uLmNvbm5lY3QoeyBhZGRyZXNzOiBwYXJzZWQuYWRkcmVzcywgcG9ydDogcGFyc2VkLnBvcnQgfSk7XG4gICAgbGV0IGNvbnRyb2xsZXIgPSBSZW1vdGVTdG9yYWdlQ29udHJvbGxlci5ub2Rlc1tub2RlSWRdO1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBjb250cm9sbGVyLmxpc3RCdWNrZXRzKGNvbmZpZy5hY2NvdW50KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICghU3RyaW5nKChlIGFzIEVycm9yKS5zdGFjayA/PyBlKS5pbmNsdWRlcyhTVE9SQUdFX05PVF9BVVRIRU5USUNBVEVEKSkgdGhyb3cgZTtcbiAgICAgICAgYXdhaXQgYXV0aGVudGljYXRlU3RvcmFnZSh7IGFkZHJlc3M6IHBhcnNlZC5hZGRyZXNzLCBwb3J0OiBwYXJzZWQucG9ydCwgbm9kZUlkIH0pO1xuICAgICAgICByZXR1cm4gYXdhaXQgY29udHJvbGxlci5saXN0QnVja2V0cyhjb25maWcuYWNjb3VudCk7XG4gICAgfVxufVxuXG4vKiogTGl2ZSBpbmZvIGZvciBvbmUgYnVja2V0IGdpdmVuIGl0cyByb3V0aW5nIFVSTCAoZ2V0Q29uZmlnOiByb3V0aW5nIGNvbmZpZywgaW5kZXggdG90YWxzLCBkaXNrXG4gKiAgbGltaXQsIGluLXByb2dyZXNzIHN5bmNocm9uaXphdGlvbikuIE9uZSBhdXRoZW50aWNhdGVkIGNhbGwgdG8gdGhhdCBzZXJ2ZXIgLSBhIGxpZ2h0LCBzYWZlXG4gKiAgYWx0ZXJuYXRpdmUgdG8gaW5zdGFudGlhdGluZyBhbiBBcmNoaXZlc0NoYWluLCB3aGljaCB3b3VsZCBzdGFydCBzeW5jaHJvbml6YXRpb24gbWFjaGluZXJ5LiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEJ1Y2tldEluZm8oY29uZmlnOiB7IHVybDogc3RyaW5nOyBhY2NvdW50TmFtZT86IHN0cmluZyB9KTogUHJvbWlzZTxBcmNoaXZlc0NvbmZpZz4ge1xuICAgIGxldCByZW1vdGUgPSBuZXcgQXJjaGl2ZXNSZW1vdGUoeyB1cmw6IGNvbmZpZy51cmwsIGFjY291bnROYW1lOiBjb25maWcuYWNjb3VudE5hbWUsIHdhaXRGb3JBY2Nlc3M6IGZhbHNlIH0pO1xuICAgIHJldHVybiBhd2FpdCByZW1vdGUuZ2V0Q29uZmlnKCk7XG59XG4iXX0=
|
|
781
|
-
/* _JS_SOURCE_HASH = "
|
|
789
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlQXJjaGl2ZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjcmVhdGVBcmNoaXZlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUUxQixtREFBd0Q7QUFDeEQsMkRBQXFEO0FBQ3JELDRDQUlzQjtBQUN0QixpREFJd0I7QUFDeEIsbUVBQWdFO0FBQ2hFLHFEQUF3RjtBQUN4Riw0Q0FBaUQ7QUFDakQsNkRBQTBHO0FBQzFHLDJEQUF5RjtBQUN6RixtREFBa0c7QUFFbEcsZ0dBQWdHO0FBQ2hHLG1HQUFtRztBQUNuRyxnR0FBZ0c7QUFDaEcsa0dBQWtHO0FBQ2xHLG1HQUFtRztBQUNuRyxtR0FBbUc7QUFDbkcsbUdBQW1HO0FBQ25HLG9GQUFvRjtBQUVwRixNQUFNLG9CQUFvQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQzNDLG1HQUFtRztBQUNuRyxpRUFBaUU7QUFDakUsTUFBTSw0QkFBNEIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQy9DLE1BQU0saUNBQWlDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUNwRCxrR0FBa0c7QUFDbEcsMkJBQTJCO0FBQzNCLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUMxQywyRkFBMkY7QUFDM0Ysb0RBQW9EO0FBQ3BELE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUUvQyxrR0FBa0c7QUFDbEcsa0dBQWtHO0FBQ2xHLGlHQUFpRztBQUNqRyxpR0FBaUc7QUFDakcsU0FBZ0IsaUJBQWlCLENBQUMsTUFBc0M7SUFDcEUsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQzlCLE9BQU8sSUFBSSw2QkFBaUIsQ0FBQyxFQUFFLFVBQVUsRUFBRSxJQUFBLGdDQUFpQixFQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxV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LFVBQVUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3hELENBQUM7QUFDTCxDQUFDO0FBWkQsOENBWUM7QUFFRDs7a0dBRWtHO0FBQzNGLEtBQUssVUFBVSxhQUFhLENBQUMsTUFBNkM7SUFDN0UsSUFBSSxNQUFNLEdBQUcsSUFBSSwrQkFBYyxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDNUcsT0FBTyxNQUFNLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUNwQyxDQUFDO0FBSEQsc0NBR0MiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuYWxsb3djbGllbnQgPSB0cnVlO1xuXG5pbXBvcnQgeyBpc05vZGUsIHNvcnQgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9taXNjXCI7XG5pbXBvcnQgeyBkZWxheSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2JhdGNoaW5nXCI7XG5pbXBvcnQge1xuICAgIElBcmNoaXZlcywgUmVtb3RlQ29uZmlnLCBSZW1vdGVDb25maWdCYXNlLCBIb3N0ZWRDb25maWcsIEJhY2tibGF6ZUNvbmZpZyxcbiAgICBBcmNoaXZlRmlsZUluZm8sIEFyY2hpdmVzQ29uZmlnLCBBcmNoaXZlc1N5bmNTdGF0dXMsIFdSSVRFX1BBU1RfV0lORE9XX0dSQUNFLCBTVE9SQUdFX1dST05HX1ZBTElEX1dJTkRPVyxcbiAgICBTVE9SQUdFX1dST05HX1JPVVRFLCBGVUxMX1JPVVRFLCBWQVJJQUJMRV9TSEFSRCxcbn0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHtcbiAgICBST1VUSU5HX0ZJTEUsIGdldENvbmZpZ1ZlcnNpb24sIHBhcnNlSG9zdGVkVXJsLCBwYXJzZUJhY2tibGF6ZVVybCxcbiAgICBub3JtYWxpemVSZW1vdGVDb25maWcsIG5vcm1hbGl6ZVNvdXJjZSwgcGFyc2VSb3V0aW5nRGF0YSwgc2VyaWFsaXplUmVtb3RlQ29uZmlnLFxuICAgIGdldFJvdXRlLCByb3V0ZUNvbnRhaW5zLCBwYXJzZVZhcmlhYmxlUm91dGUsXG59IGZyb20gXCIuL3JlbW90ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgU29ja2V0RnVuY3Rpb24gfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL1NvY2tldEZ1bmN0aW9uXCI7XG5pbXBvcnQgeyBBcmNoaXZlc1JlbW90ZSwgcGFyc2VTdG9yYWdlVXJsLCBhdXRoZW50aWNhdGVTdG9yYWdlIH0gZnJvbSBcIi4vQXJjaGl2ZXNSZW1vdGVcIjtcbmltcG9ydCB7IEFyY2hpdmVzQmFja2JsYXplIH0gZnJvbSBcIi4uL2JhY2tibGF6ZVwiO1xuaW1wb3J0IHsgZ2V0U3RvcmFnZVNlcnZlckNvbmZpZ09wdGlvbmFsLCBnZXRMb2NhbEFyY2hpdmVzLCBTZXJ2ZXJCdWNrZXRJbmZvIH0gZnJvbSBcIi4vc3RvcmFnZVNlcnZlclN0YXRlXCI7XG5pbXBvcnQgeyBSZW1vdGVTdG9yYWdlQ29udHJvbGxlciwgU1RPUkFHRV9OT1RfQVVUSEVOVElDQVRFRCB9IGZyb20gXCIuL3N0b3JhZ2VDb250cm9sbGVyXCI7XG5pbXBvcnQgeyBTb3VyY2VXcmFwcGVyLCBSRVRSWV9TVEFSVF9ERUxBWSwgUkVUUllfTUFYX0RFTEFZLCBSRVRSWV9HUk9XVEggfSBmcm9tIFwiLi9zb3VyY2VXcmFwcGVyXCI7XG5cbi8vIFR1cm5zIGEgUmVtb3RlQ29uZmlnIGludG8gYSB1c2FibGUgSUFyY2hpdmVzIChjcmVhdGVBcmNoaXZlcykuIEluaXRpYWxpemF0aW9uIGlzIGxhenk6IG9uIHRoZVxuLy8gZmlyc3QgY2FsbCB3ZSB3YWxrIHRoZSBzb3VyY2VzIElOIE9SREVSIGFuZCB0aGUgZmlyc3Qgb25lIHRoYXQgYW5zd2VycyBpcyBhdXRob3JpdGF0aXZlIChzb3VyY2VzXG4vLyBhcmUgc3luY2hyb25pemVkIGNvcGllcyBvZiB0aGUgc2FtZSBidWNrZXQsIHNvIHdlIG5ldmVyIGNvbnN1bHQgdGhlIHJlc3QpLiBJdHMgc3RvcmVkIHJvdXRpbmdcbi8vIGNvbmZpZyB3aW5zIG92ZXIgdGhlIGluLW1lbW9yeSBvbmUgLSB1bmxlc3Mgb3VycyBoYXMgYSBzdHJpY3RseSBuZXdlciB2ZXJzaW9uLCBpbiB3aGljaCBjYXNlIHdlXG4vLyB3cml0ZSBvdXJzIChjcmVhdGluZyB0aGUgYnVja2V0IHdoZW4gbm8gcm91dGluZyBleGlzdHMgYXQgYWxsKS4gQSBmYWlsZWQgaW5pdCAoYWxsIHNvdXJjZXMgZG93bixcbi8vIG9yIHRoZSByb3V0aW5nIHdyaXRlIHdhcyByZWplY3RlZCkgc3RheXMgZmFpbGVkIGZvciBjYWxsZXJzIGJ1dCByZXRyaWVzIGl0c2VsZiBpbiB0aGUgYmFja2dyb3VuZFxuLy8gd2l0aCBhIHJhbXBpbmcgZGVsYXkuIE9uY2UgcnVubmluZywgd2UgcmUtcmVhZCB0aGUgcm91dGluZyBjb25maWcgZXZlcnkgQ09ORklHX1BPTExfSU5URVJWQUwgYW5kXG4vLyByZWJ1aWxkIHRoZSBzb3VyY2UgbGlzdCB3aGVuIGl0IGNoYW5nZWQgKHJldXNpbmcgd3JhcHBlcnMgZm9yIHVuY2hhbmdlZCBzb3VyY2VzKS5cblxuY29uc3QgQ09ORklHX1BPTExfSU5URVJWQUwgPSA1ICogNjAgKiAxMDAwO1xuLy8gV3JvbmctdmFsaWQtd2luZG93IHJlamVjdGlvbnMgd2l0aGluIHRoaXMgZGlzdGFuY2Ugb2YgYSBrbm93biB3aW5kb3cgYm91bmRhcnkgYXJlIGp1c3QgdXMgcmFjaW5nXG4vLyB0aGUgYm91bmRhcnkgaXRzZWxmIC0gd2FpdGluZyBmaXhlcyB0aGVtLCBubyBuZXcgY29uZmlnIG5lZWRlZFxuY29uc3QgV1JPTkdfVEFSR0VUX0JPVU5EQVJZX1dJTkRPVyA9IDMwICogMTAwMDtcbmNvbnN0IFdST05HX1RBUkdFVF9CT1VOREFSWV9SRVRSWV9ERUxBWSA9IDE1ICogMTAwMDtcbi8vIE90aGVyd2lzZSBvdXIgY29uZmlnIGlzIHN0YWxlOyByZS1mZXRjaCBpdCBmcm9tIHRoZSBzZXJ2ZXIsIGF0IG1vc3QgdGhpcyBvZnRlbiAod2hlbiB0aHJvdHRsZWQsXG4vLyByZXRyeSB3aXRoIHdoYXQgd2UgaGF2ZSlcbmNvbnN0IENPTkZJR19SRUZSRVNIX1RIUk9UVExFID0gMzAgKiAxMDAwO1xuLy8gV2hlbiBldmVyeSBzb3VyY2UgbG9va3MgZG93biwgYWxsIG9mIHRoZW0gYXJlIHJlLWNvbnRhY3RlZCAocm91dGluZyByZS1yZWFkICsgY29ubmVjdGlvblxuLy8gcmUtYXR0ZW1wdCkgYmVmb3JlIGdpdmluZyB1cCAtIGF0IG1vc3QgdGhpcyBvZnRlblxuY29uc3QgQVZBSUxBQklMSVRZX1JFQ0hFQ0tfVEhST1RUTEUgPSA1ICogMTAwMDtcblxuLy8gVGhlIGRpcmVjdCBBUEkgSUFyY2hpdmVzIGZvciBvbmUgc291cmNlLCB3aXRoIG5vIFVSTC1mb3JtIGZhbGxiYWNrIGFuZCBubyBjaGFpbmluZy4gVXNlZCBieSB0aGVcbi8vIHN0b3JhZ2Ugc2VydmVyIGZvciBpdHMgc3luY2hyb25pemF0aW9uIHNvdXJjZXMuIERlbmllZCBjYWxscyB0aHJvdyBpbW1lZGlhdGVseSAocmVnaXN0ZXJpbmcgdGhlXG4vLyBhY2Nlc3MgcmVxdWVzdCBpbiB0aGUgYmFja2dyb3VuZCk6IHRoZSBzeW5jIGxvb3BzIHJldHJ5LWFuZC1sb2cgdW50aWwgYWNjZXNzIGlzIGdyYW50ZWQsIHdoaWxlXG4vLyBleHBsaWNpdCB3cml0ZXMgc3VyZmFjZSB0aGUgZGVuaWFsICh3aXRoIGdyYW50IGluc3RydWN0aW9ucykgdG8gdGhlIGNhbGxlciBpbnN0ZWFkIG9mIGhhbmdpbmcuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXBpQXJjaGl2ZXMoc291cmNlOiBIb3N0ZWRDb25maWcgfCBCYWNrYmxhemVDb25maWcpOiBJQXJjaGl2ZXMge1xuICAgIGlmIChzb3VyY2UudHlwZSA9PT0gXCJiYWNrYmxhemVcIikge1xuICAgICAgICByZXR1cm4gbmV3IEFyY2hpdmVzQmFja2JsYXplKHsgYnVja2V0TmFtZTogcGFyc2VCYWNrYmxhemVVcmwoc291cmNlLnVybCkuYnVja2V0TmFtZSwgcHVibGljOiBzb3VyY2UucHVibGljLCBpbW11dGFibGU6IHNvdXJjZS5pbW11dGFibGUgfSk7XG4gICAgfVxuICAgIGxldCBwYXJzZWQgPSBwYXJzZUhvc3RlZFVybChzb3VyY2UudXJsKTtcbiAgICBsZXQgc2VydmVyID0gaXNOb2RlKCkgJiYgZ2V0U3RvcmFnZVNlcnZlckNvbmZpZ09wdGlvbmFsKCkgfHwgdW5kZWZpbmVkO1xuICAgIGlmIChzZXJ2ZXIgJiYgcGFyc2VkLmFkZHJlc3MgPT09IHNlcnZlci5kb21haW4gJiYgcGFyc2VkLnBvcnQgPT09IHNlcnZlci5wb3J0KSB7XG4gICAgICAgIC8vIFRoaXMgc291cmNlIGlzIGEgYnVja2V0IGhvc3RlZCBieSBvdXIgb3duIHByb2Nlc3MgLSB1c2UgaXQgZGlyZWN0bHkgaW5zdGVhZCBvZiBjYWxsaW5nXG4gICAgICAgIC8vIG91cnNlbHZlcyBvdmVyIEhUVFBTXG4gICAgICAgIHJldHVybiBnZXRMb2NhbEFyY2hpdmVzKHBhcnNlZC5hY2NvdW50LCBwYXJzZWQuYnVja2V0TmFtZSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQXJjaGl2ZXNSZW1vdGUoeyB1cmw6IHNvdXJjZS51cmwsIGFjY291bnROYW1lOiBzb3VyY2UuYWNjb3VudE5hbWUsIHdhaXRGb3JBY2Nlc3M6IGZhbHNlIH0pO1xufVxuXG50eXBlIENoYWluU3RhdGUgPSB7XG4gICAgY29uZmlnOiBSZW1vdGVDb25maWc7XG4gICAgc291cmNlczogU291cmNlV3JhcHBlcltdO1xufTtcblxuZnVuY3Rpb24gY29uZmlnV2luZG93Q3VycmVudChjb25maWc6IEhvc3RlZENvbmZpZyB8IEJhY2tibGF6ZUNvbmZpZyk6IGJvb2xlYW4ge1xuICAgIGxldCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGxldCBbc3RhcnQsIGVuZF0gPSBjb25maWcudmFsaWRXaW5kb3c7XG4gICAgcmV0dXJuIHN0YXJ0IC0gV1JJVEVfUEFTVF9XSU5ET1dfR1JBQ0UgPD0gbm93ICYmIG5vdyA8PSBlbmQgKyBXUklURV9QQVNUX1dJTkRPV19HUkFDRTtcbn1cblxuLy8gQ2xpZW50IHdyaXRlcyB0YXJnZXQgb25seSB0aGUgQ1VSUkVOVExZIHZhbGlkIHNvdXJjZTogYSBmdXR1cmUtd2luZG93IHNvdXJjZSByZWNlaXZlcyBpdHMgZGF0YVxuLy8gdGhyb3VnaCBzZXJ2ZXItc2lkZSBkb3duc3RyZWFtIHByb3BhZ2F0aW9uL2JhY2tmaWxsLCBuZXZlciBkaXJlY3RseSBmcm9tIGNsaWVudHNcbmZ1bmN0aW9uIGNvbmZpZ0FjY2VwdHNXcml0ZXMoY29uZmlnOiBIb3N0ZWRDb25maWcgfCBCYWNrYmxhemVDb25maWcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gY29uZmlnV2luZG93Q3VycmVudChjb25maWcpO1xufVxuXG5leHBvcnQgY2xhc3MgQXJjaGl2ZXNDaGFpbiBpbXBsZW1lbnRzIElBcmNoaXZlcyB7XG4gICAgcHJpdmF0ZSBjb25maWd1cmVkOiBSZW1vdGVDb25maWc7XG4gICAgLy8gVGhlIGNvbmZpZyB3ZSBhY3R1YWxseSBydW4gb24gKHRoZSBhdXRob3JpdGF0aXZlIHN0b3JlZCBvbmUgYWZ0ZXIgaW5pdClcbiAgICBwcml2YXRlIGFjdGl2ZUNvbmZpZzogUmVtb3RlQ29uZmlnO1xuICAgIHByaXZhdGUgc3RhdGVQcm9taXNlOiBQcm9taXNlPENoYWluU3RhdGU+IHwgdW5kZWZpbmVkO1xuICAgIHByaXZhdGUgaW5pdFJldHJ5RGVsYXkgPSBSRVRSWV9TVEFSVF9ERUxBWTtcbiAgICBwcml2YXRlIGluaXRSZXRyeVRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IHVuZGVmaW5lZDtcbiAgICBwcml2YXRlIHBvbGxUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+IHwgdW5kZWZpbmVkO1xuICAgIHByaXZhdGUgZGlzcG9zZWQgPSBmYWxzZTtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZzogUmVtb3RlQ29uZmlnIHwgUmVtb3RlQ29uZmlnQmFzZSkge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyZWQgPSBub3JtYWxpemVSZW1vdGVDb25maWcoY29uZmlnKTtcbiAgICAgICAgdGhpcy5hY3RpdmVDb25maWcgPSB0aGlzLmNvbmZpZ3VyZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldERlYnVnTmFtZSgpIHtcbiAgICAgICAgbGV0IHVybHMgPSB0aGlzLmFjdGl2ZUNvbmZpZy5zb3VyY2VzLm1hcCh4ID0+IHR5cGVvZiB4ID09PSBcInN0cmluZ1wiICYmIHggfHwgKHggYXMgSG9zdGVkQ29uZmlnIHwgQmFja2JsYXplQ29uZmlnKS51cmwpO1xuICAgICAgICByZXR1cm4gYGNoYWluLyR7dXJscy5qb2luKFwiLFwiKX1gO1xuICAgIH1cblxuICAgIC8vIExhenkgaW5pdCB0aGF0IHJldGhyb3dzIGl0cyBlcnJvciB0byBldmVyeSBjYWxsZXIsIHdoaWxlIGEgYmFja2dyb3VuZCB0aW1lciByZXNldHMgYW5kXG4gICAgLy8gcmV0cmllcyBpdCB3aXRoIGEgcmFtcGluZyBkZWxheSAtIHNvIGEgY2hhaW4gdGhhdCBjb3VsZG4ndCBpbml0aWFsaXplIGZpeGVzIGl0c2VsZiBvbmNlIGFcbiAgICAvLyBzb3VyY2UgY29tZXMgYmFjaywgd2l0aG91dCBhbnkgY2FsbGVyIGhhdmluZyB0byBkcml2ZSBpdC5cbiAgICBwcml2YXRlIGdldFN0YXRlKCk6IFByb21pc2U8Q2hhaW5TdGF0ZT4ge1xuICAgICAgICBpZiAodGhpcy5kaXNwb3NlZCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihgQXJjaGl2ZXNDaGFpbiAke3RoaXMuZ2V0RGVidWdOYW1lKCl9IGhhcyBiZWVuIGRpc3Bvc2VkYCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5zdGF0ZVByb21pc2UpIHtcbiAgICAgICAgICAgIGxldCBwcm9taXNlID0gdGhpcy5pbml0KCk7XG4gICAgICAgICAgICB0aGlzLnN0YXRlUHJvbWlzZSA9IHByb21pc2U7XG4gICAgICAgICAgICBwcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFJldHJ5RGVsYXkgPSBSRVRSWV9TVEFSVF9ERUxBWTtcbiAgICAgICAgICAgIH0sIChlOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRpc3Bvc2VkIHx8IHRoaXMuaW5pdFJldHJ5VGltZXIpIHJldHVybjtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBTdG9yYWdlIGluaXQgZmFpbGVkIGZvciAke3RoaXMuZ2V0RGVidWdOYW1lKCl9LCByZXRyeWluZyBpbiAke01hdGgucm91bmQodGhpcy5pbml0UmV0cnlEZWxheSAvIDEwMDApfXMuICR7ZS5zdGFjayA/PyBlfWApO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFJldHJ5VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0UmV0cnlUaW1lciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGVQcm9taXNlID09PSBwcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlUHJvbWlzZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldFN0YXRlKCkuY2F0Y2goKCkgPT4geyB9KTtcbiAgICAgICAgICAgICAgICB9LCB0aGlzLmluaXRSZXRyeURlbGF5KTtcbiAgICAgICAgICAgICAgICAodGhpcy5pbml0UmV0cnlUaW1lciBhcyB7IHVucmVmPzogKCkgPT4gdm9pZCB9KS51bnJlZj8uKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmV0cnlEZWxheSA9IE1hdGgubWluKFJFVFJZX01BWF9ERUxBWSwgdGhpcy5pbml0UmV0cnlEZWxheSAqIFJFVFJZX0dST1dUSCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZVByb21pc2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBpbml0KCk6IFByb21pc2U8Q2hhaW5TdGF0ZT4ge1xuICAgICAgICBsZXQgY29uZmlncyA9IHRoaXMuY29uZmlndXJlZC5zb3VyY2VzLm1hcChub3JtYWxpemVTb3VyY2UpO1xuICAgICAgICAvLyBFVkVSWSBzb3VyY2UgaXMgY29udGFjdGVkIGZvciBpdHMgcGljdHVyZSBvZiB0aGUgcm91dGluZyBjb25maWcgKHBlciB0aGUgc3BlYzogdGhlIGNvbmZpZ1xuICAgICAgICAvLyBpcyBkdXBsaWNhdGVkIGludG8gYWxsIG9mIHRoZW0pIC0gd2hpY2ggYWxzbyBlc3RhYmxpc2hlcyBvdXIgY29ubmVjdGlvbiB0byBldmVyeSBub2RlIHVwXG4gICAgICAgIC8vIGZyb250LiBDb250YWN0IGlzIHBhcmFsbGVsOyBBRE9QVElPTiBpcyBkZXRlcm1pbmlzdGljIGJ5IGNvbmZpZyBvcmRlciBhbW9uZyB0aGUgc291cmNlc1xuICAgICAgICAvLyB0aGF0IGFuc3dlcmVkICh0aGUgZmlyc3QgdXAgc291cmNlIGlzIGF1dGhvcml0YXRpdmUpLlxuICAgICAgICBsZXQgZmV0Y2hlcyA9IGF3YWl0IFByb21pc2UuYWxsKGNvbmZpZ3MubWFwKGFzeW5jIHNvdXJjZUNvbmZpZyA9PiB7XG4gICAgICAgICAgICBsZXQgcHJvYmUgPSBhd2FpdCBTb3VyY2VXcmFwcGVyLmNyZWF0ZShzb3VyY2VDb25maWcsIHsgYmFja2dyb3VuZDogZmFsc2UgfSk7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHByb2JlLnJlYWQoYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuZ2V0KFJPVVRJTkdfRklMRSkpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHByb2JlLCBzb3VyY2VDb25maWcsIHJlc3BvbmRlZDogdHJ1ZSwgbGF0ZW5jeTogRGF0ZS5ub3coKSAtIHN0YXJ0LCBleGlzdGluZzogZGF0YSAmJiBwYXJzZVJvdXRpbmdEYXRhKGRhdGEpIHx8IHVuZGVmaW5lZCwgZXJyb3I6IFwiXCIgfTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBwcm9iZSwgc291cmNlQ29uZmlnLCByZXNwb25kZWQ6IGZhbHNlLCBsYXRlbmN5OiAwLCBleGlzdGluZzogdW5kZWZpbmVkLCBlcnJvcjogYCR7c291cmNlQ29uZmlnLnVybH06ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgZm91bmQgPSBmZXRjaGVzLmZpbmQoeCA9PiB4LnJlc3BvbmRlZCk7XG4gICAgICAgICAgICBpZiAoIWZvdW5kKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgaW5pdGlhbGl6ZSBzdG9yYWdlIGZvciAke3RoaXMuZ2V0RGVidWdOYW1lKCl9OiBubyBzb3VyY2UgYW5zd2VyZWQuICR7ZmV0Y2hlcy5tYXAoeCA9PiB4LmVycm9yKS5qb2luKFwiIHwgXCIpfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGV4aXN0aW5nID0gZm91bmQuZXhpc3Rpbmc7XG4gICAgICAgICAgICBsZXQgYWN0aXZlID0gdGhpcy5jb25maWd1cmVkO1xuICAgICAgICAgICAgbGV0IG5lZWRzV3JpdGUgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKGV4aXN0aW5nICYmIGdldENvbmZpZ1ZlcnNpb24oZXhpc3RpbmcpID49IGdldENvbmZpZ1ZlcnNpb24odGhpcy5jb25maWd1cmVkKSkge1xuICAgICAgICAgICAgICAgIGlmIChnZXRDb25maWdWZXJzaW9uKGV4aXN0aW5nKSA9PT0gZ2V0Q29uZmlnVmVyc2lvbih0aGlzLmNvbmZpZ3VyZWQpICYmIEpTT04uc3RyaW5naWZ5KGV4aXN0aW5nKSAhPT0gSlNPTi5zdHJpbmdpZnkodGhpcy5jb25maWd1cmVkKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBBcmNoaXZlcyBjb25maWd1cmF0aW9uIHVwZGF0ZWQgd2l0aG91dCB1cGRhdGluZyB0aGUgdmVyc2lvbiwgZm9yICR7Zm91bmQuc291cmNlQ29uZmlnLnVybH0uIFVwZGF0ZXMgd2lsbCBiZSBpZ25vcmVkIHVudGlsIHlvdSBpbmNyZWFzZSB0aGUgdmVyc2lvbi4gVXNpbmc6ICR7SlNPTi5zdHJpbmdpZnkoZXhpc3RpbmcpfSwgaWdub3Jpbmc6ICR7SlNPTi5zdHJpbmdpZnkodGhpcy5jb25maWd1cmVkKX1gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYWN0aXZlID0gZXhpc3Rpbmc7XG4gICAgICAgICAgICAgICAgbmVlZHNXcml0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5lZWRzV3JpdGUpIHtcbiAgICAgICAgICAgICAgICAvLyBXZSBkZWNpZGVkIHRvIHdyaXRlIChvdXJzIGlzIG5ld2VyIHRoYW4gdGhlIGF1dGhvcml0YXRpdmUgZmlyc3QtdXAgc291cmNlJ3MsIG9yXG4gICAgICAgICAgICAgICAgLy8gbm8gcm91dGluZyBleGlzdHMgeWV0KS4gVGhlIHdyaXRlIGdvZXMgdG8gYWxsIHNvdXJjZXMsIHNvIGl0IGlzIHJlZnVzZWQgdW5sZXNzXG4gICAgICAgICAgICAgICAgLy8gb3VyIHZlcnNpb24gaXMgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIEVWRVJZIHNvdXJjZSdzIHN0b3JlZCB2ZXJzaW9uIChhbGwgYWxyZWFkeVxuICAgICAgICAgICAgICAgIC8vIGZldGNoZWQgYWJvdmUpIC0gYSBzb3VyY2UgYXQgKG9yIHBhc3QpIG91ciB2ZXJzaW9uIG1lYW5zIHRoaXMgdmVyc2lvbiBudW1iZXIgaXNcbiAgICAgICAgICAgICAgICAvLyB0YWtlbiwgYW5kIHdyaXRpbmcgYW55d2F5IHdvdWxkIGxlYXZlIHNvdXJjZXMgYXQgdGhlIHNhbWUgdmVyc2lvbiB3aXRoIGRpZmZlcmVudFxuICAgICAgICAgICAgICAgIC8vIGNvbnRlbnQsIGVhY2ggcmVqZWN0aW5nIHRoZSBvdGhlcidzIHB1c2hlcyBmb3JldmVyLiBEb3duIHNvdXJjZXMgYXJlIHN0aWxsXG4gICAgICAgICAgICAgICAgLy8gcHJvdGVjdGVkIGJ5IHRoZSBzZXJ2ZXItc2lkZSB2ZXJzaW9uIGd1YXJkIHdoZW4gdGhlIHdyaXRlIGV2ZW50dWFsbHkgcmVhY2hlcyB0aGVtLlxuICAgICAgICAgICAgICAgIGxldCBiZXN0OiBSZW1vdGVDb25maWcgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgbGV0IGNvbmZsaWN0VXJsOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZmV0Y2ggb2YgZmV0Y2hlcykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgc3RvcmVkID0gZmV0Y2guZXhpc3Rpbmc7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc3RvcmVkKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFiZXN0IHx8IGdldENvbmZpZ1ZlcnNpb24oc3RvcmVkKSA+IGdldENvbmZpZ1ZlcnNpb24oYmVzdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3QgPSBzdG9yZWQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGdldENvbmZpZ1ZlcnNpb24oc3RvcmVkKSA9PT0gZ2V0Q29uZmlnVmVyc2lvbih0aGlzLmNvbmZpZ3VyZWQpICYmIEpTT04uc3RyaW5naWZ5KHN0b3JlZCkgIT09IEpTT04uc3RyaW5naWZ5KHRoaXMuY29uZmlndXJlZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZsaWN0VXJsID0gZmV0Y2guc291cmNlQ29uZmlnLnVybDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYmVzdCAmJiBnZXRDb25maWdWZXJzaW9uKGJlc3QpID49IGdldENvbmZpZ1ZlcnNpb24odGhpcy5jb25maWd1cmVkKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29uZmxpY3RVcmwgJiYgZ2V0Q29uZmlnVmVyc2lvbihiZXN0KSA9PT0gZ2V0Q29uZmlnVmVyc2lvbih0aGlzLmNvbmZpZ3VyZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBBcmNoaXZlcyBjb25maWd1cmF0aW9uIHVwZGF0ZWQgd2l0aG91dCB1cGRhdGluZyB0aGUgdmVyc2lvbiwgZm9yICR7Y29uZmxpY3RVcmx9LiBVcGRhdGVzIHdpbGwgYmUgaWdub3JlZCB1bnRpbCB5b3UgaW5jcmVhc2UgdGhlIHZlcnNpb24uIFVzaW5nOiAke0pTT04uc3RyaW5naWZ5KGJlc3QpfSwgaWdub3Jpbmc6ICR7SlNPTi5zdHJpbmdpZnkodGhpcy5jb25maWd1cmVkKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhY3RpdmUgPSBiZXN0O1xuICAgICAgICAgICAgICAgICAgICBuZWVkc1dyaXRlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHNvdXJjZXMgPSBhd2FpdCB0aGlzLmJ1aWxkU291cmNlcyhhY3RpdmUpO1xuICAgICAgICAgICAgaWYgKG5lZWRzV3JpdGUpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgdXBkYXRlIG9ubHkgaGFwcGVucyB3aGVuIEVWRVJZIHNvdXJjZSB3b3VsZCBhY2NlcHQgaXQgLSBhIHBhcnRpYWwgdXBkYXRlXG4gICAgICAgICAgICAgICAgLy8gd291bGQgbGVhdmUgdGhlIHNvdXJjZXMgb3V0IG9mIHN5bmMsIGFuZCBhIGNsaWVudCB3aXRob3V0IGFjY2VzcyByZXRyeWluZyB0aGVcbiAgICAgICAgICAgICAgICAvLyB3cml0ZSBmb3JldmVyIHdvdWxkIG5ldmVyIGluaXRpYWxpemUuIFdpdGhvdXQgZnVsbCBhY2Nlc3Mgd2UgcnVuIG9uIHRoZSBzdG9yZWRcbiAgICAgICAgICAgICAgICAvLyBjb25maWcgKHdoZW4gdGhlcmUgaXMgb25lKSBhbmQgbG9nIHRoZSBwcm9ibGVtIGluc3RlYWQuXG4gICAgICAgICAgICAgICAgbGV0IG1pc3Npbmc6IHN0cmluZ1tdID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYXdhaXQgc291cmNlLmhhc1dyaXRlQWNjZXNzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaXNzaW5nLnB1c2goc291cmNlLmNvbmZpZy51cmwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtaXNzaW5nLnB1c2goYCR7c291cmNlLmNvbmZpZy51cmx9IChjaGVjayBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9KWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChtaXNzaW5nLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBOb3Qgd3JpdGluZyB0aGUgc3RvcmFnZSByb3V0aW5nIGNvbmZpZyBmb3IgJHt0aGlzLmdldERlYnVnTmFtZSgpfSAodmVyc2lvbiAke2dldENvbmZpZ1ZlcnNpb24odGhpcy5jb25maWd1cmVkKX0pOiBubyB3cml0ZSBhY2Nlc3MgdG8gJHttaXNzaW5nLmpvaW4oXCIsIFwiKX0uICR7ZXhpc3RpbmcgJiYgYFJ1bm5pbmcgb24gdGhlIHN0b3JlZCBjb25maWcgKHZlcnNpb24gJHtnZXRDb25maWdWZXJzaW9uKGV4aXN0aW5nKX0pIGluc3RlYWQuYCB8fCBgTm8gc3RvcmVkIGNvbmZpZyBleGlzdHMsIHNvIHRoZSBidWNrZXQgY2Fubm90IGJlIGNyZWF0ZWQgdW50aWwgd3JpdGUgYWNjZXNzIGlzIGdyYW50ZWQuYH1gKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmUgPSBleGlzdGluZztcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZXMgPSBhd2FpdCB0aGlzLmJ1aWxkU291cmNlcyhhY3RpdmUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgcmVqZWN0ZWQgd3JpdGUgZmFpbHMgaW5pdCwgd2hpY2ggcmV0cmllcyBmcm9tIHNjcmF0Y2ggLSByZS1yZWFkaW5nIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcm91dGluZywgc28gbG9zaW5nIGEgY3JlYXRlIHJhY2UgdG8gYW5vdGhlciBjbGllbnQganVzdCBhZG9wdHMgdGhlaXJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbmZpZyBvbiB0aGUgbmV4dCBhdHRlbXB0LlxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZm91bmQucHJvYmUud3JpdGUoYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuc2V0KFJPVVRJTkdfRklMRSwgc2VyaWFsaXplUmVtb3RlQ29uZmlnKHRoaXMuY29uZmlndXJlZCkpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRoZSByb3V0aW5nIGZldGNoZXMgZG91YmxlIGFzIG91ciBmaXJzdCBsYXRlbmN5IG1lYXN1cmVtZW50czogdmFyaWFibGUtc2hhcmQgcGlja2luZ1xuICAgICAgICAgICAgLy8gd29ya3MgaW1tZWRpYXRlbHksIGluc3RlYWQgb2Ygd2FpdGluZyBmb3IgdGhlIGZpcnN0IHBpbmcgcGFzcyB0byBsYW5kXG4gICAgICAgICAgICBmb3IgKGxldCBzb3VyY2Ugb2Ygc291cmNlcykge1xuICAgICAgICAgICAgICAgIGxldCBmZXRjaCA9IGZldGNoZXMuZmluZCh4ID0+IHgucmVzcG9uZGVkICYmIHguc291cmNlQ29uZmlnLnVybCA9PT0gc291cmNlLmNvbmZpZy51cmwpO1xuICAgICAgICAgICAgICAgIGlmIChmZXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2Uuc2VlZExhdGVuY3koZmV0Y2gubGF0ZW5jeSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hY3RpdmVDb25maWcgPSBhY3RpdmU7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0Q29uZmlnUG9sbCgpO1xuICAgICAgICAgICAgcmV0dXJuIHsgY29uZmlnOiBhY3RpdmUsIHNvdXJjZXMgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGZvciAobGV0IGZldGNoIG9mIGZldGNoZXMpIHtcbiAgICAgICAgICAgICAgICBmZXRjaC5wcm9iZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGJ1aWxkU291cmNlcyhjb25maWc6IFJlbW90ZUNvbmZpZyk6IFByb21pc2U8U291cmNlV3JhcHBlcltdPiB7XG4gICAgICAgIGxldCBzb3VyY2VzOiBTb3VyY2VXcmFwcGVyW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgc291cmNlQ29uZmlnIG9mIGNvbmZpZy5zb3VyY2VzLm1hcChub3JtYWxpemVTb3VyY2UpKSB7XG4gICAgICAgICAgICBsZXQgc291cmNlID0gYXdhaXQgU291cmNlV3JhcHBlci5jcmVhdGUoc291cmNlQ29uZmlnKTtcbiAgICAgICAgICAgIC8vIExhdGVuY3kgKGZvciB2YXJpYWJsZS1zaGFyZCB0YXJnZXQgcHJlZmVyZW5jZSkgaXMgdHJhY2tlZCBmcm9tIGluaXRpYWxpemF0aW9uIG9uXG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnRQaW5naW5nKCk7XG4gICAgICAgICAgICBzb3VyY2VzLnB1c2goc291cmNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc291cmNlcztcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXJ0Q29uZmlnUG9sbCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMucG9sbFRpbWVyIHx8IHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgdGhpcy5wb2xsVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEFjdGl2ZUNvbmZpZygpLmNhdGNoKChlOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYENoZWNraW5nIGZvciBhIG5ldyBzdG9yYWdlIHJvdXRpbmcgY29uZmlnIGZhaWxlZCBmb3IgJHt0aGlzLmdldERlYnVnTmFtZSgpfTogJHtlLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgQ09ORklHX1BPTExfSU5URVJWQUwpO1xuICAgICAgICAodGhpcy5wb2xsVGltZXIgYXMgeyB1bnJlZj86ICgpID0+IHZvaWQgfSkudW5yZWY/LigpO1xuICAgIH1cblxuICAgIC8vIERlZHVwbGljYXRlcyBjb25jdXJyZW50IHJlZnJlc2hlcyAodGhlIHBvbGwgdGltZXIgYW5kIHdyb25nLXRhcmdldCB3cml0ZSByZXRyaWVzIHNoYXJlIHRoaXMpXG4gICAgcHJpdmF0ZSBjb25maWdSZWZyZXNoSW5GbGlnaHQ6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG4gICAgcHJpdmF0ZSByZWZyZXNoQWN0aXZlQ29uZmlnKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoIXRoaXMuY29uZmlnUmVmcmVzaEluRmxpZ2h0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ1JlZnJlc2hJbkZsaWdodCA9IHRoaXMuY2hlY2tGb3JOZXdDb25maWcoKS5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ1JlZnJlc2hJbkZsaWdodCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZ1JlZnJlc2hJbkZsaWdodDtcbiAgICB9XG5cbiAgICAvLyBUaGUgbGF0ZXN0IGNvbmZpZywgYXMgdGhlIHNlcnZlciBJTlRFUlBSRVRTIGl0OiBnZXRDb25maWcgY2FycmllcyBpbi1tZW1vcnkgb3ZlcmxheXMgKGRlcGxveVxuICAgIC8vIHRha2VvdmVyIHJlbWFwcykgdGhhdCBhcmUgZGVsaWJlcmF0ZWx5IG5ldmVyIHdyaXR0ZW4gaW50byB0aGUgcm91dGluZyBmaWxlLCBzbyBpdCdzXG4gICAgLy8gcHJlZmVycmVkIG92ZXIgcmVhZGluZyB0aGUgcmF3IGZpbGUuIFVSTC1vbmx5IGNoYWlucyBmYWxsIGJhY2sgdG8gdGhlIHJhdyBmaWxlLlxuICAgIHByaXZhdGUgYXN5bmMgZmV0Y2hMYXRlc3RDb25maWcoc3RhdGU6IENoYWluU3RhdGUpOiBQcm9taXNlPFJlbW90ZUNvbmZpZyB8IHVuZGVmaW5lZD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGNvbmZpZyA9IGF3YWl0IHRoaXMucnVuKHN0YXRlLCB7IGFwaU9ubHk6IHRydWUgfSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuZ2V0Q29uZmlnKCkpO1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5yZW1vdGVDb25maWcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplUmVtb3RlQ29uZmlnKGNvbmZpZy5yZW1vdGVDb25maWcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIHsgfVxuICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHRoaXMucnVuKHN0YXRlLCB7fSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuZ2V0KFJPVVRJTkdfRklMRSkpO1xuICAgICAgICBpZiAoIWRhdGEpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiBwYXJzZVJvdXRpbmdEYXRhKGRhdGEpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgY2hlY2tGb3JOZXdDb25maWcoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmRpc3Bvc2VkIHx8ICF0aGlzLnN0YXRlUHJvbWlzZSkgcmV0dXJuO1xuICAgICAgICBsZXQgc3RhdGU6IENoYWluU3RhdGU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzdGF0ZSA9IGF3YWl0IHRoaXMuc3RhdGVQcm9taXNlO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIEluaXQgaXMgZmFpbGluZzsgaXRzIG93biByZXRyeSBsb29wIGhhbmRsZXMgdGhhdFxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBsYXRlc3QgPSBhd2FpdCB0aGlzLmZldGNoTGF0ZXN0Q29uZmlnKHN0YXRlKTtcbiAgICAgICAgaWYgKCFsYXRlc3QpIHJldHVybjtcbiAgICAgICAgYXdhaXQgdGhpcy5hZG9wdE5ld0NvbmZpZyhzdGF0ZSwgbGF0ZXN0KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGFkb3B0TmV3Q29uZmlnKHN0YXRlOiBDaGFpblN0YXRlLCBsYXRlc3Q6IFJlbW90ZUNvbmZpZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkobGF0ZXN0KSA9PT0gSlNPTi5zdHJpbmdpZnkoc3RhdGUuY29uZmlnKSkgcmV0dXJuO1xuICAgICAgICBjb25zb2xlLmxvZyhgU3RvcmFnZSByb3V0aW5nIGNvbmZpZyBjaGFuZ2VkIGZvciAke3RoaXMuZ2V0RGVidWdOYW1lKCl9LCByZWJ1aWxkaW5nIHNvdXJjZXNgKTtcbiAgICAgICAgbGV0IG9sZEJ5Q29uZmlnID0gbmV3IE1hcChzdGF0ZS5zb3VyY2VzLm1hcChzb3VyY2UgPT4gW0pTT04uc3RyaW5naWZ5KHNvdXJjZS5jb25maWcpLCBzb3VyY2VdKSk7XG4gICAgICAgIGxldCBzb3VyY2VzOiBTb3VyY2VXcmFwcGVyW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgc291cmNlQ29uZmlnIG9mIGxhdGVzdC5zb3VyY2VzLm1hcChub3JtYWxpemVTb3VyY2UpKSB7XG4gICAgICAgICAgICBsZXQga2V5ID0gSlNPTi5zdHJpbmdpZnkoc291cmNlQ29uZmlnKTtcbiAgICAgICAgICAgIGxldCBvbGQgPSBvbGRCeUNvbmZpZy5nZXQoa2V5KTtcbiAgICAgICAgICAgIGlmIChvbGQpIHtcbiAgICAgICAgICAgICAgICBvbGRCeUNvbmZpZy5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgICAgICBzb3VyY2VzLnB1c2gob2xkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHNvdXJjZSA9IGF3YWl0IFNvdXJjZVdyYXBwZXIuY3JlYXRlKHNvdXJjZUNvbmZpZyk7XG4gICAgICAgICAgICAgICAgc291cmNlLnN0YXJ0UGluZ2luZygpO1xuICAgICAgICAgICAgICAgIHNvdXJjZXMucHVzaChzb3VyY2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEluLWZsaWdodCByZXF1ZXN0cyBzdGlsbCBob2xkIHRoZSBvbGQgd3JhcHBlcnMgYW5kIGZpbmlzaCBmaW5lOyBkaXNwb3NlIGp1c3Qgc3RvcHMgYW55XG4gICAgICAgIC8vIGJhY2tncm91bmQgcmVjb25uZWN0L3BpbmcgbG9vcHNcbiAgICAgICAgZm9yIChsZXQgbGVmdG92ZXIgb2Ygb2xkQnlDb25maWcudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIGxlZnRvdmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFjdGl2ZUNvbmZpZyA9IGxhdGVzdDtcbiAgICAgICAgdGhpcy5zdGF0ZVByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoeyBjb25maWc6IGxhdGVzdCwgc291cmNlcyB9KTtcbiAgICB9XG5cbiAgICAvLyBXaGVuIGV2ZXJ5IHNvdXJjZSBsb29rcyBkb3duLCB0aGUgcm91dGluZyBjb25maWcgaXMgcmUtcmVhZCBmcm9tIEVWRVJZIHNvdXJjZSAtIHdoaWNoIGJvdGhcbiAgICAvLyByZS1hdHRlbXB0cyB0aGVpciBjb25uZWN0aW9ucyAob3VyIGxpdmVuZXNzIHJlLWNoZWNrKSBhbmQgZGlzY292ZXJzIGEgcm91dGluZyB1cGRhdGUgd2UgbWF5XG4gICAgLy8gaGF2ZSBtaXNzZWQgKGFkb3B0aW5nIGl0IHJlLWluaXRpYWxpemVzIHRoZSBzb3VyY2UgbGlzdCkuIENvbmN1cnJlbnQgY2FsbGVycyBzaGFyZSBvbmUgcGFzcy5cbiAgICBwcml2YXRlIGxhc3RBdmFpbGFiaWxpdHlSZWNoZWNrID0gMDtcbiAgICBwcml2YXRlIGF2YWlsYWJpbGl0eVJlY2hlY2tJbkZsaWdodDogUHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZDtcbiAgICBwcml2YXRlIHJlY2hlY2tBdmFpbGFiaWxpdHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmF2YWlsYWJpbGl0eVJlY2hlY2tJbkZsaWdodCkgcmV0dXJuIHRoaXMuYXZhaWxhYmlsaXR5UmVjaGVja0luRmxpZ2h0O1xuICAgICAgICBpZiAoRGF0ZS5ub3coKSAtIHRoaXMubGFzdEF2YWlsYWJpbGl0eVJlY2hlY2sgPCBBVkFJTEFCSUxJVFlfUkVDSEVDS19USFJPVFRMRSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB0aGlzLmxhc3RBdmFpbGFiaWxpdHlSZWNoZWNrID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdGhpcy5hdmFpbGFiaWxpdHlSZWNoZWNrSW5GbGlnaHQgPSB0aGlzLnJlY2hlY2tBdmFpbGFiaWxpdHlOb3coKS5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYXZhaWxhYmlsaXR5UmVjaGVja0luRmxpZ2h0ID0gdW5kZWZpbmVkO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXZhaWxhYmlsaXR5UmVjaGVja0luRmxpZ2h0O1xuICAgIH1cbiAgICBwcml2YXRlIGFzeW5jIHJlY2hlY2tBdmFpbGFiaWxpdHlOb3coKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICh0aGlzLmRpc3Bvc2VkIHx8ICF0aGlzLnN0YXRlUHJvbWlzZSkgcmV0dXJuO1xuICAgICAgICBsZXQgc3RhdGU6IENoYWluU3RhdGU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzdGF0ZSA9IGF3YWl0IHRoaXMuc3RhdGVQcm9taXNlO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIEluaXQgaXMgZmFpbGluZzsgaXRzIG93biByZXRyeSBsb29wIGhhbmRsZXMgdGhhdFxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoc3RhdGUuc291cmNlcy5tYXAoYXN5bmMgc291cmNlID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IGRhdGEgPSBhd2FpdCBzb3VyY2UucmVhZChhcmNoaXZlcyA9PiBhcmNoaXZlcy5nZXQoUk9VVElOR19GSUxFKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEgJiYgcGFyc2VSb3V0aW5nRGF0YShkYXRhKSB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG4gICAgICAgIGxldCBsYXRlc3QgPSByZXN1bHRzLmZpbmQoeCA9PiB4KTtcbiAgICAgICAgaWYgKCFsYXRlc3QpIHJldHVybjtcbiAgICAgICAgYXdhaXQgdGhpcy5hZG9wdE5ld0NvbmZpZyhzdGF0ZSwgbGF0ZXN0KTtcbiAgICB9XG5cbiAgICAvLyBSdW5zIGEgcmVxdWVzdCBhZ2FpbnN0IHRoZSBmaXJzdCBhdmFpbGFibGUgc291cmNlICh0aGF0IGNvdmVycyB0aGUga2V5J3Mgcm91dGUsIHdoZW4gb25lIGlzXG4gICAgLy8gZ2l2ZW4pLCBtb3ZpbmcgdG8gdGhlIG5leHQgb25lIE9OTFkgd2hlbiB0aGUgc291cmNlJ3MgV2ViU29ja2V0IGlzIGRvd24gKGNoZWNrZWQgZGlyZWN0bHkgLVxuICAgIC8vIG5ldmVyIGJ5IGluc3BlY3RpbmcgdGhlIGVycm9yLCB3aGljaCBpcyBhcmJpdHJhcnkgZGF0YSkuIEFuIGVycm9yIGZyb20gYSBjb25uZWN0ZWQgc291cmNlIGlzXG4gICAgLy8gYW4gYXBwbGljYXRpb24gZXJyb3IgYW5kIHRocm93cyBhcy1pcy4gQSBkb3duIHNvdXJjZSBnZXRzIGl0cyBiYWNrZ3JvdW5kIHJlY29ubmVjdCBraWNrZWQuXG4gICAgcHJpdmF0ZSBhc3luYyBydW48VD4oc3RhdGU6IENoYWluU3RhdGUsIGNvbmZpZzogeyBhcGlPbmx5PzogYm9vbGVhbjsgd3JpdGU/OiBib29sZWFuOyByb3V0ZT86IG51bWJlciB9LCBydW46IChhcmNoaXZlczogSUFyY2hpdmVzKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIGlmIChjb25maWcud3JpdGUpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJ1bldyaXRlKGNvbmZpZy5yb3V0ZSwgcnVuKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVjaGVja2VkQXZhaWxhYmlsaXR5ID0gZmFsc2U7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBsZXQgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgc291cmNlIG9mIHN0YXRlLnNvdXJjZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLnJvdXRlICE9PSB1bmRlZmluZWQgJiYgIXJvdXRlQ29udGFpbnMoc291cmNlLmNvbmZpZy5yb3V0ZSwgY29uZmlnLnJvdXRlKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgaWYgKCFjb25maWdXaW5kb3dDdXJyZW50KHNvdXJjZS5jb25maWcpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29uZmlnLmFwaU9ubHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBhcGkgPSBzb3VyY2UuYXBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhcGkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChgJHtzb3VyY2UuY29uZmlnLnVybH0gaGFzIFVSTC1vbmx5IGFjY2Vzcywgd2hpY2ggY2Fubm90IHNlcnZlIHRoaXMgb3BlcmF0aW9uYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgcnVuKGFwaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHNvdXJjZS5yZWFkKHJ1bik7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlLmlzQ29ubmVjdGVkKCkpIHRocm93IGU7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZS5ub3RlRmFpbHVyZSgpO1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChTdHJpbmcoKGUgYXMgRXJyb3IpLnN0YWNrID8/IGUpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBFdmVyeSBzb3VyY2UgZmFpbGVkOiByZS1jb250YWN0IGV2ZXJ5dGhpbmcgKHJvdXRpbmcgcmUtcmVhZCArIGNvbm5lY3Rpb24gcmUtYXR0ZW1wdCxcbiAgICAgICAgICAgIC8vIHBvc3NpYmx5IGFkb3B0aW5nIGEgcm91dGluZyB1cGRhdGUpIGFuZCB0cnkgb25jZSBtb3JlIGJlZm9yZSBnaXZpbmcgdXBcbiAgICAgICAgICAgIGlmICghcmVjaGVja2VkQXZhaWxhYmlsaXR5KSB7XG4gICAgICAgICAgICAgICAgcmVjaGVja2VkQXZhaWxhYmlsaXR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlY2hlY2tBdmFpbGFiaWxpdHkoKTtcbiAgICAgICAgICAgICAgICBzdGF0ZSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGUoKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQWxsIHNvdXJjZXMgZmFpbGVkIGZvciAke3RoaXMuZ2V0RGVidWdOYW1lKCl9JHtjb25maWcucm91dGUgIT09IHVuZGVmaW5lZCAmJiBgIChyb3V0ZSAke2NvbmZpZy5yb3V0ZX0pYCB8fCBcIlwifTogJHtlcnJvcnMuam9pbihcIiB8IFwiKSB8fCBcIm5vIHNvdXJjZXMgYXZhaWxhYmxlXCJ9YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBXcml0ZXMgYXJlIGNvbnNpc3RlbnQ6IHRoZXkgZ28gdG8gdGhlIGZpcnN0IGN1cnJlbnRseS12YWxpZCBzb3VyY2UgY292ZXJpbmcgdGhlIGtleSdzIHJvdXRlXG4gICAgLy8gYW5kIE5FVkVSIGZhaWwgb3ZlciB0byBhbm90aGVyIG5vZGUgLSBhIGNsaWVudCB3cm9uZ2x5IGRlY2lkaW5nIG5vZGVzIGFyZSBkb3duIG11c3Qgbm90XG4gICAgLy8gc2NhdHRlciBpdHMgd3JpdGVzIGFjcm9zcyB0aGUgY2hhaW4uIChSZWFkcyBmYWlsIG92ZXIgZnJlZWx5IGFib3ZlOiBzb3VyY2VzIGFyZSBzeW5jaHJvbml6ZWRcbiAgICAvLyBjb3BpZXMsIHNvIHJlYWRpbmcgZnJvbSBhbnkgb2YgdGhlbSBpcyBzYWZlLikgVGhlIG9uZSByZXRyeSBpcyBmb3IgYSB3aW5kb3cgYm91bmRhcnkgcGFzc2luZ1xuICAgIC8vIChvciBhIHJvdXRlIGRpc2FncmVlbWVudCkgbWlkLXdyaXRlLCB3aGljaCByZS1yZXNvbHZlcyB0aGUgdGFyZ2V0IHJhdGhlciB0aGFuIGZhbGxpbmcgYmFjay5cbiAgICBwcml2YXRlIGFzeW5jIHJ1bldyaXRlPFQ+KHJvdXRlOiBudW1iZXIgfCB1bmRlZmluZWQsIHJ1bjogKGFyY2hpdmVzOiBJQXJjaGl2ZXMpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAgICAgbGV0IHJldHJpZWRXcm9uZ1dpbmRvdyA9IGZhbHNlO1xuICAgICAgICBsZXQgcmV0cmllZFdyb25nUm91dGUgPSBmYWxzZTtcbiAgICAgICAgbGV0IHJlY2hlY2tlZEF2YWlsYWJpbGl0eSA9IGZhbHNlO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5nZXRTdGF0ZSgpO1xuICAgICAgICAgICAgbGV0IHRhcmdldCA9IHN0YXRlLnNvdXJjZXMuZmluZCh4ID0+IGNvbmZpZ0FjY2VwdHNXcml0ZXMoeC5jb25maWcpICYmIChyb3V0ZSA9PT0gdW5kZWZpbmVkIHx8IHJvdXRlQ29udGFpbnMoeC5jb25maWcucm91dGUsIHJvdXRlKSkpO1xuICAgICAgICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgICAgICAgICAvLyBCZWZvcmUgZ2l2aW5nIHVwLCByZS1jb250YWN0IGV2ZXJ5IHNvdXJjZSBvbmNlIChyb3V0aW5nIHJlLXJlYWQgKyBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgLy8gcmUtYXR0ZW1wdCwgcG9zc2libHkgYWRvcHRpbmcgYSByb3V0aW5nIHVwZGF0ZSB0aGF0IGZpeGVzIHRoZSB0YXJnZXQpXG4gICAgICAgICAgICAgICAgaWYgKCFyZWNoZWNrZWRBdmFpbGFiaWxpdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVjaGVja2VkQXZhaWxhYmlsaXR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWNoZWNrQXZhaWxhYmlsaXR5KCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHNvdXJjZSBhY2NlcHRzIHdyaXRlcyBmb3IgJHt0aGlzLmdldERlYnVnTmFtZSgpfSR7cm91dGUgIT09IHVuZGVmaW5lZCAmJiBgIChyb3V0ZSAke3JvdXRlfSlgIHx8IFwiXCJ9IChldmVyeSBzb3VyY2UgaXMgb3V0c2lkZSBpdHMgdmFsaWQgd2luZG93IG9yIG91dHNpZGUgdGhlIGtleSdzIHJvdXRlKWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGFyZ2V0LndyaXRlKHJ1bik7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgbGV0IG1lc3NhZ2UgPSBTdHJpbmcoKGUgYXMgRXJyb3IpLnN0YWNrID8/IGUpO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFNUT1JBR0VfV1JPTkdfVkFMSURfV0lORE9XKSAmJiAhcmV0cmllZFdyb25nV2luZG93KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHJpZWRXcm9uZ1dpbmRvdyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucHJlcGFyZVdyb25nVGFyZ2V0UmV0cnkoc3RhdGUsIFwid2luZG93XCIpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoU1RPUkFHRV9XUk9OR19ST1VURSkgJiYgIXJldHJpZWRXcm9uZ1JvdXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHJpZWRXcm9uZ1JvdXRlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlV3JvbmdUYXJnZXRSZXRyeShzdGF0ZSwgXCJyb3V0ZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFRoZSBjb25uZWN0aW9uIGRpZWQgZHVyaW5nIChvciBiZWZvcmUpIHRoZSByZXF1ZXN0LiBPbmUgZnVsbCByZS1jb250YWN0IHBhc3MsXG4gICAgICAgICAgICAgICAgLy8gdGhlbiBvbmUgcmV0cnkgLSBzdGlsbCB0aGUgc2FtZSBjb25zaXN0ZW50IHRhcmdldCwgbmV2ZXIgYSBkaWZmZXJlbnQgbm9kZS5cbiAgICAgICAgICAgICAgICBpZiAoIXRhcmdldC5pc0Nvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5ub3RlRmFpbHVyZSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXJlY2hlY2tlZEF2YWlsYWJpbGl0eSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVjaGVja2VkQXZhaWxhYmlsaXR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVjaGVja0F2YWlsYWJpbGl0eSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbGFzdENvbmZpZ1JlZnJlc2ggPSAwO1xuICAgIC8vIEEgd3JvbmctdGFyZ2V0IHJlamVjdGlvbiBtZWFucyBlaXRoZXIgd2UgcmFjZWQgYSB3aW5kb3cgYm91bmRhcnkgKHRpbWUgZml4ZXMgaXQpIG9yIG91clxuICAgIC8vIGNvbmZpZyBpcyBzdGFsZSAtIGUuZy4gYSBkZXBsb3ktdGFrZW92ZXIgcmVtYXAgdGhhdCBvbmx5IGV4aXN0cyBpbiB0aGUgc2VydmVyJ3MgbWVtb3J5XG4gICAgcHJpdmF0ZSBhc3luYyBwcmVwYXJlV3JvbmdUYXJnZXRSZXRyeShzdGF0ZTogQ2hhaW5TdGF0ZSwga2luZDogXCJ3aW5kb3dcIiB8IFwicm91dGVcIik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoa2luZCA9PT0gXCJ3aW5kb3dcIikge1xuICAgICAgICAgICAgbGV0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBsZXQgbmVhckJvdW5kYXJ5ID0gc3RhdGUuc291cmNlcy5zb21lKHNvdXJjZSA9PiBzb3VyY2UuY29uZmlnLnZhbGlkV2luZG93LnNvbWUodCA9PiB0ID4gMCAmJiB0IDwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgJiYgTWF0aC5hYnModCAtIG5vdykgPD0gV1JPTkdfVEFSR0VUX0JPVU5EQVJZX1dJTkRPVykpO1xuICAgICAgICAgICAgaWYgKG5lYXJCb3VuZGFyeSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IGRlbGF5KFdST05HX1RBUkdFVF9CT1VOREFSWV9SRVRSWV9ERUxBWSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChEYXRlLm5vdygpIC0gdGhpcy5sYXN0Q29uZmlnUmVmcmVzaCA8IENPTkZJR19SRUZSRVNIX1RIUk9UVExFKSByZXR1cm47XG4gICAgICAgIHRoaXMubGFzdENvbmZpZ1JlZnJlc2ggPSBEYXRlLm5vdygpO1xuICAgICAgICBhd2FpdCB0aGlzLnJlZnJlc2hBY3RpdmVDb25maWcoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlcXVlc3Q8VD4oY29uZmlnOiB7IGFwaU9ubHk/OiBib29sZWFuOyB3cml0ZT86IGJvb2xlYW47IHJvdXRlPzogbnVtYmVyIH0sIHJ1bjogKGFyY2hpdmVzOiBJQXJjaGl2ZXMpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5nZXRTdGF0ZSgpO1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW4oc3RhdGUsIGNvbmZpZywgcnVuKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgYWNjZXNzLXBhZ2UgbGluayAocGx1cyBvdXIgbWFjaGluZUlkL2lwLCBmb3IgdGhlIGFwcHJvdmVyIHRvIG1hdGNoIHRoZSByZXF1ZXN0KSBmb3IgdGhlXG4gICAgLy8gZmlyc3QgaG9zdGVkIHNvdXJjZSB0aGF0IGhhc24ndCBncmFudGVkIHVzIGFjY2Vzcy4gdW5kZWZpbmVkIHdoZW4gd2UgaGF2ZSBhY2Nlc3MgZXZlcnl3aGVyZVxuICAgIC8vIHdlIGNhbiBoYXZlIGl0LiBBbHNvIHJlZ2lzdGVycyB0aGUgYWNjZXNzIHJlcXVlc3Qgc2VydmVyLXNpZGUuXG4gICAgcHVibGljIGFzeW5jIHdhaXRpbmdGb3JBY2Nlc3MoKTogUHJvbWlzZTx7IGxpbms6IHN0cmluZzsgbWFjaGluZUlkOiBzdHJpbmc7IGlwOiBzdHJpbmcgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICBsZXQgc3RhdGUgPSBhd2FpdCB0aGlzLmdldFN0YXRlKCk7XG4gICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzdGF0ZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICBpZiAoc291cmNlLmFwaSBpbnN0YW5jZW9mIEFyY2hpdmVzUmVtb3RlKSB7XG4gICAgICAgICAgICAgICAgbGV0IHdhaXRpbmcgPSBhd2FpdCBzb3VyY2UuYXBpLndhaXRpbmdGb3JBY2Nlc3MoKTtcbiAgICAgICAgICAgICAgICBpZiAod2FpdGluZykgcmV0dXJuIHdhaXRpbmc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0KGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IHsgcmFuZ2U/OiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH0gfSk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCB0aGlzLmdldDIoZmlsZU5hbWUsIGNvbmZpZyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgJiYgcmVzdWx0LmRhdGEgfHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0MihmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiB7IHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9IH0pOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVxdWVzdCh7IHJvdXRlOiBnZXRSb3V0ZShmaWxlTmFtZSkgfSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuZ2V0MihmaWxlTmFtZSwgY29uZmlnKSk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBnZXRJbmZvKGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlcXVlc3QoeyByb3V0ZTogZ2V0Um91dGUoZmlsZU5hbWUpIH0sIGFyY2hpdmVzID0+IGFyY2hpdmVzLmdldEluZm8oZmlsZU5hbWUpKTtcbiAgICB9XG5cbiAgICAvLyBBIG1pbmltYWwgc2V0IG9mIGNvbm5lY3RlZCwgY3VycmVudGx5LXZhbGlkIEFQSSBzb3VyY2VzIHdob3NlIHJvdXRlcyBjb3ZlciBbMCwgMSkgLSBsaXN0aW5nXG4gICAgLy8gb3BlcmF0aW9ucyBtdXN0IG1lcmdlIGV2ZXJ5IHNoYXJkLiBHcmVlZHkgc3dlZXA6IHJlcGVhdGVkbHkgdGFrZSB0aGUgc291cmNlIHRoYXQgZXh0ZW5kc1xuICAgIC8vIGNvdmVyYWdlIHRoZSBmdXJ0aGVzdC4gSW4gcHJhY3RpY2UgdGhpcyBpcyBvbmUgc291cmNlICh1bnNoYXJkZWQpLCBvciBvbmUgcGVyIHNoYXJkLlxuICAgIHByaXZhdGUgc2VsZWN0Q292ZXJpbmdTb3VyY2VzKHN0YXRlOiBDaGFpblN0YXRlLCBleGNsdWRlZDogU2V0PFNvdXJjZVdyYXBwZXI+KTogU291cmNlV3JhcHBlcltdIHtcbiAgICAgICAgbGV0IGNhbmRpZGF0ZXMgPSBzdGF0ZS5zb3VyY2VzLmZpbHRlcih4ID0+IGNvbmZpZ1dpbmRvd0N1cnJlbnQoeC5jb25maWcpICYmIHguYXBpICYmICFleGNsdWRlZC5oYXMoeCkpO1xuICAgICAgICBsZXQgY2hvc2VuOiBTb3VyY2VXcmFwcGVyW10gPSBbXTtcbiAgICAgICAgbGV0IGNvdmVyZWQgPSAwO1xuICAgICAgICB3aGlsZSAoY292ZXJlZCA8IDEpIHtcbiAgICAgICAgICAgIGxldCBiZXN0OiBTb3VyY2VXcmFwcGVyIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgbGV0IGJlc3RFbmQgPSBjb3ZlcmVkO1xuICAgICAgICAgICAgZm9yIChsZXQgc291cmNlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICAgICAgICBsZXQgW3N0YXJ0LCBlbmRdID0gc291cmNlLmNvbmZpZy5yb3V0ZSB8fCBGVUxMX1JPVVRFO1xuICAgICAgICAgICAgICAgIGlmIChzdGFydCA+IGNvdmVyZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGlmIChlbmQgPiBiZXN0RW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGJlc3RFbmQgPSBlbmQ7XG4gICAgICAgICAgICAgICAgICAgIGJlc3QgPSBzb3VyY2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFiZXN0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY292ZXIgdGhlIGZ1bGwgcm91dGUgc3BhY2UgZm9yICR7dGhpcy5nZXREZWJ1Z05hbWUoKX06IHRoZSBhdmFpbGFibGUgc291cmNlcyBvbmx5IGNvdmVyIHVwIHRvICR7Y292ZXJlZH0gKHNvbWUgc2hhcmRzIGFyZSBkb3duIG9yIFVSTC1vbmx5KWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2hvc2VuLnB1c2goYmVzdCk7XG4gICAgICAgICAgICBjb3ZlcmVkID0gYmVzdEVuZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2hvc2VuO1xuICAgIH1cblxuICAgIC8vIEZhbnMgb25lIGNhbGwgb3V0IG92ZXIgYSBjb3ZlcmluZyBzZXQgb2Ygc2hhcmRzLiBTb3VyY2VzIGFyZSBuZXZlciBwcmUtZmlsdGVyZWQgYnlcbiAgICAvLyBjb25uZWN0aXZpdHkgLSB0aGUgcmVxdWVzdCBpcyBhdHRlbXB0ZWQsIGFuZCBhIGZhaWx1cmUgd2l0aCB0aGUgc29ja2V0IGRvd24gYWZ0ZXJ3YXJkc1xuICAgIC8vIGV4Y2x1ZGVzIHRoYXQgc291cmNlIGFuZCByZS1zZWxlY3RzIHRoZSBjb3ZlcmluZyBzZXQgKGFuIGVycm9yIGZyb20gYSBsaXZlIHNvdXJjZSB0aHJvd3MpLlxuICAgIHByaXZhdGUgYXN5bmMgcnVuT25Db3ZlcmluZzxUPihydW46IChhcmNoaXZlczogSUFyY2hpdmVzKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUW10+IHtcbiAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5nZXRTdGF0ZSgpO1xuICAgICAgICBsZXQgZXhjbHVkZWQgPSBuZXcgU2V0PFNvdXJjZVdyYXBwZXI+KCk7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBsZXQgY292ZXJpbmcgPSB0aGlzLnNlbGVjdENvdmVyaW5nU291cmNlcyhzdGF0ZSwgZXhjbHVkZWQpO1xuICAgICAgICAgICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChjb3ZlcmluZy5tYXAoYXN5bmMgc291cmNlID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgYXBpID0gc291cmNlLmFwaTtcbiAgICAgICAgICAgICAgICBpZiAoIWFwaSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c291cmNlLmNvbmZpZy51cmx9IGhhcyBVUkwtb25seSBhY2Nlc3MsIHdoaWNoIGNhbm5vdCBzZXJ2ZSB0aGlzIG9wZXJhdGlvbmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogYXdhaXQgcnVuKGFwaSkgfTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuaXNDb25uZWN0ZWQoKSkgdGhyb3cgZTtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlLm5vdGVGYWlsdXJlKCk7XG4gICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGVkLmFkZChzb3VyY2UpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHRzLmV2ZXJ5KHggPT4geCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAoeCA9PiAoeCBhcyB7IHZhbHVlOiBUIH0pLnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBmaW5kKHByZWZpeDogc3RyaW5nLCBjb25maWc/OiB7IHNoYWxsb3c/OiBib29sZWFuOyB0eXBlOiBcImZpbGVzXCIgfCBcImZvbGRlcnNcIiB9KTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgICAgICByZXR1cm4gKGF3YWl0IHRoaXMuZmluZEluZm8ocHJlZml4LCBjb25maWcpKS5tYXAoeCA9PiB4LnBhdGgpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZmluZEluZm8ocHJlZml4OiBzdHJpbmcsIGNvbmZpZz86IHsgc2hhbGxvdz86IGJvb2xlYW47IHR5cGU6IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgdGhpcy5ydW5PbkNvdmVyaW5nKGFyY2hpdmVzID0+IGFyY2hpdmVzLmZpbmRJbmZvKHByZWZpeCwgY29uZmlnKSk7XG4gICAgICAgIC8vIE92ZXJsYXBwaW5nIHNoYXJkcyBjYW4gYm90aCByZXBvcnQgYSBwYXRoOyB0aGUgbmV3ZXN0IHdpbnNcbiAgICAgICAgbGV0IGJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBBcmNoaXZlRmlsZUluZm8+KCk7XG4gICAgICAgIGZvciAobGV0IGxpc3Qgb2YgcmVzdWx0cykge1xuICAgICAgICAgICAgZm9yIChsZXQgZmlsZSBvZiBsaXN0KSB7XG4gICAgICAgICAgICAgICAgbGV0IGV4aXN0aW5nID0gYnlQYXRoLmdldChmaWxlLnBhdGgpO1xuICAgICAgICAgICAgICAgIGlmICghZXhpc3RpbmcgfHwgZmlsZS5jcmVhdGVUaW1lID4gZXhpc3RpbmcuY3JlYXRlVGltZSkge1xuICAgICAgICAgICAgICAgICAgICBieVBhdGguc2V0KGZpbGUucGF0aCwgZmlsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBtZXJnZWQgPSBbLi4uYnlQYXRoLnZhbHVlcygpXTtcbiAgICAgICAgc29ydChtZXJnZWQsIHggPT4geC5wYXRoKTtcbiAgICAgICAgcmV0dXJuIG1lcmdlZDtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldENoYW5nZXNBZnRlcih0aW1lOiBudW1iZXIpOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgdGhpcy5ydW5PbkNvdmVyaW5nKGFzeW5jIGFyY2hpdmVzID0+IHtcbiAgICAgICAgICAgIGlmICghYXJjaGl2ZXMuZ2V0Q2hhbmdlc0FmdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2FyY2hpdmVzLmdldERlYnVnTmFtZSgpfSBkb2VzIG5vdCBzdXBwb3J0IGdldENoYW5nZXNBZnRlcmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGFyY2hpdmVzLmdldENoYW5nZXNBZnRlcih0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGxldCBieVBhdGggPSBuZXcgTWFwPHN0cmluZywgQXJjaGl2ZUZpbGVJbmZvPigpO1xuICAgICAgICBmb3IgKGxldCBsaXN0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGZpbGUgb2YgbGlzdCkge1xuICAgICAgICAgICAgICAgIGxldCBleGlzdGluZyA9IGJ5UGF0aC5nZXQoZmlsZS5wYXRoKTtcbiAgICAgICAgICAgICAgICBpZiAoIWV4aXN0aW5nIHx8IGZpbGUuY3JlYXRlVGltZSA+IGV4aXN0aW5nLmNyZWF0ZVRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgYnlQYXRoLnNldChmaWxlLnBhdGgsIGZpbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgbWVyZ2VkID0gWy4uLmJ5UGF0aC52YWx1ZXMoKV07XG4gICAgICAgIHNvcnQobWVyZ2VkLCB4ID0+IHgucGF0aCk7XG4gICAgICAgIHJldHVybiBtZXJnZWQ7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBnZXRTeW5jU3RhdHVzKCk6IFByb21pc2U8QXJjaGl2ZXNTeW5jU3RhdHVzPiB7XG4gICAgICAgIGxldCBzdGF0dXNlcyA9IGF3YWl0IHRoaXMucnVuT25Db3ZlcmluZyhhc3luYyBhcmNoaXZlcyA9PiB7XG4gICAgICAgICAgICBpZiAoIWFyY2hpdmVzLmdldFN5bmNTdGF0dXMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7YXJjaGl2ZXMuZ2V0RGVidWdOYW1lKCl9IGRvZXMgbm90IHN1cHBvcnQgZ2V0U3luY1N0YXR1c2ApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGFyY2hpdmVzLmdldFN5bmNTdGF0dXMoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhbGxTY2Fuc0NvbXBsZXRlOiBzdGF0dXNlcy5ldmVyeSh4ID0+IHguYWxsU2NhbnNDb21wbGV0ZSksXG4gICAgICAgICAgICBpbmRleFNpemU6IHN0YXR1c2VzLnJlZHVjZSgoc3VtLCB4KSA9PiBzdW0gKyB4LmluZGV4U2l6ZSwgMCksXG4gICAgICAgICAgICBzb3VyY2VzOiBzdGF0dXNlcy5mbGF0TWFwKHggPT4geC5zb3VyY2VzKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldENvbmZpZygpOiBQcm9taXNlPEFyY2hpdmVzQ29uZmlnPiB7XG4gICAgICAgIGxldCBzdGF0ZSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGUoKTtcbiAgICAgICAgaWYgKCFzdGF0ZS5zb3VyY2VzLnNvbWUoeCA9PiB4LmFwaSkpIHJldHVybiB7IHJlbW90ZUNvbmZpZzogc3RhdGUuY29uZmlnIH07XG4gICAgICAgIGxldCBjb25maWcgPSBhd2FpdCB0aGlzLnJ1bihzdGF0ZSwgeyBhcGlPbmx5OiB0cnVlIH0sIGFyY2hpdmVzID0+IGFyY2hpdmVzLmdldENvbmZpZygpKTtcbiAgICAgICAgcmV0dXJuIHsgLi4uY29uZmlnLCByZW1vdGVDb25maWc6IHN0YXRlLmNvbmZpZyB9O1xuICAgIH1cbiAgICAvKiogVHJ1ZSBvbmx5IHdoZW4gRVZFUlkgd3JpdGUtcmVjZWl2aW5nIHNvdXJjZSB3b3VsZCBhY2NlcHQgb3VyIHdyaXRlcyAocGFydGlhbCB3cml0ZSBhY2Nlc3NcbiAgICAgKiAgZGVzeW5jaHJvbml6ZXMgc291cmNlcywgc28gaXQgY291bnRzIGFzIG5vIGFjY2VzcykuICovXG4gICAgcHVibGljIGFzeW5jIGhhc1dyaXRlQWNjZXNzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBsZXQgc3RhdGUgPSBhd2FpdCB0aGlzLmdldFN0YXRlKCk7XG4gICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzdGF0ZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICBpZiAoIWNvbmZpZ0FjY2VwdHNXcml0ZXMoc291cmNlLmNvbmZpZykpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFhd2FpdCBzb3VyY2UuaGFzV3JpdGVBY2Nlc3MoKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKiBSZXR1cm5zIHRoZSBmdWxsIGtleSB3cml0dGVuLiBQbGFpbiBrZXlzIGNvbWUgYmFjayB1bmNoYW5nZWQ7IGtleXMgY29udGFpbmluZyBWQVJJQUJMRV9TSEFSRFxuICAgICAqICBhcmUgYXV0b21hdGljYWxseSBtYXRlcmlhbGl6ZWQgKGEgc2hhcmQgdmFsdWUgaXMgcGlja2VkIGFuZCBlbWJlZGRlZCwgc2VlIHNldFZhcmlhYmxlU2hhcmQpXG4gICAgICogIGFuZCB0aGUgY2FsbGVyIG5lZWRzIHRoZSByZXR1cm5lZCBrZXkgdG8gZXZlciByZWFkIHRoZSB2YWx1ZSBiYWNrLiAqL1xuICAgIHB1YmxpYyBhc3luYyBzZXQoZmlsZU5hbWU6IHN0cmluZywgZGF0YTogQnVmZmVyLCBjb25maWc/OiB7IGxhc3RNb2RpZmllZD86IG51bWJlciB9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgaWYgKGZpbGVOYW1lLmluY2x1ZGVzKFZBUklBQkxFX1NIQVJEKSAmJiBwYXJzZVZhcmlhYmxlUm91dGUoZmlsZU5hbWUpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNldFZhcmlhYmxlU2hhcmQoZmlsZU5hbWUsIGRhdGEsIGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5yZXF1ZXN0KHsgd3JpdGU6IHRydWUsIHJvdXRlOiBnZXRSb3V0ZShmaWxlTmFtZSkgfSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuc2V0KGZpbGVOYW1lLCBkYXRhLCBjb25maWcpKTtcbiAgICAgICAgcmV0dXJuIGZpbGVOYW1lO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZGVsKGZpbGVOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZXF1ZXN0KHsgd3JpdGU6IHRydWUsIHJvdXRlOiBnZXRSb3V0ZShmaWxlTmFtZSkgfSwgYXJjaGl2ZXMgPT4gYXJjaGl2ZXMuZGVsKGZpbGVOYW1lKSk7XG4gICAgfVxuXG4gICAgLy8gV3JpdGVzIGEgYmFyZSB2YXJpYWJsZS1zaGFyZCBrZXk6IHBpY2tzIHRoZSBsb3dlc3QtbGF0ZW5jeSB1cCB3cml0ZSBzaGFyZCwgbWF0ZXJpYWxpemVzIHRoZVxuICAgIC8vIGtleSB3aXRoIGEgcmFuZG9tIHZhbHVlIGluc2lkZSB0aGF0IHNoYXJkJ3Mgcm91dGUsIHdyaXRlcyBpdCwgYW5kIHJldHVybnMgdGhlIEZVTEwga2V5XG4gICAgLy8gYWN0dWFsbHkgd3JpdHRlbi4gVW5saWtlIG5vcm1hbCB3cml0ZXMgdGhpcyBDQU4gbW92ZSB0byBhbm90aGVyIHNoYXJkIHdoZW4gdGhlIHByZWZlcnJlZCBvbmVcbiAgICAvLyBpcyBkb3duIChlcnJvciArIHNvY2tldCBkb3duLCBzYW1lIHJ1bGUgYXMgcmVhZHMpIC0gZWFjaCBzaGFyZCByZWNlaXZlcyBhIGRpZmZlcmVudCBrZXksIHNvXG4gICAgLy8gd3JpdGUgY29uc2lzdGVuY3kgaXMgcHJlc2VydmVkLlxuICAgIHByaXZhdGUgYXN5bmMgc2V0VmFyaWFibGVTaGFyZChrZXk6IHN0cmluZywgZGF0YTogQnVmZmVyLCBjb25maWc/OiB7IGxhc3RNb2RpZmllZD86IG51bWJlciB9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgbGV0IHJlY2hlY2tlZEF2YWlsYWJpbGl0eSA9IGZhbHNlO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgbGV0IHN0YXRlID0gYXdhaXQgdGhpcy5nZXRTdGF0ZSgpO1xuICAgICAgICAgICAgLy8gUGVyLXNoYXJkIHdyaXRlIGNvbnNpc3RlbmN5IHN0aWxsIGhvbGRzOiB3aXRoaW4gYSByb3V0ZSwgb25seSB0aGUgRklSU1Qgc291cmNlIG1heVxuICAgICAgICAgICAgLy8gdGFrZSB3cml0ZXMgLSBsYXRlbmN5IG9ubHkgcGlja3MgV0hJQ0ggc2hhcmQgdGhlIGtleSBtYXRlcmlhbGl6ZXMgaW50b1xuICAgICAgICAgICAgbGV0IHRhcmdldHNCeVJvdXRlID0gbmV3IE1hcDxzdHJpbmcsIFNvdXJjZVdyYXBwZXI+KCk7XG4gICAgICAgICAgICBmb3IgKGxldCBzb3VyY2Ugb2Ygc3RhdGUuc291cmNlcykge1xuICAgICAgICAgICAgICAgIGlmICghY29uZmlnQWNjZXB0c1dyaXRlcyhzb3VyY2UuY29uZmlnKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgbGV0IHJvdXRlS2V5ID0gSlNPTi5zdHJpbmdpZnkoc291cmNlLmNvbmZpZy5yb3V0ZSB8fCBGVUxMX1JPVVRFKTtcbiAgICAgICAgICAgICAgICBpZiAoIXRhcmdldHNCeVJvdXRlLmhhcyhyb3V0ZUtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0c0J5Um91dGUuc2V0KHJvdXRlS2V5LCBzb3VyY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCB0YXJnZXRzID0gWy4uLnRhcmdldHNCeVJvdXRlLnZhbHVlcygpXTtcbiAgICAgICAgICAgIHNvcnQodGFyZ2V0cywgeCA9PiB4LmdldExhdGVuY3koKSk7XG4gICAgICAgICAgICBsZXQgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgdGFyZ2V0IG9mIHRhcmdldHMpIHtcbiAgICAgICAgICAgICAgICBsZXQgW3N0YXJ0LCBlbmRdID0gdGFyZ2V0LmNvbmZpZy5yb3V0ZSB8fCBGVUxMX1JPVVRFO1xuICAgICAgICAgICAgICAgIGxldCBmdWxsS2V5ID0ga2V5LnJlcGxhY2UoVkFSSUFCTEVfU0hBUkQsIFZBUklBQkxFX1NIQVJEICsgXCJfXCIgKyAoc3RhcnQgKyBNYXRoLnJhbmRvbSgpICogKGVuZCAtIHN0YXJ0KSkpO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRhcmdldC53cml0ZShhcmNoaXZlcyA9PiBhcmNoaXZlcy5zZXQoZnVsbEtleSwgZGF0YSwgY29uZmlnKSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmdWxsS2V5O1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogSWYgd2UgcnVuIGludG8gY2FzZXMgd2hlbiB0cmFuc3BvcnQgbGV2ZWwgZXJyb3JzIGhhcHBlbiwgYnV0IHdlIGFyZSBzdGlsbCBjb25uZWN0ZWQsIHRoZW4gd2UgbWlnaHQgd2FudCB0byBhZGQgYWRkaXRpb25hbCBjaGVja2luZyBoZXJlLCBhZGRpdGlvbmFsIGVycm9ycyBpbiB3aGljaCB3ZSB3aWxsIHJldHJ5IHRoZSBvdGhlciB0YXJnZXRzLiBIb3dldmVyLCBpZGVhbGx5LCBjaGVja2luZyBpZiB0aGUgV2ViU29ja2V0IGNvbm5lY3Rpb24gaXMgc3RpbGwgY29ubmVjdGVkIHdpbGwgaGFuZGxlIGFsbCB0aG9zZSBjYXNlcy4gRGlzdGluZ3Vpc2hpbmcgYmV0d2VlbiBhcHBsaWNhdGlvbiBlcnJvcnMgKHdoaWNoIHdlIGNhbid0IHJldHJ5KSBhbmQgdHJhbnNwb3J0IGVycm9ycy5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldC5pc0Nvbm5lY3RlZCgpKSB0aHJvdyBlO1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQubm90ZUZhaWx1cmUoKTtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2goU3RyaW5nKChlIGFzIEVycm9yKS5zdGFjayA/PyBlKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRXZlcnkgc2hhcmQgZmFpbGVkOiByZS1jb250YWN0IGV2ZXJ5dGhpbmcgYW5kIHRyeSBvbmNlIG1vcmUgYmVmb3JlIGdpdmluZyB1cFxuICAgICAgICAgICAgaWYgKCFyZWNoZWNrZWRBdmFpbGFiaWxpdHkpIHtcbiAgICAgICAgICAgICAgICByZWNoZWNrZWRBdmFpbGFiaWxpdHkgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVjaGVja0F2YWlsYWJpbGl0eSgpO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFdmVyeSB2YXJpYWJsZS1zaGFyZCB3cml0ZSB0YXJnZXQgZmFpbGVkIGZvciAke3RoaXMuZ2V0RGVidWdOYW1lKCl9OiAke2Vycm9ycy5qb2luKFwiIHwgXCIpIHx8IFwibm8gc291cmNlcyBhY2NlcHQgd3JpdGVzXCJ9YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgc2V0TGFyZ2VGaWxlKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IGdldE5leHREYXRhKCk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChjb25maWcucGF0aC5pbmNsdWRlcyhWQVJJQUJMRV9TSEFSRCkgJiYgcGFyc2VWYXJpYWJsZVJvdXRlKGNvbmZpZy5wYXRoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHNldExhcmdlRmlsZSBkb2VzIG5vdCBzdXBwb3J0IFZBUklBQkxFX1NIQVJEIGtleXMgKHRoZXJlIGlzIG5vIHdheSB0byByZXR1cm4gdGhlIG1hdGVyaWFsaXplZCBrZXkpOyB3cml0ZSB0aGUgZmlsZSB3aXRoIHNldCwgb3IgbWF0ZXJpYWxpemUgdGhlIGtleSB5b3Vyc2VsZi4gS2V5OiAke0pTT04uc3RyaW5naWZ5KGNvbmZpZy5wYXRoKX1gKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcm91dGUgPSBnZXRSb3V0ZShjb25maWcucGF0aCk7XG4gICAgICAgIGxldCByZWNoZWNrZWRBdmFpbGFiaWxpdHkgPSBmYWxzZTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGxldCBzdGF0ZSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGUoKTtcbiAgICAgICAgICAgIC8vIFNhbWUgY29uc2lzdGVuY3kgcnVsZSBhcyBydW5Xcml0ZTogdGhlIGZpcnN0IGN1cnJlbnRseS12YWxpZCBzb3VyY2UgZm9yIHRoZSByb3V0ZSwgb3Igbm90aGluZ1xuICAgICAgICAgICAgbGV0IHRhcmdldCA9IHN0YXRlLnNvdXJjZXMuZmluZCh4ID0+IGNvbmZpZ0FjY2VwdHNXcml0ZXMoeC5jb25maWcpICYmIHJvdXRlQ29udGFpbnMoeC5jb25maWcucm91dGUsIHJvdXRlKSk7XG4gICAgICAgICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICAgICAgICAgIGlmICghcmVjaGVja2VkQXZhaWxhYmlsaXR5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY2hlY2tlZEF2YWlsYWJpbGl0eSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVjaGVja0F2YWlsYWJpbGl0eSgpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBzb3VyY2UgYWNjZXB0cyB3cml0ZXMgZm9yIHNldExhcmdlRmlsZSBvbiAke3RoaXMuZ2V0RGVidWdOYW1lKCl9IChyb3V0ZSAke3JvdXRlfSlgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGFyZ2V0LndyaXRlKGFyY2hpdmVzID0+IGFyY2hpdmVzLnNldExhcmdlRmlsZShjb25maWcpKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIGRhdGEgc3RyZWFtIGNhbm5vdCBiZSByZXdvdW5kLCBzbyBhIG1pZC11cGxvYWQgZGlzY29ubmVjdCBjYW5ub3QgYmUgcmV0cmllZFxuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0LmlzQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Lm5vdGVGYWlsdXJlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0VVJMKHBhdGg6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGxldCBzdGF0ZSA9IGF3YWl0IHRoaXMuZ2V0U3RhdGUoKTtcbiAgICAgICAgbGV0IHJvdXRlID0gZ2V0Um91dGUocGF0aCk7XG4gICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzdGF0ZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICBpZiAoc291cmNlLmNvbmZpZy5wdWJsaWMgPT09IGZhbHNlKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmICghcm91dGVDb250YWlucyhzb3VyY2UuY29uZmlnLnJvdXRlLCByb3V0ZSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHNvdXJjZS51cmwpIHJldHVybiBhd2FpdCBzb3VyY2UudXJsLmdldFVSTChwYXRoKTtcbiAgICAgICAgICAgIGlmIChzb3VyY2UuYXBpKSByZXR1cm4gYXdhaXQgc291cmNlLmFwaS5nZXRVUkwocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBwdWJsaWMgc291cmNlIGNvdmVyaW5nIHJvdXRlICR7cm91dGV9IHRvIGJ1aWxkIGEgVVJMIGZyb20gZm9yICR7dGhpcy5nZXREZWJ1Z05hbWUoKX1gKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNwb3NlZCA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLnBvbGxUaW1lcikge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnBvbGxUaW1lcik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaW5pdFJldHJ5VGltZXIpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmluaXRSZXRyeVRpbWVyKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc3RhdGVQcm9taXNlID0gdGhpcy5zdGF0ZVByb21pc2U7XG4gICAgICAgIGlmIChzdGF0ZVByb21pc2UpIHtcbiAgICAgICAgICAgIHZvaWQgc3RhdGVQcm9taXNlLnRoZW4oc3RhdGUgPT4ge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IHNvdXJjZSBvZiBzdGF0ZS5zb3VyY2VzKSB7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgKCkgPT4geyB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gVGhlIElBcmNoaXZlcyBmb3IgYSBSZW1vdGVDb25maWcgKG9yIGEgc2luZ2xlIHNvdXJjZSAtIGEgcm91dGluZyBVUkwgc3RyaW5nIHdvcmtzKS4gRnVsbHkgbGF6eTpcbi8vIG5vdGhpbmcgaXMgY29udGFjdGVkIHVudGlsIHRoZSBmaXJzdCBjYWxsLiBDYWxsIGRpc3Bvc2UoKSB3aGVuIGRvbmUgd2l0aCBpdCwgc28gaXRzIGJhY2tncm91bmRcbi8vIHJldHJ5L3BvbGwgbG9vcHMgc3RvcC5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBcmNoaXZlcyhjb25maWc6IFJlbW90ZUNvbmZpZyB8IFJlbW90ZUNvbmZpZ0Jhc2UpOiBBcmNoaXZlc0NoYWluIHtcbiAgICByZXR1cm4gbmV3IEFyY2hpdmVzQ2hhaW4oY29uZmlnKTtcbn1cblxuLyoqIEV2ZXJ5IGJ1Y2tldCBhbiBhY2NvdW50IGhhcyBvbiBvbmUgc3RvcmFnZSBzZXJ2ZXIgLSBhY3RpdmUgYW5kIGluYWN0aXZlIC0gd2l0aCBlYWNoIGJ1Y2tldCdzXG4gKiAgY29uZmlndXJhdGlvbi4gT25lIGF1dGhlbnRpY2F0ZWQgY2FsbCAodGhlIG5vcm1hbCB0cnVzdCBzeXN0ZW0gYXBwbGllcyk6IG5vIEFyY2hpdmVzQ2hhaW4sIG5vXG4gKiAgc3luY2hyb25pemF0aW9uLCBhbmQgaW5hY3RpdmUgYnVja2V0cyBvbiB0aGUgc2VydmVyIHN0YXkgaW5hY3RpdmUuIEFueSBVUkwgYWRkcmVzc2luZyB0aGVcbiAqICBzZXJ2ZXIgd29ya3MgKGEgYnVja2V0IHJvdXRpbmcgVVJMLCBvciBqdXN0IGh0dHBzOi8vaG9zdDpwb3J0KS4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsaXN0U2VydmVyQnVja2V0cyhjb25maWc6IHsgdXJsOiBzdHJpbmc7IGFjY291bnQ6IHN0cmluZyB9KTogUHJvbWlzZTxTZXJ2ZXJCdWNrZXRJbmZvW10+IHtcbiAgICBTb2NrZXRGdW5jdGlvbi5FTkFCTEVfQ0xJRU5UX01PREUgPSB0cnVlO1xuICAgIGxldCBwYXJzZWQgPSBwYXJzZVN0b3JhZ2VVcmwoY29uZmlnLnVybCk7XG4gICAgbGV0IG5vZGVJZCA9IFNvY2tldEZ1bmN0aW9uLmNvbm5lY3QoeyBhZGRyZXNzOiBwYXJzZWQuYWRkcmVzcywgcG9ydDogcGFyc2VkLnBvcnQgfSk7XG4gICAgbGV0IGNvbnRyb2xsZXIgPSBSZW1vdGVTdG9yYWdlQ29udHJvbGxlci5ub2Rlc1tub2RlSWRdO1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBjb250cm9sbGVyLmxpc3RCdWNrZXRzKGNvbmZpZy5hY2NvdW50KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICghU3RyaW5nKChlIGFzIEVycm9yKS5zdGFjayA/PyBlKS5pbmNsdWRlcyhTVE9SQUdFX05PVF9BVVRIRU5USUNBVEVEKSkgdGhyb3cgZTtcbiAgICAgICAgYXdhaXQgYXV0aGVudGljYXRlU3RvcmFnZSh7IGFkZHJlc3M6IHBhcnNlZC5hZGRyZXNzLCBwb3J0OiBwYXJzZWQucG9ydCwgbm9kZUlkIH0pO1xuICAgICAgICByZXR1cm4gYXdhaXQgY29udHJvbGxlci5saXN0QnVja2V0cyhjb25maWcuYWNjb3VudCk7XG4gICAgfVxufVxuXG4vKiogTGl2ZSBpbmZvIGZvciBvbmUgYnVja2V0IGdpdmVuIGl0cyByb3V0aW5nIFVSTCAoZ2V0Q29uZmlnOiByb3V0aW5nIGNvbmZpZywgaW5kZXggdG90YWxzLCBkaXNrXG4gKiAgbGltaXQsIGluLXByb2dyZXNzIHN5bmNocm9uaXphdGlvbikuIE9uZSBhdXRoZW50aWNhdGVkIGNhbGwgdG8gdGhhdCBzZXJ2ZXIgLSBhIGxpZ2h0LCBzYWZlXG4gKiAgYWx0ZXJuYXRpdmUgdG8gaW5zdGFudGlhdGluZyBhbiBBcmNoaXZlc0NoYWluLCB3aGljaCB3b3VsZCBzdGFydCBzeW5jaHJvbml6YXRpb24gbWFjaGluZXJ5LiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEJ1Y2tldEluZm8oY29uZmlnOiB7IHVybDogc3RyaW5nOyBhY2NvdW50TmFtZT86IHN0cmluZyB9KTogUHJvbWlzZTxBcmNoaXZlc0NvbmZpZz4ge1xuICAgIGxldCByZW1vdGUgPSBuZXcgQXJjaGl2ZXNSZW1vdGUoeyB1cmw6IGNvbmZpZy51cmwsIGFjY291bnROYW1lOiBjb25maWcuYWNjb3VudE5hbWUsIHdhaXRGb3JBY2Nlc3M6IGZhbHNlIH0pO1xuICAgIHJldHVybiBhd2FpdCByZW1vdGUuZ2V0Q29uZmlnKCk7XG59XG4iXX0=
|
|
790
|
+
/* _JS_SOURCE_HASH = "24132a8f95064ab454f6ec54e9a2e7d01a8baac17398ede4dc15218f122061be"; */
|
|
@@ -77,7 +77,20 @@ class SourceWrapper {
|
|
|
77
77
|
return wrapper;
|
|
78
78
|
}
|
|
79
79
|
getDebugName() {
|
|
80
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlV3JhcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNvdXJjZVdyYXBwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsTUFBTSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFFMUIsbURBQXdEO0FBQ3hELDJEQUFxRDtBQUNyRCxvREFBaUQ7QUFFakQsaURBQW1HO0FBQ25HLHFEQUFrRDtBQUNsRCwrQ0FBNEM7QUFDNUMsNENBQWlEO0FBQ2pELDZEQUF3RjtBQUUzRSxRQUFBLGlCQUFpQixHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDN0IsUUFBQSxlQUFlLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDaEMsUUFBQSxZQUFZLEdBQUcsR0FBRyxDQUFDO0FBQ2hDLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUMxQyxNQUFNLGFBQWEsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQztBQUV4QixLQUFLLFVBQVUsaUJBQWlCO0lBQzVCLElBQUksQ0FBQyxJQUFBLGFBQU0sR0FBRTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzVCLElBQUksQ0FBQztRQUNELE1BQU0sSUFBQSxxQkFBUyxFQUFDLGlDQUFpQyxDQUFDLENBQUM7UUFDbkQsTUFBTSxJQUFBLHFCQUFTLEVBQUMsK0JBQStCLENBQUMsQ0FBQztRQUNqRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBQUMsV0FBTSxDQUFDO1FBQ0wsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztBQUNMLENBQUM7QUFFRCxtR0FBbUc7QUFDbkcsbUdBQW1HO0FBQ25HLGtHQUFrRztBQUNsRyw2RkFBNkY7QUFDN0YsOEZBQThGO0FBQzlGLDZGQUE2RjtBQUM3RixNQUFhLGFBQWE7SUFTdEIsWUFDVyxNQUFzQztJQUM3QyxvRkFBb0Y7SUFDNUUsVUFBbUI7UUFGcEIsV0FB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LElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEMsQ0FBQztJQUNMLENBQUM7Q0FDSjtBQWxNRCxzQ0FrTUMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuYWxsb3djbGllbnQgPSB0cnVlO1xuXG5pbXBvcnQgeyBpc05vZGUsIHNvcnQgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9taXNjXCI7XG5pbXBvcnQgeyBkZWxheSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2JhdGNoaW5nXCI7XG5pbXBvcnQgeyBnZXRTZWNyZXQgfSBmcm9tIFwiLi4vLi4vbWlzYy9nZXRTZWNyZXRcIjtcbmltcG9ydCB7IElBcmNoaXZlcywgSG9zdGVkQ29uZmlnLCBCYWNrYmxhemVDb25maWcgfSBmcm9tIFwiLi4vSUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBST1VUSU5HX0ZJTEUsIGdldEJ1Y2tldEJhc2VVcmwsIHBhcnNlSG9zdGVkVXJsLCBwYXJzZUJhY2tibGF6ZVVybCB9IGZyb20gXCIuL3JlbW90ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgQXJjaGl2ZXNSZW1vdGUgfSBmcm9tIFwiLi9BcmNoaXZlc1JlbW90ZVwiO1xuaW1wb3J0IHsgQXJjaGl2ZXNVcmwgfSBmcm9tIFwiLi9BcmNoaXZlc1VybFwiO1xuaW1wb3J0IHsgQXJjaGl2ZXNCYWNrYmxhemUgfSBmcm9tIFwiLi4vYmFja2JsYXplXCI7XG5pbXBvcnQgeyBnZXRTdG9yYWdlU2VydmVyQ29uZmlnT3B0aW9uYWwsIGdldExvY2FsQXJjaGl2ZXMgfSBmcm9tIFwiLi9zdG9yYWdlU2VydmVyU3RhdGVcIjtcblxuZXhwb3J0IGNvbnN0IFJFVFJZX1NUQVJUX0RFTEFZID0gMiAqIDEwMDA7XG5leHBvcnQgY29uc3QgUkVUUllfTUFYX0RFTEFZID0gNSAqIDYwICogMTAwMDtcbmV4cG9ydCBjb25zdCBSRVRSWV9HUk9XVEggPSAxLjU7XG5jb25zdCBBQ0NFU1NfUkVDSEVDS19JTlRFUlZBTCA9IDYwICogMTAwMDtcbmNvbnN0IFBJTkdfSU5URVJWQUwgPSA2MCAqIDEwMDA7XG5jb25zdCBQSU5HX0hJU1RPUlkgPSAxMDtcblxuYXN5bmMgZnVuY3Rpb24gaGFzQmFja2JsYXplQ3JlZHMoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKCFpc05vZGUoKSkgcmV0dXJuIGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGdldFNlY3JldChcImJhY2tibGF6ZS5qc29uLmFwcGxpY2F0aW9uS2V5SWRcIik7XG4gICAgICAgIGF3YWl0IGdldFNlY3JldChcImJhY2tibGF6ZS5qc29uLmFwcGxpY2F0aW9uS2V5XCIpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuLy8gT25lIHNvdXJjZSBvZiBhIFJlbW90ZUNvbmZpZywgYXMgYSB1c2FibGUgSUFyY2hpdmVzLiBSZWFkcyBmYWxsIGJhY2sgdG8gdGhlIHB1YmxpYy1VUkwgZm9ybSB3aGVuXG4vLyB3ZSBkb24ndCBoYXZlIEFQSSBhY2Nlc3M7IHdyaXRlcyBhbHdheXMgYXR0ZW1wdCB0aGUgQVBJIChzbyBhY2Nlc3MgZ3JhbnRlZCBsYXRlciBpcyBwaWNrZWQgdXAgb25cbi8vIHRoZSBuZXh0IHdyaXRlKS4gV2hlbiBhIGNhbGwgZmFpbHMgd2hpbGUgdGhlIFdlYlNvY2tldCBpcyBkb3duLCBub3RlRmFpbHVyZSBzdGFydHMgYSBiYWNrZ3JvdW5kXG4vLyByZWNvbm5lY3QgbG9vcCB3aXRoIGEgcmFtcGluZyBkZWxheSAtIGl0IG5ldmVyIGJsb2NrcyBjYWxsZXJzLCBpdCBqdXN0IGtlZXBzIHRyeWluZyBzbyB0aGVcbi8vIGNvbm5lY3Rpb24gZXZlbnR1YWxseSBjb21lcyBiYWNrLiBTb3VyY2VzIHdpdGhvdXQgYSBXZWJTb2NrZXQgKGJhY2tibGF6ZSwgVVJMLWZvcm0sIG91ciBvd25cbi8vIGxvY2FsIHNlcnZlcikgcmVwb3J0IGFsd2F5cy1jb25uZWN0ZWQ6IHRoZXkncmUgbGFzdC1yZXNvcnQgc291cmNlcyB3aGVyZSB0aHJvd2luZyBpcyBmaW5lLlxuZXhwb3J0IGNsYXNzIFNvdXJjZVdyYXBwZXIge1xuICAgIHB1YmxpYyBhcGk/OiBJQXJjaGl2ZXM7XG4gICAgcHVibGljIHVybD86IEFyY2hpdmVzVXJsO1xuICAgIHB1YmxpYyB3cml0ZUJsb2NrZWQ/OiBzdHJpbmc7XG4gICAgcHJpdmF0ZSByZW1vdGU/OiBBcmNoaXZlc1JlbW90ZTtcbiAgICBwcml2YXRlIGRpc3Bvc2VkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSByZWNvbm5lY3RSdW5uaW5nID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBhY2Nlc3NDYWNoZT86IHsgaGFzQWNjZXNzOiBib29sZWFuOyB0aW1lOiBudW1iZXIgfTtcblxuICAgIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgICAgIHB1YmxpYyBjb25maWc6IEhvc3RlZENvbmZpZyB8IEJhY2tibGF6ZUNvbmZpZyxcbiAgICAgICAgLy8gZmFsc2UgZm9yIHNob3J0LWxpdmVkIHByb2JlIGluc3RhbmNlcywgd2hpY2ggbXVzdCBuZXZlciBsZWF2ZSBhIHJldHJ5IGxvb3AgYmVoaW5kXG4gICAgICAgIHByaXZhdGUgYmFja2dyb3VuZDogYm9vbGVhbixcbiAgICApIHsgfVxuXG4gICAgcHVibGljIHN0YXRpYyBhc3luYyBjcmVhdGUoY29uZmlnOiBIb3N0ZWRDb25maWcgfCBCYWNrYmxhemVDb25maWcsIG9wdGlvbnM/OiB7IGJhY2tncm91bmQ/OiBib29sZWFuIH0pOiBQcm9taXNlPFNvdXJjZVdyYXBwZXI+IHtcbiAgICAgICAgbGV0IHdyYXBwZXIgPSBuZXcgU291cmNlV3JhcHBlcihjb25maWcsIG9wdGlvbnM/LmJhY2tncm91bmQgIT09IGZhbHNlKTtcbiAgICAgICAgaWYgKGNvbmZpZy50eXBlID09PSBcImJhY2tibGF6ZVwiKSB7XG4gICAgICAgICAgICBpZiAoYXdhaXQgaGFzQmFja2JsYXplQ3JlZHMoKSkge1xuICAgICAgICAgICAgICAgIHdyYXBwZXIuYXBpID0gbmV3IEFyY2hpdmVzQmFja2JsYXplKHsgYnVja2V0TmFtZTogcGFyc2VCYWNrYmxhemVVcmwoY29uZmlnLnVybCkuYnVja2V0TmFtZSwgcHVibGljOiBjb25maWcucHVibGljLCBpbW11dGFibGU6IGNvbmZpZy5pbW11dGFibGUgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzTm9kZSgpKSB7XG4gICAgICAgICAgICAgICAgd3JhcHBlci53cml0ZUJsb2NrZWQgPSBgTm8gYmFja2JsYXplIGNyZWRlbnRpYWxzIGZvciAke2NvbmZpZy51cmx9LiBQcm92aWRlIGJhY2tibGF6ZS5qc29uLmFwcGxpY2F0aW9uS2V5SWQgYW5kIGJhY2tibGF6ZS5qc29uLmFwcGxpY2F0aW9uS2V5IHZpYSBnZXRTZWNyZXQgdG8gZW5hYmxlIEFQSSBhY2Nlc3MuYDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgd3JhcHBlci53cml0ZUJsb2NrZWQgPSBgQnJvd3NlcnMgY2Fubm90IHdyaXRlIHRvIGJhY2tibGF6ZSAoYnVja2V0ICR7Y29uZmlnLnVybH0pYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghd3JhcHBlci5hcGkgJiYgY29uZmlnLnB1YmxpYyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICB3cmFwcGVyLnVybCA9IG5ldyBBcmNoaXZlc1VybChnZXRCdWNrZXRCYXNlVXJsKGNvbmZpZy51cmwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwYXJzZWQgPSBwYXJzZUhvc3RlZFVybChjb25maWcudXJsKTtcbiAgICAgICAgbGV0IHNlcnZlciA9IGlzTm9kZSgpICYmIGdldFN0b3JhZ2VTZXJ2ZXJDb25maWdPcHRpb25hbCgpIHx8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHNlcnZlciAmJiBwYXJzZWQuYWRkcmVzcyA9PT0gc2VydmVyLmRvbWFpbiAmJiBwYXJzZWQucG9ydCA9PT0gc2VydmVyLnBvcnQpIHtcbiAgICAgICAgICAgIC8vIEEgYnVja2V0IGhvc3RlZCBieSBvdXIgb3duIHByb2Nlc3MgLSB1c2UgaXQgZGlyZWN0bHkgaW5zdGVhZCBvZiBjYWxsaW5nIG91cnNlbHZlc1xuICAgICAgICAgICAgd3JhcHBlci5hcGkgPSBnZXRMb2NhbEFyY2hpdmVzKHBhcnNlZC5hY2NvdW50LCBwYXJzZWQuYnVja2V0TmFtZSk7XG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlcjtcbiAgICAgICAgfVxuICAgICAgICB3cmFwcGVyLnJlbW90ZSA9IG5ldyBBcmNoaXZlc1JlbW90ZSh7IHVybDogY29uZmlnLnVybCwgYWNjb3VudE5hbWU6IGNvbmZpZy5hY2NvdW50TmFtZSwgd2FpdEZvckFjY2VzczogZmFsc2UgfSk7XG4gICAgICAgIHdyYXBwZXIuYXBpID0gd3JhcHBlci5yZW1vdGU7XG4gICAgICAgIGlmIChjb25maWcucHVibGljICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgd3JhcHBlci51cmwgPSBuZXcgQXJjaGl2ZXNVcmwoZ2V0QnVja2V0QmFzZVVybChjb25maWcudXJsKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGdldERlYnVnTmFtZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYHNvdXJjZS8ke3RoaXMuY29uZmlnLnVybH1gO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzLnJlbW90ZS5pc0Nvbm5lY3RlZCgpO1xuICAgIH1cblxuICAgIC8qKiBDYWxsIGFmdGVyIGEgcmVxdWVzdCBmYWlsZWQgd2hpbGUgaXNDb25uZWN0ZWQoKSB3YXMgZmFsc2U6IHN0YXJ0cyAoaWYgbm90IGFscmVhZHkgcnVubmluZylcbiAgICAgKiAgdGhlIGJhY2tncm91bmQgcmVjb25uZWN0IGxvb3AuIE5ldmVyIGJsb2NrcyAtIHRoZSBmYWlsZWQgcmVxdWVzdCBzdGlsbCB0aHJvd3MuICovXG4gICAgcHVibGljIG5vdGVGYWlsdXJlKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuYmFja2dyb3VuZCB8fCB0aGlzLmRpc3Bvc2VkIHx8IHRoaXMucmVjb25uZWN0UnVubmluZykgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSByZXR1cm47XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYENhbm5vdCBjb25uZWN0IHRvIHN0b3JhZ2Ugc291cmNlICR7dGhpcy5jb25maWcudXJsfWApO1xuICAgICAgICB0aGlzLnJlY29ubmVjdFJ1bm5pbmcgPSB0cnVlO1xuICAgICAgICB2b2lkIHRoaXMucmVjb25uZWN0TG9vcCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVjb25uZWN0TG9vcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IHJldHJ5RGVsYXkgPSBSRVRSWV9TVEFSVF9ERUxBWTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIGF3YWl0IGRlbGF5KHJldHJ5RGVsYXkpO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdFJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSBicmVhaztcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gQW55IGNhbGwgcmUtZXN0YWJsaXNoZXMgdGhlIFdlYlNvY2tldDsgdGhlIHJlc3VsdCBkb2Vzbid0IG1hdHRlclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVtb3RlPy5nZXRJbmZvKFJPVVRJTkdfRklMRSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gRXZlbiBhIGZhaWxpbmcgY2FsbCAoZS5nLiBhY2Nlc3MgZGVuaWVkKSBwcm92ZXMgdGhlIGNvbm5lY3Rpb24gaXMgYmFja1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGVkKCkpIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgQ2Fubm90IGNvbm5lY3QgdG8gc3RvcmFnZSBzb3VyY2UgJHt0aGlzLmNvbmZpZy51cmx9LCByZXRyeWluZyBpbiAke01hdGgucm91bmQocmV0cnlEZWxheSAvIDEwMDApfXMuICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXRyeURlbGF5ID0gTWF0aC5taW4oUkVUUllfTUFYX0RFTEFZLCByZXRyeURlbGF5ICogUkVUUllfR1JPV1RIKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlY29ubmVjdFJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgY29uc29sZS5sb2coYFJlY29ubmVjdGVkIHRvIHN0b3JhZ2Ugc291cmNlICR7dGhpcy5jb25maWcudXJsfWApO1xuICAgIH1cblxuICAgIC8vIEZvciBob3N0ZWQgc291cmNlczogY2FjaGVkIGFjY2VzcyBjaGVjaywgc28gcmVhZHMga25vdyB3aGV0aGVyIHRvIHVzZSB0aGUgQVBJIG9yIHRoZSBwdWJsaWNcbiAgICAvLyBVUkwgZm9ybS4gQWNjZXNzLCBvbmNlIHNlZW4sIGlzIGFzc3VtZWQgdG8gc3RpY2s7IG5vLWFjY2VzcyBpcyByZS1jaGVja2VkIHBlcmlvZGljYWxseSAodGhlXG4gICAgLy8gY2hlY2sgYWxzbyByZWdpc3RlcnMgb3VyIGFjY2VzcyByZXF1ZXN0IHNlcnZlci1zaWRlLCB3aGljaCBsb2dzIHRoZSBncmFudCBsaW5rKS5cbiAgICBwcml2YXRlIGFzeW5jIGNoZWNrQWNjZXNzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBsZXQgcmVtb3RlID0gdGhpcy5yZW1vdGU7XG4gICAgICAgIGlmICghcmVtb3RlKSByZXR1cm4gISF0aGlzLmFwaTtcbiAgICAgICAgbGV0IGNhY2hlZCA9IHRoaXMuYWNjZXNzQ2FjaGU7XG4gICAgICAgIGlmIChjYWNoZWQgJiYgKGNhY2hlZC5oYXNBY2Nlc3MgfHwgRGF0ZS5ub3coKSAtIGNhY2hlZC50aW1lIDwgQUNDRVNTX1JFQ0hFQ0tfSU5URVJWQUwpKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkLmhhc0FjY2VzcztcbiAgICAgICAgfVxuICAgICAgICBsZXQgd2FpdGluZyA9IGF3YWl0IHJlbW90ZS53YWl0aW5nRm9yQWNjZXNzKCk7XG4gICAgICAgIHRoaXMuYWNjZXNzQ2FjaGUgPSB7IGhhc0FjY2VzczogIXdhaXRpbmcsIHRpbWU6IERhdGUubm93KCkgfTtcbiAgICAgICAgaWYgKHdhaXRpbmcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgTm8gYWNjZXNzIHRvIHN0b3JhZ2UgYWNjb3VudCBmb3IgJHt0aGlzLmNvbmZpZy51cmx9IChvdXIgbWFjaGluZSAke3dhaXRpbmcubWFjaGluZUlkfSwgaXAgJHt3YWl0aW5nLmlwfSkuIFJlYWRpbmcgdmlhIHRoZSBwdWJsaWMgVVJMIGZvcm0gd2hlcmUgcG9zc2libGUuIEdyYW50IGFjY2VzcyBhdCAke3dhaXRpbmcubGlua31gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gIXdhaXRpbmc7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJlYWQ8VD4ocnVuOiAoYXJjaGl2ZXM6IElBcmNoaXZlcykgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgICAgICBpZiAodGhpcy5hcGkgJiYgYXdhaXQgdGhpcy5jaGVja0FjY2VzcygpKSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgcnVuKHRoaXMuYXBpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy51cmwpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBydW4odGhpcy51cmwpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFwaSkge1xuICAgICAgICAgICAgLy8gTm8gcHVibGljIFVSTCBmb3JtIC0gbGV0IHRoZSBBUEkgY2FsbCB0aHJvdyBpdHMgb3duIGVycm9yICh3aGljaCBpbmNsdWRlcyB0aGUgYWNjZXNzXG4gICAgICAgICAgICAvLyBpbnN0cnVjdGlvbnMgZm9yIGhvc3RlZCBzb3VyY2VzKVxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHJ1bih0aGlzLmFwaSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTb3VyY2UgJHt0aGlzLmNvbmZpZy51cmx9IGhhcyBubyBBUEkgYWNjZXNzIGFuZCBubyBwdWJsaWMgVVJMIGZvcm0gKHB1YmxpYzogZmFsc2UpYCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGhhc1dyaXRlQWNjZXNzKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBpZiAodGhpcy53cml0ZUJsb2NrZWQgfHwgIXRoaXMuYXBpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmFwaS5oYXNXcml0ZUFjY2VzcygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcGluZ3M6IG51bWJlcltdID0gW107XG4gICAgcHJpdmF0ZSBwaW5nVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPiB8IHVuZGVmaW5lZDtcbiAgICBwcml2YXRlIGxvZ2dlZENvbm5lY3RlZCA9IGZhbHNlO1xuXG4gICAgLyoqIFN0YXJ0cyBtZWFzdXJpbmcgdGhpcyBzb3VyY2UncyBsYXRlbmN5IChmb3IgdmFyaWFibGUtc2hhcmQgdGFyZ2V0IHByZWZlcmVuY2UpLiBPbmx5IGhvc3RlZFxuICAgICAqICByZW1vdGVzIGFyZSBwaW5nZWQ7IG91ciBvd24gbG9jYWwgc2VydmVyIGNvdW50cyBhcyAwLCBldmVyeXRoaW5nIGVsc2UgYXMgSW5maW5pdHkuICovXG4gICAgcHVibGljIHN0YXJ0UGluZ2luZygpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcmVtb3RlID0gdGhpcy5yZW1vdGU7XG4gICAgICAgIGlmICghcmVtb3RlIHx8IHRoaXMucGluZ1RpbWVyIHx8IHRoaXMuZGlzcG9zZWQpIHJldHVybjtcbiAgICAgICAgbGV0IG1lYXN1cmUgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW1vdGUucGluZygpO1xuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgLy8gQSBmYWlsZWQgcGluZyBpcyBhbHNvIG91ciBlYXJsaWVzdCBkb3duLWRldGVjdGlvblxuICAgICAgICAgICAgICAgIHRoaXMubm90ZUZhaWx1cmUoKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMubG9nZ2VkQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZWRDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDb25uZWN0ZWQgdG8gc3RvcmFnZSBzb3VyY2UgJHt0aGlzLmNvbmZpZy51cmx9ICgke0RhdGUubm93KCkgLSBzdGFydH1tcylgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucGluZ3MucHVzaChEYXRlLm5vdygpIC0gc3RhcnQpO1xuICAgICAgICAgICAgaWYgKHRoaXMucGluZ3MubGVuZ3RoID4gUElOR19ISVNUT1JZKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5waW5ncy5zaGlmdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB2b2lkIG1lYXN1cmUoKTtcbiAgICAgICAgdGhpcy5waW5nVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICB2b2lkIG1lYXN1cmUoKTtcbiAgICAgICAgfSwgUElOR19JTlRFUlZBTCk7XG4gICAgICAgICh0aGlzLnBpbmdUaW1lciBhcyB7IHVucmVmPzogKCkgPT4gdm9pZCB9KS51bnJlZj8uKCk7XG4gICAgfVxuXG4gICAgLyoqIE1lZGlhbiBvZiB0aGUgcmVjZW50IHBpbmdzLiBTb3VyY2VzIHRoYXQgY2FuJ3QgYmUgcGluZ2VkIHNvcnQgbGFzdCAoSW5maW5pdHkpLCBleGNlcHQgb3VyXG4gICAgICogIG93biBpbi1wcm9jZXNzIHNlcnZlciwgd2hpY2ggaXMgdGhlIGJlc3QgcG9zc2libGUgdGFyZ2V0ICgwKS4gKi9cbiAgICBwdWJsaWMgZ2V0TGF0ZW5jeSgpOiBudW1iZXIge1xuICAgICAgICBpZiAoIXRoaXMucmVtb3RlKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25maWcudHlwZSA9PT0gXCJyZW1vdGVcIiAmJiB0aGlzLmFwaSkgcmV0dXJuIDA7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnBpbmdzLmxlbmd0aCkgcmV0dXJuIEluZmluaXR5O1xuICAgICAgICBsZXQgc29ydGVkID0gWy4uLnRoaXMucGluZ3NdO1xuICAgICAgICBzb3J0KHNvcnRlZCwgeCA9PiB4KTtcbiAgICAgICAgcmV0dXJuIHNvcnRlZFtNYXRoLmZsb29yKHNvcnRlZC5sZW5ndGggLyAyKV07XG4gICAgfVxuXG4gICAgLyoqIFdyaXRlcyBhbHdheXMgZ28gdGhyb3VnaCB0aGUgQVBJLCBzbyBhIHBlcm1pc3Npb24gZXJyb3IgdGhyb3dzIHRvIHRoZSBjYWxsZXIgb24gZXZlcnkgd3JpdGVcbiAgICAgKiAgKGFuZCBhY2Nlc3MgZ3JhbnRlZCBpbiB0aGUgbWVhbnRpbWUgaXMgcGlja2VkIHVwIGF1dG9tYXRpY2FsbHkpLiAqL1xuICAgIHB1YmxpYyBhc3luYyB3cml0ZTxUPihydW46IChhcmNoaXZlczogSUFyY2hpdmVzKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIGlmICh0aGlzLndyaXRlQmxvY2tlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMud3JpdGVCbG9ja2VkKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYXBpID0gdGhpcy5hcGk7XG4gICAgICAgIGlmICghYXBpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNvdXJjZSAke3RoaXMuY29uZmlnLnVybH0gaGFzIG5vIEFQSSBhY2Nlc3MsIHNvIGl0IGNhbm5vdCBhY2NlcHQgd3JpdGVzYCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHJ1bihhcGkpO1xuICAgICAgICB0aGlzLmFjY2Vzc0NhY2hlID0geyBoYXNBY2Nlc3M6IHRydWUsIHRpbWU6IERhdGUubm93KCkgfTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNwb3NlZCA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLnBpbmdUaW1lcikge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnBpbmdUaW1lcik7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=
|
|
231
|
-
/* _JS_SOURCE_HASH = "
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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} (
|
|
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;
|