sliftutils 1.7.90 → 1.7.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/index.d.ts +38 -79
  2. package/misc/https/dist/cloudflareHelpers.ts.cache +2 -2
  3. package/misc/https/dist/dns.ts.cache +2 -2
  4. package/package.json +1 -1
  5. package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +2 -2
  6. package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +2 -2
  7. package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +2 -2
  8. package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +2 -2
  9. package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +2 -2
  10. package/storage/BulkDatabase2/dist/blockCache.ts.cache +2 -2
  11. package/storage/BulkDatabase2/dist/mergeLock.ts.cache +2 -2
  12. package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +2 -2
  13. package/storage/BulkDatabase2/dist/streamLog.ts.cache +2 -2
  14. package/storage/BulkDatabase2/dist/syncClient.ts.cache +2 -2
  15. package/storage/IArchives.d.ts +1 -0
  16. package/storage/IArchives.ts +3 -0
  17. package/storage/remoteStorage/accessStats.d.ts +12 -0
  18. package/storage/remoteStorage/accessStats.ts +47 -0
  19. package/storage/remoteStorage/blobStore.d.ts +6 -1
  20. package/storage/remoteStorage/blobStore.ts +34 -5
  21. package/storage/remoteStorage/createArchives.ts +13 -6
  22. package/storage/remoteStorage/dist/accessStats.ts.cache +42 -3
  23. package/storage/remoteStorage/dist/blobStore.ts.cache +6 -3
  24. package/storage/remoteStorage/dist/intermediateManagement.ts.cache +56 -50
  25. package/storage/remoteStorage/dist/storageController.ts.cache +36 -29
  26. package/storage/remoteStorage/dist/storageServerState.ts.cache +110 -233
  27. package/storage/remoteStorage/dist/storeConfig.ts.cache +2 -2
  28. package/storage/remoteStorage/dist/storePlan.ts.cache +4 -56
  29. package/storage/remoteStorage/intermediateManagement.d.ts +2 -3
  30. package/storage/remoteStorage/intermediateManagement.ts +53 -46
  31. package/storage/remoteStorage/storageController.ts +22 -14
  32. package/storage/remoteStorage/storageServerState.d.ts +15 -55
  33. package/storage/remoteStorage/storageServerState.ts +106 -268
  34. package/storage/remoteStorage/storeConfig.d.ts +2 -0
  35. package/storage/remoteStorage/storeConfig.ts +2 -0
  36. package/storage/remoteStorage/storePlan.d.ts +0 -20
  37. package/storage/remoteStorage/storePlan.ts +1 -69
@@ -10,6 +10,7 @@ const serverConfig_1 = require("./serverConfig");
10
10
  const createArchives_1 = require("./createArchives");
11
11
  const storePlan_1 = require("./storePlan");
12
12
  const storageServerState_1 = require("./storageServerState");
13
+ const bucketDisk_1 = require("./bucketDisk");
13
14
  const ArchivesDelayed_1 = require("./ArchivesDelayed");
14
15
  const blobStore_1 = require("./blobStore");
15
16
  // Deploy switchovers, and the handovers they cause. A switchover is a source moving to a new port for a few minutes: we give it a virtual valid window on that port (an "intermediate"), which means the write target changes twice in quick succession, which means the store taking over has to go and collect the writes that landed just before it did. None of that is storage - it is scheduling - so it lives here rather than in the store or in the server's bucket state.
@@ -24,20 +25,21 @@ const OWN_CONFIG_WRITE_THROTTLE = 30 * 1000;
24
25
  const INTERMEDIATE_MAINTAIN_INTERVAL = 60 * 1000;
25
26
  const scheduledBoundaryScans = new Set();
26
27
  const boundaryScansRunning = new Set();
27
- /** Called whenever a bucket's state is (re)built: arms the scans its upcoming window boundaries need. Each scan is scheduled once - the key includes the boundary it is for - so re-arming on every config change is harmless. */
28
- function scheduleBoundaryWork(loaded) {
28
+ /** Called every time a store applies a routing config to itself (see BlobStore's onRoutingApplied): arms the scans the config's upcoming window boundaries need. Each scan is scheduled once - the key includes the boundary it is for - so re-arming on every config application is harmless. */
29
+ function scheduleBoundaryWork(account, bucketName, routing) {
29
30
  var _a, _b;
30
- let key = `${loaded.account}/${loaded.bucketName}`;
31
+ let key = `${account}/${bucketName}`;
32
+ let selfEntries = (0, storePlan_1.findSelfIndexes)(routing, account, bucketName).map(i => routing.sources[i]);
31
33
  let now = Date.now();
32
34
  let starts = new Set();
33
- for (let self of loaded.selfEntries) {
35
+ for (let self of selfEntries) {
34
36
  let start = self.validWindow[0];
35
37
  if (start > now && start < Number.MAX_SAFE_INTEGER) {
36
38
  starts.add(start);
37
39
  }
38
40
  }
39
41
  // A window we have only just taken over, on a server that has only just started: the boundary happened while we were not running, so its scan still has to happen
40
- for (let self of loaded.selfEntries) {
42
+ for (let self of selfEntries) {
41
43
  let [start, end] = self.validWindow;
42
44
  if (!(start <= now && now < end) || start <= 0)
43
45
  continue;
@@ -48,7 +50,7 @@ function scheduleBoundaryWork(loaded) {
48
50
  continue;
49
51
  scheduledBoundaryScans.add(scheduleKey);
50
52
  let timer = setTimeout(() => {
51
- void runBoundaryScan(loaded, start, STARTUP_BOUNDARY_SCAN_DELAY, "startup+30s").catch((e) => { var _a; return console.error(`Boundary scan for bucket ${key} failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`); });
53
+ void runBoundaryScan(account, bucketName, start, STARTUP_BOUNDARY_SCAN_DELAY, "startup+30s").catch((e) => { var _a; return console.error(`Boundary scan for bucket ${key} failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`); });
52
54
  }, STARTUP_BOUNDARY_SCAN_DELAY);
53
55
  (_b = (_a = timer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
54
56
  }
@@ -69,7 +71,7 @@ function scheduleBoundaryWork(loaded) {
69
71
  arm();
70
72
  return;
71
73
  }
72
- void runBoundaryScan(loaded, start, offset).catch((e) => { var _a; return console.error(`Boundary scan for bucket ${key} failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`); });
74
+ void runBoundaryScan(account, bucketName, start, offset).catch((e) => { var _a; return console.error(`Boundary scan for bucket ${key} failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`); });
73
75
  }, Math.min(at - Date.now(), MAX_TIMER_DELAY));
74
76
  (_b = (_a = timer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
75
77
  };
@@ -78,10 +80,10 @@ function scheduleBoundaryWork(loaded) {
78
80
  }
79
81
  }
80
82
  exports.scheduleBoundaryWork = scheduleBoundaryWork;
81
- /** Collects the writes that landed on the previous window's owners just before a boundary, into the store that has just taken over. Who owned what is worked out purely from the config (see previousWindowOwners); this only does the pulling. */
82
- async function runBoundaryScan(loaded, windowStart, offset, offsetLabel) {
83
+ /** Collects the writes that landed on the previous window's owners just before a boundary, into the store that has just taken over. Who owned what is worked out purely from the config (see previousWindowOwners); this only does the pulling. The config is read off the disk at FIRE time, not captured when the scan was armed - it may have changed in between, and the newest copy is the one the handover actually happened under. */
84
+ async function runBoundaryScan(account, bucketName, windowStart, offset, offsetLabel) {
83
85
  var _a;
84
- let key = `${loaded.account}/${loaded.bucketName}`;
86
+ let key = `${account}/${bucketName}`;
85
87
  let label = `bucket ${key}, window starting ${new Date(windowStart).toISOString()}, offset ${offsetLabel || `${offset / 1000}s`}`;
86
88
  if (boundaryScansRunning.has(key)) {
87
89
  console.log(`Skipping boundary scan (${label}): the previous boundary scan is still running`);
@@ -89,27 +91,25 @@ async function runBoundaryScan(loaded, windowStart, offset, offsetLabel) {
89
91
  }
90
92
  boundaryScansRunning.add(key);
91
93
  try {
92
- let effective = loaded.routing;
94
+ let effective = await (0, bucketDisk_1.readRoutingFromDisk)(account, bucketName);
93
95
  if (!effective)
94
96
  return;
95
- let handovers = (0, storePlan_1.previousWindowOwners)(effective, windowStart, (0, storePlan_1.findSelfIndexes)(effective, loaded.account, loaded.bucketName));
97
+ let handovers = (0, storePlan_1.previousWindowOwners)(effective, windowStart, (0, storePlan_1.findSelfIndexes)(effective, account, bucketName));
96
98
  if (!handovers.length)
97
99
  return;
98
100
  console.log(`Boundary scan (${label}): ${handovers.length} route(s) taking over: ${handovers.map(x => `${JSON.stringify(x.route)} from ${x.scanOwnDisk && "our own disk" || ""}${x.scanOwnDisk && x.remotes.size && " + " || ""}${[...x.remotes.keys()].map(i => `source ${i}`).join(", ")}`).join("; ")}`);
99
101
  let since = windowStart - BOUNDARY_SCAN_LOOKBACK;
100
102
  for (let handover of handovers) {
101
- let selfStore = loaded.stores.find(x => x.name === handover.name);
102
- if (!selfStore)
103
- continue;
103
+ let selfStore = (0, storageServerState_1.getStore)(account, bucketName, handover.name);
104
104
  if (handover.scanOwnDisk) {
105
- await selfStore.store.rescanBase();
105
+ await selfStore.rescanBase();
106
106
  }
107
107
  for (let [sourceIndex, route] of handover.remotes) {
108
108
  let ownerSource = effective.sources[sourceIndex];
109
109
  if (typeof ownerSource === "string")
110
110
  continue;
111
111
  try {
112
- await selfStore.store.boundaryScanRemote((0, createArchives_1.createApiArchives)(ownerSource), { since, route });
112
+ await selfStore.boundaryScanRemote((0, createArchives_1.createApiArchives)(ownerSource), { since, route });
113
113
  }
114
114
  catch (e) {
115
115
  console.error(`Boundary scan (${label}) of previous-window owner (source index ${sourceIndex}) failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`);
@@ -144,38 +144,33 @@ function reinjectIntermediates(current, incoming) {
144
144
  exports.reinjectIntermediates = reinjectIntermediates;
145
145
  // Per bucket, not global: a switchover has to write every bucket's windows at once, and a shared throttle would let only one bucket through per interval
146
146
  const lastOwnConfigWrite = new Map();
147
- async function writeOwnRoutingConfig(loaded, updated, reason) {
148
- let key = `${loaded.account}/${loaded.bucketName}`;
147
+ async function writeOwnRoutingConfig(config) {
148
+ let { account, bucketName, current, updated, reason } = config;
149
+ let key = `${account}/${bucketName}`;
149
150
  let sinceLast = Date.now() - (lastOwnConfigWrite.get(key) || 0);
150
151
  if (sinceLast < OWN_CONFIG_WRITE_THROTTLE) {
151
152
  console.log(`Not writing our own routing config update for bucket ${key} (${reason}): the last one was ${sinceLast}ms ago, under the ${OWN_CONFIG_WRITE_THROTTLE}ms throttle. Retrying on the next maintenance pass.`);
152
153
  return;
153
154
  }
154
155
  lastOwnConfigWrite.set(key, Date.now());
155
- // A switchover writes on top of whatever the bucket is running; with no config at all there is nothing to switch over
156
- if (!loaded.routing)
157
- return;
158
- let currentVersion = (0, remoteConfig_1.getConfigVersion)(loaded.routing);
156
+ let currentVersion = (0, remoteConfig_1.getConfigVersion)(current);
159
157
  let version = (0, intermediateSources_1.nextIntermediateVersion)(currentVersion);
160
158
  let next = { ...updated, version };
161
159
  console.log(`Writing ${remoteConfig_1.ROUTING_FILE} for bucket ${key} (${reason}), version ${currentVersion} -> ${version}: ${JSON.stringify(next)}`);
162
160
  let data = Buffer.from((0, remoteConfig_1.serializeRemoteConfig)(next));
163
- // Into one of our own stores - it applies it and its peers pull it - and directly to the other servers, which is what makes a switchover take effect in seconds rather than at the next poll
164
- let ourStore = loaded.stores[0];
165
- if (ourStore) {
166
- await (0, storageServerState_1.writeRoutingConfig)(loaded.account, loaded.bucketName, ourStore.name, data);
167
- }
168
- await propagateRoutingConfig(loaded, next, data);
161
+ // Into the store holding the newest copy - it applies it and its peers pull it - and directly to the other servers, which is what makes a switchover take effect in seconds rather than at the next poll
162
+ await (0, storageServerState_1.writeRoutingConfig)(account, bucketName, config.storeName, data);
163
+ await propagateRoutingConfig({ account, bucketName, current, next, data });
169
164
  }
170
- async function propagateRoutingConfig(loaded, next, data) {
171
- var _a, _b;
165
+ async function propagateRoutingConfig(config) {
166
+ var _a;
172
167
  let targets = new Map();
173
- for (let source of [...((_a = loaded.routing) === null || _a === void 0 ? void 0 : _a.sources) || [], ...next.sources]) {
168
+ for (let source of [...config.current.sources, ...config.next.sources]) {
174
169
  if (typeof source === "string" || source.intermediate)
175
170
  continue;
176
171
  if (source.type === "remote") {
177
172
  let parsed = (0, remoteConfig_1.parseHostedUrl)(source.url);
178
- if (parsed.account !== loaded.account || parsed.bucketName !== loaded.bucketName)
173
+ if (parsed.account !== config.account || parsed.bucketName !== config.bucketName)
179
174
  continue;
180
175
  }
181
176
  if (targets.has(source.url))
@@ -184,31 +179,39 @@ async function propagateRoutingConfig(loaded, next, data) {
184
179
  }
185
180
  for (let [url, source] of targets) {
186
181
  try {
187
- await (0, createArchives_1.createApiArchives)(source).set(remoteConfig_1.ROUTING_FILE, data);
188
- console.log(`Wrote ${remoteConfig_1.ROUTING_FILE} for bucket ${loaded.account}/${loaded.bucketName} to ${url}`);
182
+ await (0, createArchives_1.createApiArchives)(source).set(remoteConfig_1.ROUTING_FILE, config.data);
183
+ console.log(`Wrote ${remoteConfig_1.ROUTING_FILE} for bucket ${config.account}/${config.bucketName} to ${url}`);
189
184
  }
190
185
  catch (e) {
191
- console.error(`Propagating our routing config update to ${url} failed: ${(_b = e.stack) !== null && _b !== void 0 ? _b : e}`);
186
+ console.error(`Propagating our routing config update to ${url} failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`);
192
187
  }
193
188
  }
194
189
  }
195
- /** Keeps every loaded bucket's switchover windows current: gives our alternate port its window while a takeover is in flight, and takes expired ones back out. */
190
+ /** Keeps every active bucket's switchover windows current: gives our alternate port its window while a takeover is in flight, and takes expired ones back out. */
196
191
  async function maintainIntermediates() {
197
192
  let { domain, port } = (0, serverConfig_1.getStorageServerConfig)();
198
193
  let takeover = (0, deployTakeover_1.getTakeoverIntermediate)();
199
194
  let written = [];
200
195
  let alreadyCorrect = [];
201
196
  let notOurs = [];
202
- // ONLY buckets already in memory. A switchover must never load a bucket: loading starts its synchronization, and buckets nothing has touched (legacy ones especially) have no writes to hand off in the first place. One that does get used mid-switchover loads on that access, and the next pass gives it its window.
203
- let states = (0, storageServerState_1.getBucketStates)();
204
- for (let loaded of states) {
205
- let key = `${loaded.account}/${loaded.bucketName}`;
206
- let routing = loaded.routing;
207
- if (!routing)
197
+ // ONLY buckets already active. A switchover must never activate a bucket: that starts its synchronization, and buckets nothing has touched (legacy ones especially) have no writes to hand off in the first place. One that does get used mid-switchover activates on that access, and the next pass gives it its window.
198
+ let activeKeys = (0, storageServerState_1.getActiveBucketKeys)();
199
+ for (let { account, bucketName } of activeKeys) {
200
+ let key = `${account}/${bucketName}`;
201
+ let newest = await (0, bucketDisk_1.readNewestRoutingFile)(account, bucketName);
202
+ if (!newest)
208
203
  continue;
204
+ let routing;
205
+ try {
206
+ routing = (0, remoteConfig_1.parseRoutingData)(newest.data);
207
+ }
208
+ catch (e) {
209
+ console.error(`Skipping switchover maintenance for bucket ${key}: its routing config could not be parsed (${e.message})`);
210
+ continue;
211
+ }
209
212
  let expired = (0, intermediateSources_1.expireIntermediateSources)(routing, Date.now());
210
213
  if (JSON.stringify(expired) !== JSON.stringify(routing)) {
211
- await writeOwnRoutingConfig(loaded, expired, `switchover windows expired more than ${intermediateSources_1.INTERMEDIATE_EXPIRE_GRACE / 1000}s ago`);
214
+ await writeOwnRoutingConfig({ account, bucketName, storeName: newest.name, current: routing, updated: expired, reason: `switchover windows expired more than ${intermediateSources_1.INTERMEDIATE_EXPIRE_GRACE / 1000}s ago` });
212
215
  written.push(key);
213
216
  continue;
214
217
  }
@@ -234,17 +237,17 @@ async function maintainIntermediates() {
234
237
  alreadyCorrect.push(key);
235
238
  continue;
236
239
  }
237
- await writeOwnRoutingConfig(loaded, injected, `we are a deploy successor: writes route to our alternate port ${takeover.altPort} from ${new Date(takeover.start).toISOString()} until our predecessor is killed at ${new Date(takeover.end).toISOString()}`);
240
+ await writeOwnRoutingConfig({ account, bucketName, storeName: newest.name, current: routing, updated: injected, reason: `we are a deploy successor: writes route to our alternate port ${takeover.altPort} from ${new Date(takeover.start).toISOString()} until our predecessor is killed at ${new Date(takeover.end).toISOString()}` });
238
241
  written.push(key);
239
242
  }
240
243
  if (!takeover)
241
244
  return;
242
- if (!states.length) {
245
+ if (!activeKeys.length) {
243
246
  console.log(`No active buckets, so no config files to write the intermediate into (a bucket is only active once something uses it)`);
244
247
  return;
245
248
  }
246
249
  if (!written.length) {
247
- console.log(`Wrote no config files: of ${states.length} active buckets, ${alreadyCorrect.length} already contain the intermediate and ${notOurs.length} are not hosted by us`);
250
+ console.log(`Wrote no config files: of ${activeKeys.length} active buckets, ${alreadyCorrect.length} already contain the intermediate and ${notOurs.length} are not hosted by us`);
248
251
  }
249
252
  }
250
253
  /** Our predecessor still holds the main port and has been serving all along, so it - not us - knows which buckets are in use. We activate exactly those, which is what makes their config files get the intermediate; nothing else on disk is touched. */
@@ -267,7 +270,10 @@ async function activatePredecessorBuckets() {
267
270
  console.log(`Our predecessor on ${url} has ${keys.length} active buckets, activating them here so their config files get the intermediate: ${keys.map(x => `${x.account}/${x.bucketName}`).join(", ")}`);
268
271
  for (let { account, bucketName } of keys) {
269
272
  try {
270
- await (0, storageServerState_1.getLoadedBucket)(account, bucketName);
273
+ let result = await (0, storageServerState_1.activateBucket)(account, bucketName);
274
+ if (typeof result === "string") {
275
+ console.error(`Activating bucket ${account}/${bucketName} (active on our predecessor) failed: ${result}`);
276
+ }
271
277
  }
272
278
  catch (e) {
273
279
  console.error(`Activating bucket ${account}/${bucketName} (active on our predecessor) failed: ${(_b = e.stack) !== null && _b !== void 0 ? _b : e}`);
@@ -282,5 +288,5 @@ exports.startIntermediateMaintenance = (0, caching_1.lazy)(() => {
282
288
  })().catch((e) => { var _a; return console.error(`Writing the intermediate into the config files failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`); });
283
289
  (0, batching_1.runInfinitePoll)(INTERMEDIATE_MAINTAIN_INTERVAL, maintainIntermediates);
284
290
  });
285
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJtZWRpYXRlTWFuYWdlbWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImludGVybWVkaWF0ZU1hbmFnZW1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseURBQW1EO0FBQ25ELDJEQUErRDtBQUUvRCxpREFBNkg7QUFDN0gsK0RBQXdLO0FBQ3hLLHFEQUEyRDtBQUMzRCxpREFBd0Q7QUFDeEQscURBQWlGO0FBQ2pGLDJDQUFvRTtBQUNwRSw2REFBeUc7QUFDekcsdURBQTZEO0FBQzdELDJDQUFzRDtBQUV0RCxvZEFBb2Q7QUFFcGQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDcEMsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDO0FBQzdCLDhKQUE4SjtBQUM5SixNQUFNLHFCQUFxQixHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ2hFLHNIQUFzSDtBQUN0SCxNQUFNLHNCQUFzQixHQUFHLDBDQUF3QixHQUFHLG1DQUF1QixDQUFDO0FBQ2xGLE1BQU0sMkJBQTJCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUM5QyxNQUFNLHlCQUF5QixHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDNUMsTUFBTSw4QkFBOEIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRWpELE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztBQUNqRCxNQUFNLG9CQUFvQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7QUFFL0Msa09BQWtPO0FBQ2xPLFNBQWdCLG9CQUFvQixDQUFDLE1BQW1COztJQUNwRCxJQUFJLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ25ELElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxH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QUMvQyxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNULE9BQU8sQ0FBQyxLQUFLLENBQUMscUJBQXFCLE9BQU8sSUFBSSxVQUFVLHdDQUF3QyxNQUFDLENBQVcsQ0FBQyxLQUFLLG1DQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDL0gsQ0FBQztJQUNMLENBQUM7QUFDTCxDQUFDO0FBRUQseUxBQXlMO0FBQzVLLFFBQUEsNEJBQTRCLEdBQUcsSUFBQSxjQUFJLEVBQUMsR0FBRyxFQUFFO0lBQ2xELEtBQUssQ0FBQyxLQUFLLElBQUksRUFBRTtRQUNiLE1BQU0sMEJBQTBCLEVBQUUsQ0FBQztRQUNuQyxNQUFNLHFCQUFxQixFQUFFLENBQUM7SUFDbEMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFRLEVBQUUsRUFBRSxXQUFDLE9BQUEsT0FBTyxDQUFDLEtBQUssQ0FBQywwREFBMEQsTUFBQSxDQUFDLENBQUMsS0FBSyxtQ0FBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBLEVBQUEsQ0FBQyxDQUFDO0lBQ2xILElBQUEsMEJBQWUsRUFBQyw4QkFBOEIsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0FBQzNFLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbGF6eSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2NhY2hpbmdcIjtcbmltcG9ydCB7IHJ1bkluZmluaXRlUG9sbCB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2JhdGNoaW5nXCI7XG5pbXBvcnQgeyBSZW1vdGVDb25maWcsIFNvdXJjZUNvbmZpZywgSG9zdGVkQ29uZmlnIH0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHsgUk9VVElOR19GSUxFLCBnZXRDb25maWdWZXJzaW9uLCBzZXJpYWxpemVSZW1vdGVDb25maWcsIHBhcnNlSG9zdGVkVXJsLCByZXBsYWNlSG9zdGVkVXJsUG9ydCB9IGZyb20gXCIuL3JlbW90ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgaW5qZWN0SW50ZXJtZWRpYXRlU291cmNlLCBleHBpcmVJbnRlcm1lZGlhdGVTb3VyY2VzLCBnZXRJbnRlcm1lZGlhdGVTb3VyY2VzLCBuZXh0SW50ZXJtZWRpYXRlVmVyc2lvbiwgSU5URVJNRURJQVRFX0VYUElSRV9HUkFDRSB9IGZyb20gXCIuL2ludGVybWVkaWF0ZVNvdXJjZXNcIjtcbmltcG9ydCB7IGdldFRha2VvdmVySW50ZXJtZWRpYXRlIH0gZnJvbSBcIi4vZGVwbG95VGFrZW92ZXJcIjtcbmltcG9ydCB7IGdldFN0b3JhZ2VTZXJ2ZXJDb25maWcgfSBmcm9tIFwiLi9zZXJ2ZXJDb25maWdcIjtcbmltcG9ydCB7IGNyZWF0ZUFwaUFyY2hpdmVzLCBsaXN0U2VydmVyQWN0aXZlQnVja2V0S2V5cyB9IGZyb20gXCIuL2NyZWF0ZUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBmaW5kU2VsZkluZGV4ZXMsIHByZXZpb3VzV2luZG93T3duZXJzIH0gZnJvbSBcIi4vc3RvcmVQbGFuXCI7XG5pbXBvcnQgeyBCdWNrZXRTdGF0ZSwgZ2V0QnVja2V0U3RhdGVzLCBnZXRMb2FkZWRCdWNrZXQsIHdyaXRlUm91dGluZ0NvbmZpZyB9IGZyb20gXCIuL3N0b3JhZ2VTZXJ2ZXJTdGF0ZVwiO1xuaW1wb3J0IHsgREVGQVVMVF9GQVNUX1dSSVRFX0RFTEFZIH0gZnJvbSBcIi4vQXJjaGl2ZXNEZWxheWVkXCI7XG5pbXBvcnQgeyBXSU5ET1dfRU5EX0ZMVVNIX01BUkdJTiB9IGZyb20gXCIuL2Jsb2JTdG9yZVwiO1xuXG4vLyBEZXBsb3kgc3dpdGNob3ZlcnMsIGFuZCB0aGUgaGFuZG92ZXJzIHRoZXkgY2F1c2UuIEEgc3dpdGNob3ZlciBpcyBhIHNvdXJjZSBtb3ZpbmcgdG8gYSBuZXcgcG9ydCBmb3IgYSBmZXcgbWludXRlczogd2UgZ2l2ZSBpdCBhIHZpcnR1YWwgdmFsaWQgd2luZG93IG9uIHRoYXQgcG9ydCAoYW4gXCJpbnRlcm1lZGlhdGVcIiksIHdoaWNoIG1lYW5zIHRoZSB3cml0ZSB0YXJnZXQgY2hhbmdlcyB0d2ljZSBpbiBxdWljayBzdWNjZXNzaW9uLCB3aGljaCBtZWFucyB0aGUgc3RvcmUgdGFraW5nIG92ZXIgaGFzIHRvIGdvIGFuZCBjb2xsZWN0IHRoZSB3cml0ZXMgdGhhdCBsYW5kZWQganVzdCBiZWZvcmUgaXQgZGlkLiBOb25lIG9mIHRoYXQgaXMgc3RvcmFnZSAtIGl0IGlzIHNjaGVkdWxpbmcgLSBzbyBpdCBsaXZlcyBoZXJlIHJhdGhlciB0aGFuIGluIHRoZSBzdG9yZSBvciBpbiB0aGUgc2VydmVyJ3MgYnVja2V0IHN0YXRlLlxuXG5jb25zdCBNQVhfVElNRVJfREVMQVkgPSAyICoqIDMxIC0gMTtcbmNvbnN0IEJPVU5EQVJZX0JVRkZFUiA9IDEwMDA7XG4vLyBBIGhhbmRvdmVyIGlzIHNjYW5uZWQganVzdCBiZWZvcmUgdGhlIGJvdW5kYXJ5LCBqdXN0IGFmdGVyLCBhbmQgYWdhaW4gYSBsaXR0bGUgbGF0ZXIgLSB0aGUgbGFzdCB3cml0ZXMgdG8gdGhlIG9sZCB0YXJnZXQgY2FuIGxhbmQgYWZ0ZXIgdGhlIGJvdW5kYXJ5IGl0c2VsZlxuY29uc3QgQk9VTkRBUllfU0NBTl9PRkZTRVRTID0gWy0zMCAqIDEwMDAsIDIgKiAxMDAwLCAzMCAqIDEwMDBdO1xuLy8gSG93IGZhciBiYWNrIGEgYm91bmRhcnkgc2NhbiBhc2tzIGZvciBjaGFuZ2VzOiBldmVyeXRoaW5nIHRoYXQgY291bGQgc3RpbGwgaGF2ZSBiZWVuIGJ1ZmZlcmVkIHdoZW4gdGhlIHdpbmRvdyBlbmRlZFxuY29uc3QgQk9VTkRBUllfU0NBTl9MT09LQkFDSyA9IERFRkFVTFRfRkFTVF9XUklURV9ERUxBWSArIFdJTkRPV19FTkRfRkxVU0hfTUFSR0lOO1xuY29uc3QgU1RBUlRVUF9CT1VOREFSWV9TQ0FOX0RFTEFZID0gMzAgKiAxMDAwO1xuY29uc3QgT1dOX0NPTkZJR19XUklURV9USFJPVFRMRSA9IDMwICogMTAwMDtcbmNvbnN0IElOVEVSTUVESUFURV9NQUlOVEFJTl9JTlRFUlZBTCA9IDYwICogMTAwMDtcblxuY29uc3Qgc2NoZWR1bGVkQm91bmRhcnlTY2FucyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuY29uc3QgYm91bmRhcnlTY2Fuc1J1bm5pbmcgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuLyoqIENhbGxlZCB3aGVuZXZlciBhIGJ1Y2tldCdzIHN0YXRlIGlzIChyZSlidWlsdDogYXJtcyB0aGUgc2NhbnMgaXRzIHVwY29taW5nIHdpbmRvdyBib3VuZGFyaWVzIG5lZWQuIEVhY2ggc2NhbiBpcyBzY2hlZHVsZWQgb25jZSAtIHRoZSBrZXkgaW5jbHVkZXMgdGhlIGJvdW5kYXJ5IGl0IGlzIGZvciAtIHNvIHJlLWFybWluZyBvbiBldmVyeSBjb25maWcgY2hhbmdlIGlzIGhhcm1sZXNzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjaGVkdWxlQm91bmRhcnlXb3JrKGxvYWRlZDogQnVja2V0U3RhdGUpOiB2b2lkIHtcbiAgICBsZXQga2V5ID0gYCR7bG9hZGVkLmFjY291bnR9LyR7bG9hZGVkLmJ1Y2tldE5hbWV9YDtcbiAgICBsZXQgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBsZXQgc3RhcnRzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgZm9yIChsZXQgc2VsZiBvZiBsb2FkZWQuc2VsZkVudHJpZXMpIHtcbiAgICAgICAgbGV0IHN0YXJ0ID0gc2VsZi52YWxpZFdpbmRvd1swXTtcbiAgICAgICAgaWYgKHN0YXJ0ID4gbm93ICYmIHN0YXJ0IDwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgICAgIHN0YXJ0cy5hZGQoc3RhcnQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEEgd2luZG93IHdlIGhhdmUgb25seSBqdXN0IHRha2VuIG92ZXIsIG9uIGEgc2VydmVyIHRoYXQgaGFzIG9ubHkganVzdCBzdGFydGVkOiB0aGUgYm91bmRhcnkgaGFwcGVuZWQgd2hpbGUgd2Ugd2VyZSBub3QgcnVubmluZywgc28gaXRzIHNjYW4gc3RpbGwgaGFzIHRvIGhhcHBlblxuICAgIGZvciAobGV0IHNlbGYgb2YgbG9hZGVkLnNlbGZFbnRyaWVzKSB7XG4gICAgICAgIGxldCBbc3RhcnQsIGVuZF0gPSBzZWxmLnZhbGlkV2luZG93O1xuICAgICAgICBpZiAoIShzdGFydCA8PSBub3cgJiYgbm93IDwgZW5kKSB8fCBzdGFydCA8PSAwKSBjb250aW51ZTtcbiAgICAgICAgaWYgKG5vdyAtIHN0YXJ0ID4gQk9VTkRBUllfU0NBTl9MT09LQkFDSykgY29udGludWU7XG4gICAgICAgIGxldCBzY2hlZHVsZUtleSA9IGAke2tleX18JHtzdGFydH18c3RhcnR1cGA7XG4gICAgICAgIGlmIChzY2hlZHVsZWRCb3VuZGFyeVNjYW5zLmhhcyhzY2hlZHVsZUtleSkpIGNvbnRpbnVlO1xuICAgICAgICBzY2hlZHVsZWRCb3VuZGFyeVNjYW5zLmFkZChzY2hlZHVsZUtleSk7XG4gICAgICAgIGxldCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdm9pZCBydW5Cb3VuZGFyeVNjYW4obG9hZGVkLCBzdGFydCwgU1RBUlRVUF9CT1VOREFSWV9TQ0FOX0RFTEFZLCBcInN0YXJ0dXArMzBzXCIpLmNhdGNoKChlOiBFcnJvcikgPT4gY29uc29sZS5lcnJvcihgQm91bmRhcnkgc2NhbiBmb3IgYnVja2V0ICR7a2V5fSBmYWlsZWQ6ICR7ZS5zdGFjayA/PyBlfWApKTtcbiAgICAgICAgfSwgU1RBUlRVUF9CT1VOREFSWV9TQ0FOX0RFTEFZKTtcbiAgICAgICAgKHRpbWVyIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgICB9XG4gICAgZm9yIChsZXQgc3RhcnQgb2Ygc3RhcnRzKSB7XG4gICAgICAgIGZvciAobGV0IG9mZnNldCBvZiBCT1VOREFSWV9TQ0FOX09GRlNFVFMpIHtcbiAgICAgICAgICAgIGxldCBhdCA9IHN0YXJ0ICsgb2Zmc2V0O1xuICAgICAgICAgICAgaWYgKGF0IDw9IG5vdykgY29udGludWU7XG4gICAgICAgICAgICBsZXQgc2NoZWR1bGVLZXkgPSBgJHtrZXl9fCR7c3RhcnR9fCR7b2Zmc2V0fWA7XG4gICAgICAgICAgICBpZiAoc2NoZWR1bGVkQm91bmRhcnlTY2Fucy5oYXMoc2NoZWR1bGVLZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIHNjaGVkdWxlZEJvdW5kYXJ5U2NhbnMuYWRkKHNjaGVkdWxlS2V5KTtcbiAgICAgICAgICAgIC8vIFJlLWFybWVkIHJhdGhlciB0aGFuIHRydXN0ZWQ6IGEgbG9uZyB0aW1lciBjYW4gZmlyZSBlYXJseSBhZnRlciBhIHN1c3BlbmQsIGFuZCBmaXJpbmcgZWFybHkgd291bGQgc2NhbiBmb3IgYSBoYW5kb3ZlciB0aGF0IGhhcyBub3QgaGFwcGVuZWRcbiAgICAgICAgICAgIGxldCBhcm0gPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChEYXRlLm5vdygpIDwgYXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFybSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZvaWQgcnVuQm91bmRhcnlTY2FuKGxvYWRlZCwgc3RhcnQsIG9mZnNldCkuY2F0Y2goKGU6IEVycm9yKSA9PiBjb25zb2xlLmVycm9yKGBCb3VuZGFyeSBzY2FuIGZvciBidWNrZXQgJHtrZXl9IGZhaWxlZDogJHtlLnN0YWNrID8/IGV9YCkpO1xuICAgICAgICAgICAgICAgIH0sIE1hdGgubWluKGF0IC0gRGF0ZS5ub3coKSwgTUFYX1RJTUVSX0RFTEFZKSk7XG4gICAgICAgICAgICAgICAgKHRpbWVyIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhcm0oKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqIENvbGxlY3RzIHRoZSB3cml0ZXMgdGhhdCBsYW5kZWQgb24gdGhlIHByZXZpb3VzIHdpbmRvdydzIG93bmVycyBqdXN0IGJlZm9yZSBhIGJvdW5kYXJ5LCBpbnRvIHRoZSBzdG9yZSB0aGF0IGhhcyBqdXN0IHRha2VuIG92ZXIuIFdobyBvd25lZCB3aGF0IGlzIHdvcmtlZCBvdXQgcHVyZWx5IGZyb20gdGhlIGNvbmZpZyAoc2VlIHByZXZpb3VzV2luZG93T3duZXJzKTsgdGhpcyBvbmx5IGRvZXMgdGhlIHB1bGxpbmcuICovXG5hc3luYyBmdW5jdGlvbiBydW5Cb3VuZGFyeVNjYW4obG9hZGVkOiBCdWNrZXRTdGF0ZSwgd2luZG93U3RhcnQ6IG51bWJlciwgb2Zmc2V0OiBudW1iZXIsIG9mZnNldExhYmVsPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IGtleSA9IGAke2xvYWRlZC5hY2NvdW50fS8ke2xvYWRlZC5idWNrZXROYW1lfWA7XG4gICAgbGV0IGxhYmVsID0gYGJ1Y2tldCAke2tleX0sIHdpbmRvdyBzdGFydGluZyAke25ldyBEYXRlKHdpbmRvd1N0YXJ0KS50b0lTT1N0cmluZygpfSwgb2Zmc2V0ICR7b2Zmc2V0TGFiZWwgfHwgYCR7b2Zmc2V0IC8gMTAwMH1zYH1gO1xuICAgIGlmIChib3VuZGFyeVNjYW5zUnVubmluZy5oYXMoa2V5KSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgU2tpcHBpbmcgYm91bmRhcnkgc2NhbiAoJHtsYWJlbH0pOiB0aGUgcHJldmlvdXMgYm91bmRhcnkgc2NhbiBpcyBzdGlsbCBydW5uaW5nYCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgYm91bmRhcnlTY2Fuc1J1bm5pbmcuYWRkKGtleSk7XG4gICAgdHJ5IHtcbiAgICAgICAgbGV0IGVmZmVjdGl2ZSA9IGxvYWRlZC5yb3V0aW5nO1xuICAgICAgICBpZiAoIWVmZmVjdGl2ZSkgcmV0dXJuO1xuICAgICAgICBsZXQgaGFuZG92ZXJzID0gcHJldmlvdXNXaW5kb3dPd25lcnMoZWZmZWN0aXZlLCB3aW5kb3dTdGFydCwgZmluZFNlbGZJbmRleGVzKGVmZmVjdGl2ZSwgbG9hZGVkLmFjY291bnQsIGxvYWRlZC5idWNrZXROYW1lKSk7XG4gICAgICAgIGlmICghaGFuZG92ZXJzLmxlbmd0aCkgcmV0dXJuO1xuICAgICAgICBjb25zb2xlLmxvZyhgQm91bmRhcnkgc2NhbiAoJHtsYWJlbH0pOiAke2hhbmRvdmVycy5sZW5ndGh9IHJvdXRlKHMpIHRha2luZyBvdmVyOiAke2hhbmRvdmVycy5tYXAoeCA9PiBgJHtKU09OLnN0cmluZ2lmeSh4LnJvdXRlKX0gZnJvbSAke3guc2Nhbk93bkRpc2sgJiYgXCJvdXIgb3duIGRpc2tcIiB8fCBcIlwifSR7eC5zY2FuT3duRGlzayAmJiB4LnJlbW90ZXMuc2l6ZSAmJiBcIiArIFwiIHx8IFwiXCJ9JHtbLi4ueC5yZW1vdGVzLmtleXMoKV0ubWFwKGkgPT4gYHNvdXJjZSAke2l9YCkuam9pbihcIiwgXCIpfWApLmpvaW4oXCI7IFwiKX1gKTtcbiAgICAgICAgbGV0IHNpbmNlID0gd2luZG93U3RhcnQgLSBCT1VOREFSWV9TQ0FOX0xPT0tCQUNLO1xuICAgICAgICBmb3IgKGxldCBoYW5kb3ZlciBvZiBoYW5kb3ZlcnMpIHtcbiAgICAgICAgICAgIGxldCBzZWxmU3RvcmUgPSBsb2FkZWQuc3RvcmVzLmZpbmQoeCA9PiB4Lm5hbWUgPT09IGhhbmRvdmVyLm5hbWUpO1xuICAgICAgICAgICAgaWYgKCFzZWxmU3RvcmUpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKGhhbmRvdmVyLnNjYW5Pd25EaXNrKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgc2VsZlN0b3JlLnN0b3JlLnJlc2NhbkJhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IFtzb3VyY2VJbmRleCwgcm91dGVdIG9mIGhhbmRvdmVyLnJlbW90ZXMpIHtcbiAgICAgICAgICAgICAgICBsZXQgb3duZXJTb3VyY2UgPSBlZmZlY3RpdmUuc291cmNlc1tzb3VyY2VJbmRleF07XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvd25lclNvdXJjZSA9PT0gXCJzdHJpbmdcIikgY29udGludWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgc2VsZlN0b3JlLnN0b3JlLmJvdW5kYXJ5U2NhblJlbW90ZShjcmVhdGVBcGlBcmNoaXZlcyhvd25lclNvdXJjZSksIHsgc2luY2UsIHJvdXRlIH0pO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQm91bmRhcnkgc2NhbiAoJHtsYWJlbH0pIG9mIHByZXZpb3VzLXdpbmRvdyBvd25lciAoc291cmNlIGluZGV4ICR7c291cmNlSW5kZXh9KSBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYm91bmRhcnlTY2Fuc1J1bm5pbmcuZGVsZXRlKGtleSk7XG4gICAgfVxufVxuXG4vKiogQW4gb3BlcmF0b3IncyBjb25maWcga25vd3Mgbm90aGluZyBhYm91dCBhIHN3aXRjaG92ZXIgdGhhdCBpcyBpbiBmbGlnaHQgcmlnaHQgbm93LCBzbyB3cml0aW5nIGl0IGFzLWlzIHdvdWxkIGNhbmNlbCBvbmUgbWlkLWhhbmRvdmVyLiBUaGUgaW4tZmxpZ2h0IHdpbmRvd3MgYXJlIHB1dCBiYWNrIGludG8gaXQgZmlyc3QuICovXG5leHBvcnQgZnVuY3Rpb24gcmVpbmplY3RJbnRlcm1lZGlhdGVzKGN1cnJlbnQ6IFJlbW90ZUNvbmZpZyB8IHVuZGVmaW5lZCwgaW5jb21pbmc6IFJlbW90ZUNvbmZpZyk6IFJlbW90ZUNvbmZpZyB7XG4gICAgaWYgKCFjdXJyZW50KSByZXR1cm4gaW5jb21pbmc7XG4gICAgbGV0IHN0b3JlZCA9IGluY29taW5nO1xuICAgIGxldCByZWluamVjdGVkID0gMDtcbiAgICBmb3IgKGxldCBpbnRlcm1lZGlhdGUgb2YgZ2V0SW50ZXJtZWRpYXRlU291cmNlcyhleHBpcmVJbnRlcm1lZGlhdGVTb3VyY2VzKGN1cnJlbnQsIERhdGUubm93KCkpKSkge1xuICAgICAgICBzdG9yZWQgPSBpbmplY3RJbnRlcm1lZGlhdGVTb3VyY2Uoc3RvcmVkLCB7XG4gICAgICAgICAgICBzcGxpdFVybDogaW50ZXJtZWRpYXRlLmludGVybWVkaWF0ZSB8fCBpbnRlcm1lZGlhdGUudXJsLFxuICAgICAgICAgICAgaW50ZXJtZWRpYXRlVXJsOiBpbnRlcm1lZGlhdGUudXJsLFxuICAgICAgICAgICAgc3RhcnQ6IGludGVybWVkaWF0ZS52YWxpZFdpbmRvd1swXSxcbiAgICAgICAgICAgIGVuZDogaW50ZXJtZWRpYXRlLnZhbGlkV2luZG93WzFdLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVpbmplY3RlZCsrO1xuICAgIH1cbiAgICBpZiAocmVpbmplY3RlZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgUmUtaW5qZWN0ZWQgJHtyZWluamVjdGVkfSBpbi1mbGlnaHQgc3dpdGNob3ZlciB3aW5kb3cocykgaW50byBhbiBpbmNvbWluZyByb3V0aW5nIGNvbmZpZyAodmVyc2lvbiAke2dldENvbmZpZ1ZlcnNpb24oaW5jb21pbmcpfSlgKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0b3JlZDtcbn1cblxuLy8gUGVyIGJ1Y2tldCwgbm90IGdsb2JhbDogYSBzd2l0Y2hvdmVyIGhhcyB0byB3cml0ZSBldmVyeSBidWNrZXQncyB3aW5kb3dzIGF0IG9uY2UsIGFuZCBhIHNoYXJlZCB0aHJvdHRsZSB3b3VsZCBsZXQgb25seSBvbmUgYnVja2V0IHRocm91Z2ggcGVyIGludGVydmFsXG5jb25zdCBsYXN0T3duQ29uZmlnV3JpdGUgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG5hc3luYyBmdW5jdGlvbiB3cml0ZU93blJvdXRpbmdDb25maWcobG9hZGVkOiBCdWNrZXRTdGF0ZSwgdXBkYXRlZDogUmVtb3RlQ29uZmlnLCByZWFzb246IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCBrZXkgPSBgJHtsb2FkZWQuYWNjb3VudH0vJHtsb2FkZWQuYnVja2V0TmFtZX1gO1xuICAgIGxldCBzaW5jZUxhc3QgPSBEYXRlLm5vdygpIC0gKGxhc3RPd25Db25maWdXcml0ZS5nZXQoa2V5KSB8fCAwKTtcbiAgICBpZiAoc2luY2VMYXN0IDwgT1dOX0NPTkZJR19XUklURV9USFJPVFRMRSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgTm90IHdyaXRpbmcgb3VyIG93biByb3V0aW5nIGNvbmZpZyB1cGRhdGUgZm9yIGJ1Y2tldCAke2tleX0gKCR7cmVhc29ufSk6IHRoZSBsYXN0IG9uZSB3YXMgJHtzaW5jZUxhc3R9bXMgYWdvLCB1bmRlciB0aGUgJHtPV05fQ09ORklHX1dSSVRFX1RIUk9UVExFfW1zIHRocm90dGxlLiBSZXRyeWluZyBvbiB0aGUgbmV4dCBtYWludGVuYW5jZSBwYXNzLmApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGxhc3RPd25Db25maWdXcml0ZS5zZXQoa2V5LCBEYXRlLm5vdygpKTtcbiAgICAvLyBBIHN3aXRjaG92ZXIgd3JpdGVzIG9uIHRvcCBvZiB3aGF0ZXZlciB0aGUgYnVja2V0IGlzIHJ1bm5pbmc7IHdpdGggbm8gY29uZmlnIGF0IGFsbCB0aGVyZSBpcyBub3RoaW5nIHRvIHN3aXRjaCBvdmVyXG4gICAgaWYgKCFsb2FkZWQucm91dGluZykgcmV0dXJuO1xuICAgIGxldCBjdXJyZW50VmVyc2lvbiA9IGdldENvbmZpZ1ZlcnNpb24obG9hZGVkLnJvdXRpbmcpO1xuICAgIGxldCB2ZXJzaW9uID0gbmV4dEludGVybWVkaWF0ZVZlcnNpb24oY3VycmVudFZlcnNpb24pO1xuICAgIGxldCBuZXh0OiBSZW1vdGVDb25maWcgPSB7IC4uLnVwZGF0ZWQsIHZlcnNpb24gfTtcbiAgICBjb25zb2xlLmxvZyhgV3JpdGluZyAke1JPVVRJTkdfRklMRX0gZm9yIGJ1Y2tldCAke2tleX0gKCR7cmVhc29ufSksIHZlcnNpb24gJHtjdXJyZW50VmVyc2lvbn0gLT4gJHt2ZXJzaW9ufTogJHtKU09OLnN0cmluZ2lmeShuZXh0KX1gKTtcbiAgICBsZXQgZGF0YSA9IEJ1ZmZlci5mcm9tKHNlcmlhbGl6ZVJlbW90ZUNvbmZpZyhuZXh0KSk7XG4gICAgLy8gSW50byBvbmUgb2Ygb3VyIG93biBzdG9yZXMgLSBpdCBhcHBsaWVzIGl0IGFuZCBpdHMgcGVlcnMgcHVsbCBpdCAtIGFuZCBkaXJlY3RseSB0byB0aGUgb3RoZXIgc2VydmVycywgd2hpY2ggaXMgd2hhdCBtYWtlcyBhIHN3aXRjaG92ZXIgdGFrZSBlZmZlY3QgaW4gc2Vjb25kcyByYXRoZXIgdGhhbiBhdCB0aGUgbmV4dCBwb2xsXG4gICAgbGV0IG91clN0b3JlID0gbG9hZGVkLnN0b3Jlc1swXTtcbiAgICBpZiAob3VyU3RvcmUpIHtcbiAgICAgICAgYXdhaXQgd3JpdGVSb3V0aW5nQ29uZmlnKGxvYWRlZC5hY2NvdW50LCBsb2FkZWQuYnVja2V0TmFtZSwgb3VyU3RvcmUubmFtZSwgZGF0YSk7XG4gICAgfVxuICAgIGF3YWl0IHByb3BhZ2F0ZVJvdXRpbmdDb25maWcobG9hZGVkLCBuZXh0LCBkYXRhKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcHJvcGFnYXRlUm91dGluZ0NvbmZpZyhsb2FkZWQ6IEJ1Y2tldFN0YXRlLCBuZXh0OiBSZW1vdGVDb25maWcsIGRhdGE6IEJ1ZmZlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCB0YXJnZXRzID0gbmV3IE1hcDxzdHJpbmcsIFNvdXJjZUNvbmZpZz4oKTtcbiAgICBmb3IgKGxldCBzb3VyY2Ugb2YgWy4uLmxvYWRlZC5yb3V0aW5nPy5zb3VyY2VzIHx8IFtdLCAuLi5uZXh0LnNvdXJjZXNdKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc291cmNlID09PSBcInN0cmluZ1wiIHx8IHNvdXJjZS5pbnRlcm1lZGlhdGUpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoc291cmNlLnR5cGUgPT09IFwicmVtb3RlXCIpIHtcbiAgICAgICAgICAgIGxldCBwYXJzZWQgPSBwYXJzZUhvc3RlZFVybChzb3VyY2UudXJsKTtcbiAgICAgICAgICAgIGlmIChwYXJzZWQuYWNjb3VudCAhPT0gbG9hZGVkLmFjY291bnQgfHwgcGFyc2VkLmJ1Y2tldE5hbWUgIT09IGxvYWRlZC5idWNrZXROYW1lKSBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGFyZ2V0cy5oYXMoc291cmNlLnVybCkpIGNvbnRpbnVlO1xuICAgICAgICB0YXJnZXRzLnNldChzb3VyY2UudXJsLCBzb3VyY2UpO1xuICAgIH1cbiAgICBmb3IgKGxldCBbdXJsLCBzb3VyY2VdIG9mIHRhcmdldHMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGNyZWF0ZUFwaUFyY2hpdmVzKHNvdXJjZSkuc2V0KFJPVVRJTkdfRklMRSwgZGF0YSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgV3JvdGUgJHtST1VUSU5HX0ZJTEV9IGZvciBidWNrZXQgJHtsb2FkZWQuYWNjb3VudH0vJHtsb2FkZWQuYnVja2V0TmFtZX0gdG8gJHt1cmx9YCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFByb3BhZ2F0aW5nIG91ciByb3V0aW5nIGNvbmZpZyB1cGRhdGUgdG8gJHt1cmx9IGZhaWxlZDogJHsoZSBhcyBFcnJvcikuc3RhY2sgPz8gZX1gKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqIEtlZXBzIGV2ZXJ5IGxvYWRlZCBidWNrZXQncyBzd2l0Y2hvdmVyIHdpbmRvd3MgY3VycmVudDogZ2l2ZXMgb3VyIGFsdGVybmF0ZSBwb3J0IGl0cyB3aW5kb3cgd2hpbGUgYSB0YWtlb3ZlciBpcyBpbiBmbGlnaHQsIGFuZCB0YWtlcyBleHBpcmVkIG9uZXMgYmFjayBvdXQuICovXG5hc3luYyBmdW5jdGlvbiBtYWludGFpbkludGVybWVkaWF0ZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IHsgZG9tYWluLCBwb3J0IH0gPSBnZXRTdG9yYWdlU2VydmVyQ29uZmlnKCk7XG4gICAgbGV0IHRha2VvdmVyID0gZ2V0VGFrZW92ZXJJbnRlcm1lZGlhdGUoKTtcbiAgICBsZXQgd3JpdHRlbjogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgYWxyZWFkeUNvcnJlY3Q6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IG5vdE91cnM6IHN0cmluZ1tdID0gW107XG4gICAgLy8gT05MWSBidWNrZXRzIGFscmVhZHkgaW4gbWVtb3J5LiBBIHN3aXRjaG92ZXIgbXVzdCBuZXZlciBsb2FkIGEgYnVja2V0OiBsb2FkaW5nIHN0YXJ0cyBpdHMgc3luY2hyb25pemF0aW9uLCBhbmQgYnVja2V0cyBub3RoaW5nIGhhcyB0b3VjaGVkIChsZWdhY3kgb25lcyBlc3BlY2lhbGx5KSBoYXZlIG5vIHdyaXRlcyB0byBoYW5kIG9mZiBpbiB0aGUgZmlyc3QgcGxhY2UuIE9uZSB0aGF0IGRvZXMgZ2V0IHVzZWQgbWlkLXN3aXRjaG92ZXIgbG9hZHMgb24gdGhhdCBhY2Nlc3MsIGFuZCB0aGUgbmV4dCBwYXNzIGdpdmVzIGl0IGl0cyB3aW5kb3cuXG4gICAgbGV0IHN0YXRlcyA9IGdldEJ1Y2tldFN0YXRlcygpO1xuICAgIGZvciAobGV0IGxvYWRlZCBvZiBzdGF0ZXMpIHtcbiAgICAgICAgbGV0IGtleSA9IGAke2xvYWRlZC5hY2NvdW50fS8ke2xvYWRlZC5idWNrZXROYW1lfWA7XG4gICAgICAgIGxldCByb3V0aW5nID0gbG9hZGVkLnJvdXRpbmc7XG4gICAgICAgIGlmICghcm91dGluZykgY29udGludWU7XG4gICAgICAgIGxldCBleHBpcmVkID0gZXhwaXJlSW50ZXJtZWRpYXRlU291cmNlcyhyb3V0aW5nLCBEYXRlLm5vdygpKTtcbiAgICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KGV4cGlyZWQpICE9PSBKU09OLnN0cmluZ2lmeShyb3V0aW5nKSkge1xuICAgICAgICAgICAgYXdhaXQgd3JpdGVPd25Sb3V0aW5nQ29uZmlnKGxvYWRlZCwgZXhwaXJlZCwgYHN3aXRjaG92ZXIgd2luZG93cyBleHBpcmVkIG1vcmUgdGhhbiAke0lOVEVSTUVESUFURV9FWFBJUkVfR1JBQ0UgLyAxMDAwfXMgYWdvYCk7XG4gICAgICAgICAgICB3cml0dGVuLnB1c2goa2V5KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGFrZW92ZXIpIGNvbnRpbnVlO1xuICAgICAgICBsZXQgbWFpblVybCA9IHJvdXRpbmcuc291cmNlcy5maW5kKHggPT4ge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB4ID09PSBcInN0cmluZ1wiIHx8IHgudHlwZSAhPT0gXCJyZW1vdGVcIiB8fCB4LmludGVybWVkaWF0ZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgbGV0IHBhcnNlZCA9IHBhcnNlSG9zdGVkVXJsKHgudXJsKTtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZWQuYWRkcmVzcyA9PT0gZG9tYWluICYmIHBhcnNlZC5wb3J0ID09PSBwb3J0O1xuICAgICAgICB9KSBhcyBIb3N0ZWRDb25maWcgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmICghbWFpblVybCkge1xuICAgICAgICAgICAgbm90T3Vycy5wdXNoKGtleSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgaW5qZWN0ZWQgPSBpbmplY3RJbnRlcm1lZGlhdGVTb3VyY2Uocm91dGluZywge1xuICAgICAgICAgICAgc3BsaXRVcmw6IG1haW5VcmwudXJsLFxuICAgICAgICAgICAgaW50ZXJtZWRpYXRlVXJsOiByZXBsYWNlSG9zdGVkVXJsUG9ydChtYWluVXJsLnVybCwgdGFrZW92ZXIuYWx0UG9ydCksXG4gICAgICAgICAgICBzdGFydDogdGFrZW92ZXIuc3RhcnQsXG4gICAgICAgICAgICBlbmQ6IHRha2VvdmVyLmVuZCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChKU09OLnN0cmluZ2lmeShpbmplY3RlZCkgPT09IEpTT04uc3RyaW5naWZ5KHJvdXRpbmcpKSB7XG4gICAgICAgICAgICBhbHJlYWR5Q29ycmVjdC5wdXNoKGtleSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB3cml0ZU93blJvdXRpbmdDb25maWcobG9hZGVkLCBpbmplY3RlZCwgYHdlIGFyZSBhIGRlcGxveSBzdWNjZXNzb3I6IHdyaXRlcyByb3V0ZSB0byBvdXIgYWx0ZXJuYXRlIHBvcnQgJHt0YWtlb3Zlci5hbHRQb3J0fSBmcm9tICR7bmV3IERhdGUodGFrZW92ZXIuc3RhcnQpLnRvSVNPU3RyaW5nKCl9IHVudGlsIG91ciBwcmVkZWNlc3NvciBpcyBraWxsZWQgYXQgJHtuZXcgRGF0ZSh0YWtlb3Zlci5lbmQpLnRvSVNPU3RyaW5nKCl9YCk7XG4gICAgICAgIHdyaXR0ZW4ucHVzaChrZXkpO1xuICAgIH1cbiAgICBpZiAoIXRha2VvdmVyKSByZXR1cm47XG4gICAgaWYgKCFzdGF0ZXMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBObyBhY3RpdmUgYnVja2V0cywgc28gbm8gY29uZmlnIGZpbGVzIHRvIHdyaXRlIHRoZSBpbnRlcm1lZGlhdGUgaW50byAoYSBidWNrZXQgaXMgb25seSBhY3RpdmUgb25jZSBzb21ldGhpbmcgdXNlcyBpdClgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXdyaXR0ZW4ubGVuZ3RoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBXcm90ZSBubyBjb25maWcgZmlsZXM6IG9mICR7c3RhdGVzLmxlbmd0aH0gYWN0aXZlIGJ1Y2tldHMsICR7YWxyZWFkeUNvcnJlY3QubGVuZ3RofSBhbHJlYWR5IGNvbnRhaW4gdGhlIGludGVybWVkaWF0ZSBhbmQgJHtub3RPdXJzLmxlbmd0aH0gYXJlIG5vdCBob3N0ZWQgYnkgdXNgKTtcbiAgICB9XG59XG5cbi8qKiBPdXIgcHJlZGVjZXNzb3Igc3RpbGwgaG9sZHMgdGhlIG1haW4gcG9ydCBhbmQgaGFzIGJlZW4gc2VydmluZyBhbGwgYWxvbmcsIHNvIGl0IC0gbm90IHVzIC0ga25vd3Mgd2hpY2ggYnVja2V0cyBhcmUgaW4gdXNlLiBXZSBhY3RpdmF0ZSBleGFjdGx5IHRob3NlLCB3aGljaCBpcyB3aGF0IG1ha2VzIHRoZWlyIGNvbmZpZyBmaWxlcyBnZXQgdGhlIGludGVybWVkaWF0ZTsgbm90aGluZyBlbHNlIG9uIGRpc2sgaXMgdG91Y2hlZC4gKi9cbmFzeW5jIGZ1bmN0aW9uIGFjdGl2YXRlUHJlZGVjZXNzb3JCdWNrZXRzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCB7IGRvbWFpbiwgcG9ydCB9ID0gZ2V0U3RvcmFnZVNlcnZlckNvbmZpZygpO1xuICAgIGxldCB1cmwgPSBgaHR0cHM6Ly8ke2RvbWFpbn06JHtwb3J0fWA7XG4gICAgbGV0IGtleXM6IHsgYWNjb3VudDogc3RyaW5nOyBidWNrZXROYW1lOiBzdHJpbmcgfVtdO1xuICAgIHRyeSB7XG4gICAgICAgIGtleXMgPSBhd2FpdCBsaXN0U2VydmVyQWN0aXZlQnVja2V0S2V5cyh7IHVybCB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYENvdWxkIG5vdCBhc2sgb3VyIHByZWRlY2Vzc29yIG9uICR7dXJsfSB3aGljaCBidWNrZXRzIGFyZSBhY3RpdmUsIHNvIG9ubHkgYnVja2V0cyB1c2VkIG9uIHRoaXMgcHJvY2VzcyBnZXQgdGhlIGludGVybWVkaWF0ZTogJHsoZSBhcyBFcnJvcikuc3RhY2sgPz8gZX1gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIWtleXMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBPdXIgcHJlZGVjZXNzb3Igb24gJHt1cmx9IGhhcyBubyBhY3RpdmUgYnVja2V0cywgc28gdGhlcmUgYXJlIG5vIGNvbmZpZyBmaWxlcyB0byB3cml0ZSB0aGUgaW50ZXJtZWRpYXRlIGludG9gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhgT3VyIHByZWRlY2Vzc29yIG9uICR7dXJsfSBoYXMgJHtrZXlzLmxlbmd0aH0gYWN0aXZlIGJ1Y2tldHMsIGFjdGl2YXRpbmcgdGhlbSBoZXJlIHNvIHRoZWlyIGNvbmZpZyBmaWxlcyBnZXQgdGhlIGludGVybWVkaWF0ZTogJHtrZXlzLm1hcCh4ID0+IGAke3guYWNjb3VudH0vJHt4LmJ1Y2tldE5hbWV9YCkuam9pbihcIiwgXCIpfWApO1xuICAgIGZvciAobGV0IHsgYWNjb3VudCwgYnVja2V0TmFtZSB9IG9mIGtleXMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGdldExvYWRlZEJ1Y2tldChhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQWN0aXZhdGluZyBidWNrZXQgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9IChhY3RpdmUgb24gb3VyIHByZWRlY2Vzc29yKSBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKiBTdGFydGVkIGJ5IGRlcGxveVRha2VvdmVyIG9uY2Ugd2UgYXJlIGFjdHVhbGx5IGEgZGVwbG95IHN1Y2Nlc3NvciBsaXN0ZW5pbmcgb24gYW4gYWx0ZXJuYXRlIHBvcnQuIFVudGlsIHRoZW4gdGhlcmUgYXJlIG5vIHN3aXRjaG92ZXIgd2luZG93cyB0byB3cml0ZSBvciBleHBpcmUsIHNvIG5vdGhpbmcgcG9sbHMuICovXG5leHBvcnQgY29uc3Qgc3RhcnRJbnRlcm1lZGlhdGVNYWludGVuYW5jZSA9IGxhenkoKCkgPT4ge1xuICAgIHZvaWQgKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgYWN0aXZhdGVQcmVkZWNlc3NvckJ1Y2tldHMoKTtcbiAgICAgICAgYXdhaXQgbWFpbnRhaW5JbnRlcm1lZGlhdGVzKCk7XG4gICAgfSkoKS5jYXRjaCgoZTogRXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoYFdyaXRpbmcgdGhlIGludGVybWVkaWF0ZSBpbnRvIHRoZSBjb25maWcgZmlsZXMgZmFpbGVkOiAke2Uuc3RhY2sgPz8gZX1gKSk7XG4gICAgcnVuSW5maW5pdGVQb2xsKElOVEVSTUVESUFURV9NQUlOVEFJTl9JTlRFUlZBTCwgbWFpbnRhaW5JbnRlcm1lZGlhdGVzKTtcbn0pO1xuIl19
286
- /* _JS_SOURCE_HASH = "7bbb52afe3a16abf19ef19720f1016edefc4895af6e118ddb8394d7ff8996a1a"; */
291
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJtZWRpYXRlTWFuYWdlbWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImludGVybWVkaWF0ZU1hbmFnZW1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseURBQW1EO0FBQ25ELDJEQUErRDtBQUUvRCxpREFBK0k7QUFDL0ksK0RBQXdLO0FBQ3hLLHFEQUEyRDtBQUMzRCxpREFBd0Q7QUFDeEQscURBQWlGO0FBQ2pGLDJDQUFvRTtBQUNwRSw2REFBeUc7QUFDekcsNkNBQTBFO0FBQzFFLHVEQUE2RDtBQUM3RCwyQ0FBc0Q7QUFFdEQsb2RBQW9kO0FBRXBkLE1BQU0sZUFBZSxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQztBQUM3Qiw4SkFBOEo7QUFDOUosTUFBTSxxQkFBcUIsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsSUFBSSxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUNoRSxzSEFBc0g7QUFDdEgsTUFBTSxzQkFBc0IsR0FBRywwQ0FBd0IsR0FBRyxtQ0FBdUIsQ0FBQztBQUNsRixNQUFNLDJCQUEyQixHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDOUMsTUFBTSx5QkFBeUIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQzVDLE1BQU0sOEJBQThCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUVqRCxNQUFNLHNCQUFzQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7QUFDakQsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0FBRS9DLGtTQUFrUztBQUNsUyxTQUFnQixvQkFBb0IsQ0FBQyxPQUFlLEVBQUUsVUFBa0IsRUFBRSxPQUFxQjs7SUFDM0YsSUFBSSxHQUFHLEdBQUcsR0FBRyxPQUFPLElBQUksVUFBVSxFQUFFLENBQUM7SUFDckMsSUFBSSxXQUFXLEdB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QUFDLEtBQUssQ0FBQywwREFBMEQsTUFBQSxDQUFDLENBQUMsS0FBSyxtQ0FBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBLEVBQUEsQ0FBQyxDQUFDO0lBQ2xILElBQUEsMEJBQWUsRUFBQyw4QkFBOEIsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0FBQzNFLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbGF6eSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2NhY2hpbmdcIjtcbmltcG9ydCB7IHJ1bkluZmluaXRlUG9sbCB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2JhdGNoaW5nXCI7XG5pbXBvcnQgeyBSZW1vdGVDb25maWcsIFNvdXJjZUNvbmZpZywgSG9zdGVkQ29uZmlnIH0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHsgUk9VVElOR19GSUxFLCBnZXRDb25maWdWZXJzaW9uLCBzZXJpYWxpemVSZW1vdGVDb25maWcsIHBhcnNlUm91dGluZ0RhdGEsIHBhcnNlSG9zdGVkVXJsLCByZXBsYWNlSG9zdGVkVXJsUG9ydCB9IGZyb20gXCIuL3JlbW90ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgaW5qZWN0SW50ZXJtZWRpYXRlU291cmNlLCBleHBpcmVJbnRlcm1lZGlhdGVTb3VyY2VzLCBnZXRJbnRlcm1lZGlhdGVTb3VyY2VzLCBuZXh0SW50ZXJtZWRpYXRlVmVyc2lvbiwgSU5URVJNRURJQVRFX0VYUElSRV9HUkFDRSB9IGZyb20gXCIuL2ludGVybWVkaWF0ZVNvdXJjZXNcIjtcbmltcG9ydCB7IGdldFRha2VvdmVySW50ZXJtZWRpYXRlIH0gZnJvbSBcIi4vZGVwbG95VGFrZW92ZXJcIjtcbmltcG9ydCB7IGdldFN0b3JhZ2VTZXJ2ZXJDb25maWcgfSBmcm9tIFwiLi9zZXJ2ZXJDb25maWdcIjtcbmltcG9ydCB7IGNyZWF0ZUFwaUFyY2hpdmVzLCBsaXN0U2VydmVyQWN0aXZlQnVja2V0S2V5cyB9IGZyb20gXCIuL2NyZWF0ZUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBmaW5kU2VsZkluZGV4ZXMsIHByZXZpb3VzV2luZG93T3duZXJzIH0gZnJvbSBcIi4vc3RvcmVQbGFuXCI7XG5pbXBvcnQgeyBnZXRBY3RpdmVCdWNrZXRLZXlzLCBnZXRTdG9yZSwgYWN0aXZhdGVCdWNrZXQsIHdyaXRlUm91dGluZ0NvbmZpZyB9IGZyb20gXCIuL3N0b3JhZ2VTZXJ2ZXJTdGF0ZVwiO1xuaW1wb3J0IHsgcmVhZFJvdXRpbmdGcm9tRGlzaywgcmVhZE5ld2VzdFJvdXRpbmdGaWxlIH0gZnJvbSBcIi4vYnVja2V0RGlza1wiO1xuaW1wb3J0IHsgREVGQVVMVF9GQVNUX1dSSVRFX0RFTEFZIH0gZnJvbSBcIi4vQXJjaGl2ZXNEZWxheWVkXCI7XG5pbXBvcnQgeyBXSU5ET1dfRU5EX0ZMVVNIX01BUkdJTiB9IGZyb20gXCIuL2Jsb2JTdG9yZVwiO1xuXG4vLyBEZXBsb3kgc3dpdGNob3ZlcnMsIGFuZCB0aGUgaGFuZG92ZXJzIHRoZXkgY2F1c2UuIEEgc3dpdGNob3ZlciBpcyBhIHNvdXJjZSBtb3ZpbmcgdG8gYSBuZXcgcG9ydCBmb3IgYSBmZXcgbWludXRlczogd2UgZ2l2ZSBpdCBhIHZpcnR1YWwgdmFsaWQgd2luZG93IG9uIHRoYXQgcG9ydCAoYW4gXCJpbnRlcm1lZGlhdGVcIiksIHdoaWNoIG1lYW5zIHRoZSB3cml0ZSB0YXJnZXQgY2hhbmdlcyB0d2ljZSBpbiBxdWljayBzdWNjZXNzaW9uLCB3aGljaCBtZWFucyB0aGUgc3RvcmUgdGFraW5nIG92ZXIgaGFzIHRvIGdvIGFuZCBjb2xsZWN0IHRoZSB3cml0ZXMgdGhhdCBsYW5kZWQganVzdCBiZWZvcmUgaXQgZGlkLiBOb25lIG9mIHRoYXQgaXMgc3RvcmFnZSAtIGl0IGlzIHNjaGVkdWxpbmcgLSBzbyBpdCBsaXZlcyBoZXJlIHJhdGhlciB0aGFuIGluIHRoZSBzdG9yZSBvciBpbiB0aGUgc2VydmVyJ3MgYnVja2V0IHN0YXRlLlxuXG5jb25zdCBNQVhfVElNRVJfREVMQVkgPSAyICoqIDMxIC0gMTtcbmNvbnN0IEJPVU5EQVJZX0JVRkZFUiA9IDEwMDA7XG4vLyBBIGhhbmRvdmVyIGlzIHNjYW5uZWQganVzdCBiZWZvcmUgdGhlIGJvdW5kYXJ5LCBqdXN0IGFmdGVyLCBhbmQgYWdhaW4gYSBsaXR0bGUgbGF0ZXIgLSB0aGUgbGFzdCB3cml0ZXMgdG8gdGhlIG9sZCB0YXJnZXQgY2FuIGxhbmQgYWZ0ZXIgdGhlIGJvdW5kYXJ5IGl0c2VsZlxuY29uc3QgQk9VTkRBUllfU0NBTl9PRkZTRVRTID0gWy0zMCAqIDEwMDAsIDIgKiAxMDAwLCAzMCAqIDEwMDBdO1xuLy8gSG93IGZhciBiYWNrIGEgYm91bmRhcnkgc2NhbiBhc2tzIGZvciBjaGFuZ2VzOiBldmVyeXRoaW5nIHRoYXQgY291bGQgc3RpbGwgaGF2ZSBiZWVuIGJ1ZmZlcmVkIHdoZW4gdGhlIHdpbmRvdyBlbmRlZFxuY29uc3QgQk9VTkRBUllfU0NBTl9MT09LQkFDSyA9IERFRkFVTFRfRkFTVF9XUklURV9ERUxBWSArIFdJTkRPV19FTkRfRkxVU0hfTUFSR0lOO1xuY29uc3QgU1RBUlRVUF9CT1VOREFSWV9TQ0FOX0RFTEFZID0gMzAgKiAxMDAwO1xuY29uc3QgT1dOX0NPTkZJR19XUklURV9USFJPVFRMRSA9IDMwICogMTAwMDtcbmNvbnN0IElOVEVSTUVESUFURV9NQUlOVEFJTl9JTlRFUlZBTCA9IDYwICogMTAwMDtcblxuY29uc3Qgc2NoZWR1bGVkQm91bmRhcnlTY2FucyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuY29uc3QgYm91bmRhcnlTY2Fuc1J1bm5pbmcgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuLyoqIENhbGxlZCBldmVyeSB0aW1lIGEgc3RvcmUgYXBwbGllcyBhIHJvdXRpbmcgY29uZmlnIHRvIGl0c2VsZiAoc2VlIEJsb2JTdG9yZSdzIG9uUm91dGluZ0FwcGxpZWQpOiBhcm1zIHRoZSBzY2FucyB0aGUgY29uZmlnJ3MgdXBjb21pbmcgd2luZG93IGJvdW5kYXJpZXMgbmVlZC4gRWFjaCBzY2FuIGlzIHNjaGVkdWxlZCBvbmNlIC0gdGhlIGtleSBpbmNsdWRlcyB0aGUgYm91bmRhcnkgaXQgaXMgZm9yIC0gc28gcmUtYXJtaW5nIG9uIGV2ZXJ5IGNvbmZpZyBhcHBsaWNhdGlvbiBpcyBoYXJtbGVzcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzY2hlZHVsZUJvdW5kYXJ5V29yayhhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgcm91dGluZzogUmVtb3RlQ29uZmlnKTogdm9pZCB7XG4gICAgbGV0IGtleSA9IGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gO1xuICAgIGxldCBzZWxmRW50cmllcyA9IGZpbmRTZWxmSW5kZXhlcyhyb3V0aW5nLCBhY2NvdW50LCBidWNrZXROYW1lKS5tYXAoaSA9PiByb3V0aW5nLnNvdXJjZXNbaV0gYXMgSG9zdGVkQ29uZmlnKTtcbiAgICBsZXQgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBsZXQgc3RhcnRzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgZm9yIChsZXQgc2VsZiBvZiBzZWxmRW50cmllcykge1xuICAgICAgICBsZXQgc3RhcnQgPSBzZWxmLnZhbGlkV2luZG93WzBdO1xuICAgICAgICBpZiAoc3RhcnQgPiBub3cgJiYgc3RhcnQgPCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUikge1xuICAgICAgICAgICAgc3RhcnRzLmFkZChzdGFydCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gQSB3aW5kb3cgd2UgaGF2ZSBvbmx5IGp1c3QgdGFrZW4gb3Zlciwgb24gYSBzZXJ2ZXIgdGhhdCBoYXMgb25seSBqdXN0IHN0YXJ0ZWQ6IHRoZSBib3VuZGFyeSBoYXBwZW5lZCB3aGlsZSB3ZSB3ZXJlIG5vdCBydW5uaW5nLCBzbyBpdHMgc2NhbiBzdGlsbCBoYXMgdG8gaGFwcGVuXG4gICAgZm9yIChsZXQgc2VsZiBvZiBzZWxmRW50cmllcykge1xuICAgICAgICBsZXQgW3N0YXJ0LCBlbmRdID0gc2VsZi52YWxpZFdpbmRvdztcbiAgICAgICAgaWYgKCEoc3RhcnQgPD0gbm93ICYmIG5vdyA8IGVuZCkgfHwgc3RhcnQgPD0gMCkgY29udGludWU7XG4gICAgICAgIGlmIChub3cgLSBzdGFydCA+IEJPVU5EQVJZX1NDQU5fTE9PS0JBQ0spIGNvbnRpbnVlO1xuICAgICAgICBsZXQgc2NoZWR1bGVLZXkgPSBgJHtrZXl9fCR7c3RhcnR9fHN0YXJ0dXBgO1xuICAgICAgICBpZiAoc2NoZWR1bGVkQm91bmRhcnlTY2Fucy5oYXMoc2NoZWR1bGVLZXkpKSBjb250aW51ZTtcbiAgICAgICAgc2NoZWR1bGVkQm91bmRhcnlTY2Fucy5hZGQoc2NoZWR1bGVLZXkpO1xuICAgICAgICBsZXQgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHZvaWQgcnVuQm91bmRhcnlTY2FuKGFjY291bnQsIGJ1Y2tldE5hbWUsIHN0YXJ0LCBTVEFSVFVQX0JPVU5EQVJZX1NDQU5fREVMQVksIFwic3RhcnR1cCszMHNcIikuY2F0Y2goKGU6IEVycm9yKSA9PiBjb25zb2xlLmVycm9yKGBCb3VuZGFyeSBzY2FuIGZvciBidWNrZXQgJHtrZXl9IGZhaWxlZDogJHtlLnN0YWNrID8/IGV9YCkpO1xuICAgICAgICB9LCBTVEFSVFVQX0JPVU5EQVJZX1NDQU5fREVMQVkpO1xuICAgICAgICAodGltZXIgYXMgeyB1bnJlZj86ICgpID0+IHZvaWQgfSkudW5yZWY/LigpO1xuICAgIH1cbiAgICBmb3IgKGxldCBzdGFydCBvZiBzdGFydHMpIHtcbiAgICAgICAgZm9yIChsZXQgb2Zmc2V0IG9mIEJPVU5EQVJZX1NDQU5fT0ZGU0VUUykge1xuICAgICAgICAgICAgbGV0IGF0ID0gc3RhcnQgKyBvZmZzZXQ7XG4gICAgICAgICAgICBpZiAoYXQgPD0gbm93KSBjb250aW51ZTtcbiAgICAgICAgICAgIGxldCBzY2hlZHVsZUtleSA9IGAke2tleX18JHtzdGFydH18JHtvZmZzZXR9YDtcbiAgICAgICAgICAgIGlmIChzY2hlZHVsZWRCb3VuZGFyeVNjYW5zLmhhcyhzY2hlZHVsZUtleSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgc2NoZWR1bGVkQm91bmRhcnlTY2Fucy5hZGQoc2NoZWR1bGVLZXkpO1xuICAgICAgICAgICAgLy8gUmUtYXJtZWQgcmF0aGVyIHRoYW4gdHJ1c3RlZDogYSBsb25nIHRpbWVyIGNhbiBmaXJlIGVhcmx5IGFmdGVyIGEgc3VzcGVuZCwgYW5kIGZpcmluZyBlYXJseSB3b3VsZCBzY2FuIGZvciBhIGhhbmRvdmVyIHRoYXQgaGFzIG5vdCBoYXBwZW5lZFxuICAgICAgICAgICAgbGV0IGFybSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKERhdGUubm93KCkgPCBhdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJtKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdm9pZCBydW5Cb3VuZGFyeVNjYW4oYWNjb3VudCwgYnVja2V0TmFtZSwgc3RhcnQsIG9mZnNldCkuY2F0Y2goKGU6IEVycm9yKSA9PiBjb25zb2xlLmVycm9yKGBCb3VuZGFyeSBzY2FuIGZvciBidWNrZXQgJHtrZXl9IGZhaWxlZDogJHtlLnN0YWNrID8/IGV9YCkpO1xuICAgICAgICAgICAgICAgIH0sIE1hdGgubWluKGF0IC0gRGF0ZS5ub3coKSwgTUFYX1RJTUVSX0RFTEFZKSk7XG4gICAgICAgICAgICAgICAgKHRpbWVyIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhcm0oKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqIENvbGxlY3RzIHRoZSB3cml0ZXMgdGhhdCBsYW5kZWQgb24gdGhlIHByZXZpb3VzIHdpbmRvdydzIG93bmVycyBqdXN0IGJlZm9yZSBhIGJvdW5kYXJ5LCBpbnRvIHRoZSBzdG9yZSB0aGF0IGhhcyBqdXN0IHRha2VuIG92ZXIuIFdobyBvd25lZCB3aGF0IGlzIHdvcmtlZCBvdXQgcHVyZWx5IGZyb20gdGhlIGNvbmZpZyAoc2VlIHByZXZpb3VzV2luZG93T3duZXJzKTsgdGhpcyBvbmx5IGRvZXMgdGhlIHB1bGxpbmcuIFRoZSBjb25maWcgaXMgcmVhZCBvZmYgdGhlIGRpc2sgYXQgRklSRSB0aW1lLCBub3QgY2FwdHVyZWQgd2hlbiB0aGUgc2NhbiB3YXMgYXJtZWQgLSBpdCBtYXkgaGF2ZSBjaGFuZ2VkIGluIGJldHdlZW4sIGFuZCB0aGUgbmV3ZXN0IGNvcHkgaXMgdGhlIG9uZSB0aGUgaGFuZG92ZXIgYWN0dWFsbHkgaGFwcGVuZWQgdW5kZXIuICovXG5hc3luYyBmdW5jdGlvbiBydW5Cb3VuZGFyeVNjYW4oYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcsIHdpbmRvd1N0YXJ0OiBudW1iZXIsIG9mZnNldDogbnVtYmVyLCBvZmZzZXRMYWJlbD86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxldCBrZXkgPSBgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9YDtcbiAgICBsZXQgbGFiZWwgPSBgYnVja2V0ICR7a2V5fSwgd2luZG93IHN0YXJ0aW5nICR7bmV3IERhdGUod2luZG93U3RhcnQpLnRvSVNPU3RyaW5nKCl9LCBvZmZzZXQgJHtvZmZzZXRMYWJlbCB8fCBgJHtvZmZzZXQgLyAxMDAwfXNgfWA7XG4gICAgaWYgKGJvdW5kYXJ5U2NhbnNSdW5uaW5nLmhhcyhrZXkpKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBTa2lwcGluZyBib3VuZGFyeSBzY2FuICgke2xhYmVsfSk6IHRoZSBwcmV2aW91cyBib3VuZGFyeSBzY2FuIGlzIHN0aWxsIHJ1bm5pbmdgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBib3VuZGFyeVNjYW5zUnVubmluZy5hZGQoa2V5KTtcbiAgICB0cnkge1xuICAgICAgICBsZXQgZWZmZWN0aXZlID0gYXdhaXQgcmVhZFJvdXRpbmdGcm9tRGlzayhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICAgICAgaWYgKCFlZmZlY3RpdmUpIHJldHVybjtcbiAgICAgICAgbGV0IGhhbmRvdmVycyA9IHByZXZpb3VzV2luZG93T3duZXJzKGVmZmVjdGl2ZSwgd2luZG93U3RhcnQsIGZpbmRTZWxmSW5kZXhlcyhlZmZlY3RpdmUsIGFjY291bnQsIGJ1Y2tldE5hbWUpKTtcbiAgICAgICAgaWYgKCFoYW5kb3ZlcnMubGVuZ3RoKSByZXR1cm47XG4gICAgICAgIGNvbnNvbGUubG9nKGBCb3VuZGFyeSBzY2FuICgke2xhYmVsfSk6ICR7aGFuZG92ZXJzLmxlbmd0aH0gcm91dGUocykgdGFraW5nIG92ZXI6ICR7aGFuZG92ZXJzLm1hcCh4ID0+IGAke0pTT04uc3RyaW5naWZ5KHgucm91dGUpfSBmcm9tICR7eC5zY2FuT3duRGlzayAmJiBcIm91ciBvd24gZGlza1wiIHx8IFwiXCJ9JHt4LnNjYW5Pd25EaXNrICYmIHgucmVtb3Rlcy5zaXplICYmIFwiICsgXCIgfHwgXCJcIn0ke1suLi54LnJlbW90ZXMua2V5cygpXS5tYXAoaSA9PiBgc291cmNlICR7aX1gKS5qb2luKFwiLCBcIil9YCkuam9pbihcIjsgXCIpfWApO1xuICAgICAgICBsZXQgc2luY2UgPSB3aW5kb3dTdGFydCAtIEJPVU5EQVJZX1NDQU5fTE9PS0JBQ0s7XG4gICAgICAgIGZvciAobGV0IGhhbmRvdmVyIG9mIGhhbmRvdmVycykge1xuICAgICAgICAgICAgbGV0IHNlbGZTdG9yZSA9IGdldFN0b3JlKGFjY291bnQsIGJ1Y2tldE5hbWUsIGhhbmRvdmVyLm5hbWUpO1xuICAgICAgICAgICAgaWYgKGhhbmRvdmVyLnNjYW5Pd25EaXNrKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgc2VsZlN0b3JlLnJlc2NhbkJhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IFtzb3VyY2VJbmRleCwgcm91dGVdIG9mIGhhbmRvdmVyLnJlbW90ZXMpIHtcbiAgICAgICAgICAgICAgICBsZXQgb3duZXJTb3VyY2UgPSBlZmZlY3RpdmUuc291cmNlc1tzb3VyY2VJbmRleF07XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvd25lclNvdXJjZSA9PT0gXCJzdHJpbmdcIikgY29udGludWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgc2VsZlN0b3JlLmJvdW5kYXJ5U2NhblJlbW90ZShjcmVhdGVBcGlBcmNoaXZlcyhvd25lclNvdXJjZSksIHsgc2luY2UsIHJvdXRlIH0pO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQm91bmRhcnkgc2NhbiAoJHtsYWJlbH0pIG9mIHByZXZpb3VzLXdpbmRvdyBvd25lciAoc291cmNlIGluZGV4ICR7c291cmNlSW5kZXh9KSBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYm91bmRhcnlTY2Fuc1J1bm5pbmcuZGVsZXRlKGtleSk7XG4gICAgfVxufVxuXG4vKiogQW4gb3BlcmF0b3IncyBjb25maWcga25vd3Mgbm90aGluZyBhYm91dCBhIHN3aXRjaG92ZXIgdGhhdCBpcyBpbiBmbGlnaHQgcmlnaHQgbm93LCBzbyB3cml0aW5nIGl0IGFzLWlzIHdvdWxkIGNhbmNlbCBvbmUgbWlkLWhhbmRvdmVyLiBUaGUgaW4tZmxpZ2h0IHdpbmRvd3MgYXJlIHB1dCBiYWNrIGludG8gaXQgZmlyc3QuICovXG5leHBvcnQgZnVuY3Rpb24gcmVpbmplY3RJbnRlcm1lZGlhdGVzKGN1cnJlbnQ6IFJlbW90ZUNvbmZpZyB8IHVuZGVmaW5lZCwgaW5jb21pbmc6IFJlbW90ZUNvbmZpZyk6IFJlbW90ZUNvbmZpZyB7XG4gICAgaWYgKCFjdXJyZW50KSByZXR1cm4gaW5jb21pbmc7XG4gICAgbGV0IHN0b3JlZCA9IGluY29taW5nO1xuICAgIGxldCByZWluamVjdGVkID0gMDtcbiAgICBmb3IgKGxldCBpbnRlcm1lZGlhdGUgb2YgZ2V0SW50ZXJtZWRpYXRlU291cmNlcyhleHBpcmVJbnRlcm1lZGlhdGVTb3VyY2VzKGN1cnJlbnQsIERhdGUubm93KCkpKSkge1xuICAgICAgICBzdG9yZWQgPSBpbmplY3RJbnRlcm1lZGlhdGVTb3VyY2Uoc3RvcmVkLCB7XG4gICAgICAgICAgICBzcGxpdFVybDogaW50ZXJtZWRpYXRlLmludGVybWVkaWF0ZSB8fCBpbnRlcm1lZGlhdGUudXJsLFxuICAgICAgICAgICAgaW50ZXJtZWRpYXRlVXJsOiBpbnRlcm1lZGlhdGUudXJsLFxuICAgICAgICAgICAgc3RhcnQ6IGludGVybWVkaWF0ZS52YWxpZFdpbmRvd1swXSxcbiAgICAgICAgICAgIGVuZDogaW50ZXJtZWRpYXRlLnZhbGlkV2luZG93WzFdLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVpbmplY3RlZCsrO1xuICAgIH1cbiAgICBpZiAocmVpbmplY3RlZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgUmUtaW5qZWN0ZWQgJHtyZWluamVjdGVkfSBpbi1mbGlnaHQgc3dpdGNob3ZlciB3aW5kb3cocykgaW50byBhbiBpbmNvbWluZyByb3V0aW5nIGNvbmZpZyAodmVyc2lvbiAke2dldENvbmZpZ1ZlcnNpb24oaW5jb21pbmcpfSlgKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0b3JlZDtcbn1cblxuLy8gUGVyIGJ1Y2tldCwgbm90IGdsb2JhbDogYSBzd2l0Y2hvdmVyIGhhcyB0byB3cml0ZSBldmVyeSBidWNrZXQncyB3aW5kb3dzIGF0IG9uY2UsIGFuZCBhIHNoYXJlZCB0aHJvdHRsZSB3b3VsZCBsZXQgb25seSBvbmUgYnVja2V0IHRocm91Z2ggcGVyIGludGVydmFsXG5jb25zdCBsYXN0T3duQ29uZmlnV3JpdGUgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG5hc3luYyBmdW5jdGlvbiB3cml0ZU93blJvdXRpbmdDb25maWcoY29uZmlnOiB7IGFjY291bnQ6IHN0cmluZzsgYnVja2V0TmFtZTogc3RyaW5nOyBzdG9yZU5hbWU6IHN0cmluZzsgY3VycmVudDogUmVtb3RlQ29uZmlnOyB1cGRhdGVkOiBSZW1vdGVDb25maWc7IHJlYXNvbjogc3RyaW5nIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgeyBhY2NvdW50LCBidWNrZXROYW1lLCBjdXJyZW50LCB1cGRhdGVkLCByZWFzb24gfSA9IGNvbmZpZztcbiAgICBsZXQga2V5ID0gYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWA7XG4gICAgbGV0IHNpbmNlTGFzdCA9IERhdGUubm93KCkgLSAobGFzdE93bkNvbmZpZ1dyaXRlLmdldChrZXkpIHx8IDApO1xuICAgIGlmIChzaW5jZUxhc3QgPCBPV05fQ09ORklHX1dSSVRFX1RIUk9UVExFKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBOb3Qgd3JpdGluZyBvdXIgb3duIHJvdXRpbmcgY29uZmlnIHVwZGF0ZSBmb3IgYnVja2V0ICR7a2V5fSAoJHtyZWFzb259KTogdGhlIGxhc3Qgb25lIHdhcyAke3NpbmNlTGFzdH1tcyBhZ28sIHVuZGVyIHRoZSAke09XTl9DT05GSUdfV1JJVEVfVEhST1RUTEV9bXMgdGhyb3R0bGUuIFJldHJ5aW5nIG9uIHRoZSBuZXh0IG1haW50ZW5hbmNlIHBhc3MuYCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGFzdE93bkNvbmZpZ1dyaXRlLnNldChrZXksIERhdGUubm93KCkpO1xuICAgIGxldCBjdXJyZW50VmVyc2lvbiA9IGdldENvbmZpZ1ZlcnNpb24oY3VycmVudCk7XG4gICAgbGV0IHZlcnNpb24gPSBuZXh0SW50ZXJtZWRpYXRlVmVyc2lvbihjdXJyZW50VmVyc2lvbik7XG4gICAgbGV0IG5leHQ6IFJlbW90ZUNvbmZpZyA9IHsgLi4udXBkYXRlZCwgdmVyc2lvbiB9O1xuICAgIGNvbnNvbGUubG9nKGBXcml0aW5nICR7Uk9VVElOR19GSUxFfSBmb3IgYnVja2V0ICR7a2V5fSAoJHtyZWFzb259KSwgdmVyc2lvbiAke2N1cnJlbnRWZXJzaW9ufSAtPiAke3ZlcnNpb259OiAke0pTT04uc3RyaW5naWZ5KG5leHQpfWApO1xuICAgIGxldCBkYXRhID0gQnVmZmVyLmZyb20oc2VyaWFsaXplUmVtb3RlQ29uZmlnKG5leHQpKTtcbiAgICAvLyBJbnRvIHRoZSBzdG9yZSBob2xkaW5nIHRoZSBuZXdlc3QgY29weSAtIGl0IGFwcGxpZXMgaXQgYW5kIGl0cyBwZWVycyBwdWxsIGl0IC0gYW5kIGRpcmVjdGx5IHRvIHRoZSBvdGhlciBzZXJ2ZXJzLCB3aGljaCBpcyB3aGF0IG1ha2VzIGEgc3dpdGNob3ZlciB0YWtlIGVmZmVjdCBpbiBzZWNvbmRzIHJhdGhlciB0aGFuIGF0IHRoZSBuZXh0IHBvbGxcbiAgICBhd2FpdCB3cml0ZVJvdXRpbmdDb25maWcoYWNjb3VudCwgYnVja2V0TmFtZSwgY29uZmlnLnN0b3JlTmFtZSwgZGF0YSk7XG4gICAgYXdhaXQgcHJvcGFnYXRlUm91dGluZ0NvbmZpZyh7IGFjY291bnQsIGJ1Y2tldE5hbWUsIGN1cnJlbnQsIG5leHQsIGRhdGEgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHByb3BhZ2F0ZVJvdXRpbmdDb25maWcoY29uZmlnOiB7IGFjY291bnQ6IHN0cmluZzsgYnVja2V0TmFtZTogc3RyaW5nOyBjdXJyZW50OiBSZW1vdGVDb25maWc7IG5leHQ6IFJlbW90ZUNvbmZpZzsgZGF0YTogQnVmZmVyIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgdGFyZ2V0cyA9IG5ldyBNYXA8c3RyaW5nLCBTb3VyY2VDb25maWc+KCk7XG4gICAgZm9yIChsZXQgc291cmNlIG9mIFsuLi5jb25maWcuY3VycmVudC5zb3VyY2VzLCAuLi5jb25maWcubmV4dC5zb3VyY2VzXSkge1xuICAgICAgICBpZiAodHlwZW9mIHNvdXJjZSA9PT0gXCJzdHJpbmdcIiB8fCBzb3VyY2UuaW50ZXJtZWRpYXRlKSBjb250aW51ZTtcbiAgICAgICAgaWYgKHNvdXJjZS50eXBlID09PSBcInJlbW90ZVwiKSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gcGFyc2VIb3N0ZWRVcmwoc291cmNlLnVybCk7XG4gICAgICAgICAgICBpZiAocGFyc2VkLmFjY291bnQgIT09IGNvbmZpZy5hY2NvdW50IHx8IHBhcnNlZC5idWNrZXROYW1lICE9PSBjb25maWcuYnVja2V0TmFtZSkgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhcmdldHMuaGFzKHNvdXJjZS51cmwpKSBjb250aW51ZTtcbiAgICAgICAgdGFyZ2V0cy5zZXQoc291cmNlLnVybCwgc291cmNlKTtcbiAgICB9XG4gICAgZm9yIChsZXQgW3VybCwgc291cmNlXSBvZiB0YXJnZXRzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBjcmVhdGVBcGlBcmNoaXZlcyhzb3VyY2UpLnNldChST1VUSU5HX0ZJTEUsIGNvbmZpZy5kYXRhKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBXcm90ZSAke1JPVVRJTkdfRklMRX0gZm9yIGJ1Y2tldCAke2NvbmZpZy5hY2NvdW50fS8ke2NvbmZpZy5idWNrZXROYW1lfSB0byAke3VybH1gKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgUHJvcGFnYXRpbmcgb3VyIHJvdXRpbmcgY29uZmlnIHVwZGF0ZSB0byAke3VybH0gZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5zdGFjayA/PyBlfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKiogS2VlcHMgZXZlcnkgYWN0aXZlIGJ1Y2tldCdzIHN3aXRjaG92ZXIgd2luZG93cyBjdXJyZW50OiBnaXZlcyBvdXIgYWx0ZXJuYXRlIHBvcnQgaXRzIHdpbmRvdyB3aGlsZSBhIHRha2VvdmVyIGlzIGluIGZsaWdodCwgYW5kIHRha2VzIGV4cGlyZWQgb25lcyBiYWNrIG91dC4gKi9cbmFzeW5jIGZ1bmN0aW9uIG1haW50YWluSW50ZXJtZWRpYXRlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgeyBkb21haW4sIHBvcnQgfSA9IGdldFN0b3JhZ2VTZXJ2ZXJDb25maWcoKTtcbiAgICBsZXQgdGFrZW92ZXIgPSBnZXRUYWtlb3ZlckludGVybWVkaWF0ZSgpO1xuICAgIGxldCB3cml0dGVuOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBhbHJlYWR5Q29ycmVjdDogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgbm90T3Vyczogc3RyaW5nW10gPSBbXTtcbiAgICAvLyBPTkxZIGJ1Y2tldHMgYWxyZWFkeSBhY3RpdmUuIEEgc3dpdGNob3ZlciBtdXN0IG5ldmVyIGFjdGl2YXRlIGEgYnVja2V0OiB0aGF0IHN0YXJ0cyBpdHMgc3luY2hyb25pemF0aW9uLCBhbmQgYnVja2V0cyBub3RoaW5nIGhhcyB0b3VjaGVkIChsZWdhY3kgb25lcyBlc3BlY2lhbGx5KSBoYXZlIG5vIHdyaXRlcyB0byBoYW5kIG9mZiBpbiB0aGUgZmlyc3QgcGxhY2UuIE9uZSB0aGF0IGRvZXMgZ2V0IHVzZWQgbWlkLXN3aXRjaG92ZXIgYWN0aXZhdGVzIG9uIHRoYXQgYWNjZXNzLCBhbmQgdGhlIG5leHQgcGFzcyBnaXZlcyBpdCBpdHMgd2luZG93LlxuICAgIGxldCBhY3RpdmVLZXlzID0gZ2V0QWN0aXZlQnVja2V0S2V5cygpO1xuICAgIGZvciAobGV0IHsgYWNjb3VudCwgYnVja2V0TmFtZSB9IG9mIGFjdGl2ZUtleXMpIHtcbiAgICAgICAgbGV0IGtleSA9IGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gO1xuICAgICAgICBsZXQgbmV3ZXN0ID0gYXdhaXQgcmVhZE5ld2VzdFJvdXRpbmdGaWxlKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgICAgICBpZiAoIW5ld2VzdCkgY29udGludWU7XG4gICAgICAgIGxldCByb3V0aW5nOiBSZW1vdGVDb25maWc7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByb3V0aW5nID0gcGFyc2VSb3V0aW5nRGF0YShuZXdlc3QuZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFNraXBwaW5nIHN3aXRjaG92ZXIgbWFpbnRlbmFuY2UgZm9yIGJ1Y2tldCAke2tleX06IGl0cyByb3V0aW5nIGNvbmZpZyBjb3VsZCBub3QgYmUgcGFyc2VkICgkeyhlIGFzIEVycm9yKS5tZXNzYWdlfSlgKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGxldCBleHBpcmVkID0gZXhwaXJlSW50ZXJtZWRpYXRlU291cmNlcyhyb3V0aW5nLCBEYXRlLm5vdygpKTtcbiAgICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KGV4cGlyZWQpICE9PSBKU09OLnN0cmluZ2lmeShyb3V0aW5nKSkge1xuICAgICAgICAgICAgYXdhaXQgd3JpdGVPd25Sb3V0aW5nQ29uZmlnKHsgYWNjb3VudCwgYnVja2V0TmFtZSwgc3RvcmVOYW1lOiBuZXdlc3QubmFtZSwgY3VycmVudDogcm91dGluZywgdXBkYXRlZDogZXhwaXJlZCwgcmVhc29uOiBgc3dpdGNob3ZlciB3aW5kb3dzIGV4cGlyZWQgbW9yZSB0aGFuICR7SU5URVJNRURJQVRFX0VYUElSRV9HUkFDRSAvIDEwMDB9cyBhZ29gIH0pO1xuICAgICAgICAgICAgd3JpdHRlbi5wdXNoKGtleSk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRha2VvdmVyKSBjb250aW51ZTtcbiAgICAgICAgbGV0IG1haW5VcmwgPSByb3V0aW5nLnNvdXJjZXMuZmluZCh4ID0+IHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgeCA9PT0gXCJzdHJpbmdcIiB8fCB4LnR5cGUgIT09IFwicmVtb3RlXCIgfHwgeC5pbnRlcm1lZGlhdGUpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGxldCBwYXJzZWQgPSBwYXJzZUhvc3RlZFVybCh4LnVybCk7XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VkLmFkZHJlc3MgPT09IGRvbWFpbiAmJiBwYXJzZWQucG9ydCA9PT0gcG9ydDtcbiAgICAgICAgfSkgYXMgSG9zdGVkQ29uZmlnIHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAoIW1haW5VcmwpIHtcbiAgICAgICAgICAgIG5vdE91cnMucHVzaChrZXkpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGluamVjdGVkID0gaW5qZWN0SW50ZXJtZWRpYXRlU291cmNlKHJvdXRpbmcsIHtcbiAgICAgICAgICAgIHNwbGl0VXJsOiBtYWluVXJsLnVybCxcbiAgICAgICAgICAgIGludGVybWVkaWF0ZVVybDogcmVwbGFjZUhvc3RlZFVybFBvcnQobWFpblVybC51cmwsIHRha2VvdmVyLmFsdFBvcnQpLFxuICAgICAgICAgICAgc3RhcnQ6IHRha2VvdmVyLnN0YXJ0LFxuICAgICAgICAgICAgZW5kOiB0YWtlb3Zlci5lbmQsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkoaW5qZWN0ZWQpID09PSBKU09OLnN0cmluZ2lmeShyb3V0aW5nKSkge1xuICAgICAgICAgICAgYWxyZWFkeUNvcnJlY3QucHVzaChrZXkpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgd3JpdGVPd25Sb3V0aW5nQ29uZmlnKHsgYWNjb3VudCwgYnVja2V0TmFtZSwgc3RvcmVOYW1lOiBuZXdlc3QubmFtZSwgY3VycmVudDogcm91dGluZywgdXBkYXRlZDogaW5qZWN0ZWQsIHJlYXNvbjogYHdlIGFyZSBhIGRlcGxveSBzdWNjZXNzb3I6IHdyaXRlcyByb3V0ZSB0byBvdXIgYWx0ZXJuYXRlIHBvcnQgJHt0YWtlb3Zlci5hbHRQb3J0fSBmcm9tICR7bmV3IERhdGUodGFrZW92ZXIuc3RhcnQpLnRvSVNPU3RyaW5nKCl9IHVudGlsIG91ciBwcmVkZWNlc3NvciBpcyBraWxsZWQgYXQgJHtuZXcgRGF0ZSh0YWtlb3Zlci5lbmQpLnRvSVNPU3RyaW5nKCl9YCB9KTtcbiAgICAgICAgd3JpdHRlbi5wdXNoKGtleSk7XG4gICAgfVxuICAgIGlmICghdGFrZW92ZXIpIHJldHVybjtcbiAgICBpZiAoIWFjdGl2ZUtleXMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBObyBhY3RpdmUgYnVja2V0cywgc28gbm8gY29uZmlnIGZpbGVzIHRvIHdyaXRlIHRoZSBpbnRlcm1lZGlhdGUgaW50byAoYSBidWNrZXQgaXMgb25seSBhY3RpdmUgb25jZSBzb21ldGhpbmcgdXNlcyBpdClgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXdyaXR0ZW4ubGVuZ3RoKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBXcm90ZSBubyBjb25maWcgZmlsZXM6IG9mICR7YWN0aXZlS2V5cy5sZW5ndGh9IGFjdGl2ZSBidWNrZXRzLCAke2FscmVhZHlDb3JyZWN0Lmxlbmd0aH0gYWxyZWFkeSBjb250YWluIHRoZSBpbnRlcm1lZGlhdGUgYW5kICR7bm90T3Vycy5sZW5ndGh9IGFyZSBub3QgaG9zdGVkIGJ5IHVzYCk7XG4gICAgfVxufVxuXG4vKiogT3VyIHByZWRlY2Vzc29yIHN0aWxsIGhvbGRzIHRoZSBtYWluIHBvcnQgYW5kIGhhcyBiZWVuIHNlcnZpbmcgYWxsIGFsb25nLCBzbyBpdCAtIG5vdCB1cyAtIGtub3dzIHdoaWNoIGJ1Y2tldHMgYXJlIGluIHVzZS4gV2UgYWN0aXZhdGUgZXhhY3RseSB0aG9zZSwgd2hpY2ggaXMgd2hhdCBtYWtlcyB0aGVpciBjb25maWcgZmlsZXMgZ2V0IHRoZSBpbnRlcm1lZGlhdGU7IG5vdGhpbmcgZWxzZSBvbiBkaXNrIGlzIHRvdWNoZWQuICovXG5hc3luYyBmdW5jdGlvbiBhY3RpdmF0ZVByZWRlY2Vzc29yQnVja2V0cygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsZXQgeyBkb21haW4sIHBvcnQgfSA9IGdldFN0b3JhZ2VTZXJ2ZXJDb25maWcoKTtcbiAgICBsZXQgdXJsID0gYGh0dHBzOi8vJHtkb21haW59OiR7cG9ydH1gO1xuICAgIGxldCBrZXlzOiB7IGFjY291bnQ6IHN0cmluZzsgYnVja2V0TmFtZTogc3RyaW5nIH1bXTtcbiAgICB0cnkge1xuICAgICAgICBrZXlzID0gYXdhaXQgbGlzdFNlcnZlckFjdGl2ZUJ1Y2tldEtleXMoeyB1cmwgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBDb3VsZCBub3QgYXNrIG91ciBwcmVkZWNlc3NvciBvbiAke3VybH0gd2hpY2ggYnVja2V0cyBhcmUgYWN0aXZlLCBzbyBvbmx5IGJ1Y2tldHMgdXNlZCBvbiB0aGlzIHByb2Nlc3MgZ2V0IHRoZSBpbnRlcm1lZGlhdGU6ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFrZXlzLmxlbmd0aCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgT3VyIHByZWRlY2Vzc29yIG9uICR7dXJsfSBoYXMgbm8gYWN0aXZlIGJ1Y2tldHMsIHNvIHRoZXJlIGFyZSBubyBjb25maWcgZmlsZXMgdG8gd3JpdGUgdGhlIGludGVybWVkaWF0ZSBpbnRvYCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc29sZS5sb2coYE91ciBwcmVkZWNlc3NvciBvbiAke3VybH0gaGFzICR7a2V5cy5sZW5ndGh9IGFjdGl2ZSBidWNrZXRzLCBhY3RpdmF0aW5nIHRoZW0gaGVyZSBzbyB0aGVpciBjb25maWcgZmlsZXMgZ2V0IHRoZSBpbnRlcm1lZGlhdGU6ICR7a2V5cy5tYXAoeCA9PiBgJHt4LmFjY291bnR9LyR7eC5idWNrZXROYW1lfWApLmpvaW4oXCIsIFwiKX1gKTtcbiAgICBmb3IgKGxldCB7IGFjY291bnQsIGJ1Y2tldE5hbWUgfSBvZiBrZXlzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgYWN0aXZhdGVCdWNrZXQoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEFjdGl2YXRpbmcgYnVja2V0ICR7YWNjb3VudH0vJHtidWNrZXROYW1lfSAoYWN0aXZlIG9uIG91ciBwcmVkZWNlc3NvcikgZmFpbGVkOiAke3Jlc3VsdH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQWN0aXZhdGluZyBidWNrZXQgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9IChhY3RpdmUgb24gb3VyIHByZWRlY2Vzc29yKSBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKiBTdGFydGVkIGJ5IGRlcGxveVRha2VvdmVyIG9uY2Ugd2UgYXJlIGFjdHVhbGx5IGEgZGVwbG95IHN1Y2Nlc3NvciBsaXN0ZW5pbmcgb24gYW4gYWx0ZXJuYXRlIHBvcnQuIFVudGlsIHRoZW4gdGhlcmUgYXJlIG5vIHN3aXRjaG92ZXIgd2luZG93cyB0byB3cml0ZSBvciBleHBpcmUsIHNvIG5vdGhpbmcgcG9sbHMuICovXG5leHBvcnQgY29uc3Qgc3RhcnRJbnRlcm1lZGlhdGVNYWludGVuYW5jZSA9IGxhenkoKCkgPT4ge1xuICAgIHZvaWQgKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgYWN0aXZhdGVQcmVkZWNlc3NvckJ1Y2tldHMoKTtcbiAgICAgICAgYXdhaXQgbWFpbnRhaW5JbnRlcm1lZGlhdGVzKCk7XG4gICAgfSkoKS5jYXRjaCgoZTogRXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoYFdyaXRpbmcgdGhlIGludGVybWVkaWF0ZSBpbnRvIHRoZSBjb25maWcgZmlsZXMgZmFpbGVkOiAke2Uuc3RhY2sgPz8gZX1gKSk7XG4gICAgcnVuSW5maW5pdGVQb2xsKElOVEVSTUVESUFURV9NQUlOVEFJTl9JTlRFUlZBTCwgbWFpbnRhaW5JbnRlcm1lZGlhdGVzKTtcbn0pO1xuIl19
292
+ /* _JS_SOURCE_HASH = "f231f1b916304542008b87de269f6933d850d180a611d8781f99dc0998f9e54c"; */