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