sliftutils 1.7.70 → 1.7.72
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/dist/treeSummary.ts.cache +2 -2
- package/index.d.ts +505 -257
- package/misc/dist/environment.ts.cache +2 -2
- package/misc/dist/getSecret.ts.cache +2 -2
- package/misc/dist/strings.ts.cache +2 -2
- package/misc/dist/zip.ts.cache +2 -2
- package/misc/https/dist/certs.ts.cache +2 -2
- package/misc/https/dist/hostServer.ts.cache +5 -2
- package/misc/https/dist/persistentLocalStorage.ts.cache +2 -2
- package/package.json +1 -1
- package/render-utils/dist/observer.tsx.cache +2 -2
- package/spec.txt +10 -0
- package/storage/ArchivesDisk.d.ts +4 -13
- package/storage/ArchivesDisk.ts +6 -4
- package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/blockCache.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/mergeLock.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/streamLog.ts.cache +2 -2
- package/storage/BulkDatabase2/dist/syncClient.ts.cache +2 -2
- package/storage/IArchives.d.ts +14 -10
- package/storage/IArchives.ts +16 -4
- package/storage/backblaze.d.ts +3 -9
- package/storage/backblaze.ts +22 -19
- package/storage/dist/ArchivesDisk.ts.cache +6 -3
- package/storage/dist/FileFolderAPI.tsx.cache +2 -2
- package/storage/dist/IArchives.ts.cache +18 -4
- package/storage/dist/IndexedDBFileFolderAPI.ts.cache +2 -2
- package/storage/dist/JSONStorage.ts.cache +2 -2
- package/storage/dist/PendingManager.tsx.cache +2 -2
- package/storage/dist/TransactionStorage.ts.cache +2 -2
- package/storage/dist/backblaze.ts.cache +36 -27
- package/storage/dist/fileSystemPointer.ts.cache +2 -2
- package/storage/dist/remoteFileStorage.ts.cache +2 -2
- package/storage/remoteStorage/ArchivesRemote.d.ts +5 -9
- package/storage/remoteStorage/ArchivesRemote.ts +25 -20
- package/storage/remoteStorage/ArchivesUrl.d.ts +3 -9
- package/storage/remoteStorage/ArchivesUrl.ts +7 -5
- package/storage/remoteStorage/accessPage.tsx +4 -4
- package/storage/remoteStorage/accessStats.d.ts +2 -0
- package/storage/remoteStorage/accessStats.ts +32 -0
- package/storage/remoteStorage/blobStore.d.ts +193 -88
- package/storage/remoteStorage/blobStore.ts +535 -400
- package/storage/remoteStorage/bucketDisk.d.ts +18 -0
- package/storage/remoteStorage/bucketDisk.ts +66 -0
- package/storage/remoteStorage/createArchives.d.ts +4 -10
- package/storage/remoteStorage/createArchives.ts +102 -63
- package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +29 -20
- package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +8 -5
- package/storage/remoteStorage/dist/accessPage.tsx.cache +6 -6
- package/storage/remoteStorage/dist/accessStats.ts.cache +39 -4
- package/storage/remoteStorage/dist/blobStore.ts.cache +517 -375
- package/storage/remoteStorage/dist/bucketDisk.ts.cache +72 -0
- package/storage/remoteStorage/dist/cliArgs.ts.cache +2 -2
- package/storage/remoteStorage/dist/createArchives.ts.cache +112 -58
- package/storage/remoteStorage/dist/deployTakeover.ts.cache +2 -2
- package/storage/remoteStorage/dist/intermediateSources.ts.cache +13 -13
- package/storage/remoteStorage/dist/remoteConfig.ts.cache +19 -3
- package/storage/remoteStorage/dist/serverConfig.ts.cache +116 -0
- package/storage/remoteStorage/dist/sourceWrapper.ts.cache +7 -6
- package/storage/remoteStorage/dist/sourcesList.ts.cache +6 -3
- package/storage/remoteStorage/dist/storageClientController.ts.cache +2 -2
- package/storage/remoteStorage/dist/storageController.ts.cache +224 -191
- package/storage/remoteStorage/dist/storageServer.ts.cache +9 -9
- package/storage/remoteStorage/dist/storageServerState.ts.cache +330 -567
- package/storage/remoteStorage/dist/storePlan.ts.cache +149 -0
- package/storage/remoteStorage/dist/validation.ts.cache +40 -0
- package/storage/remoteStorage/grantAccessCli.ts +1 -1
- package/storage/remoteStorage/intermediateSources.d.ts +3 -5
- package/storage/remoteStorage/intermediateSources.ts +14 -16
- package/storage/remoteStorage/remoteConfig.d.ts +2 -2
- package/storage/remoteStorage/remoteConfig.ts +19 -3
- package/storage/remoteStorage/serverConfig.d.ts +27 -0
- package/storage/remoteStorage/serverConfig.ts +109 -0
- package/storage/remoteStorage/sourceWrapper.d.ts +3 -3
- package/storage/remoteStorage/sourceWrapper.ts +7 -6
- package/storage/remoteStorage/sourcesList.ts +3 -0
- package/storage/remoteStorage/storageController.d.ts +118 -36
- package/storage/remoteStorage/storageController.ts +166 -168
- package/storage/remoteStorage/storageServer.ts +1 -1
- package/storage/remoteStorage/storageServerState.d.ts +52 -63
- package/storage/remoteStorage/storageServerState.ts +340 -584
- package/storage/remoteStorage/storePlan.d.ts +34 -0
- package/storage/remoteStorage/storePlan.ts +166 -0
- package/storage/remoteStorage/validation.d.ts +4 -0
- package/storage/remoteStorage/validation.ts +31 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
6
|
-
//exports.BlobStore = exports.WINDOW_END_FLUSH_MARGIN = exports.DEFAULT_FAST_WRITE_DELAY = void 0;
|
|
6
|
+
//exports.BlobStore = exports.RawDiskStore = exports.WINDOW_END_FLUSH_MARGIN = exports.DEFAULT_FAST_WRITE_DELAY = void 0;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const caching_1 = require("socket-function/src/caching");
|
|
9
9
|
const batching_1 = require("socket-function/src/batching");
|
|
@@ -13,10 +13,11 @@ const IArchives_1 = require("../IArchives");
|
|
|
13
13
|
const ArchivesDisk_1 = require("../ArchivesDisk");
|
|
14
14
|
const backblaze_1 = require("../backblaze");
|
|
15
15
|
const remoteConfig_1 = require("./remoteConfig");
|
|
16
|
+
const storePlan_1 = require("./storePlan");
|
|
16
17
|
const BulkDatabaseBase_1 = require("../BulkDatabase2/BulkDatabaseBase");
|
|
17
18
|
const FileFolderAPI_1 = require("../FileFolderAPI");
|
|
18
19
|
const sourcesList_1 = require("./sourcesList");
|
|
19
|
-
// The storage engine of the remote storage server. Data lives in synchronization sources (at minimum an ArchivesDisk, the local disk); BlobStore keeps an index of every file (path, last modified time, size, and which source currently holds the data) in a BulkDatabase2, and synchronizes the index from all sources (see ArchivesSource in IArchives.ts). Every startup fully rescans each source's metadata, so the index self-heals; the file with the highest write time wins across all sources, so multiple sources need no stacking order.
|
|
20
|
+
// The storage engine of the remote storage server. Data lives in synchronization sources (at minimum an ArchivesDisk, the local disk); BlobStore keeps an index of every file (path, last modified time, size, and which source currently holds the data) in a BulkDatabase2, and synchronizes the index from all sources (see ArchivesSource in IArchives.ts). Every startup fully rescans each source's metadata, so the index self-heals; the file with the highest write time wins across all sources, so multiple sources need no stacking order. The store also holds its own routing entries (the self entries of the ONE route it serves), so it validates writes itself: valid windows, routes, immutability, and internal-push acceptance.
|
|
20
21
|
exports.DEFAULT_FAST_WRITE_DELAY = misc_1.timeInMinute * 5;
|
|
21
22
|
const FAST_FLUSH_POLL = 1000 * 15;
|
|
22
23
|
// Fast writes are never delayed past our own valid window, and within this margin of the window's end they write through immediately - so when the next window's source takes over, the writes are already on disk
|
|
@@ -46,6 +47,47 @@ const FULL_SYNC_SLOW_ERROR_INTERVAL = 1000 * 60 * 60;
|
|
|
46
47
|
// A reconcile pass skips failing files (one bad value must not stop the rest), but this many failures in a row means the target itself is down, so the pass aborts until the next scan cycle
|
|
47
48
|
const RECONCILE_MAX_CONSECUTIVE_FAILURES = 5;
|
|
48
49
|
const RECONCILE_ERROR_LOG_LIMIT = 3;
|
|
50
|
+
const WRONG_TARGET_LOG_THROTTLE = 60 * 1000;
|
|
51
|
+
/** rawDisk buckets: the disk IS the store. No index, no synchronization, no window/route/immutability validation. */
|
|
52
|
+
class RawDiskStore {
|
|
53
|
+
constructor(disk) {
|
|
54
|
+
this.disk = disk;
|
|
55
|
+
}
|
|
56
|
+
async get2(config) {
|
|
57
|
+
return await this.disk.get2(config.path, { range: config.range, includeTombstones: config.includeTombstones });
|
|
58
|
+
}
|
|
59
|
+
async set(config) {
|
|
60
|
+
await this.disk.set(config.path, config.data, { lastModified: config.lastModified });
|
|
61
|
+
}
|
|
62
|
+
async del(config) {
|
|
63
|
+
if (config.path === remoteConfig_1.ROUTING_FILE) {
|
|
64
|
+
throw new Error(`The routing config ${JSON.stringify(remoteConfig_1.ROUTING_FILE)} cannot be deleted (overwrite it to change the bucket's configuration)`);
|
|
65
|
+
}
|
|
66
|
+
await this.disk.del(config.path, { lastModified: config.lastModified });
|
|
67
|
+
}
|
|
68
|
+
async getInfo(config) {
|
|
69
|
+
return await this.disk.getInfo(config.path, { includeTombstones: config.includeTombstones });
|
|
70
|
+
}
|
|
71
|
+
async findInfo(config) {
|
|
72
|
+
return await this.disk.findInfo(config.prefix, { shallow: config.shallow, type: config.type });
|
|
73
|
+
}
|
|
74
|
+
async getChangesAfter2(config) {
|
|
75
|
+
return await this.disk.getChangesAfter2(config);
|
|
76
|
+
}
|
|
77
|
+
async startLargeUpload() {
|
|
78
|
+
return await this.disk.startLargeUpload();
|
|
79
|
+
}
|
|
80
|
+
async appendLargeUpload(config) {
|
|
81
|
+
await this.disk.appendLargeUpload(config.id, config.data);
|
|
82
|
+
}
|
|
83
|
+
async finishLargeUpload(config) {
|
|
84
|
+
await this.disk.finishLargeUpload(config.id, config.path, config.lastModified);
|
|
85
|
+
}
|
|
86
|
+
async cancelLargeUpload(config) {
|
|
87
|
+
await this.disk.cancelLargeUpload(config.id);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.RawDiskStore = RawDiskStore;
|
|
49
91
|
function newScanTally() {
|
|
50
92
|
return { filtered: 0, new: 0, updated: 0, tombstone: 0, unchanged: 0 };
|
|
51
93
|
}
|
|
@@ -64,11 +106,41 @@ function newSourceState() {
|
|
|
64
106
|
stopped: { stop: false },
|
|
65
107
|
};
|
|
66
108
|
}
|
|
109
|
+
let lastWrongTargetLog = 0;
|
|
110
|
+
function logWrongTargetRejection(message) {
|
|
111
|
+
if (Date.now() - lastWrongTargetLog < WRONG_TARGET_LOG_THROTTLE)
|
|
112
|
+
return;
|
|
113
|
+
lastWrongTargetLog = Date.now();
|
|
114
|
+
console.log(message);
|
|
115
|
+
}
|
|
67
116
|
class BlobStore {
|
|
68
117
|
constructor(folder, sources, config) {
|
|
118
|
+
var _a;
|
|
69
119
|
this.folder = folder;
|
|
70
120
|
this.sources = sources;
|
|
71
121
|
this.config = config;
|
|
122
|
+
// #region Main interface
|
|
123
|
+
this.init = (0, caching_1.lazy)(async () => {
|
|
124
|
+
var _a;
|
|
125
|
+
for (let i = 0; i < this.sources.length; i++) {
|
|
126
|
+
await this.registerSlot(i);
|
|
127
|
+
}
|
|
128
|
+
await this.loadIndex();
|
|
129
|
+
this.syncStarted = true;
|
|
130
|
+
for (let i = 0; i < this.sources.length; i++) {
|
|
131
|
+
if (!this.isLive(i))
|
|
132
|
+
continue;
|
|
133
|
+
void this.runSourceSync(i);
|
|
134
|
+
}
|
|
135
|
+
(0, batching_1.runInfinitePoll)(FAST_FLUSH_POLL, () => this.flushOverlay(), this.stopped);
|
|
136
|
+
(0, batching_1.runInfinitePoll)(INDEX_FLUSH_INTERVAL, () => this.flushIndex(), this.stopped);
|
|
137
|
+
(0, batching_1.runInfinitePoll)(TOMBSTONE_CLEANUP_INTERVAL, () => this.cleanupTombstones(), this.stopped);
|
|
138
|
+
if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.readerDiskLimit) {
|
|
139
|
+
(0, batching_1.runInfinitePoll)(DISK_LIMIT_CHECK_INTERVAL, () => this.enforceDiskLimit(), this.stopped);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
// #endregion
|
|
143
|
+
// #region Internals
|
|
72
144
|
this.stopped = { stop: false };
|
|
73
145
|
// The index's BulkDatabase2 files live under <folder>/index. "blobIndex2": the "blobIndex" generation persisted sources-array positions as the holding source, which are not stable across runs - its entries are unusable, so it is simply never read again.
|
|
74
146
|
this.index = new BulkDatabaseBase_1.BulkDatabaseBase("blobIndex2", BulkDatabaseBase_1.noopReactiveDeps, async (p) => {
|
|
@@ -93,74 +165,15 @@ class BlobStore {
|
|
|
93
165
|
this.overlay = new Map();
|
|
94
166
|
this.sourceStates = this.sources.map(() => newSourceState());
|
|
95
167
|
this.syncStarted = false;
|
|
168
|
+
this.entries = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.entries) || [];
|
|
96
169
|
// The persistent identities behind IndexEntry.sourcesListIndex (see SourcesList)
|
|
97
170
|
this.sourcesList = new sourcesList_1.SourcesList(path_1.default.join(this.folder, "index", "sourcesList.txt"));
|
|
98
171
|
// Per slot: the persistent sourcesListIndex of that slot's URL, filled by registerSlot before the slot's sync runs
|
|
99
172
|
this.slotSourcesListIndexes = [];
|
|
100
173
|
this.slotRegistrations = [];
|
|
101
|
-
this.init = (0, caching_1.lazy)(async () => {
|
|
102
|
-
var _a;
|
|
103
|
-
for (let i = 0; i < this.sources.length; i++) {
|
|
104
|
-
await this.registerSlot(i);
|
|
105
|
-
}
|
|
106
|
-
await this.loadIndex();
|
|
107
|
-
this.syncStarted = true;
|
|
108
|
-
for (let i = 0; i < this.sources.length; i++) {
|
|
109
|
-
if (!this.isLive(i))
|
|
110
|
-
continue;
|
|
111
|
-
void this.runSourceSync(i);
|
|
112
|
-
}
|
|
113
|
-
(0, batching_1.runInfinitePoll)(FAST_FLUSH_POLL, () => this.flushOverlay(), this.stopped);
|
|
114
|
-
(0, batching_1.runInfinitePoll)(INDEX_FLUSH_INTERVAL, () => this.flushIndex(), this.stopped);
|
|
115
|
-
(0, batching_1.runInfinitePoll)(TOMBSTONE_CLEANUP_INTERVAL, () => this.cleanupTombstones(), this.stopped);
|
|
116
|
-
if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.readerDiskLimit) {
|
|
117
|
-
(0, batching_1.runInfinitePoll)(DISK_LIMIT_CHECK_INTERVAL, () => this.enforceDiskLimit(), this.stopped);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
174
|
// readerDiskLimit: the disk is only a bounded read cache, so once it exceeds the limit, the least recently used files are deleted from it - but ONLY when another source verifiably holds a same-or-newer copy (the only copy of a file is never deleted), and the index entry repoints to that source so reads keep working (re-caching on the next read).
|
|
121
175
|
this.evicting = false;
|
|
122
176
|
}
|
|
123
|
-
isLive(sourceIndex) {
|
|
124
|
-
return !!this.sources[sourceIndex] && !this.sourceStates[sourceIndex].dead;
|
|
125
|
-
}
|
|
126
|
-
registerSlot(slot) {
|
|
127
|
-
let existing = this.slotRegistrations[slot];
|
|
128
|
-
if (existing)
|
|
129
|
-
return existing;
|
|
130
|
-
let registration = this.sourcesList.ensure(this.sources[slot].url).then(index => {
|
|
131
|
-
this.slotSourcesListIndexes[slot] = index;
|
|
132
|
-
});
|
|
133
|
-
this.slotRegistrations[slot] = registration;
|
|
134
|
-
return registration;
|
|
135
|
-
}
|
|
136
|
-
// The persistent sourcesListIndex of a slot - only valid once the slot's registration resolved (init and runSourceSync guarantee that before any indexing happens)
|
|
137
|
-
sourcesListIndexOfSlot(slot) {
|
|
138
|
-
var _a;
|
|
139
|
-
let index = this.slotSourcesListIndexes[slot];
|
|
140
|
-
if (index === undefined) {
|
|
141
|
-
throw new Error(`Source slot ${slot} (${(_a = this.sources[slot]) === null || _a === void 0 ? void 0 : _a.url}) has no registered sourcesListIndex yet (store ${this.folder})`);
|
|
142
|
-
}
|
|
143
|
-
return index;
|
|
144
|
-
}
|
|
145
|
-
// The live slot currently serving a persistent sourcesListIndex, or undefined when no configured source has that URL anymore. Linear, but the sources list is tiny and this is always current (slots dying, or several slots sharing one URL across valid windows, need no bookkeeping).
|
|
146
|
-
slotForSourcesListIndex(sourcesListIndex) {
|
|
147
|
-
for (let i = 0; i < this.slotSourcesListIndexes.length; i++) {
|
|
148
|
-
if (this.slotSourcesListIndexes[i] === sourcesListIndex && this.isLive(i))
|
|
149
|
-
return i;
|
|
150
|
-
}
|
|
151
|
-
return undefined;
|
|
152
|
-
}
|
|
153
|
-
// The IArchives currently holding an entry's bytes: the live slot when the holder is still configured, otherwise resolved (cached) straight from its persisted URL - windows/routes decide when a source is scanned or written, but for reading bytes we know it holds, the URL alone is enough
|
|
154
|
-
async getEntryHolder(entry) {
|
|
155
|
-
var _a, _b;
|
|
156
|
-
let slot = this.slotForSourcesListIndex(entry.sourcesListIndex);
|
|
157
|
-
if (slot !== undefined)
|
|
158
|
-
return this.sources[slot].source;
|
|
159
|
-
let url = this.sourcesList.getUrl(entry.sourcesListIndex) || await this.sourcesList.getUrlReloading(entry.sourcesListIndex);
|
|
160
|
-
if (!url)
|
|
161
|
-
return undefined;
|
|
162
|
-
return (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.resolveSourceUrl) === null || _b === void 0 ? void 0 : _b.call(_a, url);
|
|
163
|
-
}
|
|
164
177
|
// Stops all synchronization scans/polls and flushes pending writes. Only used when the store genuinely cannot continue (rawDisk flip, process shutdown) - routine config changes go through updateSources instead, which the store survives.
|
|
165
178
|
async dispose() {
|
|
166
179
|
this.stopped.stop = true;
|
|
@@ -170,64 +183,288 @@ class BlobStore {
|
|
|
170
183
|
await this.flushOverlay(true);
|
|
171
184
|
await this.flushIndex();
|
|
172
185
|
}
|
|
173
|
-
async
|
|
174
|
-
|
|
175
|
-
this.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
let
|
|
180
|
-
let
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
+
async get2(config) {
|
|
187
|
+
if (config.internal) {
|
|
188
|
+
return await this.getInternal2(config);
|
|
189
|
+
}
|
|
190
|
+
await this.init();
|
|
191
|
+
let key = config.path;
|
|
192
|
+
let range = config.range;
|
|
193
|
+
let overlayEntry = this.overlay.get(key);
|
|
194
|
+
if (overlayEntry) {
|
|
195
|
+
// An empty file IS a missing file (tombstone)
|
|
196
|
+
if (overlayEntry.data.length === 0 && !config.includeTombstones)
|
|
197
|
+
return undefined;
|
|
198
|
+
let data = overlayEntry.data;
|
|
199
|
+
let size = data.length;
|
|
200
|
+
if (range) {
|
|
201
|
+
data = data.subarray(Math.min(range.start, data.length), Math.min(range.end, data.length));
|
|
202
|
+
}
|
|
203
|
+
return { data, writeTime: overlayEntry.t, size };
|
|
204
|
+
}
|
|
205
|
+
let entry = await this.getIndexEntry(key);
|
|
206
|
+
if (!entry)
|
|
207
|
+
return undefined;
|
|
208
|
+
if (entry.size === 0) {
|
|
209
|
+
if (!config.includeTombstones)
|
|
210
|
+
return undefined;
|
|
211
|
+
// A tombstone has no stored bytes - the index entry alone is the deletion, so the flag-caller gets its write time with empty data
|
|
212
|
+
return { data: Buffer.alloc(0), writeTime: entry.writeTime, size: 0 };
|
|
213
|
+
}
|
|
214
|
+
entry.lastAccess = Date.now();
|
|
215
|
+
let holderArchives = await this.getEntryHolder(entry);
|
|
216
|
+
let result;
|
|
217
|
+
let holderError;
|
|
218
|
+
if (holderArchives) {
|
|
219
|
+
try {
|
|
220
|
+
// includeTombstones: the holder answering "deleted" (a tombstone, with its write time) must be distinguishable from "I lost the file" - the former is authoritative and must NOT fall back to older copies, which would resurrect the deletion for this read
|
|
221
|
+
let answer = await holderArchives.get2(key, { range, internal: true, includeTombstones: true });
|
|
222
|
+
if (answer && answer.data && !answer.data.length && !(range && answer.size) && answer.writeTime >= entry.writeTime) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
// NOTE: a ranged read of a real file can legitimately be empty (range past EOF), so only unranged emptiness means tombstone/absent
|
|
226
|
+
if (answer && answer.data && (answer.data.length || range && answer.size)) {
|
|
227
|
+
result = { data: answer.data, writeTime: answer.writeTime, size: answer.size };
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
holderError = e;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (result) {
|
|
235
|
+
// Ranged reads can't populate a cache (they're partial)
|
|
236
|
+
if (this.slotForSourcesListIndex(entry.sourcesListIndex) !== 0 && !range) {
|
|
237
|
+
await this.cacheRead(key, result);
|
|
238
|
+
}
|
|
239
|
+
return result;
|
|
240
|
+
}
|
|
241
|
+
// The routing file is only ever read off our own disk - falling back to another source's copy would synchronize it between nodes through the read path, which it never is
|
|
242
|
+
if (key === remoteConfig_1.ROUTING_FILE) {
|
|
243
|
+
if (holderError)
|
|
244
|
+
throw holderError;
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
// The holder is down or lost the file. ANY other source's copy beats no value - even an OLDER one - and it's copied onto our disk so the next read doesn't depend on luck.
|
|
248
|
+
let holderSlot = this.slotForSourcesListIndex(entry.sourcesListIndex);
|
|
249
|
+
for (let i = 0; i < this.sources.length; i++) {
|
|
250
|
+
if (i === holderSlot || !this.isLive(i))
|
|
186
251
|
continue;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
252
|
+
let fallback;
|
|
253
|
+
try {
|
|
254
|
+
let answer = await this.sources[i].source.get2(key, { internal: true });
|
|
255
|
+
// Empty data counts as absent - a tombstone, not content (this read is unranged, so emptiness is unambiguous)
|
|
256
|
+
if (answer && answer.data && answer.data.length) {
|
|
257
|
+
fallback = { data: answer.data, writeTime: answer.writeTime, size: answer.size };
|
|
258
|
+
}
|
|
190
259
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
260
|
+
catch (_a) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
if (!fallback)
|
|
264
|
+
continue;
|
|
265
|
+
await this.cacheRead(key, fallback);
|
|
266
|
+
let data = fallback.data;
|
|
267
|
+
if (range) {
|
|
268
|
+
data = data.subarray(Math.min(range.start, data.length), Math.min(range.end, data.length));
|
|
269
|
+
}
|
|
270
|
+
return { data, writeTime: fallback.writeTime, size: fallback.size };
|
|
194
271
|
}
|
|
272
|
+
if (holderError)
|
|
273
|
+
throw holderError;
|
|
274
|
+
// The holder answered "not there" and no other source has it either: the entry was stale
|
|
275
|
+
this.deleteIndexEntry(key);
|
|
276
|
+
return undefined;
|
|
195
277
|
}
|
|
196
|
-
|
|
197
|
-
|
|
278
|
+
async set(config) {
|
|
279
|
+
let { path: key, data } = config;
|
|
280
|
+
if (!data.length) {
|
|
281
|
+
throw new Error(`set was called with an empty buffer for ${JSON.stringify(key)} (store ${this.folder}): an empty file IS a deletion in this system and would read back as missing - call del instead`);
|
|
282
|
+
}
|
|
283
|
+
await this.init();
|
|
284
|
+
let writeTime = config.lastModified || Date.now();
|
|
285
|
+
let route = (0, remoteConfig_1.getRoute)(key);
|
|
286
|
+
// The routing file defines the windows/routes, so they can't possibly apply to it (and it never flows through validation)
|
|
287
|
+
if (key !== remoteConfig_1.ROUTING_FILE && this.entries.length) {
|
|
288
|
+
if (!config.lastModified) {
|
|
289
|
+
let timeValid = this.entries.filter(x => writeTime >= x.validWindow[0] && writeTime < x.validWindow[1]);
|
|
290
|
+
if (!timeValid.length) {
|
|
291
|
+
logWrongTargetRejection(`Rejecting fresh write of ${JSON.stringify(key)} (store ${this.folder}): writeTime ${writeTime} (${new Date(writeTime).toISOString()}) is outside all our valid windows ${JSON.stringify(this.entries.map(x => x.validWindow))} (a switchover moved the write target)`);
|
|
292
|
+
throw new Error(`${IArchives_1.STORAGE_WRONG_VALID_WINDOW} This store is not a valid write target at ${writeTime} (our valid windows: ${JSON.stringify(this.entries.map(x => x.validWindow))}, store ${this.folder}). Re-resolve the currently valid source and retry.`);
|
|
293
|
+
}
|
|
294
|
+
if (!timeValid.some(x => (0, remoteConfig_1.routeContains)(x.route, route))) {
|
|
295
|
+
logWrongTargetRejection(`Rejecting fresh write of ${JSON.stringify(key)} (store ${this.folder}): route ${route} is outside our routes ${JSON.stringify(timeValid.map(x => x.route || IArchives_1.FULL_ROUTE))} at writeTime ${writeTime} (the client's shard config is stale)`);
|
|
296
|
+
throw new Error(`${IArchives_1.STORAGE_WRONG_ROUTE} This store does not handle route ${route} (key ${JSON.stringify(key)}, our routes at this time: ${JSON.stringify(timeValid.map(x => x.route || IArchives_1.FULL_ROUTE))}, store ${this.folder}). Re-resolve the source for this key and retry.`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (config.forceSetImmutable) {
|
|
300
|
+
if (!config.lastModified) {
|
|
301
|
+
throw new Error(`forceSetImmutable requires lastModified (synchronization writes are ordered by their write time), writing ${JSON.stringify(key)} (store ${this.folder})`);
|
|
302
|
+
}
|
|
303
|
+
// Immutability wins: an existing path is kept instead of the push throwing (see SetConfig.forceSetImmutable)
|
|
304
|
+
let self = (0, storePlan_1.selectEntryAt)(this.entries, writeTime, route);
|
|
305
|
+
if ((self === null || self === void 0 ? void 0 : self.immutable) && await this.getInfo({ path: key }))
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
await this.assertMutable(key, writeTime);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (config.internal) {
|
|
313
|
+
if (!config.lastModified) {
|
|
314
|
+
throw new Error(`Internal writes must carry lastModified (they are synchronization pushes, ordered by their write time), writing ${JSON.stringify(key)} (store ${this.folder})`);
|
|
315
|
+
}
|
|
316
|
+
this.assertInternalWriteAccepted(key, config.lastModified, route);
|
|
317
|
+
await this.setInternal(key, data, { lastModified: config.lastModified });
|
|
198
318
|
return;
|
|
199
|
-
this.indexFileCount += direction;
|
|
200
|
-
this.indexByteCount += entry.size * direction;
|
|
201
|
-
// Entries can reference a source no longer configured (readable via getEntryHolder, but with no slot to count under)
|
|
202
|
-
let slot = this.slotForSourcesListIndex(entry.sourcesListIndex);
|
|
203
|
-
if (slot !== undefined) {
|
|
204
|
-
this.sourceFileCounts[slot] += direction;
|
|
205
|
-
this.sourceByteCounts[slot] += entry.size * direction;
|
|
206
319
|
}
|
|
320
|
+
let self = this.entries.length && (0, storePlan_1.selectEntryAt)(this.entries, writeTime, route) || undefined;
|
|
321
|
+
await this.setOrDelete(key, data, { fast: self === null || self === void 0 ? void 0 : self.fast, writeDelay: self === null || self === void 0 ? void 0 : self.writeDelay, lastModified: config.lastModified });
|
|
207
322
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
this.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
323
|
+
async del(config) {
|
|
324
|
+
let key = config.path;
|
|
325
|
+
if (key === remoteConfig_1.ROUTING_FILE) {
|
|
326
|
+
throw new Error(`The routing config ${JSON.stringify(remoteConfig_1.ROUTING_FILE)} cannot be deleted (overwrite it to change the bucket's configuration)`);
|
|
327
|
+
}
|
|
328
|
+
await this.init();
|
|
329
|
+
if (config.internal) {
|
|
330
|
+
if (!config.lastModified) {
|
|
331
|
+
throw new Error(`Internal deletions must carry lastModified (they are synchronization pushes, ordered by their write time), deleting ${JSON.stringify(key)} (store ${this.folder})`);
|
|
332
|
+
}
|
|
333
|
+
this.assertInternalWriteAccepted(key, config.lastModified, (0, remoteConfig_1.getRoute)(key));
|
|
334
|
+
// setInternal treats an empty buffer as exactly a deletion: disk removal plus a tombstone index entry, no fan-out
|
|
335
|
+
await this.setInternal(key, Buffer.alloc(0), { lastModified: config.lastModified });
|
|
220
336
|
return;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
337
|
+
}
|
|
338
|
+
// Deletes are tombstone writes (an empty file IS a missing file): the size-0 index entry is ordered by write time like any other write, propagates through synchronization, and expires after TOMBSTONE_EXPIRY
|
|
339
|
+
let writeTime = config.lastModified || Date.now();
|
|
340
|
+
let self = this.entries.length && (0, storePlan_1.selectEntryAt)(this.entries, writeTime, (0, remoteConfig_1.getRoute)(key)) || undefined;
|
|
341
|
+
await this.setOrDelete(key, Buffer.alloc(0), { fast: self === null || self === void 0 ? void 0 : self.fast, writeDelay: self === null || self === void 0 ? void 0 : self.writeDelay, lastModified: config.lastModified });
|
|
342
|
+
}
|
|
343
|
+
async getInfo(config) {
|
|
344
|
+
await this.init();
|
|
345
|
+
let key = config.path;
|
|
346
|
+
let overlayEntry = this.overlay.get(key);
|
|
347
|
+
if (overlayEntry) {
|
|
348
|
+
if (!overlayEntry.data.length && !config.includeTombstones)
|
|
349
|
+
return undefined;
|
|
350
|
+
return { writeTime: overlayEntry.t, size: overlayEntry.data.length };
|
|
351
|
+
}
|
|
352
|
+
let entry = await this.getIndexEntry(key);
|
|
353
|
+
if (!entry)
|
|
354
|
+
return undefined;
|
|
355
|
+
if (!entry.size && !config.includeTombstones)
|
|
356
|
+
return undefined;
|
|
357
|
+
return { writeTime: entry.writeTime, size: entry.size };
|
|
358
|
+
}
|
|
359
|
+
async findInfo(config) {
|
|
360
|
+
await this.init();
|
|
361
|
+
await this.waitForRequiredScans();
|
|
362
|
+
let prefix = config.prefix;
|
|
363
|
+
let infos = new Map();
|
|
364
|
+
for (let [key, entry] of this.mem) {
|
|
365
|
+
if (!key.startsWith(prefix))
|
|
366
|
+
continue;
|
|
367
|
+
// Tombstones are missing files, so listings hide them
|
|
368
|
+
if (entry.size === 0)
|
|
369
|
+
continue;
|
|
370
|
+
infos.set(key, { path: key, createTime: entry.writeTime, size: entry.size });
|
|
371
|
+
}
|
|
372
|
+
for (let [key, overlayEntry] of this.overlay) {
|
|
373
|
+
if (!key.startsWith(prefix))
|
|
374
|
+
continue;
|
|
375
|
+
if (overlayEntry.data.length === 0) {
|
|
376
|
+
infos.delete(key);
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
infos.set(key, { path: key, createTime: overlayEntry.t, size: overlayEntry.data.length });
|
|
380
|
+
}
|
|
381
|
+
let files = (0, ArchivesDisk_1.applyFindInfoShape)(Array.from(infos.values()), prefix, { shallow: config.shallow, type: config.type });
|
|
382
|
+
(0, misc_1.sort)(files, x => x.path);
|
|
383
|
+
return files;
|
|
384
|
+
}
|
|
385
|
+
// All files changed after config.time — fast, straight from the in-memory index. Filters on when WE learned of the change (changedAt), so files synchronized late (with old write times) are still reported. Deletions ARE reported, as size-0 tombstone entries — that's how they propagate to stores syncing from us. config.routes lets a store syncing a partial shard ask for just its slice.
|
|
386
|
+
async getChangesAfter2(config) {
|
|
387
|
+
await this.init();
|
|
388
|
+
await this.waitForRequiredScans();
|
|
389
|
+
let inRoutes = (key) => !config.routes || config.routes.some(route => (0, remoteConfig_1.routeContains)(route, (0, remoteConfig_1.getRoute)(key)));
|
|
390
|
+
let files = [];
|
|
391
|
+
for (let [key, entry] of this.mem) {
|
|
392
|
+
if (entry.changedAt <= config.time)
|
|
393
|
+
continue;
|
|
394
|
+
if (this.overlay.has(key))
|
|
395
|
+
continue;
|
|
396
|
+
if (!inRoutes(key))
|
|
397
|
+
continue;
|
|
398
|
+
files.push({ path: key, createTime: entry.writeTime, size: entry.size });
|
|
399
|
+
}
|
|
400
|
+
for (let [key, overlayEntry] of this.overlay) {
|
|
401
|
+
if (overlayEntry.t <= config.time)
|
|
402
|
+
continue;
|
|
403
|
+
if (!inRoutes(key))
|
|
404
|
+
continue;
|
|
405
|
+
files.push({ path: key, createTime: overlayEntry.t, size: overlayEntry.data.length });
|
|
406
|
+
}
|
|
407
|
+
(0, misc_1.sort)(files, x => x.path);
|
|
408
|
+
return files;
|
|
409
|
+
}
|
|
410
|
+
async getSyncStatus() {
|
|
411
|
+
await this.init();
|
|
412
|
+
return {
|
|
413
|
+
allScansComplete: this.sourceStates.every(x => x.scanComplete),
|
|
414
|
+
indexSize: this.mem.size,
|
|
415
|
+
sources: this.sources.map((x, i) => ({
|
|
416
|
+
debugName: x.source.getDebugName(),
|
|
417
|
+
validWindow: x.validWindow,
|
|
418
|
+
route: x.route,
|
|
419
|
+
noFullSync: x.noFullSync,
|
|
420
|
+
supportsChangesAfter: this.sourceStates[i].supportsChangesAfter,
|
|
421
|
+
initialScanComplete: this.sourceStates[i].scanComplete,
|
|
422
|
+
scannedCount: this.sourceStates[i].scannedCount,
|
|
423
|
+
})).filter((x, i) => this.isLive(i)),
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
/** The cheap always-current totals plus any in-progress background synchronization. */
|
|
427
|
+
getSyncProgress() {
|
|
428
|
+
var _a;
|
|
429
|
+
return {
|
|
430
|
+
index: { fileCount: this.indexFileCount, byteCount: this.indexByteCount },
|
|
431
|
+
sources: this.sources.map((x, i) => ({
|
|
432
|
+
debugName: x.source.getDebugName(),
|
|
433
|
+
fileCount: this.sourceFileCounts[i],
|
|
434
|
+
byteCount: this.sourceByteCounts[i],
|
|
435
|
+
})).filter((x, i) => this.isLive(i)),
|
|
436
|
+
readerDiskLimit: (_a = this.config) === null || _a === void 0 ? void 0 : _a.readerDiskLimit,
|
|
437
|
+
syncing: [...this.syncActivities],
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
/** Walks the whole index for exact totals - more expensive than getSyncProgress, but immune to any drift in the maintained counters (and loads the index first, so it's never cold zeros). */
|
|
441
|
+
async computeIndexTotals() {
|
|
442
|
+
await this.init();
|
|
443
|
+
let fileCount = 0;
|
|
444
|
+
let byteCount = 0;
|
|
445
|
+
let sources = this.sources.map(x => ({ debugName: x.source.getDebugName(), fileCount: 0, byteCount: 0 }));
|
|
446
|
+
for (let entry of this.mem.values()) {
|
|
447
|
+
if (entry.size === 0)
|
|
448
|
+
continue;
|
|
449
|
+
fileCount++;
|
|
450
|
+
byteCount += entry.size;
|
|
451
|
+
let slot = this.slotForSourcesListIndex(entry.sourcesListIndex);
|
|
452
|
+
if (slot !== undefined) {
|
|
453
|
+
sources[slot].fileCount++;
|
|
454
|
+
sources[slot].byteCount += entry.size;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return { fileCount, byteCount, sources: sources.filter((x, i) => this.isLive(i)) };
|
|
224
458
|
}
|
|
225
459
|
/** Applies a config change to the RUNNING store: windows/routes update in place, new sources are added (their sync starts immediately), and removed sources' slots go dead (their scans stop, their index entries drop). The store survives every routine config evolution - it is never destroyed for a source-list change, only for structural flips it cannot express (rawDisk). Pending fast writes are re-capped to the new flush deadline (flushing immediately when it has already passed). */
|
|
226
|
-
updateSources(specs) {
|
|
460
|
+
updateSources(specs, entries) {
|
|
227
461
|
var _a;
|
|
228
462
|
if (!specs.length || specs[0].identity !== "disk") {
|
|
229
463
|
throw new Error(`updateSources expects the disk source first (identity "disk"), got ${JSON.stringify(specs.map(x => x.identity))} (store ${this.folder})`);
|
|
230
464
|
}
|
|
465
|
+
if (entries) {
|
|
466
|
+
this.entries = entries;
|
|
467
|
+
}
|
|
231
468
|
let setWindow = (i, window) => {
|
|
232
469
|
let old = this.sources[i].validWindow;
|
|
233
470
|
if (old[0] === window[0] && old[1] === window[1])
|
|
@@ -296,29 +533,6 @@ class BlobStore {
|
|
|
296
533
|
}
|
|
297
534
|
}
|
|
298
535
|
}
|
|
299
|
-
// The slot stays in the arrays forever (index entries reference sources by slot number); it just goes dead - loops stop, and its index entries drop (other sources' scans re-find any copy that's still reachable through the new config)
|
|
300
|
-
removeSource(sourceIndex) {
|
|
301
|
-
let state = this.sourceStates[sourceIndex];
|
|
302
|
-
let source = this.sources[sourceIndex].source;
|
|
303
|
-
state.dead = true;
|
|
304
|
-
state.stopped.stop = true;
|
|
305
|
-
state.scanComplete = true;
|
|
306
|
-
state.initialScan.resolve(undefined);
|
|
307
|
-
let sourcesListIndex = this.slotSourcesListIndexes[sourceIndex];
|
|
308
|
-
// The same URL can be another live slot (one entry per valid window) - the endpoint is still configured, so its entries stay
|
|
309
|
-
if (sourcesListIndex !== undefined && this.slotForSourcesListIndex(sourcesListIndex) === undefined) {
|
|
310
|
-
let dropped = 0;
|
|
311
|
-
for (let [key, entry] of this.mem) {
|
|
312
|
-
if (entry.sourcesListIndex !== sourcesListIndex)
|
|
313
|
-
continue;
|
|
314
|
-
this.deleteIndexEntry(key);
|
|
315
|
-
dropped++;
|
|
316
|
-
}
|
|
317
|
-
console.log(`Removed sync source ${source.getDebugName()} (store ${this.folder}): its scans are stopped and ${dropped} index entries it held were dropped`);
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
console.log(`Removed sync source ${source.getDebugName()} (store ${this.folder}): its scans are stopped (its URL is still served by another slot, so its index entries stay)`);
|
|
321
|
-
}
|
|
322
536
|
/** Rescans our own disk's metadata into the index - used around valid window handoffs, where another process wrote files to the shared folder that our index hasn't seen. */
|
|
323
537
|
async rescanBase() {
|
|
324
538
|
await this.init();
|
|
@@ -365,40 +579,147 @@ class BlobStore {
|
|
|
365
579
|
tally.new++;
|
|
366
580
|
}
|
|
367
581
|
}
|
|
368
|
-
console.log(`Boundary scan of ${source.getDebugName()} finished in ${Math.round((Date.now() - scanStart) / 1000)}s (store ${this.folder}): ${changes.length} changes: ${formatScanTally(tally, changes.length)}`);
|
|
582
|
+
console.log(`Boundary scan of ${source.getDebugName()} finished in ${Math.round((Date.now() - scanStart) / 1000)}s (store ${this.folder}): ${changes.length} changes: ${formatScanTally(tally, changes.length)}`);
|
|
583
|
+
}
|
|
584
|
+
// Large uploads stream onto the local disk source directly (they may not fit in memory)
|
|
585
|
+
async startLargeUpload(config) {
|
|
586
|
+
await this.init();
|
|
587
|
+
if (config === null || config === void 0 ? void 0 : config.path) {
|
|
588
|
+
await this.assertMutable(config.path, config.lastModified || Date.now());
|
|
589
|
+
}
|
|
590
|
+
return await this.getDiskSource().disk.startLargeUpload();
|
|
591
|
+
}
|
|
592
|
+
async appendLargeUpload(config) {
|
|
593
|
+
await this.getDiskSource().disk.appendLargeUpload(config.id, config.data);
|
|
594
|
+
}
|
|
595
|
+
async finishLargeUpload(config) {
|
|
596
|
+
let { disk, sourceIndex } = this.getDiskSource();
|
|
597
|
+
await disk.finishLargeUpload(config.id, config.path, config.lastModified);
|
|
598
|
+
this.overlay.delete(config.path);
|
|
599
|
+
// includeTombstones: a zero-byte upload is still a real file whose index entry must be written
|
|
600
|
+
let info = await disk.getInfo(config.path, { includeTombstones: true });
|
|
601
|
+
if (info) {
|
|
602
|
+
this.setIndexEntry(config.path, { writeTime: info.writeTime, size: info.size, sourcesListIndex: this.sourcesListIndexOfSlot(sourceIndex) });
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
async cancelLargeUpload(config) {
|
|
606
|
+
await this.getDiskSource().disk.cancelLargeUpload(config.id);
|
|
607
|
+
}
|
|
608
|
+
isLive(sourceIndex) {
|
|
609
|
+
return !!this.sources[sourceIndex] && !this.sourceStates[sourceIndex].dead;
|
|
610
|
+
}
|
|
611
|
+
registerSlot(slot) {
|
|
612
|
+
let existing = this.slotRegistrations[slot];
|
|
613
|
+
if (existing)
|
|
614
|
+
return existing;
|
|
615
|
+
let registration = this.sourcesList.ensure(this.sources[slot].url).then(index => {
|
|
616
|
+
this.slotSourcesListIndexes[slot] = index;
|
|
617
|
+
});
|
|
618
|
+
this.slotRegistrations[slot] = registration;
|
|
619
|
+
return registration;
|
|
620
|
+
}
|
|
621
|
+
// The persistent sourcesListIndex of a slot - only valid once the slot's registration resolved (init and runSourceSync guarantee that before any indexing happens)
|
|
622
|
+
sourcesListIndexOfSlot(slot) {
|
|
623
|
+
var _a;
|
|
624
|
+
let index = this.slotSourcesListIndexes[slot];
|
|
625
|
+
if (index === undefined) {
|
|
626
|
+
throw new Error(`Source slot ${slot} (${(_a = this.sources[slot]) === null || _a === void 0 ? void 0 : _a.url}) has no registered sourcesListIndex yet (store ${this.folder})`);
|
|
627
|
+
}
|
|
628
|
+
return index;
|
|
629
|
+
}
|
|
630
|
+
// The live slot currently serving a persistent sourcesListIndex, or undefined when no configured source has that URL anymore. Linear, but the sources list is tiny and this is always current (slots dying, or several slots sharing one URL across valid windows, need no bookkeeping).
|
|
631
|
+
slotForSourcesListIndex(sourcesListIndex) {
|
|
632
|
+
for (let i = 0; i < this.slotSourcesListIndexes.length; i++) {
|
|
633
|
+
if (this.slotSourcesListIndexes[i] === sourcesListIndex && this.isLive(i))
|
|
634
|
+
return i;
|
|
635
|
+
}
|
|
636
|
+
return undefined;
|
|
637
|
+
}
|
|
638
|
+
// The IArchives currently holding an entry's bytes: the live slot when the holder is still configured, otherwise resolved (cached) straight from its persisted URL - windows/routes decide when a source is scanned or written, but for reading bytes we know it holds, the URL alone is enough
|
|
639
|
+
async getEntryHolder(entry) {
|
|
640
|
+
var _a, _b;
|
|
641
|
+
let slot = this.slotForSourcesListIndex(entry.sourcesListIndex);
|
|
642
|
+
if (slot !== undefined)
|
|
643
|
+
return this.sources[slot].source;
|
|
644
|
+
let url = this.sourcesList.getUrl(entry.sourcesListIndex) || await this.sourcesList.getUrlReloading(entry.sourcesListIndex);
|
|
645
|
+
if (!url)
|
|
646
|
+
return undefined;
|
|
647
|
+
return (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.resolveSourceUrl) === null || _b === void 0 ? void 0 : _b.call(_a, url);
|
|
648
|
+
}
|
|
649
|
+
async loadIndex() {
|
|
650
|
+
let [writeTimes, sizes, sourcesListIndexes] = await Promise.all([
|
|
651
|
+
this.index.getColumn("writeTime"),
|
|
652
|
+
this.index.getColumn("size"),
|
|
653
|
+
this.index.getColumn("sourcesListIndex"),
|
|
654
|
+
]);
|
|
655
|
+
let sizeMap = new Map(sizes.map(x => [x.key, x.value]));
|
|
656
|
+
let sourcesListIndexMap = new Map(sourcesListIndexes.map(x => [x.key, x.value]));
|
|
657
|
+
for (let entry of writeTimes) {
|
|
658
|
+
let size = sizeMap.get(entry.key);
|
|
659
|
+
let sourcesListIndex = sourcesListIndexMap.get(entry.key);
|
|
660
|
+
// Explicit checks, as 0 is a valid size and a valid sourcesListIndex
|
|
661
|
+
if (size === undefined || sourcesListIndex === undefined)
|
|
662
|
+
continue;
|
|
663
|
+
// The routing config is only ever read off our own disk (see updateScanIndex), and a loaded bucket always has it there - a persisted entry pointing elsewhere is stale
|
|
664
|
+
if (entry.key === remoteConfig_1.ROUTING_FILE) {
|
|
665
|
+
sourcesListIndex = this.sourcesListIndexOfSlot(0);
|
|
666
|
+
}
|
|
667
|
+
let full = { writeTime: entry.value, size, sourcesListIndex, changedAt: entry.time, lastAccess: entry.time };
|
|
668
|
+
this.mem.set(entry.key, full);
|
|
669
|
+
this.countEntry(full, 1);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
countEntry(entry, direction) {
|
|
673
|
+
if (!entry || entry.size === 0)
|
|
674
|
+
return;
|
|
675
|
+
this.indexFileCount += direction;
|
|
676
|
+
this.indexByteCount += entry.size * direction;
|
|
677
|
+
// Entries can reference a source no longer configured (readable via getEntryHolder, but with no slot to count under)
|
|
678
|
+
let slot = this.slotForSourcesListIndex(entry.sourcesListIndex);
|
|
679
|
+
if (slot !== undefined) {
|
|
680
|
+
this.sourceFileCounts[slot] += direction;
|
|
681
|
+
this.sourceByteCounts[slot] += entry.size * direction;
|
|
682
|
+
}
|
|
369
683
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
byteCount: this.sourceByteCounts[i],
|
|
379
|
-
})).filter((x, i) => this.isLive(i)),
|
|
380
|
-
readerDiskLimit: (_a = this.config) === null || _a === void 0 ? void 0 : _a.readerDiskLimit,
|
|
381
|
-
syncing: [...this.syncActivities],
|
|
382
|
-
};
|
|
684
|
+
setIndexEntry(key, entry) {
|
|
685
|
+
var _a, _b;
|
|
686
|
+
let full = { ...entry, changedAt: Date.now(), lastAccess: Date.now() };
|
|
687
|
+
this.countEntry(this.mem.get(key), -1);
|
|
688
|
+
this.countEntry(full, 1);
|
|
689
|
+
this.mem.set(key, full);
|
|
690
|
+
this.dirty.set(key, full);
|
|
691
|
+
(_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.onIndexChanged) === null || _b === void 0 ? void 0 : _b.call(_a, key);
|
|
383
692
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
693
|
+
deleteIndexEntry(key) {
|
|
694
|
+
let existing = this.mem.get(key);
|
|
695
|
+
if (!existing)
|
|
696
|
+
return;
|
|
697
|
+
this.countEntry(existing, -1);
|
|
698
|
+
this.mem.delete(key);
|
|
699
|
+
this.dirty.set(key, undefined);
|
|
700
|
+
}
|
|
701
|
+
// The slot stays in the arrays forever (index entries reference sources by slot number); it just goes dead - loops stop, and its index entries drop (other sources' scans re-find any copy that's still reachable through the new config)
|
|
702
|
+
removeSource(sourceIndex) {
|
|
703
|
+
let state = this.sourceStates[sourceIndex];
|
|
704
|
+
let source = this.sources[sourceIndex].source;
|
|
705
|
+
state.dead = true;
|
|
706
|
+
state.stopped.stop = true;
|
|
707
|
+
state.scanComplete = true;
|
|
708
|
+
state.initialScan.resolve(undefined);
|
|
709
|
+
let sourcesListIndex = this.slotSourcesListIndexes[sourceIndex];
|
|
710
|
+
// The same URL can be another live slot (one entry per valid window) - the endpoint is still configured, so its entries stay
|
|
711
|
+
if (sourcesListIndex !== undefined && this.slotForSourcesListIndex(sourcesListIndex) === undefined) {
|
|
712
|
+
let dropped = 0;
|
|
713
|
+
for (let [key, entry] of this.mem) {
|
|
714
|
+
if (entry.sourcesListIndex !== sourcesListIndex)
|
|
715
|
+
continue;
|
|
716
|
+
this.deleteIndexEntry(key);
|
|
717
|
+
dropped++;
|
|
399
718
|
}
|
|
719
|
+
console.log(`Removed sync source ${source.getDebugName()} (store ${this.folder}): its scans are stopped and ${dropped} index entries it held were dropped`);
|
|
720
|
+
return;
|
|
400
721
|
}
|
|
401
|
-
|
|
722
|
+
console.log(`Removed sync source ${source.getDebugName()} (store ${this.folder}): its scans are stopped (its URL is still served by another slot, so its index entries stay)`);
|
|
402
723
|
}
|
|
403
724
|
async flushIndex() {
|
|
404
725
|
if (!this.dirty.size)
|
|
@@ -420,6 +741,26 @@ class BlobStore {
|
|
|
420
741
|
if (deletes.length)
|
|
421
742
|
await this.index.deleteBatch(deletes);
|
|
422
743
|
}
|
|
744
|
+
// ── validation (from this store's own routing entries) ──
|
|
745
|
+
async assertMutable(key, writeTime) {
|
|
746
|
+
if (!this.entries.length)
|
|
747
|
+
return;
|
|
748
|
+
let self = (0, storePlan_1.selectEntryAt)(this.entries, writeTime, (0, remoteConfig_1.getRoute)(key));
|
|
749
|
+
if (!(self === null || self === void 0 ? void 0 : self.immutable))
|
|
750
|
+
return;
|
|
751
|
+
if (await this.getInfo({ path: key })) {
|
|
752
|
+
throw new Error(`This store is immutable (at write time ${writeTime}) and ${JSON.stringify(key)} already exists, so it cannot be written to (store ${this.folder})`);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
// See SetConfig.internal: the stamp must land inside SOME window+route this store is configured for (any window, including past ones - synchronization moves old data), so a confused peer can't stuff data onto a store that was never meant to hold it
|
|
756
|
+
assertInternalWriteAccepted(key, writeTime, route) {
|
|
757
|
+
if (!this.entries.length)
|
|
758
|
+
return;
|
|
759
|
+
let covered = this.entries.some(x => writeTime >= x.validWindow[0] && writeTime < x.validWindow[1] && (0, remoteConfig_1.routeContains)(x.route, route));
|
|
760
|
+
if (!covered) {
|
|
761
|
+
throw new Error(`Internal write of ${JSON.stringify(key)} rejected: writeTime ${writeTime} (${new Date(writeTime).toISOString()}) at route ${route} is outside every window/route this store is configured for: ${JSON.stringify(this.entries.map(x => ({ validWindow: x.validWindow, route: x.route || IArchives_1.FULL_ROUTE })))} (store ${this.folder})`);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
423
764
|
// ── synchronization ──
|
|
424
765
|
async runSourceSync(sourceIndex) {
|
|
425
766
|
var _a;
|
|
@@ -794,103 +1135,22 @@ class BlobStore {
|
|
|
794
1135
|
await this.checkMissingKey(key);
|
|
795
1136
|
return this.mem.get(key);
|
|
796
1137
|
}
|
|
797
|
-
|
|
798
|
-
async
|
|
799
|
-
let result = await this.get2(key, config);
|
|
800
|
-
return result && result.data || undefined;
|
|
801
|
-
}
|
|
802
|
-
async get2(key, config) {
|
|
1138
|
+
/** Internal (store-to-store) read: purely the local disk, completely short-circuiting the index and holder resolution - the caller is another store, and chasing OUR remote holders while answering it is how infinite get loops between stores form. No window or route checks: if the bytes are on our disk, the caller may have them. Note fast writes still sitting in the overlay are invisible here; the caller re-finds them after our flush. */
|
|
1139
|
+
async getInternal2(config) {
|
|
803
1140
|
await this.init();
|
|
804
|
-
|
|
805
|
-
let
|
|
806
|
-
if (
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
let size = data.length;
|
|
812
|
-
if (range) {
|
|
813
|
-
data = data.subarray(Math.min(range.start, data.length), Math.min(range.end, data.length));
|
|
814
|
-
}
|
|
815
|
-
return { data, writeTime: overlayEntry.t, size };
|
|
816
|
-
}
|
|
817
|
-
let entry = await this.getIndexEntry(key);
|
|
818
|
-
if (!entry)
|
|
819
|
-
return undefined;
|
|
820
|
-
if (entry.size === 0)
|
|
821
|
-
return undefined;
|
|
822
|
-
entry.lastAccess = Date.now();
|
|
823
|
-
let holderArchives = await this.getEntryHolder(entry);
|
|
824
|
-
let result;
|
|
825
|
-
let holderError;
|
|
826
|
-
if (holderArchives) {
|
|
827
|
-
try {
|
|
828
|
-
let answer = await holderArchives.get2(key, { range, internal: true });
|
|
829
|
-
// Empty data counts as absent: an empty file IS a deletion (a tombstone stored on b2/disk), never content. NOTE: a ranged read of a real file can legitimately be empty (range past EOF), so only unranged emptiness means absent.
|
|
830
|
-
if (answer && answer.data && (answer.data.length || range && answer.size)) {
|
|
831
|
-
result = { data: answer.data, writeTime: answer.writeTime, size: answer.size };
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
catch (e) {
|
|
835
|
-
holderError = e;
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
if (result) {
|
|
839
|
-
// Ranged reads can't populate a cache (they're partial)
|
|
840
|
-
if (this.slotForSourcesListIndex(entry.sourcesListIndex) !== 0 && !range) {
|
|
841
|
-
await this.cacheRead(key, result);
|
|
1141
|
+
// includeTombstones forwards to the disk: a flag-caller (a peer store's synchronization) needs to see our deletions, not just our content. A tombstone deleted from disk entirely only lives in our index, so fall back to that.
|
|
1142
|
+
let result = await this.getDiskSource().disk.get2(config.path, { range: config.range, includeTombstones: config.includeTombstones });
|
|
1143
|
+
if (!result || !result.data) {
|
|
1144
|
+
if (config.includeTombstones) {
|
|
1145
|
+
let entry = this.mem.get(config.path);
|
|
1146
|
+
if (entry && !entry.size)
|
|
1147
|
+
return { data: Buffer.alloc(0), writeTime: entry.writeTime, size: 0 };
|
|
842
1148
|
}
|
|
843
|
-
return result;
|
|
844
|
-
}
|
|
845
|
-
// The routing file is only ever read off our own disk - falling back to another source's copy would synchronize it between nodes through the read path, which it never is
|
|
846
|
-
if (key === remoteConfig_1.ROUTING_FILE) {
|
|
847
|
-
if (holderError)
|
|
848
|
-
throw holderError;
|
|
849
1149
|
return undefined;
|
|
850
1150
|
}
|
|
851
|
-
// The holder is down or lost the file. ANY other source's copy beats no value - even an OLDER one - and it's copied onto our disk so the next read doesn't depend on luck.
|
|
852
|
-
let holderSlot = this.slotForSourcesListIndex(entry.sourcesListIndex);
|
|
853
|
-
for (let i = 0; i < this.sources.length; i++) {
|
|
854
|
-
if (i === holderSlot || !this.isLive(i))
|
|
855
|
-
continue;
|
|
856
|
-
let fallback;
|
|
857
|
-
try {
|
|
858
|
-
let answer = await this.sources[i].source.get2(key, { internal: true });
|
|
859
|
-
// Empty data counts as absent - a tombstone, not content (this read is unranged, so emptiness is unambiguous)
|
|
860
|
-
if (answer && answer.data && answer.data.length) {
|
|
861
|
-
fallback = { data: answer.data, writeTime: answer.writeTime, size: answer.size };
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
catch (_a) {
|
|
865
|
-
continue;
|
|
866
|
-
}
|
|
867
|
-
if (!fallback)
|
|
868
|
-
continue;
|
|
869
|
-
await this.cacheRead(key, fallback);
|
|
870
|
-
let data = fallback.data;
|
|
871
|
-
if (range) {
|
|
872
|
-
data = data.subarray(Math.min(range.start, data.length), Math.min(range.end, data.length));
|
|
873
|
-
}
|
|
874
|
-
return { data, writeTime: fallback.writeTime, size: fallback.size };
|
|
875
|
-
}
|
|
876
|
-
if (holderError)
|
|
877
|
-
throw holderError;
|
|
878
|
-
// The holder answered "not there" and no other source has it either: the entry was stale
|
|
879
|
-
this.deleteIndexEntry(key);
|
|
880
|
-
return undefined;
|
|
881
|
-
}
|
|
882
|
-
/** Internal (store-to-store) read: purely the local disk, completely short-circuiting the index and holder resolution - the caller is another store, and chasing OUR remote holders while answering it is how infinite get loops between stores form. No window or route checks: if the bytes are on our disk, the caller may have them. Note fast writes still sitting in the overlay are invisible here; the caller re-finds them after our flush. */
|
|
883
|
-
async getInternal2(key, config) {
|
|
884
|
-
await this.init();
|
|
885
|
-
let result = await this.getDiskSource().disk.get2(key, { range: config === null || config === void 0 ? void 0 : config.range });
|
|
886
|
-
if (!result || !result.data)
|
|
887
|
-
return undefined;
|
|
888
|
-
// An empty file on disk is a tombstone, not content (a ranged read of a real file can be legitimately empty though - range past EOF)
|
|
889
|
-
if (!result.data.length && !((config === null || config === void 0 ? void 0 : config.range) && result.size))
|
|
890
|
-
return undefined;
|
|
891
1151
|
return { data: result.data, writeTime: result.writeTime, size: result.size };
|
|
892
1152
|
}
|
|
893
|
-
/** Internal (store-to-store) write: the local disk plus our index, with NO downstream fan-out - the pushing store owns propagation, and fanning its pushes back out is how write loops between stores form.
|
|
1153
|
+
/** Internal (store-to-store) write: the local disk plus our index, with NO downstream fan-out - the pushing store owns propagation, and fanning its pushes back out is how write loops between stores form. Only-take-latest still applies here. */
|
|
894
1154
|
async setInternal(key, data, config) {
|
|
895
1155
|
await this.init();
|
|
896
1156
|
(0, IArchives_1.assertValidLastModified)(config.lastModified);
|
|
@@ -913,22 +1173,11 @@ class BlobStore {
|
|
|
913
1173
|
await this.sources[0].source.set(key, result.data, { lastModified: result.writeTime, forceSetImmutable: true, noChecks: true });
|
|
914
1174
|
this.setIndexEntry(key, { writeTime: result.writeTime, size: result.data.length, sourcesListIndex: this.sourcesListIndexOfSlot(0) });
|
|
915
1175
|
}
|
|
916
|
-
async set(key, data, config) {
|
|
917
|
-
if (!data.length) {
|
|
918
|
-
throw new Error(`set was called with an empty buffer for ${JSON.stringify(key)} (store ${this.folder}): an empty file IS a deletion in this system and would read back as missing - call del instead`);
|
|
919
|
-
}
|
|
920
|
-
return await this.setOrDelete(key, data, config);
|
|
921
|
-
}
|
|
922
|
-
async del(key, config) {
|
|
923
|
-
// Deletes are tombstone writes (an empty file IS a missing file): the size-0 index entry is ordered by write time like any other write, propagates through synchronization, and expires after TOMBSTONE_EXPIRY
|
|
924
|
-
await this.setOrDelete(key, Buffer.alloc(0), config);
|
|
925
|
-
}
|
|
926
1176
|
// The shared engine of set and del: an empty buffer is exactly a deletion here, which is why the empty-buffer rejection lives in set (the public API), not in this machinery
|
|
927
1177
|
async setOrDelete(key, data, config) {
|
|
928
1178
|
var _a, _b;
|
|
929
|
-
await this.init();
|
|
930
1179
|
(_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.onWriteCounted) === null || _b === void 0 ? void 0 : _b.call(_a, "original", data.length);
|
|
931
|
-
let lastModified = config
|
|
1180
|
+
let lastModified = config.lastModified;
|
|
932
1181
|
if (lastModified) {
|
|
933
1182
|
(0, IArchives_1.assertValidLastModified)(lastModified);
|
|
934
1183
|
let overlayEntry = this.overlay.get(key);
|
|
@@ -936,10 +1185,10 @@ class BlobStore {
|
|
|
936
1185
|
let currentTime = overlayEntry && overlayEntry.t || entry && entry.writeTime || 0;
|
|
937
1186
|
// An older write never overwrites a newer one (see IArchives.set)
|
|
938
1187
|
if (lastModified < currentTime)
|
|
939
|
-
return
|
|
1188
|
+
return;
|
|
940
1189
|
}
|
|
941
1190
|
let writeTime = lastModified || Date.now();
|
|
942
|
-
if (config
|
|
1191
|
+
if (config.fast) {
|
|
943
1192
|
// A writeDelay of zero is a real choice (no delay at all), so only an omitted delay gets the default
|
|
944
1193
|
let writeDelay = config.writeDelay;
|
|
945
1194
|
if (writeDelay === undefined) {
|
|
@@ -950,15 +1199,11 @@ class BlobStore {
|
|
|
950
1199
|
if (writeDelay > 0 && Date.now() < deadline) {
|
|
951
1200
|
let flushAt = Math.min(Date.now() + writeDelay, deadline);
|
|
952
1201
|
this.overlay.set(key, { data, t: writeTime, flushAt });
|
|
953
|
-
return
|
|
1202
|
+
return;
|
|
954
1203
|
}
|
|
955
|
-
this.overlay.delete(key);
|
|
956
|
-
await this.writeToSources(key, data, writeTime);
|
|
957
|
-
return key;
|
|
958
1204
|
}
|
|
959
1205
|
this.overlay.delete(key);
|
|
960
1206
|
await this.writeToSources(key, data, writeTime);
|
|
961
|
-
return key;
|
|
962
1207
|
}
|
|
963
1208
|
getWritableSources(config) {
|
|
964
1209
|
let writable = [];
|
|
@@ -1010,89 +1255,6 @@ class BlobStore {
|
|
|
1010
1255
|
});
|
|
1011
1256
|
}
|
|
1012
1257
|
}
|
|
1013
|
-
async getInfo(key, config) {
|
|
1014
|
-
await this.init();
|
|
1015
|
-
let overlayEntry = this.overlay.get(key);
|
|
1016
|
-
if (overlayEntry) {
|
|
1017
|
-
if (!overlayEntry.data.length && !(config === null || config === void 0 ? void 0 : config.includeTombstones))
|
|
1018
|
-
return undefined;
|
|
1019
|
-
return { writeTime: overlayEntry.t, size: overlayEntry.data.length };
|
|
1020
|
-
}
|
|
1021
|
-
let entry = await this.getIndexEntry(key);
|
|
1022
|
-
if (!entry)
|
|
1023
|
-
return undefined;
|
|
1024
|
-
if (!entry.size && !(config === null || config === void 0 ? void 0 : config.includeTombstones))
|
|
1025
|
-
return undefined;
|
|
1026
|
-
return { writeTime: entry.writeTime, size: entry.size };
|
|
1027
|
-
}
|
|
1028
|
-
async findInfo(prefix, config) {
|
|
1029
|
-
await this.init();
|
|
1030
|
-
await this.waitForRequiredScans();
|
|
1031
|
-
let infos = new Map();
|
|
1032
|
-
for (let [key, entry] of this.mem) {
|
|
1033
|
-
if (!key.startsWith(prefix))
|
|
1034
|
-
continue;
|
|
1035
|
-
// Tombstones are missing files, so listings hide them
|
|
1036
|
-
if (entry.size === 0)
|
|
1037
|
-
continue;
|
|
1038
|
-
infos.set(key, { path: key, createTime: entry.writeTime, size: entry.size });
|
|
1039
|
-
}
|
|
1040
|
-
for (let [key, overlayEntry] of this.overlay) {
|
|
1041
|
-
if (!key.startsWith(prefix))
|
|
1042
|
-
continue;
|
|
1043
|
-
if (overlayEntry.data.length === 0) {
|
|
1044
|
-
infos.delete(key);
|
|
1045
|
-
continue;
|
|
1046
|
-
}
|
|
1047
|
-
infos.set(key, { path: key, createTime: overlayEntry.t, size: overlayEntry.data.length });
|
|
1048
|
-
}
|
|
1049
|
-
let files = (0, ArchivesDisk_1.applyFindInfoShape)(Array.from(infos.values()), prefix, config);
|
|
1050
|
-
(0, misc_1.sort)(files, x => x.path);
|
|
1051
|
-
return files;
|
|
1052
|
-
}
|
|
1053
|
-
// All files changed after config.time — fast, straight from the in-memory index. Filters on when WE learned of the change (changedAt), so files synchronized late (with old write times) are still reported. Deletions ARE reported, as size-0 tombstone entries — that's how they propagate to stores syncing from us. config.routes lets a store syncing a partial shard ask for just its slice.
|
|
1054
|
-
async getChangesAfter2(config) {
|
|
1055
|
-
await this.init();
|
|
1056
|
-
await this.waitForRequiredScans();
|
|
1057
|
-
let inRoutes = (key) => !config.routes || config.routes.some(route => (0, remoteConfig_1.routeContains)(route, (0, remoteConfig_1.getRoute)(key)));
|
|
1058
|
-
let files = [];
|
|
1059
|
-
for (let [key, entry] of this.mem) {
|
|
1060
|
-
if (entry.changedAt <= config.time)
|
|
1061
|
-
continue;
|
|
1062
|
-
if (this.overlay.has(key))
|
|
1063
|
-
continue;
|
|
1064
|
-
if (!inRoutes(key))
|
|
1065
|
-
continue;
|
|
1066
|
-
files.push({ path: key, createTime: entry.writeTime, size: entry.size });
|
|
1067
|
-
}
|
|
1068
|
-
for (let [key, overlayEntry] of this.overlay) {
|
|
1069
|
-
if (overlayEntry.t <= config.time)
|
|
1070
|
-
continue;
|
|
1071
|
-
if (!inRoutes(key))
|
|
1072
|
-
continue;
|
|
1073
|
-
files.push({ path: key, createTime: overlayEntry.t, size: overlayEntry.data.length });
|
|
1074
|
-
}
|
|
1075
|
-
(0, misc_1.sort)(files, x => x.path);
|
|
1076
|
-
return files;
|
|
1077
|
-
}
|
|
1078
|
-
async getSyncStatus() {
|
|
1079
|
-
await this.init();
|
|
1080
|
-
return {
|
|
1081
|
-
allScansComplete: this.sourceStates.every(x => x.scanComplete),
|
|
1082
|
-
indexSize: this.mem.size,
|
|
1083
|
-
sources: this.sources.map((x, i) => ({
|
|
1084
|
-
debugName: x.source.getDebugName(),
|
|
1085
|
-
validWindow: x.validWindow,
|
|
1086
|
-
route: x.route,
|
|
1087
|
-
noFullSync: x.noFullSync,
|
|
1088
|
-
supportsChangesAfter: this.sourceStates[i].supportsChangesAfter,
|
|
1089
|
-
initialScanComplete: this.sourceStates[i].scanComplete,
|
|
1090
|
-
scannedCount: this.sourceStates[i].scannedCount,
|
|
1091
|
-
})).filter((x, i) => this.isLive(i)),
|
|
1092
|
-
};
|
|
1093
|
-
}
|
|
1094
|
-
// ── large uploads ──
|
|
1095
|
-
// Large uploads stream onto the local disk source directly (they may not fit in memory)
|
|
1096
1258
|
getDiskSource() {
|
|
1097
1259
|
for (let i = 0; i < this.sources.length; i++) {
|
|
1098
1260
|
let source = this.sources[i].source;
|
|
@@ -1101,26 +1263,6 @@ class BlobStore {
|
|
|
1101
1263
|
}
|
|
1102
1264
|
throw new Error(`Large uploads require an ArchivesDisk source, and this store has none (store ${this.folder})`);
|
|
1103
1265
|
}
|
|
1104
|
-
async startLargeUpload() {
|
|
1105
|
-
await this.init();
|
|
1106
|
-
return await this.getDiskSource().disk.startLargeUpload();
|
|
1107
|
-
}
|
|
1108
|
-
async appendLargeUpload(id, data) {
|
|
1109
|
-
await this.getDiskSource().disk.appendLargeUpload(id, data);
|
|
1110
|
-
}
|
|
1111
|
-
async finishLargeUpload(id, key, lastModified) {
|
|
1112
|
-
let { disk, sourceIndex } = this.getDiskSource();
|
|
1113
|
-
await disk.finishLargeUpload(id, key, lastModified);
|
|
1114
|
-
this.overlay.delete(key);
|
|
1115
|
-
// includeTombstones: a zero-byte upload is still a real file whose index entry must be written
|
|
1116
|
-
let info = await disk.getInfo(key, { includeTombstones: true });
|
|
1117
|
-
if (info) {
|
|
1118
|
-
this.setIndexEntry(key, { writeTime: info.writeTime, size: info.size, sourcesListIndex: this.sourcesListIndexOfSlot(sourceIndex) });
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
async cancelLargeUpload(id) {
|
|
1122
|
-
await this.getDiskSource().disk.cancelLargeUpload(id);
|
|
1123
|
-
}
|
|
1124
1266
|
async flushOverlay(force) {
|
|
1125
1267
|
let now = Date.now();
|
|
1126
1268
|
for (let [key, entry] of this.overlay) {
|
|
@@ -1218,5 +1360,5 @@ class BlobStore {
|
|
|
1218
1360
|
}
|
|
1219
1361
|
}
|
|
1220
1362
|
exports.BlobStore = BlobStore;
|
|
1221
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvYlN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYmxvYlN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLGdEQUF3QjtBQUN4Qix5REFBbUQ7QUFDbkQsMkRBQXNFO0FBQ3RFLG1EQUEwRTtBQUMxRSxrRUFBaUY7QUFDakYsNENBR3NCO0FBQ3RCLGtEQUFtRTtBQUNuRSw0Q0FBaUQ7QUFDakQsaURBQXVFO0FBQ3ZFLHdFQUF1RjtBQUN2RixvREFBOEY7QUFDOUYsK0NBQTRDO0FBRTVDLHVoQkFBdWhCO0FBRTFnQixRQUFBLHdCQUF3QixHQUFHLG1CQUFZLEdBQUcsQ0FBQyxDQUFDO0FBQ3pELE1BQU0sZUFBZSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7QUFDbEMsbU5BQW1OO0FBQ3RNLFFBQUEsdUJBQXVCLEdBQUcsbUJBQVksR0FBRyxDQUFDLENBQUM7QUFDeEQsbUZBQW1GO0FBQ25GLE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUN2Qyx5RUFBeUU7QUFDekUsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ3hDLGtRQUFrUTtBQUNsUSxNQUFNLG9CQUFvQixHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQzVDLE1BQU0sOEJBQThCLEdBQUcsSUFBSSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzFELDBHQUEwRztBQUMxRyxNQUFNLG1CQUFtQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7QUFDckMsc0dBQXNHO0FBQ3RHLE1BQU0sb0JBQW9CLEdBQUcsbUJBQVksQ0FBQztBQUMxQyxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7QUFDbkMsb0xBQW9MO0FBQ3BMLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNqRCxN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QUM7b0JBQUUsU0FBUztnQkFDOUIsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEMsSUFBSSxDQUFDLElBQUEsK0JBQW1CLEVBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQztvQkFBRSxTQUFTO2dCQUM1RCxJQUFJLE1BQU0sR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDO2dCQUNoQyxJQUFJLENBQUMsQ0FBQyxNQUFNLFlBQVksNkJBQWlCLENBQUM7b0JBQUUsU0FBUztnQkFDckQsS0FBSyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQVEsRUFBRSxFQUFFOztvQkFDcEMsT0FBTyxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsR0FBRyxTQUFTLE1BQU0sQ0FBQyxZQUFZLEVBQUUsWUFBWSxNQUFBLENBQUMsQ0FBQyxLQUFLLG1DQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQzdHLENBQUMsQ0FBQyxDQUFDO1lBQ1AsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0NBQ0o7QUFya0NELDhCQXFrQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgbGF6eSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2NhY2hpbmdcIjtcbmltcG9ydCB7IHJ1bkluZmluaXRlUG9sbCwgZGVsYXkgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9iYXRjaGluZ1wiO1xuaW1wb3J0IHsgdGltZUluTWludXRlLCBzb3J0LCBwcm9taXNlT2JqIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgZm9ybWF0TnVtYmVyLCBmb3JtYXRUaW1lIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvZm9ybWF0dGluZy9mb3JtYXRcIjtcbmltcG9ydCB7XG4gICAgSUFyY2hpdmVzLCBBcmNoaXZlRmlsZUluZm8sIEFyY2hpdmVzU291cmNlLCBBcmNoaXZlc1N5bmNTdGF0dXMsIENoYW5nZXNBZnRlckNvbmZpZywgR2V0Q29uZmlnLCBHZXRJbmZvQ29uZmlnLCBhc3NlcnRWYWxpZExhc3RNb2RpZmllZCxcbiAgICB3aW5kb3dBY2NlcHRzV3JpdGVzLCBTeW5jQWN0aXZpdHksIEZVTExfUk9VVEUsIGNvcHlBcmNoaXZlRmlsZSxcbn0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHsgQXJjaGl2ZXNEaXNrLCBhcHBseUZpbmRJbmZvU2hhcGUgfSBmcm9tIFwiLi4vQXJjaGl2ZXNEaXNrXCI7XG5pbXBvcnQgeyBBcmNoaXZlc0JhY2tibGF6ZSB9IGZyb20gXCIuLi9iYWNrYmxhemVcIjtcbmltcG9ydCB7IFJPVVRJTkdfRklMRSwgZ2V0Um91dGUsIHJvdXRlQ29udGFpbnMgfSBmcm9tIFwiLi9yZW1vdGVDb25maWdcIjtcbmltcG9ydCB7IEJ1bGtEYXRhYmFzZUJhc2UsIG5vb3BSZWFjdGl2ZURlcHMgfSBmcm9tIFwiLi4vQnVsa0RhdGFiYXNlMi9CdWxrRGF0YWJhc2VCYXNlXCI7XG5pbXBvcnQgeyB3cmFwSGFuZGxlLCBOb2RlSlNEaXJlY3RvcnlIYW5kbGVXcmFwcGVyLCBEaXJlY3RvcnlXcmFwcGVyIH0gZnJvbSBcIi4uL0ZpbGVGb2xkZXJBUElcIjtcbmltcG9ydCB7IFNvdXJjZXNMaXN0IH0gZnJvbSBcIi4vc291cmNlc0xpc3RcIjtcblxuLy8gVGhlIHN0b3JhZ2UgZW5naW5lIG9mIHRoZSByZW1vdGUgc3RvcmFnZSBzZXJ2ZXIuIERhdGEgbGl2ZXMgaW4gc3luY2hyb25pemF0aW9uIHNvdXJjZXMgKGF0IG1pbmltdW0gYW4gQXJjaGl2ZXNEaXNrLCB0aGUgbG9jYWwgZGlzayk7IEJsb2JTdG9yZSBrZWVwcyBhbiBpbmRleCBvZiBldmVyeSBmaWxlIChwYXRoLCBsYXN0IG1vZGlmaWVkIHRpbWUsIHNpemUsIGFuZCB3aGljaCBzb3VyY2UgY3VycmVudGx5IGhvbGRzIHRoZSBkYXRhKSBpbiBhIEJ1bGtEYXRhYmFzZTIsIGFuZCBzeW5jaHJvbml6ZXMgdGhlIGluZGV4IGZyb20gYWxsIHNvdXJjZXMgKHNlZSBBcmNoaXZlc1NvdXJjZSBpbiBJQXJjaGl2ZXMudHMpLiBFdmVyeSBzdGFydHVwIGZ1bGx5IHJlc2NhbnMgZWFjaCBzb3VyY2UncyBtZXRhZGF0YSwgc28gdGhlIGluZGV4IHNlbGYtaGVhbHM7IHRoZSBmaWxlIHdpdGggdGhlIGhpZ2hlc3Qgd3JpdGUgdGltZSB3aW5zIGFjcm9zcyBhbGwgc291cmNlcywgc28gbXVsdGlwbGUgc291cmNlcyBuZWVkIG5vIHN0YWNraW5nIG9yZGVyLlxuXG5leHBvcnQgY29uc3QgREVGQVVMVF9GQVNUX1dSSVRFX0RFTEFZID0gdGltZUluTWludXRlICogNTtcbmNvbnN0IEZBU1RfRkxVU0hfUE9MTCA9IDEwMDAgKiAxNTtcbi8vIEZhc3Qgd3JpdGVzIGFyZSBuZXZlciBkZWxheWVkIHBhc3Qgb3VyIG93biB2YWxpZCB3aW5kb3csIGFuZCB3aXRoaW4gdGhpcyBtYXJnaW4gb2YgdGhlIHdpbmRvdydzIGVuZCB0aGV5IHdyaXRlIHRocm91Z2ggaW1tZWRpYXRlbHkgLSBzbyB3aGVuIHRoZSBuZXh0IHdpbmRvdydzIHNvdXJjZSB0YWtlcyBvdmVyLCB0aGUgd3JpdGVzIGFyZSBhbHJlYWR5IG9uIGRpc2tcbmV4cG9ydCBjb25zdCBXSU5ET1dfRU5EX0ZMVVNIX01BUkdJTiA9IHRpbWVJbk1pbnV0ZSAqIDU7XG4vLyBJbmRleCBjaGFuZ2VzIGFyZSBidWZmZXJlZCBpbiBtZW1vcnkgYW5kIHdyaXR0ZW4gdG8gdGhlIEJ1bGtEYXRhYmFzZTIgaW4gYmF0Y2hlc1xuY29uc3QgSU5ERVhfRkxVU0hfSU5URVJWQUwgPSAxMDAwICogMzA7XG4vLyBTb3VyY2VzIHdpdGggYSBuYXRpdmUgKGluZGV4LWJhY2tlZCkgY2hhbmdlIGZlZWQgYXJlIHBvbGxlZCB0aGlzIG9mdGVuXG5jb25zdCBDSEFOR0VTX1BPTExfSU5URVJWQUwgPSAxMDAwICogNjA7XG4vLyBGdWxsIG1ldGFkYXRhIHJlc2NhbnMuIHN1cHBvcnRzQ2hhbmdlc0FmdGVyIGlzIHRoZSBoZXVyaXN0aWMgZm9yIFwib25lIG9mIG91ciBvd24gc3RvcmFnZSBzZXJ2ZXJzXCI6IHRoZWlyIGluZGV4LWJhY2tlZCBsaXN0aW5ncyBhcmUgY2hlYXAsIHNvIGhvdXJseSBpcyBmaW5lLiBFdmVyeXRoaW5nIGVsc2UgKGJhY2tibGF6ZSwgcGxhaW4gZGlzaykgcGF5cyB0aGUgZnVsbCBsaXN0aW5nIGNvc3QsIHNvIGl0IHJlc2NhbnMgbXVjaCBsZXNzIG9mdGVuLlxuY29uc3QgRlVMTF9SRVNDQU5fSU5URVJWQUwgPSAxMDAwICogNjAgKiA2MDtcbmNvbnN0IEZVTExfUkVTQ0FOX1VOSU5ERVhFRF9JTlRFUlZBTCA9IDEwMDAgKiA2MCAqIDYwICogNjtcbi8vIE9uIGEgcmVxdWVzdCBmb3IgYSBmaWxlIHRoZSBpbmRleCBkb2Vzbid0IGtub3csIGNoYW5nZXMtYWZ0ZXIgc291cmNlcyBhcmUgcmUtcG9sbGVkLCBhdCBtb3N0IHRoaXMgb2Z0ZW5cbmNvbnN0IE1JU1NfQ0hFQ0tfSU5URVJWQUwgPSAxMDAwICogNTtcbi8vIENoYW5nZSBwb2xscyByZS1yZXF1ZXN0IHRoaXMgbXVjaCBvdmVybGFwLCBzbyBjbG9jayBza2V3IGJldHdlZW4gdXMgYW5kIGEgc291cmNlIGNhbid0IGRyb3AgY2hhbmdlc1xuY29uc3QgQ0hBTkdFU19QT0xMX09WRVJMQVAgPSB0aW1lSW5NaW51dGU7XG5jb25zdCBTQ0FOX1JFVFJZX0RFTEFZID0gMTAwMCAqIDMwO1xuLy8gRGVsZXRlcyBhcmUgdG9tYnN0b25lcyAoYW4gZW1wdHkgZmlsZSBJUyBhIG1pc3NpbmcgZmlsZSk6IHRoZSBzaXplLTAgaW5kZXggZW50cnkgaXMgd2hhdCBsZXRzIGEgZGVsZXRpb24gcHJvcGFnYXRlL3JlY29uY2lsZSBsaWtlIGFueSBvdGhlciB3cml0ZSwgYW5kIGl0IGV4cGlyZXMgYWZ0ZXIgdGhpcyBsb25nXG5jb25zdCBUT01CU1RPTkVfRVhQSVJZID0gMTAwMCAqIDYwICogNjAgKiAyNCAqIDc7XG5jb25zdCBUT01CU1RPTkVfQ0xFQU5VUF9JTlRFUlZBTCA9IDEwMDAgKiA2MCAqIDYwO1xuLy8gV2hpbGUgYSBtZXRhZGF0YSBzY2FuIG9yIGZ1bGwgc3luYyBpcyBydW5uaW5nLCBpdHMgcHJvZ3Jlc3MgaXMgbG9nZ2VkIHRoaXMgb2Z0ZW5cbmNvbnN0IFNZTkNfUFJPR1JFU1NfTE9HX0lOVEVSVkFMID0gMTAwMCAqIDYwO1xuY29uc3QgRElTS19MSU1JVF9DSEVDS19JTlRFUlZBTCA9IDEwMDAgKiA2MDtcbi8vIEZ1bGwgc3luY3MgZG93bmxvYWQgdGhpcyBtYW55IGZpbGVzIGNvbmN1cnJlbnRseSAoaGlnaC1sYXRlbmN5IHNvdXJjZXMgbGlrZSBiYWNrYmxhemUgd291bGQgb3RoZXJ3aXNlIGNyYXdsIG9uZSByb3VuZC10cmlwIGF0IGEgdGltZSlcbmNvbnN0IEZVTExfU1lOQ19QQVJBTExFTCA9IDg7XG4vLyBBIGZ1bGwgc3luYyBydW5uaW5nIGxvbmdlciB0aGFuIHRoaXMgaXMgY29uc29sZS5lcnJvcmVkIChhbmQgYWdhaW4gZXZlcnkgaW50ZXJ2YWwgYWZ0ZXIpLCBzbyBhIHN5bmMgdGhhdCB3aWxsIHRha2UgZGF5cyBpcyBsb3VkIGluc3RlYWQgb2YgYSBxdWlldCBjb25zb2xlLmxvZyBldmVyeSBtaW51dGVcbmNvbnN0IEZVTExfU1lOQ19TTE9XX0VSUk9SX0lOVEVSVkFMID0gMTAwMCAqIDYwICogNjA7XG4vLyBBIHJlY29uY2lsZSBwYXNzIHNraXBzIGZhaWxpbmcgZmlsZXMgKG9uZSBiYWQgdmFsdWUgbXVzdCBub3Qgc3RvcCB0aGUgcmVzdCksIGJ1dCB0aGlzIG1hbnkgZmFpbHVyZXMgaW4gYSByb3cgbWVhbnMgdGhlIHRhcmdldCBpdHNlbGYgaXMgZG93biwgc28gdGhlIHBhc3MgYWJvcnRzIHVudGlsIHRoZSBuZXh0IHNjYW4gY3ljbGVcbmNvbnN0IFJFQ09OQ0lMRV9NQVhfQ09OU0VDVVRJVkVfRkFJTFVSRVMgPSA1O1xuY29uc3QgUkVDT05DSUxFX0VSUk9SX0xPR19MSU1JVCA9IDM7XG5cbmV4cG9ydCB0eXBlIFdyaXRlQ29uZmlnID0ge1xuICAgIC8vIFJlc29sdmUgb25jZSB0aGUgd3JpdGUgaXMgaW4gbWVtb3J5OyBmbHVzaCB0byB0aGUgc291cmNlcyBhZnRlciB3cml0ZURlbGF5LCBjb2FsZXNjaW5nIHdyaXRlcyB0byB0aGUgc2FtZSBrZXkgKG9ubHkgdGhlIGxhdGVzdCBpcyB3cml0dGVuKS4gRGF0YSBpcyBsb3N0IGlmIHRoZSBwcm9jZXNzIGNyYXNoZXMgZmlyc3QuXG4gICAgZmFzdD86IGJvb2xlYW47XG4gICAgd3JpdGVEZWxheT86IG51bWJlcjtcbiAgICAvLyBTdGFtcHMgdGhlIHdyaXRlIHdpdGggdGhpcyBsYXN0LXdyaXRlIHRpbWUgaW5zdGVhZCBvZiBub3cuIE9sZGVyIHRoYW4gdGhlIGN1cnJlbnQgZmlsZSdzIHRpbWUgbm8tb3BzOyBtb3JlIHRoYW4gMTUgbWludXRlcyBpbiB0aGUgZnV0dXJlIHRocm93cy4gU2VlIElBcmNoaXZlcy5zZXQuXG4gICAgbGFzdE1vZGlmaWVkPzogbnVtYmVyO1xufTtcblxuLy8gV2hhdCB0aGUgc3RvcmFnZSBzZXJ2ZXIgbmVlZHMgZnJvbSBhIGJ1Y2tldCdzIHN0b3JlLiBCbG9iU3RvcmUgaW1wbGVtZW50cyBpdCBmdWxseTsgQXJjaGl2ZXNEaXNrIGFsc28gc2F0aXNmaWVzIGl0ICh1c2VkIGRpcmVjdGx5IGZvciByYXdEaXNrIGJ1Y2tldHMpLCBtaW51cyB0aGUgb3B0aW9uYWwgaW5kZXgtYmFja2VkIG1ldGhvZHMuXG5leHBvcnQgdHlwZSBJQnVja2V0U3RvcmUgPSB7XG4gICAgZ2V0KGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IEdldENvbmZpZyk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPjtcbiAgICBnZXQyKGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IEdldENvbmZpZyk6IFByb21pc2U8eyBkYXRhOiBCdWZmZXI7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD47XG4gICAgLy8gSW50ZXJuYWwgKHN0b3JlLXRvLXN0b3JlKSBmb3Jtczsgc2VlIEdldENvbmZpZy5pbnRlcm5hbCAvIFNldENvbmZpZy5pbnRlcm5hbC4gQWJzZW50IG9uIHJhd0Rpc2sgc3RvcmVzLCB3aGVyZSB0aGUgbm9ybWFsIGZvcm1zIGFscmVhZHkgQVJFIHRoZSBkaXNrLlxuICAgIGdldEludGVybmFsMj8oZmlsZU5hbWU6IHN0cmluZywgY29uZmlnPzogR2V0Q29uZmlnKTogUHJvbWlzZTx7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPjtcbiAgICBzZXRJbnRlcm5hbD8oZmlsZU5hbWU6IHN0cmluZywgZGF0YTogQnVmZmVyLCBjb25maWc6IHsgbGFzdE1vZGlmaWVkOiBudW1iZXIgfSk6IFByb21pc2U8dm9pZD47XG4gICAgc2V0KGZpbGVOYW1lOiBzdHJpbmcsIGRhdGE6IEJ1ZmZlciwgY29uZmlnPzogV3JpdGVDb25maWcpOiBQcm9taXNlPHN0cmluZz47XG4gICAgZGVsKGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IFdyaXRlQ29uZmlnKTogUHJvbWlzZTx2b2lkPjtcbiAgICBnZXRJbmZvKGZpbGVOYW1lOiBzdHJpbmcsIGNvbmZpZz86IEdldEluZm9Db25maWcpOiBQcm9taXNlPHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPjtcbiAgICBmaW5kSW5mbyhwcmVmaXg6IHN0cmluZywgY29uZmlnPzogeyBzaGFsbG93PzogYm9vbGVhbjsgdHlwZT86IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPjtcbiAgICBnZXRDaGFuZ2VzQWZ0ZXIyKGNvbmZpZzogQ2hhbmdlc0FmdGVyQ29uZmlnKTogUHJvbWlzZTxBcmNoaXZlRmlsZUluZm9bXT47XG4gICAgZ2V0U3luY1N0YXR1cz8oKTogUHJvbWlzZTxBcmNoaXZlc1N5bmNTdGF0dXM+O1xuICAgIGdldFN5bmNQcm9ncmVzcz8oKToge1xuICAgICAgICBpbmRleDogeyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXIgfTtcbiAgICAgICAgc291cmNlczogeyBkZWJ1Z05hbWU6IHN0cmluZzsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyIH1bXTtcbiAgICAgICAgcmVhZGVyRGlza0xpbWl0PzogbnVtYmVyO1xuICAgICAgICBzeW5jaW5nOiBTeW5jQWN0aXZpdHlbXTtcbiAgICB9O1xuICAgIGNvbXB1dGVJbmRleFRvdGFscz8oKTogUHJvbWlzZTx7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlcjsgc291cmNlczogeyBkZWJ1Z05hbWU6IHN0cmluZzsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyIH1bXSB9PjtcbiAgICBzdGFydExhcmdlVXBsb2FkKCk6IFByb21pc2U8c3RyaW5nPjtcbiAgICBhcHBlbmRMYXJnZVVwbG9hZChpZDogc3RyaW5nLCBkYXRhOiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+O1xuICAgIGZpbmlzaExhcmdlVXBsb2FkKGlkOiBzdHJpbmcsIGtleTogc3RyaW5nLCBsYXN0TW9kaWZpZWQ/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+O1xuICAgIGNhbmNlbExhcmdlVXBsb2FkKGlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xufTtcblxudHlwZSBPdmVybGF5RW50cnkgPSB7XG4gICAgLy8gQSB6ZXJvLWxlbmd0aCBidWZmZXIgaXMgYSBwZW5kaW5nIGRlbGV0ZSAodG9tYnN0b25lKVxuICAgIGRhdGE6IEJ1ZmZlcjtcbiAgICB0OiBudW1iZXI7XG4gICAgZmx1c2hBdDogbnVtYmVyO1xufTtcblxuLy8gT25lIHJvdyBvZiB0aGUgQnVsa0RhdGFiYXNlMiBpbmRleCAoa2V5IGlzIHRoZSBmaWxlIHBhdGgpXG50eXBlIEJsb2JJbmRleEVudHJ5ID0ge1xuICAgIGtleTogc3RyaW5nO1xuICAgIHdyaXRlVGltZTogbnVtYmVyO1xuICAgIHNpemU6IG51bWJlcjtcbiAgICAvLyBXaGljaCBzeW5jaHJvbml6YXRpb24gc291cmNlIGN1cnJlbnRseSBob2xkcyB0aGUgZGF0YTogdGhlIGxpbmUgbnVtYmVyIG9mIHRoZSBzb3VyY2UncyBVUkwgaW4gdGhlIHN0b3JlJ3MgYXBwZW5kLW9ubHkgc291cmNlcyBsaXN0IChzZWUgU291cmNlc0xpc3QpIC0gTk9UIGEgcG9zaXRpb24gaW4gdGhlIGluLW1lbW9yeSBzb3VyY2VzIGFycmF5LCB3aGljaCBjaGFuZ2VzIGJldHdlZW4gcnVuc1xuICAgIHNvdXJjZXNMaXN0SW5kZXg6IG51bWJlcjtcbn07XG50eXBlIEluZGV4RW50cnkgPSB7XG4gICAgd3JpdGVUaW1lOiBudW1iZXI7XG4gICAgc2l6ZTogbnVtYmVyO1xuICAgIHNvdXJjZXNMaXN0SW5kZXg6IG51bWJlcjtcbiAgICAvLyBXaGVuIFdFIGxhc3QgY2hhbmdlZCB0aGlzIGVudHJ5IChub3QgdGhlIGZpbGUncyB3cml0ZSB0aW1lKSDigJQgd2hhdCBnZXRDaGFuZ2VzQWZ0ZXIyIGZpbHRlcnMgb24sIHNvIGxhdGUtYXJyaXZpbmcgZmlsZXMgd2l0aCBvbGQgd3JpdGUgdGltZXMgYXJlIHN0aWxsIHJlcG9ydGVkIGFzIGNoYW5nZXNcbiAgICBjaGFuZ2VkQXQ6IG51bWJlcjtcbiAgICAvLyBJbi1tZW1vcnkgb25seSAobm90IHBlcnNpc3RlZCk6IHdoZW4gdGhlIGZpbGUgd2FzIGxhc3Qgc2VydmVkLCBmb3IgcmVhZGVyRGlza0xpbWl0J3MgTFJVIGV2aWN0aW9uLiBTdGFydHMgYXMgY2hhbmdlZEF0IG9uIGxvYWQuXG4gICAgbGFzdEFjY2VzczogbnVtYmVyO1xufTtcblxudHlwZSBTb3VyY2VTdGF0ZSA9IHtcbiAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcjogYm9vbGVhbjtcbiAgICBpbml0aWFsU2NhbjogUmV0dXJuVHlwZTx0eXBlb2YgcHJvbWlzZU9iaj47XG4gICAgc2NhbkNvbXBsZXRlOiBib29sZWFuO1xuICAgIC8vIEZpbGVzIHNlZW4gaW4gdGhpcyBzb3VyY2UncyBzY2FucyAvIGNoYW5nZSBwb2xscyBzbyBmYXJcbiAgICBzY2FubmVkQ291bnQ6IG51bWJlcjtcbiAgICAvLyBXYXRlcm1hcmsgZm9yIGdldENoYW5nZXNBZnRlcjIgcG9sbHNcbiAgICBjaGFuZ2VzQWZ0ZXJUaW1lOiBudW1iZXI7XG4gICAgbGFzdE1pc3NDaGVjazogbnVtYmVyO1xuICAgIC8vIFBlci1zbG90IHN0b3AgdG9rZW46IGEgcmVtb3ZlZCBzb3VyY2UncyBsb29wcyBzdG9wIHdpdGhvdXQgdG91Y2hpbmcgdGhlIHJlc3Qgb2YgdGhlIHN0b3JlXG4gICAgc3RvcHBlZDogeyBzdG9wOiBib29sZWFuIH07XG4gICAgLy8gQSByZW1vdmVkIHNvdXJjZSdzIHNsb3Qgc3RheXMgaW4gdGhlIGFycmF5cyAodGhleSBhcmUgbmV2ZXIgc3BsaWNlZCwgc28gc2xvdCBudW1iZXJzIGhlbGQgYnkgcnVubmluZyBsb29wcyBzdGF5IG1lYW5pbmdmdWwpLCBtYXJrZWQgZGVhZCAtIG5ldmVyIHNjYW5uZWQsIHdyaXR0ZW4sIG9yIHJlYWQuIEluZGV4IGVudHJpZXMgZG9uJ3QgcmVmZXJlbmNlIHNsb3RzIGF0IGFsbDsgdGhleSBwZXJzaXN0IHRoZSBzb3VyY2VzIGxpc3QncyBzb3VyY2VzTGlzdEluZGV4LlxuICAgIGRlYWQ/OiBib29sZWFuO1xufTtcblxuLy8gT25lIHNvdXJjZSBvZiBhIGxpdmUgc291cmNlLWxpc3QgdXBkYXRlOyBzZWUgQmxvYlN0b3JlLnVwZGF0ZVNvdXJjZXNcbmV4cG9ydCB0eXBlIEJsb2JTb3VyY2VTcGVjID0ge1xuICAgIC8vIE1hdGNoZWQgYWdhaW5zdCBBcmNoaXZlc1NvdXJjZS5pZGVudGl0eSAoXCJkaXNrXCIgZm9yIHRoZSBiYXNlIHNsb3QpOyBlcXVhbCBpZGVudGl0aWVzIHBhaXIgb2ZmIGluIG9yZGVyXG4gICAgaWRlbnRpdHk6IHN0cmluZztcbiAgICAvLyBTZWUgQXJjaGl2ZXNTb3VyY2UudXJsXG4gICAgdXJsOiBzdHJpbmc7XG4gICAgdmFsaWRXaW5kb3c6IFtudW1iZXIsIG51bWJlcl07XG4gICAgcm91dGU/OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIG5vRnVsbFN5bmM/OiBib29sZWFuO1xuICAgIC8vIFNlZSBBcmNoaXZlc1NvdXJjZS5pbnRlcm1lZGlhdGVcbiAgICBpbnRlcm1lZGlhdGU/OiBib29sZWFuO1xuICAgIC8vIE9ubHkgY2FsbGVkIGZvciBzb3VyY2VzIHRoYXQgZG9uJ3QgbWF0Y2ggYW4gZXhpc3RpbmcgbGl2ZSBzbG90XG4gICAgY3JlYXRlOiAoKSA9PiBJQXJjaGl2ZXM7XG59O1xuXG4vLyBXaGF0IGEgc2Nhbm5lZCBsaXN0aW5nIGVudHJ5IG1lYW50IHdoZW4gY29tcGFyZWQgYWdhaW5zdCBvdXIgaW5kZXhcbnR5cGUgU2Nhbk91dGNvbWUgPSBcImZpbHRlcmVkXCIgfCBcIm5ld1wiIHwgXCJ1cGRhdGVkXCIgfCBcInRvbWJzdG9uZVwiIHwgXCJ1bmNoYW5nZWRcIjtcbnR5cGUgU2NhblRhbGx5ID0gUmVjb3JkPFNjYW5PdXRjb21lLCBudW1iZXI+O1xuZnVuY3Rpb24gbmV3U2NhblRhbGx5KCk6IFNjYW5UYWxseSB7XG4gICAgcmV0dXJuIHsgZmlsdGVyZWQ6IDAsIG5ldzogMCwgdXBkYXRlZDogMCwgdG9tYnN0b25lOiAwLCB1bmNoYW5nZWQ6IDAgfTtcbn1cbmZ1bmN0aW9uIGZvcm1hdFNjYW5UYWxseSh0YWxseTogU2NhblRhbGx5LCB0b3RhbDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBsZXQgcGN0ID0gKG46IG51bWJlcikgPT4gYCR7TWF0aC5yb3VuZChuIC8gTWF0aC5tYXgodG90YWwsIDEpICogMTAwMCkgLyAxMH0lYDtcbiAgICByZXR1cm4gYCR7dGFsbHkubmV3fSBuZXcgcGF0aHMgKCR7cGN0KHRhbGx5Lm5ldyl9KSwgJHt0YWxseS51cGRhdGVkfSBuZXdlciB3cml0ZXMgKCR7cGN0KHRhbGx5LnVwZGF0ZWQpfSksICR7dGFsbHkudG9tYnN0b25lfSBkZWxldGlvbnMgKCR7cGN0KHRhbGx5LnRvbWJzdG9uZSl9KSwgJHt0YWxseS51bmNoYW5nZWR9IHVuY2hhbmdlZCAoJHtwY3QodGFsbHkudW5jaGFuZ2VkKX0pLCAke3RhbGx5LmZpbHRlcmVkfSBvdXRzaWRlIHJvdXRlICgke3BjdCh0YWxseS5maWx0ZXJlZCl9KWA7XG59XG5cbmZ1bmN0aW9uIG5ld1NvdXJjZVN0YXRlKCk6IFNvdXJjZVN0YXRlIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcjogZmFsc2UsXG4gICAgICAgIGluaXRpYWxTY2FuOiBwcm9taXNlT2JqKCksXG4gICAgICAgIHNjYW5Db21wbGV0ZTogZmFsc2UsXG4gICAgICAgIHNjYW5uZWRDb3VudDogMCxcbiAgICAgICAgY2hhbmdlc0FmdGVyVGltZTogMCxcbiAgICAgICAgbGFzdE1pc3NDaGVjazogMCxcbiAgICAgICAgc3RvcHBlZDogeyBzdG9wOiBmYWxzZSB9LFxuICAgIH07XG59XG5cbmV4cG9ydCBjbGFzcyBCbG9iU3RvcmUgaW1wbGVtZW50cyBJQnVja2V0U3RvcmUge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGZvbGRlcjogc3RyaW5nLFxuICAgICAgICBwcml2YXRlIHNvdXJjZXM6IEFyY2hpdmVzU291cmNlW10sXG4gICAgICAgIHByaXZhdGUgY29uZmlnPzoge1xuICAgICAgICAgICAgLy8gQ2FsbGVkIHdoZW5ldmVyIGEga2V5J3MgaW5kZXggZW50cnkgY2hhbmdlcyAob3VyIG93biB3cml0ZXMgQU5EIGZpbGVzIHB1bGxlZCBpbiB2aWEgc3luY2hyb25pemF0aW9uKSDigJQgaG93IHRoZSBzdG9yYWdlIHNlcnZlciBub3RpY2VzIHJvdXRpbmcgY29uZmlnIHVwZGF0ZXMuXG4gICAgICAgICAgICBvbkluZGV4Q2hhbmdlZD86IChrZXk6IHN0cmluZykgPT4gdm9pZDtcbiAgICAgICAgICAgIC8vIExSVS1ib3VuZCB0aGUgZGlzayAoYmFzZSBzb3VyY2UpIHRvIHRoaXMgbWFueSBieXRlczsgc2VlIENvbW1vbkNvbmZpZy5yZWFkZXJEaXNrTGltaXRcbiAgICAgICAgICAgIHJlYWRlckRpc2tMaW1pdD86IG51bWJlcjtcbiAgICAgICAgICAgIC8vIEV2ZXJ5IGFjY2VwdGVkIHdyaXRlIChcIm9yaWdpbmFsXCIpIGFuZCBldmVyeSB3cml0ZSB0aGF0IGFjdHVhbGx5IHJlYWNoZWQgdGhlIHNvdXJjZXMgKFwiZmx1c2hlZFwiKS4gRmFzdCB3cml0ZXMgY29hbGVzY2UsIHNvIHRoZSB0d28gY291bnRzIGRpZmZlci5cbiAgICAgICAgICAgIG9uV3JpdGVDb3VudGVkPzogKGtpbmQ6IFwib3JpZ2luYWxcIiB8IFwiZmx1c2hlZFwiLCBieXRlczogbnVtYmVyKSA9PiB2b2lkO1xuICAgICAgICAgICAgLy8gUmVzb2x2ZXMgYSBwZXJzaXN0ZWQgc291cmNlIFVSTCAoc2VlIEFyY2hpdmVzU291cmNlLnVybCkgdG8gYSBjYWNoZWQgSUFyY2hpdmVzLCBzbyBlbnRyaWVzIHdob3NlIGhvbGRlciBpcyBubyBsb25nZXIgY29uZmlndXJlZCBjYW4gc3RpbGwgYmUgcmVhZFxuICAgICAgICAgICAgcmVzb2x2ZVNvdXJjZVVybD86ICh1cmw6IHN0cmluZykgPT4gSUFyY2hpdmVzO1xuICAgICAgICB9XG4gICAgKSB7IH1cblxuICAgIHByaXZhdGUgc3RvcHBlZCA9IHsgc3RvcDogZmFsc2UgfTtcblxuICAgIC8vIFRoZSBpbmRleCdzIEJ1bGtEYXRhYmFzZTIgZmlsZXMgbGl2ZSB1bmRlciA8Zm9sZGVyPi9pbmRleC4gXCJibG9iSW5kZXgyXCI6IHRoZSBcImJsb2JJbmRleFwiIGdlbmVyYXRpb24gcGVyc2lzdGVkIHNvdXJjZXMtYXJyYXkgcG9zaXRpb25zIGFzIHRoZSBob2xkaW5nIHNvdXJjZSwgd2hpY2ggYXJlIG5vdCBzdGFibGUgYWNyb3NzIHJ1bnMgLSBpdHMgZW50cmllcyBhcmUgdW51c2FibGUsIHNvIGl0IGlzIHNpbXBseSBuZXZlciByZWFkIGFnYWluLlxuICAgIHByaXZhdGUgaW5kZXggPSBuZXcgQnVsa0RhdGFiYXNlQmFzZTxCbG9iSW5kZXhFbnRyeT4oXCJibG9iSW5kZXgyXCIsIG5vb3BSZWFjdGl2ZURlcHMsIGFzeW5jIChwOiBzdHJpbmcpID0+IHtcbiAgICAgICAgbGV0IGJhc2U6IERpcmVjdG9yeVdyYXBwZXIgPSBuZXcgTm9kZUpTRGlyZWN0b3J5SGFuZGxlV3JhcHBlcihwYXRoLmpvaW4odGhpcy5mb2xkZXIsIFwiaW5kZXhcIikpO1xuICAgICAgICBmb3IgKGxldCBwYXJ0IG9mIHAuc3BsaXQoXCIvXCIpKSB7XG4gICAgICAgICAgICBpZiAocGFydCkgYmFzZSA9IGF3YWl0IGJhc2UuZ2V0RGlyZWN0b3J5SGFuZGxlKHBhcnQsIHsgY3JlYXRlOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB3cmFwSGFuZGxlKGJhc2UpO1xuICAgIH0pO1xuICAgIC8vIFRoZSBpbi1tZW1vcnkgY29weSBvZiB0aGUgaW5kZXguIEFsbCByZWFkcyBhcmUgc2VydmVkIGZyb20gaXQ7IGNoYW5nZXMgYXJlIGJ1ZmZlcmVkIGluIGRpcnR5IGFuZCBmbHVzaGVkIHRvIHRoZSBCdWxrRGF0YWJhc2UyIGluIGJhdGNoZXMgKHVuZGVmaW5lZCA9IGRlbGV0ZSkuXG4gICAgcHJpdmF0ZSBtZW0gPSBuZXcgTWFwPHN0cmluZywgSW5kZXhFbnRyeT4oKTtcbiAgICAvLyBMaXZlIHRvdGFscyBvdmVyIG1lbSAodG9tYnN0b25lcyBleGNsdWRlZCksIGFkanVzdGVkIG9uIGV2ZXJ5IG11dGF0aW9uIGFuZCByZWNvbXB1dGVkIG9uIGxvYWQgLSBzbyBhbnkgZHJpZnQgaGVhbHMgb24gcmVzdGFydC4gY29tcHV0ZUluZGV4VG90YWxzIGdpdmVzIHRoZSB3YWxrLXRoZS1pbmRleCB0cnV0aC5cbiAgICBwcml2YXRlIGluZGV4RmlsZUNvdW50ID0gMDtcbiAgICBwcml2YXRlIGluZGV4Qnl0ZUNvdW50ID0gMDtcbiAgICAvLyBUaGUgc2FtZSB0b3RhbHMgcGVyIGhvbGRpbmcgc291cmNlIChpbmRleCAwID0gb3VyIGRpc2ssIHdoaWNoIHJlYWRlckRpc2tMaW1pdCBib3VuZHMpXG4gICAgcHJpdmF0ZSBzb3VyY2VGaWxlQ291bnRzID0gdGhpcy5zb3VyY2VzLm1hcCgoKSA9PiAwKTtcbiAgICBwcml2YXRlIHNvdXJjZUJ5dGVDb3VudHMgPSB0aGlzLnNvdXJjZXMubWFwKCgpID0+IDApO1xuICAgIC8vIEJhY2tncm91bmQgc2NhbnMgLyBmdWxsIHN5bmNzIGN1cnJlbnRseSBpbiBwcm9ncmVzcyAoYSBTZXQgLSBvbmUgc291cmNlIGNhbiBoYXZlIGEgY2hhbmdlIHBvbGwncyBmdWxsIHN5bmMgYW5kIGEgcmVzY2FuIG92ZXJsYXBwaW5nKVxuICAgIHByaXZhdGUgc3luY0FjdGl2aXRpZXMgPSBuZXcgU2V0PFN5bmNBY3Rpdml0eT4oKTtcbiAgICBwcml2YXRlIGRpcnR5ID0gbmV3IE1hcDxzdHJpbmcsIEluZGV4RW50cnkgfCB1bmRlZmluZWQ+KCk7XG4gICAgcHJpdmF0ZSBvdmVybGF5ID0gbmV3IE1hcDxzdHJpbmcsIE92ZXJsYXlFbnRyeT4oKTtcbiAgICBwcml2YXRlIHNvdXJjZVN0YXRlcyA9IHRoaXMuc291cmNlcy5tYXAoKCkgPT4gbmV3U291cmNlU3RhdGUoKSk7XG4gICAgcHJpdmF0ZSBzeW5jU3RhcnRlZCA9IGZhbHNlO1xuICAgIC8vIFRoZSBwZXJzaXN0ZW50IGlkZW50aXRpZXMgYmVoaW5kIEluZGV4RW50cnkuc291cmNlc0xpc3RJbmRleCAoc2VlIFNvdXJjZXNMaXN0KVxuICAgIHByaXZhdGUgc291cmNlc0xpc3QgPSBuZXcgU291cmNlc0xpc3QocGF0aC5qb2luKHRoaXMuZm9sZGVyLCBcImluZGV4XCIsIFwic291cmNlc0xpc3QudHh0XCIpKTtcbiAgICAvLyBQZXIgc2xvdDogdGhlIHBlcnNpc3RlbnQgc291cmNlc0xpc3RJbmRleCBvZiB0aGF0IHNsb3QncyBVUkwsIGZpbGxlZCBieSByZWdpc3RlclNsb3QgYmVmb3JlIHRoZSBzbG90J3Mgc3luYyBydW5zXG4gICAgcHJpdmF0ZSBzbG90U291cmNlc0xpc3RJbmRleGVzOiBudW1iZXJbXSA9IFtdO1xuICAgIHByaXZhdGUgc2xvdFJlZ2lzdHJhdGlvbnM6IFByb21pc2U8dm9pZD5bXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBpc0xpdmUoc291cmNlSW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLnNvdXJjZXNbc291cmNlSW5kZXhdICYmICF0aGlzLnNvdXJjZVN0YXRlc1tzb3VyY2VJbmRleF0uZGVhZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlZ2lzdGVyU2xvdChzbG90OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IGV4aXN0aW5nID0gdGhpcy5zbG90UmVnaXN0cmF0aW9uc1tzbG90XTtcbiAgICAgICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3Rpbmc7XG4gICAgICAgIGxldCByZWdpc3RyYXRpb24gPSB0aGlzLnNvdXJjZXNMaXN0LmVuc3VyZSh0aGlzLnNvdXJjZXNbc2xvdF0udXJsKS50aGVuKGluZGV4ID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2xvdFNvdXJjZXNMaXN0SW5kZXhlc1tzbG90XSA9IGluZGV4O1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zbG90UmVnaXN0cmF0aW9uc1tzbG90XSA9IHJlZ2lzdHJhdGlvbjtcbiAgICAgICAgcmV0dXJuIHJlZ2lzdHJhdGlvbjtcbiAgICB9XG5cbiAgICAvLyBUaGUgcGVyc2lzdGVudCBzb3VyY2VzTGlzdEluZGV4IG9mIGEgc2xvdCAtIG9ubHkgdmFsaWQgb25jZSB0aGUgc2xvdCdzIHJlZ2lzdHJhdGlvbiByZXNvbHZlZCAoaW5pdCBhbmQgcnVuU291cmNlU3luYyBndWFyYW50ZWUgdGhhdCBiZWZvcmUgYW55IGluZGV4aW5nIGhhcHBlbnMpXG4gICAgcHJpdmF0ZSBzb3VyY2VzTGlzdEluZGV4T2ZTbG90KHNsb3Q6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGxldCBpbmRleCA9IHRoaXMuc2xvdFNvdXJjZXNMaXN0SW5kZXhlc1tzbG90XTtcbiAgICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU291cmNlIHNsb3QgJHtzbG90fSAoJHt0aGlzLnNvdXJjZXNbc2xvdF0/LnVybH0pIGhhcyBubyByZWdpc3RlcmVkIHNvdXJjZXNMaXN0SW5kZXggeWV0IChzdG9yZSAke3RoaXMuZm9sZGVyfSlgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuXG4gICAgLy8gVGhlIGxpdmUgc2xvdCBjdXJyZW50bHkgc2VydmluZyBhIHBlcnNpc3RlbnQgc291cmNlc0xpc3RJbmRleCwgb3IgdW5kZWZpbmVkIHdoZW4gbm8gY29uZmlndXJlZCBzb3VyY2UgaGFzIHRoYXQgVVJMIGFueW1vcmUuIExpbmVhciwgYnV0IHRoZSBzb3VyY2VzIGxpc3QgaXMgdGlueSBhbmQgdGhpcyBpcyBhbHdheXMgY3VycmVudCAoc2xvdHMgZHlpbmcsIG9yIHNldmVyYWwgc2xvdHMgc2hhcmluZyBvbmUgVVJMIGFjcm9zcyB2YWxpZCB3aW5kb3dzLCBuZWVkIG5vIGJvb2trZWVwaW5nKS5cbiAgICBwcml2YXRlIHNsb3RGb3JTb3VyY2VzTGlzdEluZGV4KHNvdXJjZXNMaXN0SW5kZXg6IG51bWJlcik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zbG90U291cmNlc0xpc3RJbmRleGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zbG90U291cmNlc0xpc3RJbmRleGVzW2ldID09PSBzb3VyY2VzTGlzdEluZGV4ICYmIHRoaXMuaXNMaXZlKGkpKSByZXR1cm4gaTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8vIFRoZSBJQXJjaGl2ZXMgY3VycmVudGx5IGhvbGRpbmcgYW4gZW50cnkncyBieXRlczogdGhlIGxpdmUgc2xvdCB3aGVuIHRoZSBob2xkZXIgaXMgc3RpbGwgY29uZmlndXJlZCwgb3RoZXJ3aXNlIHJlc29sdmVkIChjYWNoZWQpIHN0cmFpZ2h0IGZyb20gaXRzIHBlcnNpc3RlZCBVUkwgLSB3aW5kb3dzL3JvdXRlcyBkZWNpZGUgd2hlbiBhIHNvdXJjZSBpcyBzY2FubmVkIG9yIHdyaXR0ZW4sIGJ1dCBmb3IgcmVhZGluZyBieXRlcyB3ZSBrbm93IGl0IGhvbGRzLCB0aGUgVVJMIGFsb25lIGlzIGVub3VnaFxuICAgIHByaXZhdGUgYXN5bmMgZ2V0RW50cnlIb2xkZXIoZW50cnk6IEluZGV4RW50cnkpOiBQcm9taXNlPElBcmNoaXZlcyB8IHVuZGVmaW5lZD4ge1xuICAgICAgICBsZXQgc2xvdCA9IHRoaXMuc2xvdEZvclNvdXJjZXNMaXN0SW5kZXgoZW50cnkuc291cmNlc0xpc3RJbmRleCk7XG4gICAgICAgIGlmIChzbG90ICE9PSB1bmRlZmluZWQpIHJldHVybiB0aGlzLnNvdXJjZXNbc2xvdF0uc291cmNlO1xuICAgICAgICBsZXQgdXJsID0gdGhpcy5zb3VyY2VzTGlzdC5nZXRVcmwoZW50cnkuc291cmNlc0xpc3RJbmRleCkgfHwgYXdhaXQgdGhpcy5zb3VyY2VzTGlzdC5nZXRVcmxSZWxvYWRpbmcoZW50cnkuc291cmNlc0xpc3RJbmRleCk7XG4gICAgICAgIGlmICghdXJsKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWc/LnJlc29sdmVTb3VyY2VVcmw/Lih1cmwpO1xuICAgIH1cblxuICAgIHB1YmxpYyBpbml0ID0gbGF6eShhc3luYyAoKSA9PiB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyU2xvdChpKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLmxvYWRJbmRleCgpO1xuICAgICAgICB0aGlzLnN5bmNTdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNvdXJjZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0xpdmUoaSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgdm9pZCB0aGlzLnJ1blNvdXJjZVN5bmMoaSk7XG4gICAgICAgIH1cbiAgICAgICAgcnVuSW5maW5pdGVQb2xsKEZBU1RfRkxVU0hfUE9MTCwgKCkgPT4gdGhpcy5mbHVzaE92ZXJsYXkoKSwgdGhpcy5zdG9wcGVkKTtcbiAgICAgICAgcnVuSW5maW5pdGVQb2xsKElOREVYX0ZMVVNIX0lOVEVSVkFMLCAoKSA9PiB0aGlzLmZsdXNoSW5kZXgoKSwgdGhpcy5zdG9wcGVkKTtcbiAgICAgICAgcnVuSW5maW5pdGVQb2xsKFRPTUJTVE9ORV9DTEVBTlVQX0lOVEVSVkFMLCAoKSA9PiB0aGlzLmNsZWFudXBUb21ic3RvbmVzKCksIHRoaXMuc3RvcHBlZCk7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZz8ucmVhZGVyRGlza0xpbWl0KSB7XG4gICAgICAgICAgICBydW5JbmZpbml0ZVBvbGwoRElTS19MSU1JVF9DSEVDS19JTlRFUlZBTCwgKCkgPT4gdGhpcy5lbmZvcmNlRGlza0xpbWl0KCksIHRoaXMuc3RvcHBlZCk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFN0b3BzIGFsbCBzeW5jaHJvbml6YXRpb24gc2NhbnMvcG9sbHMgYW5kIGZsdXNoZXMgcGVuZGluZyB3cml0ZXMuIE9ubHkgdXNlZCB3aGVuIHRoZSBzdG9yZSBnZW51aW5lbHkgY2Fubm90IGNvbnRpbnVlIChyYXdEaXNrIGZsaXAsIHByb2Nlc3Mgc2h1dGRvd24pIC0gcm91dGluZSBjb25maWcgY2hhbmdlcyBnbyB0aHJvdWdoIHVwZGF0ZVNvdXJjZXMgaW5zdGVhZCwgd2hpY2ggdGhlIHN0b3JlIHN1cnZpdmVzLlxuICAgIHB1YmxpYyBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnN0b3BwZWQuc3RvcCA9IHRydWU7XG4gICAgICAgIGZvciAobGV0IHN0YXRlIG9mIHRoaXMuc291cmNlU3RhdGVzKSB7XG4gICAgICAgICAgICBzdGF0ZS5zdG9wcGVkLnN0b3AgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuZmx1c2hPdmVybGF5KHRydWUpO1xuICAgICAgICBhd2FpdCB0aGlzLmZsdXNoSW5kZXgoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGxvYWRJbmRleCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IFt3cml0ZVRpbWVzLCBzaXplcywgc291cmNlc0xpc3RJbmRleGVzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIHRoaXMuaW5kZXguZ2V0Q29sdW1uKFwid3JpdGVUaW1lXCIpLFxuICAgICAgICAgICAgdGhpcy5pbmRleC5nZXRDb2x1bW4oXCJzaXplXCIpLFxuICAgICAgICAgICAgdGhpcy5pbmRleC5nZXRDb2x1bW4oXCJzb3VyY2VzTGlzdEluZGV4XCIpLFxuICAgICAgICBdKTtcbiAgICAgICAgbGV0IHNpemVNYXAgPSBuZXcgTWFwKHNpemVzLm1hcCh4ID0+IFt4LmtleSwgeC52YWx1ZV0pKTtcbiAgICAgICAgbGV0IHNvdXJjZXNMaXN0SW5kZXhNYXAgPSBuZXcgTWFwKHNvdXJjZXNMaXN0SW5kZXhlcy5tYXAoeCA9PiBbeC5rZXksIHgudmFsdWVdKSk7XG4gICAgICAgIGZvciAobGV0IGVudHJ5IG9mIHdyaXRlVGltZXMpIHtcbiAgICAgICAgICAgIGxldCBzaXplID0gc2l6ZU1hcC5nZXQoZW50cnkua2V5KTtcbiAgICAgICAgICAgIGxldCBzb3VyY2VzTGlzdEluZGV4ID0gc291cmNlc0xpc3RJbmRleE1hcC5nZXQoZW50cnkua2V5KTtcbiAgICAgICAgICAgIC8vIEV4cGxpY2l0IGNoZWNrcywgYXMgMCBpcyBhIHZhbGlkIHNpemUgYW5kIGEgdmFsaWQgc291cmNlc0xpc3RJbmRleFxuICAgICAgICAgICAgaWYgKHNpemUgPT09IHVuZGVmaW5lZCB8fCBzb3VyY2VzTGlzdEluZGV4ID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgLy8gVGhlIHJvdXRpbmcgY29uZmlnIGlzIG9ubHkgZXZlciByZWFkIG9mZiBvdXIgb3duIGRpc2sgKHNlZSB1cGRhdGVTY2FuSW5kZXgpLCBhbmQgYSBsb2FkZWQgYnVja2V0IGFsd2F5cyBoYXMgaXQgdGhlcmUgLSBhIHBlcnNpc3RlZCBlbnRyeSBwb2ludGluZyBlbHNld2hlcmUgaXMgc3RhbGVcbiAgICAgICAgICAgIGlmIChlbnRyeS5rZXkgPT09IFJPVVRJTkdfRklMRSkge1xuICAgICAgICAgICAgICAgIHNvdXJjZXNMaXN0SW5kZXggPSB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgZnVsbDogSW5kZXhFbnRyeSA9IHsgd3JpdGVUaW1lOiBlbnRyeS52YWx1ZSwgc2l6ZSwgc291cmNlc0xpc3RJbmRleCwgY2hhbmdlZEF0OiBlbnRyeS50aW1lLCBsYXN0QWNjZXNzOiBlbnRyeS50aW1lIH07XG4gICAgICAgICAgICB0aGlzLm1lbS5zZXQoZW50cnkua2V5LCBmdWxsKTtcbiAgICAgICAgICAgIHRoaXMuY291bnRFbnRyeShmdWxsLCAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY291bnRFbnRyeShlbnRyeTogSW5kZXhFbnRyeSB8IHVuZGVmaW5lZCwgZGlyZWN0aW9uOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgaWYgKCFlbnRyeSB8fCBlbnRyeS5zaXplID09PSAwKSByZXR1cm47XG4gICAgICAgIHRoaXMuaW5kZXhGaWxlQ291bnQgKz0gZGlyZWN0aW9uO1xuICAgICAgICB0aGlzLmluZGV4Qnl0ZUNvdW50ICs9IGVudHJ5LnNpemUgKiBkaXJlY3Rpb247XG4gICAgICAgIC8vIEVudHJpZXMgY2FuIHJlZmVyZW5jZSBhIHNvdXJjZSBubyBsb25nZXIgY29uZmlndXJlZCAocmVhZGFibGUgdmlhIGdldEVudHJ5SG9sZGVyLCBidXQgd2l0aCBubyBzbG90IHRvIGNvdW50IHVuZGVyKVxuICAgICAgICBsZXQgc2xvdCA9IHRoaXMuc2xvdEZvclNvdXJjZXNMaXN0SW5kZXgoZW50cnkuc291cmNlc0xpc3RJbmRleCk7XG4gICAgICAgIGlmIChzbG90ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuc291cmNlRmlsZUNvdW50c1tzbG90XSArPSBkaXJlY3Rpb247XG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ5dGVDb3VudHNbc2xvdF0gKz0gZW50cnkuc2l6ZSAqIGRpcmVjdGlvbjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2V0SW5kZXhFbnRyeShrZXk6IHN0cmluZywgZW50cnk6IHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlcjsgc291cmNlc0xpc3RJbmRleDogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICAgICAgbGV0IGZ1bGw6IEluZGV4RW50cnkgPSB7IC4uLmVudHJ5LCBjaGFuZ2VkQXQ6IERhdGUubm93KCksIGxhc3RBY2Nlc3M6IERhdGUubm93KCkgfTtcbiAgICAgICAgdGhpcy5jb3VudEVudHJ5KHRoaXMubWVtLmdldChrZXkpLCAtMSk7XG4gICAgICAgIHRoaXMuY291bnRFbnRyeShmdWxsLCAxKTtcbiAgICAgICAgdGhpcy5tZW0uc2V0KGtleSwgZnVsbCk7XG4gICAgICAgIHRoaXMuZGlydHkuc2V0KGtleSwgZnVsbCk7XG4gICAgICAgIHRoaXMuY29uZmlnPy5vbkluZGV4Q2hhbmdlZD8uKGtleSk7XG4gICAgfVxuICAgIHByaXZhdGUgZGVsZXRlSW5kZXhFbnRyeShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBsZXQgZXhpc3RpbmcgPSB0aGlzLm1lbS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKCFleGlzdGluZykgcmV0dXJuO1xuICAgICAgICB0aGlzLmNvdW50RW50cnkoZXhpc3RpbmcsIC0xKTtcbiAgICAgICAgdGhpcy5tZW0uZGVsZXRlKGtleSk7XG4gICAgICAgIHRoaXMuZGlydHkuc2V0KGtleSwgdW5kZWZpbmVkKTtcbiAgICB9XG5cbiAgICAvKiogQXBwbGllcyBhIGNvbmZpZyBjaGFuZ2UgdG8gdGhlIFJVTk5JTkcgc3RvcmU6IHdpbmRvd3Mvcm91dGVzIHVwZGF0ZSBpbiBwbGFjZSwgbmV3IHNvdXJjZXMgYXJlIGFkZGVkICh0aGVpciBzeW5jIHN0YXJ0cyBpbW1lZGlhdGVseSksIGFuZCByZW1vdmVkIHNvdXJjZXMnIHNsb3RzIGdvIGRlYWQgKHRoZWlyIHNjYW5zIHN0b3AsIHRoZWlyIGluZGV4IGVudHJpZXMgZHJvcCkuIFRoZSBzdG9yZSBzdXJ2aXZlcyBldmVyeSByb3V0aW5lIGNvbmZpZyBldm9sdXRpb24gLSBpdCBpcyBuZXZlciBkZXN0cm95ZWQgZm9yIGEgc291cmNlLWxpc3QgY2hhbmdlLCBvbmx5IGZvciBzdHJ1Y3R1cmFsIGZsaXBzIGl0IGNhbm5vdCBleHByZXNzIChyYXdEaXNrKS4gUGVuZGluZyBmYXN0IHdyaXRlcyBhcmUgcmUtY2FwcGVkIHRvIHRoZSBuZXcgZmx1c2ggZGVhZGxpbmUgKGZsdXNoaW5nIGltbWVkaWF0ZWx5IHdoZW4gaXQgaGFzIGFscmVhZHkgcGFzc2VkKS4gKi9cbiAgICBwdWJsaWMgdXBkYXRlU291cmNlcyhzcGVjczogQmxvYlNvdXJjZVNwZWNbXSk6IHZvaWQge1xuICAgICAgICBpZiAoIXNwZWNzLmxlbmd0aCB8fCBzcGVjc1swXS5pZGVudGl0eSAhPT0gXCJkaXNrXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdXBkYXRlU291cmNlcyBleHBlY3RzIHRoZSBkaXNrIHNvdXJjZSBmaXJzdCAoaWRlbnRpdHkgXCJkaXNrXCIpLCBnb3QgJHtKU09OLnN0cmluZ2lmeShzcGVjcy5tYXAoeCA9PiB4LmlkZW50aXR5KSl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSlgKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc2V0V2luZG93ID0gKGk6IG51bWJlciwgd2luZG93OiBbbnVtYmVyLCBudW1iZXJdKSA9PiB7XG4gICAgICAgICAgICBsZXQgb2xkID0gdGhpcy5zb3VyY2VzW2ldLnZhbGlkV2luZG93O1xuICAgICAgICAgICAgaWYgKG9sZFswXSA9PT0gd2luZG93WzBdICYmIG9sZFsxXSA9PT0gd2luZG93WzFdKSByZXR1cm47XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgVmFsaWQgd2luZG93IGNoYW5nZWQgZm9yICR7dGhpcy5zb3VyY2VzW2ldLnNvdXJjZS5nZXREZWJ1Z05hbWUoKX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KTogWyR7b2xkLmpvaW4oXCIsIFwiKX1dIC0+IFske3dpbmRvdy5qb2luKFwiLCBcIil9XWApO1xuICAgICAgICAgICAgdGhpcy5zb3VyY2VzW2ldLnZhbGlkV2luZG93ID0gd2luZG93O1xuICAgICAgICB9O1xuICAgICAgICBzZXRXaW5kb3coMCwgc3BlY3NbMF0udmFsaWRXaW5kb3cpO1xuICAgICAgICAvLyBMaXZlIHNsb3RzIHBhaXIgd2l0aCBzcGVjcyBieSBpZGVudGl0eSwgaW4gb3JkZXIgKHRoZSBzYW1lIGVuZHBvaW50IGNhbiBhcHBlYXIgc2V2ZXJhbCB0aW1lcywgZS5nLiBvbmUgZW50cnkgcGVyIHdpbmRvdylcbiAgICAgICAgbGV0IGxpdmVCeUlkZW50aXR5ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcltdPigpO1xuICAgICAgICBsZXQgb3JpZ2luYWxMZW5ndGggPSB0aGlzLnNvdXJjZXMubGVuZ3RoO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG9yaWdpbmFsTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0xpdmUoaSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgbGV0IGlkID0gdGhpcy5zb3VyY2VzW2ldLmlkZW50aXR5O1xuICAgICAgICAgICAgaWYgKGlkID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgbGV0IGxpc3QgPSBsaXZlQnlJZGVudGl0eS5nZXQoaWQpO1xuICAgICAgICAgICAgaWYgKCFsaXN0KSB7XG4gICAgICAgICAgICAgICAgbGlzdCA9IFtdO1xuICAgICAgICAgICAgICAgIGxpdmVCeUlkZW50aXR5LnNldChpZCwgbGlzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsaXN0LnB1c2goaSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG1hdGNoZWQgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICAgICAgZm9yIChsZXQgc3BlYyBvZiBzcGVjcy5zbGljZSgxKSkge1xuICAgICAgICAgICAgbGV0IHNsb3QgPSBsaXZlQnlJZGVudGl0eS5nZXQoc3BlYy5pZGVudGl0eSk/LnNoaWZ0KCk7XG4gICAgICAgICAgICBpZiAoc2xvdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbWF0Y2hlZC5hZGQoc2xvdCk7XG4gICAgICAgICAgICAgICAgc2V0V2luZG93KHNsb3QsIHNwZWMudmFsaWRXaW5kb3cpO1xuICAgICAgICAgICAgICAgIGxldCBleGlzdGluZyA9IHRoaXMuc291cmNlc1tzbG90XTtcbiAgICAgICAgICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkoZXhpc3Rpbmcucm91dGUpICE9PSBKU09OLnN0cmluZ2lmeShzcGVjLnJvdXRlKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgUm91dGUgY2hhbmdlZCBmb3IgJHtleGlzdGluZy5zb3VyY2UuZ2V0RGVidWdOYW1lKCl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6ICR7SlNPTi5zdHJpbmdpZnkoZXhpc3Rpbmcucm91dGUpfSAtPiAke0pTT04uc3RyaW5naWZ5KHNwZWMucm91dGUpfWApO1xuICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5yb3V0ZSA9IHNwZWMucm91dGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGV4aXN0aW5nLm5vRnVsbFN5bmMgPSBzcGVjLm5vRnVsbFN5bmM7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgc291cmNlID0gc3BlYy5jcmVhdGUoKTtcbiAgICAgICAgICAgIHRoaXMuc291cmNlcy5wdXNoKHsgc291cmNlLCB1cmw6IHNwZWMudXJsLCB2YWxpZFdpbmRvdzogc3BlYy52YWxpZFdpbmRvdywgcm91dGU6IHNwZWMucm91dGUsIG5vRnVsbFN5bmM6IHNwZWMubm9GdWxsU3luYywgaW50ZXJtZWRpYXRlOiBzcGVjLmludGVybWVkaWF0ZSwgaWRlbnRpdHk6IHNwZWMuaWRlbnRpdHkgfSk7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZVN0YXRlcy5wdXNoKG5ld1NvdXJjZVN0YXRlKCkpO1xuICAgICAgICAgICAgdGhpcy5zb3VyY2VGaWxlQ291bnRzLnB1c2goMCk7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ5dGVDb3VudHMucHVzaCgwKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBBZGRlZCBzeW5jIHNvdXJjZSAke3NvdXJjZS5nZXREZWJ1Z05hbWUoKX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KWApO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3luY1N0YXJ0ZWQpIHtcbiAgICAgICAgICAgICAgICB2b2lkIHRoaXMucnVuU291cmNlU3luYyh0aGlzLnNvdXJjZXMubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBvcmlnaW5hbExlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNMaXZlKGkpIHx8IG1hdGNoZWQuaGFzKGkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlU291cmNlKGkpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBkZWFkbGluZSA9IHRoaXMuc291cmNlc1swXS52YWxpZFdpbmRvd1sxXSAtIFdJTkRPV19FTkRfRkxVU0hfTUFSR0lOO1xuICAgICAgICBsZXQgcmVjYXBwZWQgPSAwO1xuICAgICAgICBmb3IgKGxldCBlbnRyeSBvZiB0aGlzLm92ZXJsYXkudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIGlmIChlbnRyeS5mbHVzaEF0IDw9IGRlYWRsaW5lKSBjb250aW51ZTtcbiAgICAgICAgICAgIGVudHJ5LmZsdXNoQXQgPSBkZWFkbGluZTtcbiAgICAgICAgICAgIHJlY2FwcGVkKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlY2FwcGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgUmUtY2FwcGVkICR7cmVjYXBwZWR9IHBlbmRpbmcgZmFzdCB3cml0ZXMgdG8gdGhlIG5ldyBmbHVzaCBkZWFkbGluZSAke25ldyBEYXRlKGRlYWRsaW5lKS50b0lTT1N0cmluZygpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pYCk7XG4gICAgICAgICAgICBpZiAoZGVhZGxpbmUgPD0gRGF0ZS5ub3coKSkge1xuICAgICAgICAgICAgICAgIHZvaWQgdGhpcy5mbHVzaE92ZXJsYXkoKS5jYXRjaCgoZTogRXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoYEZsdXNoaW5nIGZhc3Qgd3JpdGVzIGFmdGVyIGEgdmFsaWQgd2luZG93IGNoYW5nZSBmYWlsZWQgKHN0b3JlICR7dGhpcy5mb2xkZXJ9KTogJHtlLnN0YWNrID8/IGV9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGhlIHNsb3Qgc3RheXMgaW4gdGhlIGFycmF5cyBmb3JldmVyIChpbmRleCBlbnRyaWVzIHJlZmVyZW5jZSBzb3VyY2VzIGJ5IHNsb3QgbnVtYmVyKTsgaXQganVzdCBnb2VzIGRlYWQgLSBsb29wcyBzdG9wLCBhbmQgaXRzIGluZGV4IGVudHJpZXMgZHJvcCAob3RoZXIgc291cmNlcycgc2NhbnMgcmUtZmluZCBhbnkgY29weSB0aGF0J3Mgc3RpbGwgcmVhY2hhYmxlIHRocm91Z2ggdGhlIG5ldyBjb25maWcpXG4gICAgcHJpdmF0ZSByZW1vdmVTb3VyY2Uoc291cmNlSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLnNvdXJjZVN0YXRlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIGxldCBzb3VyY2UgPSB0aGlzLnNvdXJjZXNbc291cmNlSW5kZXhdLnNvdXJjZTtcbiAgICAgICAgc3RhdGUuZGVhZCA9IHRydWU7XG4gICAgICAgIHN0YXRlLnN0b3BwZWQuc3RvcCA9IHRydWU7XG4gICAgICAgIHN0YXRlLnNjYW5Db21wbGV0ZSA9IHRydWU7XG4gICAgICAgIHN0YXRlLmluaXRpYWxTY2FuLnJlc29sdmUodW5kZWZpbmVkKTtcbiAgICAgICAgbGV0IHNvdXJjZXNMaXN0SW5kZXggPSB0aGlzLnNsb3RTb3VyY2VzTGlzdEluZGV4ZXNbc291cmNlSW5kZXhdO1xuICAgICAgICAvLyBUaGUgc2FtZSBVUkwgY2FuIGJlIGFub3RoZXIgbGl2ZSBzbG90IChvbmUgZW50cnkgcGVyIHZhbGlkIHdpbmRvdykgLSB0aGUgZW5kcG9pbnQgaXMgc3RpbGwgY29uZmlndXJlZCwgc28gaXRzIGVudHJpZXMgc3RheVxuICAgICAgICBpZiAoc291cmNlc0xpc3RJbmRleCAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc2xvdEZvclNvdXJjZXNMaXN0SW5kZXgoc291cmNlc0xpc3RJbmRleCkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbGV0IGRyb3BwZWQgPSAwO1xuICAgICAgICAgICAgZm9yIChsZXQgW2tleSwgZW50cnldIG9mIHRoaXMubWVtKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVudHJ5LnNvdXJjZXNMaXN0SW5kZXggIT09IHNvdXJjZXNMaXN0SW5kZXgpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsZXRlSW5kZXhFbnRyeShrZXkpO1xuICAgICAgICAgICAgICAgIGRyb3BwZWQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBSZW1vdmVkIHN5bmMgc291cmNlICR7c291cmNlLmdldERlYnVnTmFtZSgpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiBpdHMgc2NhbnMgYXJlIHN0b3BwZWQgYW5kICR7ZHJvcHBlZH0gaW5kZXggZW50cmllcyBpdCBoZWxkIHdlcmUgZHJvcHBlZGApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKGBSZW1vdmVkIHN5bmMgc291cmNlICR7c291cmNlLmdldERlYnVnTmFtZSgpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiBpdHMgc2NhbnMgYXJlIHN0b3BwZWQgKGl0cyBVUkwgaXMgc3RpbGwgc2VydmVkIGJ5IGFub3RoZXIgc2xvdCwgc28gaXRzIGluZGV4IGVudHJpZXMgc3RheSlgKTtcbiAgICB9XG5cbiAgICAvKiogUmVzY2FucyBvdXIgb3duIGRpc2sncyBtZXRhZGF0YSBpbnRvIHRoZSBpbmRleCAtIHVzZWQgYXJvdW5kIHZhbGlkIHdpbmRvdyBoYW5kb2Zmcywgd2hlcmUgYW5vdGhlciBwcm9jZXNzIHdyb3RlIGZpbGVzIHRvIHRoZSBzaGFyZWQgZm9sZGVyIHRoYXQgb3VyIGluZGV4IGhhc24ndCBzZWVuLiAqL1xuICAgIHB1YmxpYyBhc3luYyByZXNjYW5CYXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmluaXQoKTtcbiAgICAgICAgYXdhaXQgdGhpcy5zY2FuU291cmNlKDApO1xuICAgIH1cblxuICAgIC8qKiBBIGJvdW5kYXJ5IHNjYW4gb2YgdGhlIG5vZGUgdGhhdCBvd25lZCAocGFydCBvZikgb3VyIHJvdXRlIGluIHRoZSB2YWxpZCB3aW5kb3cgYmVmb3JlIG91cnMsIHdoZW4gdGhhdCBub2RlIGlzIGRpZmZlcmVudCBzdG9yYWdlIChhIGRpc2sgcmVzY2FuIGNhbid0IHNlZSBpdHMgd3JpdGVzKToganVzdCBpdHMgY2hhbmdlcyBzaW5jZSB0aGUgYm91bmRhcnkgbmVpZ2hib3Job29kLCB3aXRoIG1hdGNoaW5nIHZhbHVlcyBwdWxsZWQgb250byBvdXIgb3duIGRpc2suICovXG4gICAgcHVibGljIGFzeW5jIGJvdW5kYXJ5U2NhblJlbW90ZShzb3VyY2U6IElBcmNoaXZlcywgY29uZmlnOiB7IHNpbmNlOiBudW1iZXI7IHJvdXRlPzogW251bWJlciwgbnVtYmVyXSB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBsZXQgc2NhblN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgY29uc29sZS5sb2coYEJvdW5kYXJ5IHNjYW4gb2YgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IHN0YXJ0aW5nOiBjaGFuZ2VzIHNpbmNlICR7bmV3IERhdGUoY29uZmlnLnNpbmNlKS50b0lTT1N0cmluZygpfSwgcm91dGUgJHtKU09OLnN0cmluZ2lmeShjb25maWcucm91dGUgfHwgRlVMTF9ST1VURSl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSlgKTtcbiAgICAgICAgbGV0IGNoYW5nZXMgPSBhd2FpdCBzb3VyY2UuZ2V0Q2hhbmdlc0FmdGVyMih7IHRpbWU6IGNvbmZpZy5zaW5jZSwgcm91dGVzOiBjb25maWcucm91dGUgJiYgW2NvbmZpZy5yb3V0ZV0gfHwgdW5kZWZpbmVkIH0pO1xuICAgICAgICBsZXQgdGFsbHkgPSBuZXdTY2FuVGFsbHkoKTtcbiAgICAgICAgZm9yIChsZXQgZmlsZSBvZiBjaGFuZ2VzKSB7XG4gICAgICAgICAgICBpZiAoZmlsZS5wYXRoID09PSBST1VUSU5HX0ZJTEUpIHtcbiAgICAgICAgICAgICAgICB0YWxseS5maWx0ZXJlZCsrO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IG92ZXJsYXlFbnRyeSA9IHRoaXMub3ZlcmxheS5nZXQoZmlsZS5wYXRoKTtcbiAgICAgICAgICAgIGxldCBlbnRyeSA9IHRoaXMubWVtLmdldChmaWxlLnBhdGgpO1xuICAgICAgICAgICAgbGV0IGN1cnJlbnRUaW1lID0gb3ZlcmxheUVudHJ5ICYmIG92ZXJsYXlFbnRyeS50IHx8IGVudHJ5ICYmIGVudHJ5LndyaXRlVGltZSB8fCAwO1xuICAgICAgICAgICAgaWYgKGZpbGUuY3JlYXRlVGltZSA8PSBjdXJyZW50VGltZSkge1xuICAgICAgICAgICAgICAgIHRhbGx5LnVuY2hhbmdlZCsrO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZpbGUuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIC8vIEEgdG9tYnN0b25lIHN0b3JlcyBub3RoaW5nIG9uIG91ciBvd24gc291cmNlIC0gdGhlIGluZGV4IGVudHJ5IGFsb25lIHJlY29yZHMgaXRcbiAgICAgICAgICAgICAgICB0aGlzLnNldEluZGV4RW50cnkoZmlsZS5wYXRoLCB7IHdyaXRlVGltZTogZmlsZS5jcmVhdGVUaW1lLCBzaXplOiAwLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCkgfSk7XG4gICAgICAgICAgICAgICAgdGFsbHkudG9tYnN0b25lKys7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgY29waWVkID0gYXdhaXQgY29weUFyY2hpdmVGaWxlKHsgZnJvbTogc291cmNlLCB0bzogdGhpcy5zb3VyY2VzWzBdLnNvdXJjZSwgcGF0aDogZmlsZS5wYXRoLCBzaXplOiBmaWxlLnNpemUsIHdyaXRlVGltZTogZmlsZS5jcmVhdGVUaW1lLCBmb3JjZVNldEltbXV0YWJsZTogdHJ1ZSwgbm9DaGVja3M6IHRydWUsIGludGVybmFsOiB0cnVlIH0pO1xuICAgICAgICAgICAgaWYgKCFjb3BpZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKGNvcGllZC5zaXplID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRJbmRleEVudHJ5KGZpbGUucGF0aCwgeyB3cml0ZVRpbWU6IGNvcGllZC53cml0ZVRpbWUsIHNpemU6IDAsIHNvdXJjZXNMaXN0SW5kZXg6IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdCgwKSB9KTtcbiAgICAgICAgICAgICAgICB0YWxseS50b21ic3RvbmUrKztcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2V0SW5kZXhFbnRyeShmaWxlLnBhdGgsIHsgd3JpdGVUaW1lOiBjb3BpZWQud3JpdGVUaW1lLCBzaXplOiBjb3BpZWQuc2l6ZSwgc291cmNlc0xpc3RJbmRleDogdGhpcy5zb3VyY2VzTGlzdEluZGV4T2ZTbG90KDApIH0pO1xuICAgICAgICAgICAgaWYgKGVudHJ5IHx8IG92ZXJsYXlFbnRyeSkge1xuICAgICAgICAgICAgICAgIHRhbGx5LnVwZGF0ZWQrKztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGFsbHkubmV3Kys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5sb2coYEJvdW5kYXJ5IHNjYW4gb2YgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IGZpbmlzaGVkIGluICR7TWF0aC5yb3VuZCgoRGF0ZS5ub3coKSAtIHNjYW5TdGFydCkgLyAxMDAwKX1zIChzdG9yZSAke3RoaXMuZm9sZGVyfSk6ICR7Y2hhbmdlcy5sZW5ndGh9IGNoYW5nZXM6ICR7Zm9ybWF0U2NhblRhbGx5KHRhbGx5LCBjaGFuZ2VzLmxlbmd0aCl9YCk7XG4gICAgfVxuXG4gICAgLyoqIFRoZSBjaGVhcCBhbHdheXMtY3VycmVudCB0b3RhbHMgcGx1cyBhbnkgaW4tcHJvZ3Jlc3MgYmFja2dyb3VuZCBzeW5jaHJvbml6YXRpb24uICovXG4gICAgcHVibGljIGdldFN5bmNQcm9ncmVzcygpOiB7XG4gICAgICAgIGluZGV4OiB7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9O1xuICAgICAgICBzb3VyY2VzOiB7IGRlYnVnTmFtZTogc3RyaW5nOyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXIgfVtdO1xuICAgICAgICByZWFkZXJEaXNrTGltaXQ/OiBudW1iZXI7XG4gICAgICAgIHN5bmNpbmc6IFN5bmNBY3Rpdml0eVtdO1xuICAgIH0ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaW5kZXg6IHsgZmlsZUNvdW50OiB0aGlzLmluZGV4RmlsZUNvdW50LCBieXRlQ291bnQ6IHRoaXMuaW5kZXhCeXRlQ291bnQgfSxcbiAgICAgICAgICAgIHNvdXJjZXM6IHRoaXMuc291cmNlcy5tYXAoKHgsIGkpID0+ICh7XG4gICAgICAgICAgICAgICAgZGVidWdOYW1lOiB4LnNvdXJjZS5nZXREZWJ1Z05hbWUoKSxcbiAgICAgICAgICAgICAgICBmaWxlQ291bnQ6IHRoaXMuc291cmNlRmlsZUNvdW50c1tpXSxcbiAgICAgICAgICAgICAgICBieXRlQ291bnQ6IHRoaXMuc291cmNlQnl0ZUNvdW50c1tpXSxcbiAgICAgICAgICAgIH0pKS5maWx0ZXIoKHgsIGkpID0+IHRoaXMuaXNMaXZlKGkpKSxcbiAgICAgICAgICAgIHJlYWRlckRpc2tMaW1pdDogdGhpcy5jb25maWc/LnJlYWRlckRpc2tMaW1pdCxcbiAgICAgICAgICAgIHN5bmNpbmc6IFsuLi50aGlzLnN5bmNBY3Rpdml0aWVzXSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKiogV2Fsa3MgdGhlIHdob2xlIGluZGV4IGZvciBleGFjdCB0b3RhbHMgLSBtb3JlIGV4cGVuc2l2ZSB0aGFuIGdldFN5bmNQcm9ncmVzcywgYnV0IGltbXVuZSB0byBhbnkgZHJpZnQgaW4gdGhlIG1haW50YWluZWQgY291bnRlcnMgKGFuZCBsb2FkcyB0aGUgaW5kZXggZmlyc3QsIHNvIGl0J3MgbmV2ZXIgY29sZCB6ZXJvcykuICovXG4gICAgcHVibGljIGFzeW5jIGNvbXB1dGVJbmRleFRvdGFscygpOiBQcm9taXNlPHtcbiAgICAgICAgZmlsZUNvdW50OiBudW1iZXI7XG4gICAgICAgIGJ5dGVDb3VudDogbnVtYmVyO1xuICAgICAgICBzb3VyY2VzOiB7IGRlYnVnTmFtZTogc3RyaW5nOyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXIgfVtdO1xuICAgIH0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgIGxldCBmaWxlQ291bnQgPSAwO1xuICAgICAgICBsZXQgYnl0ZUNvdW50ID0gMDtcbiAgICAgICAgbGV0IHNvdXJjZXMgPSB0aGlzLnNvdXJjZXMubWFwKHggPT4gKHsgZGVidWdOYW1lOiB4LnNvdXJjZS5nZXREZWJ1Z05hbWUoKSwgZmlsZUNvdW50OiAwLCBieXRlQ291bnQ6IDAgfSkpO1xuICAgICAgICBmb3IgKGxldCBlbnRyeSBvZiB0aGlzLm1lbS52YWx1ZXMoKSkge1xuICAgICAgICAgICAgaWYgKGVudHJ5LnNpemUgPT09IDApIGNvbnRpbnVlO1xuICAgICAgICAgICAgZmlsZUNvdW50Kys7XG4gICAgICAgICAgICBieXRlQ291bnQgKz0gZW50cnkuc2l6ZTtcbiAgICAgICAgICAgIGxldCBzbG90ID0gdGhpcy5zbG90Rm9yU291cmNlc0xpc3RJbmRleChlbnRyeS5zb3VyY2VzTGlzdEluZGV4KTtcbiAgICAgICAgICAgIGlmIChzbG90ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBzb3VyY2VzW3Nsb3RdLmZpbGVDb3VudCsrO1xuICAgICAgICAgICAgICAgIHNvdXJjZXNbc2xvdF0uYnl0ZUNvdW50ICs9IGVudHJ5LnNpemU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgZmlsZUNvdW50LCBieXRlQ291bnQsIHNvdXJjZXM6IHNvdXJjZXMuZmlsdGVyKCh4LCBpKSA9PiB0aGlzLmlzTGl2ZShpKSkgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGZsdXNoSW5kZXgoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmICghdGhpcy5kaXJ0eS5zaXplKSByZXR1cm47XG4gICAgICAgIGxldCBkaXJ0eSA9IHRoaXMuZGlydHk7XG4gICAgICAgIHRoaXMuZGlydHkgPSBuZXcgTWFwKCk7XG4gICAgICAgIGxldCB3cml0ZXM6IEJsb2JJbmRleEVudHJ5W10gPSBbXTtcbiAgICAgICAgbGV0IGRlbGV0ZXM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGZvciAobGV0IFtrZXksIGVudHJ5XSBvZiBkaXJ0eSkge1xuICAgICAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgd3JpdGVzLnB1c2goeyBrZXksIHdyaXRlVGltZTogZW50cnkud3JpdGVUaW1lLCBzaXplOiBlbnRyeS5zaXplLCBzb3VyY2VzTGlzdEluZGV4OiBlbnRyeS5zb3VyY2VzTGlzdEluZGV4IH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWxldGVzLnB1c2goa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAod3JpdGVzLmxlbmd0aCkgYXdhaXQgdGhpcy5pbmRleC53cml0ZUJhdGNoKHdyaXRlcyk7XG4gICAgICAgIGlmIChkZWxldGVzLmxlbmd0aCkgYXdhaXQgdGhpcy5pbmRleC5kZWxldGVCYXRjaChkZWxldGVzKTtcbiAgICB9XG5cbiAgICAvLyDilIDilIAgc3luY2hyb25pemF0aW9uIOKUgOKUgFxuXG4gICAgcHJpdmF0ZSBhc3luYyBydW5Tb3VyY2VTeW5jKHNvdXJjZUluZGV4OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlclNsb3Qoc291cmNlSW5kZXgpO1xuICAgICAgICBsZXQgeyBzb3VyY2UgfSA9IHRoaXMuc291cmNlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuc291cmNlU3RhdGVzW3NvdXJjZUluZGV4XTtcbiAgICAgICAgLy8gUmVhZCBsaXZlIGZvciBldmVyeSBwYXNzLCBub3QgY2FwdHVyZWQgLSB1cGRhdGVTb3VyY2VzIGNhbiBjaGFuZ2UgaXQgd2hpbGUgbG9vcHMgcnVuXG4gICAgICAgIGxldCBub0Z1bGxTeW5jID0gKCkgPT4gdGhpcy5zb3VyY2VzW3NvdXJjZUluZGV4XS5ub0Z1bGxTeW5jO1xuICAgICAgICBsZXQgaW50ZXJtZWRpYXRlID0gdGhpcy5zb3VyY2VzW3NvdXJjZUluZGV4XS5pbnRlcm1lZGlhdGU7XG4gICAgICAgIGxldCBsaXN0aW5nOiBNYXA8c3RyaW5nLCBudW1iZXI+IHwgdW5kZWZpbmVkO1xuICAgICAgICB3aGlsZSAoIXRoaXMuc3RvcHBlZC5zdG9wICYmICFzdGF0ZS5zdG9wcGVkLnN0b3ApIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRGVhZEludGVybWVkaWF0ZShzb3VyY2VJbmRleCkpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgTm90IHNjYW5uaW5nIHN5bmMgc291cmNlICR7c291cmNlLmdldERlYnVnTmFtZSgpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiBpdCBpcyBhbiBpbnRlcm1lZGlhdGUgd2hvc2Ugd2luZG93IGFscmVhZHkgZW5kZWRgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IGNvbmZpZyA9IGF3YWl0IHNvdXJjZS5nZXRDb25maWcoKTtcbiAgICAgICAgICAgICAgICBzdGF0ZS5zdXBwb3J0c0NoYW5nZXNBZnRlciA9ICEhY29uZmlnLnN1cHBvcnRzQ2hhbmdlc0FmdGVyO1xuICAgICAgICAgICAgICAgIGxpc3RpbmcgPSBhd2FpdCB0aGlzLnNjYW5Tb3VyY2Uoc291cmNlSW5kZXgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGlmIChpbnRlcm1lZGlhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgSW5pdGlhbCBzY2FuIG9mIGludGVybWVkaWF0ZSBzeW5jIHNvdXJjZSAke3NvdXJjZS5nZXREZWJ1Z05hbWUoKX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KSBmYWlsZWQ7IG5vdCByZXRyeWluZyAoaW50ZXJtZWRpYXRlcyBhcmUgdGVtcG9yYXJ5IHN3aXRjaG92ZXIgcG9ydHMpOiAkeyhlIGFzIEVycm9yKS5zdGFjayA/PyBlfWApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgSW5pdGlhbCBzY2FuIG9mIHN5bmMgc291cmNlICR7c291cmNlLmdldERlYnVnTmFtZSgpfSBmYWlsZWQsIHJldHJ5aW5nOmAsIGUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGRlbGF5KFNDQU5fUkVUUllfREVMQVkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0YXRlLnNjYW5Db21wbGV0ZSA9IHRydWU7XG4gICAgICAgIHN0YXRlLmluaXRpYWxTY2FuLnJlc29sdmUodW5kZWZpbmVkKTtcbiAgICAgICAgaWYgKHRoaXMuc3RvcHBlZC5zdG9wIHx8IHN0YXRlLnN0b3BwZWQuc3RvcCkgcmV0dXJuO1xuICAgICAgICAvLyBBbiBpbnRlcm1lZGlhdGUgdGhhdCBuZXZlciBwcm9kdWNlZCBhIGxpc3RpbmcgaXMgZGVhZCBvciBkeWluZyAtIHBvbGxpbmcgYW5kIGNvcHlpbmcgZnJvbSBpdCB3b3VsZCBvbmx5IGxvZyBlcnJvcnNcbiAgICAgICAgaWYgKGludGVybWVkaWF0ZSAmJiAhbGlzdGluZykgcmV0dXJuO1xuICAgICAgICBpZiAobGlzdGluZykge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWNvbmNpbGVTb3VyY2Uoc291cmNlSW5kZXgsIGxpc3RpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghbm9GdWxsU3luYygpKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY29weVNvdXJjZUZpbGVzKHNvdXJjZUluZGV4KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBDb3B5aW5nIGZpbGVzIGZyb20gc3luYyBzb3VyY2UgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IGZhaWxlZDpgLCBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdGUuc3VwcG9ydHNDaGFuZ2VzQWZ0ZXIpIHtcbiAgICAgICAgICAgIHJ1bkluZmluaXRlUG9sbChDSEFOR0VTX1BPTExfSU5URVJWQUwsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0RlYWRJbnRlcm1lZGlhdGUoc291cmNlSW5kZXgpKSByZXR1cm47XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wb2xsQ2hhbmdlcyhzb3VyY2VJbmRleCk7XG4gICAgICAgICAgICAgICAgaWYgKCFub0Z1bGxTeW5jKCkpIGF3YWl0IHRoaXMuY29weVNvdXJjZUZpbGVzKHNvdXJjZUluZGV4KTtcbiAgICAgICAgICAgIH0sIHN0YXRlLnN0b3BwZWQpO1xuICAgICAgICAgICAgLy8gQ2hhbmdlIHBvbGxzIG9ubHkgc2hvdyB3aGF0IHRoZSBzb3VyY2UgSEFTLCBuZXZlciB3aGF0IGl0J3MgbWlzc2luZywgc28gcHVzaGVzIHJ1biBvbiB0aGUgZnVsbC1yZXNjYW4gY2FkZW5jZSAoZmluZEluZm8gb24gYW4gaW5kZXgtYmFja2VkIHNvdXJjZSBpcyBjaGVhcClcbiAgICAgICAgICAgIHJ1bkluZmluaXRlUG9sbChGVUxMX1JFU0NBTl9JTlRFUlZBTCwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRGVhZEludGVybWVkaWF0ZShzb3VyY2VJbmRleCkpIHJldHVybjtcbiAgICAgICAgICAgICAgICBsZXQgZmlsZXMgPSBhd2FpdCBzb3VyY2UuZmluZEluZm8oXCJcIik7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5yZWNvbmNpbGVTb3VyY2Uoc291cmNlSW5kZXgsIG5ldyBNYXAoZmlsZXMubWFwKHggPT4gW3gucGF0aCwgeC5jcmVhdGVUaW1lXSkpKTtcbiAgICAgICAgICAgIH0sIHN0YXRlLnN0b3BwZWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcnVuSW5maW5pdGVQb2xsKEZVTExfUkVTQ0FOX1VOSU5ERVhFRF9JTlRFUlZBTCwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRGVhZEludGVybWVkaWF0ZShzb3VyY2VJbmRleCkpIHJldHVybjtcbiAgICAgICAgICAgICAgICBsZXQgcmVzY2FuID0gYXdhaXQgdGhpcy5zY2FuU291cmNlKHNvdXJjZUluZGV4KTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlY29uY2lsZVNvdXJjZShzb3VyY2VJbmRleCwgcmVzY2FuKTtcbiAgICAgICAgICAgICAgICBpZiAoIW5vRnVsbFN5bmMoKSkgYXdhaXQgdGhpcy5jb3B5U291cmNlRmlsZXMoc291cmNlSW5kZXgpO1xuICAgICAgICAgICAgfSwgc3RhdGUuc3RvcHBlZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBbiBpbnRlcm1lZGlhdGUgaXMgYSBkZXBsb3kgc3dpdGNob3ZlcidzIHRlbXBvcmFyeSBhbHRlcm5hdGUgcG9ydDogb25jZSBpdHMgd2luZG93IGlzIHBhc3QsIHRoZSBwb3J0IGlzIGdvbmUgZm9yIGdvb2QsIHNvIHNjYW5uaW5nIGl0IChvciByZXRyeWluZyBhIGZhaWxlZCBzY2FuKSBjYW4gbmV2ZXIgc3VjY2VlZCAtIGl0IHdvdWxkIGp1c3QgbG9nIGVycm9ycyBmb3JldmVyXG4gICAgcHJpdmF0ZSBpc0RlYWRJbnRlcm1lZGlhdGUoc291cmNlSW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgeyBpbnRlcm1lZGlhdGUsIHZhbGlkV2luZG93IH0gPSB0aGlzLnNvdXJjZXNbc291cmNlSW5kZXhdO1xuICAgICAgICByZXR1cm4gISFpbnRlcm1lZGlhdGUgJiYgdmFsaWRXaW5kb3dbMV0gPD0gRGF0ZS5ub3coKTtcbiAgICB9XG5cbiAgICAvLyBGdWxsIG1ldGFkYXRhIHNjYW4gKHNpemUsIHdyaXRlVGltZSwgcGF0aCkgb2Ygb25lIHNvdXJjZSwgYXBwbGllZCB0byB0aGUgaW5kZXguIFJldHVybnMgdGhlIHNvdXJjZSdzIGxpc3RpbmcgKHBhdGggLT4gd3JpdGUgdGltZSksIHdoaWNoIHJlY29uY2lsZVNvdXJjZSB1c2VzIGZvciB0aGUgcHVzaCBkaXJlY3Rpb24uXG4gICAgcHJpdmF0ZSBhc3luYyBzY2FuU291cmNlKHNvdXJjZUluZGV4OiBudW1iZXIpOiBQcm9taXNlPE1hcDxzdHJpbmcsIG51bWJlcj4+IHtcbiAgICAgICAgbGV0IHsgc291cmNlLCByb3V0ZSB9ID0gdGhpcy5zb3VyY2VzW3NvdXJjZUluZGV4XTtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5zb3VyY2VTdGF0ZXNbc291cmNlSW5kZXhdO1xuICAgICAgICBsZXQgc2NhblN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgbGV0IGFjdGl2aXR5OiBTeW5jQWN0aXZpdHkgPSB7IHR5cGU6IFwibWV0YWRhdGFTY2FuXCIsIHNvdXJjZURlYnVnTmFtZTogc291cmNlLmdldERlYnVnTmFtZSgpLCBzdGFydFRpbWU6IHNjYW5TdGFydCB9O1xuICAgICAgICB0aGlzLnN5bmNBY3Rpdml0aWVzLmFkZChhY3Rpdml0eSk7XG4gICAgICAgIGNvbnNvbGUubG9nKGBNZXRhZGF0YSBzY2FuIG9mICR7c291cmNlLmdldERlYnVnTmFtZSgpfSBzdGFydGluZyAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pYCk7XG4gICAgICAgIGxldCBwcm9ncmVzc1RpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYE1ldGFkYXRhIHNjYW4gb2YgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IHN0aWxsIHJ1bm5pbmcgKCR7TWF0aC5yb3VuZCgoRGF0ZS5ub3coKSAtIHNjYW5TdGFydCkgLyAxMDAwKX1zLCBzdG9yZSAke3RoaXMuZm9sZGVyfSlgKTtcbiAgICAgICAgfSwgU1lOQ19QUk9HUkVTU19MT0dfSU5URVJWQUwpO1xuICAgICAgICAocHJvZ3Jlc3NUaW1lciBhcyB7IHVucmVmPzogKCkgPT4gdm9pZCB9KS51bnJlZj8uKCk7XG4gICAgICAgIC8vIFRoZSBsaXN0aW5nIHJlcXVlc3QgZGVsaWJlcmF0ZWx5IHRha2VzIG5vIHRpbWUgb3Igcm91dGUgZmlsdGVyczogb3VyIHNsb3dlc3Qgc291cmNlcyAoYmFja2JsYXplKSBzdXBwb3J0IG5laXRoZXIsIHNvIGZpbHRlcmluZyB3b3VsZCBoYXBwZW4gYWZ0ZXIgdGhlIGZ1bGwgZmV0Y2ggYW55d2F5IC0gbGl0dGxlIGJlbmVmaXQsIG1vcmUgcm9vbSBmb3IgZGVzeW5jaHJvbml6YXRpb24uIEFuZCBpZiBhIGZ1bGwgbGlzdGluZyBldmVyIGJlY29tZXMgdG9vIGJpZyB0byBzZW5kIG92ZXIgdGhlIG5ldHdvcmssIGl0IGlzIGFsc28gdG9vIGJpZyBmb3IgdGhlIHJlY2VpdmluZyBwcm9jZXNzIHRvIGhvbGQgaW4gbWVtb3J5IC0gdGhlIGZpeCBpcyBtb3JlIHJvdXRpbmcgc2hhcmRzIChlYWNoIHN0b3JpbmcgYW5kIHNlbmRpbmcgbGVzcyksIG5vdCBmaWx0ZXJpbmcuXG4gICAgICAgIGxldCBmaWxlczogQXJjaGl2ZUZpbGVJbmZvW107XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmaWxlcyA9IGF3YWl0IHNvdXJjZS5maW5kSW5mbyhcIlwiKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwocHJvZ3Jlc3NUaW1lcik7XG4gICAgICAgICAgICB0aGlzLnN5bmNBY3Rpdml0aWVzLmRlbGV0ZShhY3Rpdml0eSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlIHNvdXJjZSBtYXkgaGF2ZSBiZWVuIHJlbW92ZWQgd2hpbGUgdGhlIGxpc3Rpbmcgd2FzIGluIGZsaWdodDsgaXRzIHJlc3VsdHMgYXJlIGRlYWRcbiAgICAgICAgaWYgKHN0YXRlLnN0b3BwZWQuc3RvcCkgcmV0dXJuIG5ldyBNYXAoKTtcbiAgICAgICAgbGV0IGluZGV4U2l6ZUJlZm9yZSA9IHRoaXMubWVtLnNpemU7XG4gICAgICAgIGxldCBzZWVuID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICAgICAgbGV0IHRhbGx5ID0gbmV3U2NhblRhbGx5KCk7XG4gICAgICAgIGxldCBuZXdQYXRocyA9IDA7XG4gICAgICAgIGZvciAobGV0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICAgICAgICAgIHNlZW4uc2V0KGZpbGUucGF0aCwgZmlsZS5jcmVhdGVUaW1lKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5tZW0uaGFzKGZpbGUucGF0aCkpIHtcbiAgICAgICAgICAgICAgICBuZXdQYXRocysrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGFsbHlbdGhpcy51cGRhdGVTY2FuSW5kZXgoc291cmNlSW5kZXgsIGZpbGUpXSsrO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLnNjYW5uZWRDb3VudCA9IGZpbGVzLmxlbmd0aDtcbiAgICAgICAgLy8gSW5kZXggZW50cmllcyB0aGlzIHNvdXJjZSB3YXMgdGhlIGhvbGRlciBvZiwgYnV0IHRoYXQgdmFuaXNoZWQgZnJvbSBpdCAoZS5nLiBkZWxldGVkIHdoaWxlIHdlIHdlcmUgb2ZmbGluZSksIGNvbWUgb3V0IG9mIHRoZSBpbmRleC4gRW50cmllcyBjaGFuZ2VkIGFmdGVyIHRoZSBzY2FuIHN0YXJ0ZWQgYXJlIGtlcHQg4oCUIHRoZSBzY2FuIGxpc3RpbmcgbWF5IHNpbXBseSBwcmVkYXRlIHRoZW0uIFRvbWJzdG9uZXMgaGF2ZSBubyBwaHlzaWNhbCBmaWxlIGZvciBhIGxpc3RpbmcgdG8gdm91Y2ggZm9yLCBzbyB0aGV5J3JlIGV4ZW1wdCAoY2xlYW51cFRvbWJzdG9uZXMgZXhwaXJlcyB0aGVtIGluc3RlYWQpLlxuICAgICAgICBsZXQgcmVtb3ZlZEZyb21JbmRleCA9IDA7XG4gICAgICAgIGxldCBtaXNzaW5nT25Tb3VyY2UgPSAwO1xuICAgICAgICBsZXQgc2Nhbm5lZFNvdXJjZXNMaXN0SW5kZXggPSB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3Qoc291cmNlSW5kZXgpO1xuICAgICAgICBmb3IgKGxldCBba2V5LCBlbnRyeV0gb2YgdGhpcy5tZW0pIHtcbiAgICAgICAgICAgIGlmIChzZWVuLmhhcyhrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmIChlbnRyeS5zb3VyY2VzTGlzdEluZGV4ID09PSBzY2FubmVkU291cmNlc0xpc3RJbmRleCAmJiBlbnRyeS5zaXplICE9PSAwICYmIGVudHJ5LmNoYW5nZWRBdCA8IHNjYW5TdGFydCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsZXRlSW5kZXhFbnRyeShrZXkpO1xuICAgICAgICAgICAgICAgIHJlbW92ZWRGcm9tSW5kZXgrKztcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIENvdW50ZWQgb25seSB3aGVuIHRoZSBzb3VyY2UgU0hPVUxEIGhvbGQgdGhlIGVudHJ5IChpdHMgcm91dGUgbWF0Y2hlcykgLSB0aGVzZSBhcmUgd2hhdCB0aGUgcmVjb25jaWxlIHBhc3MgcHVzaGVzIHRvIGl0ICh3aGljaCBhbHNvIGlnbm9yZXMgdGhlIHZhbGlkIHdpbmRvdzogc3luY2hyb25pemF0aW9uIG1vdmVzIGV4aXN0aW5nIHZhbHVlcywgdGhlIHdpbmRvdyBvbmx5IHJvdXRlcyBmcmVzaCB3cml0ZXMpXG4gICAgICAgICAgICBpZiAoZW50cnkuc2l6ZSA9PT0gMCB8fCBrZXkgPT09IFJPVVRJTkdfRklMRSkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoIXJvdXRlQ29udGFpbnMocm91dGUsIGdldFJvdXRlKGtleSkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIG1pc3NpbmdPblNvdXJjZSsrO1xuICAgICAgICB9XG4gICAgICAgIC8vIFBlcmNlbnRhZ2VzIGFyZSBvZiB0aGUgdW5pb24gb2YgYm90aCBzaWRlcyAob3VyIGluZGV4ICsgdGhlaXIgbGlzdGluZyksIHNvIGV2ZXJ5IGNvdW50IGhhcyBhIHN0YWJsZSBkZW5vbWluYXRvclxuICAgICAgICBsZXQgdW5pb24gPSBpbmRleFNpemVCZWZvcmUgKyBuZXdQYXRocztcbiAgICAgICAgbGV0IHBjdCA9IChuOiBudW1iZXIpID0+IGAke01hdGgucm91bmQobiAvIE1hdGgubWF4KHVuaW9uLCAxKSAqIDEwMDApIC8gMTB9JWA7XG4gICAgICAgIGNvbnNvbGUubG9nKGBNZXRhZGF0YSBzY2FuIG9mICR7c291cmNlLmdldERlYnVnTmFtZSgpfSBmaW5pc2hlZCBpbiAke01hdGgucm91bmQoKERhdGUubm93KCkgLSBzY2FuU3RhcnQpIC8gMTAwMCl9cyAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiAke2ZpbGVzLmxlbmd0aH0gbGlzdGVkIHZzICR7aW5kZXhTaXplQmVmb3JlfSBpbmRleGVkICh1bmlvbiAke3VuaW9ufSk6ICR7Zm9ybWF0U2NhblRhbGx5KHRhbGx5LCB1bmlvbil9LCAke21pc3NpbmdPblNvdXJjZX0gaW4gaW5kZXggYnV0IG1pc3Npbmcgb24gc291cmNlICgke3BjdChtaXNzaW5nT25Tb3VyY2UpfSksICR7cmVtb3ZlZEZyb21JbmRleH0gcmVtb3ZlZCBmcm9tIGluZGV4ICgke3BjdChyZW1vdmVkRnJvbUluZGV4KX0pYCk7XG4gICAgICAgIHN0YXRlLmNoYW5nZXNBZnRlclRpbWUgPSBNYXRoLm1heChzdGF0ZS5jaGFuZ2VzQWZ0ZXJUaW1lLCBzY2FuU3RhcnQgLSBDSEFOR0VTX1BPTExfT1ZFUkxBUCk7XG4gICAgICAgIHJldHVybiBzZWVuO1xuICAgIH1cblxuICAgIC8vIFRoZSBwdXNoIGRpcmVjdGlvbiBvZiBzeW5jaHJvbml6YXRpb246IGV2ZXJ5dGhpbmcgd2Uga25vdyB0aGF0IHRoZSBzb3VyY2UgaXMgbWlzc2luZyAob3IgaG9sZHMgYW4gb2xkZXIgY29weSBvZikgaXMgd3JpdHRlbiB0byBpdCDigJQgaW5jbHVkaW5nIGRlbGV0aW9ucywgYXMgdG9tYnN0b25lIHdyaXRlcy4gVGhpcyBpcyB3aGF0IGhlYWxzIGEgc291cmNlIHdob3NlIGJhY2tncm91bmQgd3JpdGVzIGZhaWxlZCAoZS5nLiBpdCB3YXMgZG93bik6IHRoZSBuZXh0IHNjYW4gc2VlcyB3aGF0J3MgbWlzc2luZyBhbmQgcmUtc2VuZHMgaXQuIEEgZmFpbGluZyBmaWxlIGlzIHNraXBwZWQsIG5vdCBmYXRhbCAoaW1tdXRhYmxlIHRhcmdldHMgYXJlIGhhbmRsZWQgYnkgZm9yY2VTZXRJbW11dGFibGUsIGFuZCBvbmUgdW5yZWFkYWJsZSB2YWx1ZSBtdXN0IG5vdCBzdG9wIHRoZSByZXN0IG9mIHRoZSBwYXNzKSAtIG9ubHkgYSBydW4gb2YgY29uc2VjdXRpdmUgZmFpbHVyZXMgKHRoZSBzb3VyY2UgaXRzZWxmIGlzIGRvd24pIGFib3J0cyB1bnRpbCB0aGUgbmV4dCBzY2FuIGN5Y2xlLlxuICAgIHByaXZhdGUgYXN5bmMgcmVjb25jaWxlU291cmNlKHNvdXJjZUluZGV4OiBudW1iZXIsIGxpc3Rpbmc6IE1hcDxzdHJpbmcsIG51bWJlcj4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IHsgc291cmNlLCB2YWxpZFdpbmRvdywgcm91dGUgfSA9IHRoaXMuc291cmNlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuc291cmNlU3RhdGVzW3NvdXJjZUluZGV4XTtcbiAgICAgICAgbGV0IGFjY2VwdHNXcml0ZXMgPSB3aW5kb3dBY2NlcHRzV3JpdGVzKHZhbGlkV2luZG93KTtcbiAgICAgICAgbGV0IHRhcmdldFNvdXJjZXNMaXN0SW5kZXggPSB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3Qoc291cmNlSW5kZXgpO1xuICAgICAgICBsZXQgcHVzaGVkID0gMDtcbiAgICAgICAgbGV0IGZhaWxlZCA9IDA7XG4gICAgICAgIGxldCBjb25zZWN1dGl2ZUZhaWx1cmVzID0gMDtcbiAgICAgICAgbGV0IGVycm9yczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgbGV0IGFib3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgW2tleSwgZW50cnldIG9mIHRoaXMubWVtKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdG9wcGVkLnN0b3AgfHwgc3RhdGUuc3RvcHBlZC5zdG9wKSByZXR1cm47XG4gICAgICAgICAgICBpZiAoZW50cnkuc291cmNlc0xpc3RJbmRleCA9PT0gdGFyZ2V0U291cmNlc0xpc3RJbmRleCkgY29udGludWU7XG4gICAgICAgICAgICAvLyBUaGUgcm91dGluZyBmaWxlIGlzIE5FVkVSIHN5bmNocm9uaXplZCBiZXR3ZWVuIHN0b3JhZ2Ugbm9kZXMgLSBpdCBpcyBvbmx5IGV2ZXIgd3JpdHRlbiBkaXJlY3RseSB0byBlYWNoIG5vZGUsIGFuZCBvbmx5IGV2ZXIgcmVhZCBvZmYgb3VyIG93biBkaXNrXG4gICAgICAgICAgICBpZiAoa2V5ID09PSBST1VUSU5HX0ZJTEUpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFhY2NlcHRzV3JpdGVzKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmICghcm91dGVDb250YWlucyhyb3V0ZSwgZ2V0Um91dGUoa2V5KSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgbGV0IHRoZWlyVGltZSA9IGxpc3RpbmcuZ2V0KGtleSk7XG4gICAgICAgICAgICBpZiAodGhlaXJUaW1lICE9PSB1bmRlZmluZWQgJiYgdGhlaXJUaW1lID49IGVudHJ5LndyaXRlVGltZSkgY29udGludWU7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChlbnRyeS5zaXplID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEEgZGVsZXRpb24gb25seSBuZWVkcyBwdXNoaW5nIHdoaWxlIHRoZSBzb3VyY2Ugc3RpbGwgaG9sZHMgYW4gb2xkZXIgY29weS4gSXQgdHJhdmVscyBhcyBkZWwgKG5ldmVyIGFzIGFuIGVtcHR5IHNldCAtIHNldCByZWplY3RzIGVtcHR5IGJ1ZmZlcnMpLCB3aXRoIHRoZSBPUklHSU5BTCBkZWxldGlvbiB0aW1lIHNvIG9yZGVyaW5nIHN1cnZpdmVzLlxuICAgICAgICAgICAgICAgICAgICBpZiAodGhlaXJUaW1lID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBzb3VyY2UuZGVsKGtleSwgeyBsYXN0TW9kaWZpZWQ6IGVudHJ5LndyaXRlVGltZSwgbm9DaGVja3M6IHRydWUsIGludGVybmFsOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgICAgICBwdXNoZWQrKztcbiAgICAgICAgICAgICAgICAgICAgY29uc2VjdXRpdmVGYWlsdXJlcyA9IDA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgaG9sZGVyID0gYXdhaXQgdGhpcy5nZXRFbnRyeUhvbGRlcihlbnRyeSk7XG4gICAgICAgICAgICAgICAgaWYgKCFob2xkZXIpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGxldCBjb3BpZWQgPSBhd2FpdCBjb3B5QXJjaGl2ZUZpbGUoeyBmcm9tOiBob2xkZXIsIHRvOiBzb3VyY2UsIHBhdGg6IGtleSwgc2l6ZTogZW50cnkuc2l6ZSwgd3JpdGVUaW1lOiBlbnRyeS53cml0ZVRpbWUsIGZvcmNlU2V0SW1tdXRhYmxlOiB0cnVlLCBub0NoZWNrczogdHJ1ZSwgaW50ZXJuYWw6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgaWYgKCFjb3BpZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIHB1c2hlZCsrO1xuICAgICAgICAgICAgICAgIGNvbnNlY3V0aXZlRmFpbHVyZXMgPSAwO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGZhaWxlZCsrO1xuICAgICAgICAgICAgICAgIGNvbnNlY3V0aXZlRmFpbHVyZXMrKztcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3JzLmxlbmd0aCA8IFJFQ09OQ0lMRV9FUlJPUl9MT0dfTElNSVQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JzLnB1c2goYCR7a2V5fTogJHsoZSBhcyBFcnJvcikuc3RhY2sgPz8gZX1gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNvbnNlY3V0aXZlRmFpbHVyZXMgPj0gUkVDT05DSUxFX01BWF9DT05TRUNVVElWRV9GQUlMVVJFUykge1xuICAgICAgICAgICAgICAgICAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChmYWlsZWQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFJlY29uY2lsaW5nIHN5bmMgc291cmNlICR7c291cmNlLmdldERlYnVnTmFtZSgpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiBwdXNoZWQgJHtwdXNoZWR9IGZpbGVzLCAke2ZhaWxlZH0gZmFpbGVkJHthYm9ydGVkICYmIGAgYmVmb3JlIGFib3J0aW5nIHRoZSBwYXNzICgke2NvbnNlY3V0aXZlRmFpbHVyZXN9IGNvbnNlY3V0aXZlIGZhaWx1cmVzIC0gdGhlIHNvdXJjZSBsb29rcyBkb3duOyB0aGUgbmV4dCBzY2FuIGN5Y2xlIHJldHJpZXMpYCB8fCBcIlwifS4gRmlyc3QgZXJyb3JzOiAke2Vycm9ycy5qb2luKFwiIHwgXCIpfWApO1xuICAgICAgICB9IGVsc2UgaWYgKHB1c2hlZCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFJlY29uY2lsZWQgc3luYyBzb3VyY2UgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6IHB1c2hlZCAke3B1c2hlZH0gZmlsZXMgaXQgd2FzIG1pc3Npbmcgb3IgaGVsZCBvbGRlciBjb3BpZXMgb2ZgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlU2NhbkluZGV4KHNvdXJjZUluZGV4OiBudW1iZXIsIGZpbGU6IEFyY2hpdmVGaWxlSW5mbyk6IFNjYW5PdXRjb21lIHtcbiAgICAgICAgLy8gQW4gaW4tZmxpZ2h0IHNjYW4gY2FuIG91dGxpdmUgaXRzIHNvdXJjZSdzIHJlbW92YWw7IGl0cyByZXN1bHRzIGFyZSBkZWFkXG4gICAgICAgIGlmICghdGhpcy5pc0xpdmUoc291cmNlSW5kZXgpKSByZXR1cm4gXCJmaWx0ZXJlZFwiO1xuICAgICAgICBpZiAoZmlsZS5wYXRoID09PSBST1VUSU5HX0ZJTEUpIHtcbiAgICAgICAgICAgIC8vIFRoZSByb3V0aW5nIGNvbmZpZyBpcyBORVZFUiBwdWxsZWQgZnJvbSBvdGhlciBzb3VyY2VzIC0gaXQgb25seSBldmVyIGFycml2ZXMgYXMgYW4gZXhwbGljaXQsIHZlcnNpb24tdmFsaWRhdGVkIHdyaXRlLCBhbmQgaXMgb25seSBldmVyIHJlYWQgb2ZmIG91ciBvd24gZGlzay4gUm91dGUgYW5kIHZhbGlkLXdpbmRvdyBmaWx0ZXJzIGNhbid0IHBvc3NpYmx5IGFwcGx5IHRvIGl0IGVpdGhlcjogaXQgaXMgdGhlIGZpbGUgREVGSU5JTkcgdGhlbSwgc28gZmlsdGVyaW5nIGl0IHdvdWxkIG1lYW4gY2VydGFpbiBzb3VyY2VzIGNvdWxkIG5ldmVyIGhhdmUgdGhlaXIgcm91dGluZyBjb25maWcgdXBkYXRlZCwgZXZlci5cbiAgICAgICAgICAgIGlmIChzb3VyY2VJbmRleCAhPT0gMCkgcmV0dXJuIFwiZmlsdGVyZWRcIjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoZSB2YWxpZCB3aW5kb3cgaXMgZGVsaWJlcmF0ZWx5IE5PVCBhcHBsaWVkIGhlcmU6IGl0IGRlY2lkZXMgd2hlcmUgV1JJVEVTIHJvdXRlLCBidXQgYSBzY2FuIGlzIHVzIGFza2luZyBhIHNvdXJjZSB3aGF0IGl0IGFscmVhZHkgaG9sZHMgLSBleGlzdGluZyB2YWx1ZXMgc3luY2hyb25pemUgcmVnYXJkbGVzcyBvZiB0aGUgd2luZG93ICh0aGUgc2FtZSByZWFzb25pbmcgdGhhdCBsZXRzIHN5bmNocm9uaXphdGlvbiBpZ25vcmUgdGhlIGltbXV0YWJsZSBmbGFnKS4gT25seSB0aGUgcm91dGUgZmlsdGVyczogYSBwYXJ0aWFsbHktb3ZlcmxhcHBpbmcgc2hhcmQncyBsaXN0aW5nIGxlZ2l0aW1hdGVseSBpbmNsdWRlcyBrZXlzIHRoYXQgYXJlbid0IG91cnMuXG4gICAgICAgICAgICBsZXQgeyByb3V0ZSB9ID0gdGhpcy5zb3VyY2VzW3NvdXJjZUluZGV4XTtcbiAgICAgICAgICAgIGlmICghcm91dGVDb250YWlucyhyb3V0ZSwgZ2V0Um91dGUoZmlsZS5wYXRoKSkpIHJldHVybiBcImZpbHRlcmVkXCI7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGV4aXN0aW5nID0gdGhpcy5tZW0uZ2V0KGZpbGUucGF0aCk7XG4gICAgICAgIC8vIFRoZSBoaWdoZXN0IHdyaXRlIHRpbWUgd2lucyBhY3Jvc3MgYWxsIHNvdXJjZXMgKHRpZXMga2VlcCB0aGUgZXhpc3RpbmcgZW50cnkpXG4gICAgICAgIGlmIChleGlzdGluZyAmJiBmaWxlLmNyZWF0ZVRpbWUgPD0gZXhpc3Rpbmcud3JpdGVUaW1lKSByZXR1cm4gXCJ1bmNoYW5nZWRcIjtcbiAgICAgICAgdGhpcy5zZXRJbmRleEVudHJ5KGZpbGUucGF0aCwgeyB3cml0ZVRpbWU6IGZpbGUuY3JlYXRlVGltZSwgc2l6ZTogZmlsZS5zaXplLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3Qoc291cmNlSW5kZXgpIH0pO1xuICAgICAgICBpZiAoZmlsZS5zaXplID09PSAwKSByZXR1cm4gXCJ0b21ic3RvbmVcIjtcbiAgICAgICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gXCJ1cGRhdGVkXCI7XG4gICAgICAgIHJldHVybiBcIm5ld1wiO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcG9sbENoYW5nZXMoc291cmNlSW5kZXg6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBsZXQgeyBzb3VyY2UsIHJvdXRlIH0gPSB0aGlzLnNvdXJjZXNbc291cmNlSW5kZXhdO1xuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLnNvdXJjZVN0YXRlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIGxldCBwb2xsU3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICBsZXQgY2hhbmdlcyA9IGF3YWl0IHNvdXJjZS5nZXRDaGFuZ2VzQWZ0ZXIyKHsgdGltZTogc3RhdGUuY2hhbmdlc0FmdGVyVGltZSwgcm91dGVzOiByb3V0ZSAmJiBbcm91dGVdIHx8IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgbGV0IHRhbGx5ID0gbmV3U2NhblRhbGx5KCk7XG4gICAgICAgIGZvciAobGV0IGZpbGUgb2YgY2hhbmdlcykge1xuICAgICAgICAgICAgdGFsbHlbdGhpcy51cGRhdGVTY2FuSW5kZXgoc291cmNlSW5kZXgsIGZpbGUpXSsrO1xuICAgICAgICB9XG4gICAgICAgIC8vIFBvbGxzIHJ1biBjb25zdGFudGx5LCBzbyBvbmx5IHRoZSBvbmVzIHRoYXQgYWN0dWFsbHkgY2hhbmdlZCB0aGUgaW5kZXggZ2V0IGEgbGluZVxuICAgICAgICBpZiAodGFsbHkubmV3IHx8IHRhbGx5LnVwZGF0ZWQgfHwgdGFsbHkudG9tYnN0b25lKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgQ2hhbmdlcyBwb2xsIG9mICR7c291cmNlLmdldERlYnVnTmFtZSgpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiAke2NoYW5nZXMubGVuZ3RofSBjaGFuZ2VzOiAke2Zvcm1hdFNjYW5UYWxseSh0YWxseSwgY2hhbmdlcy5sZW5ndGgpfWApO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLnNjYW5uZWRDb3VudCArPSBjaGFuZ2VzLmxlbmd0aDtcbiAgICAgICAgc3RhdGUuY2hhbmdlc0FmdGVyVGltZSA9IHBvbGxTdGFydCAtIENIQU5HRVNfUE9MTF9PVkVSTEFQO1xuICAgIH1cblxuICAgIC8vIERvd25sb2FkcyB0aGUgZmlsZXMgYSBzb3VyY2UgY3VycmVudGx5IGhvbGRzIG9udG8gb3VyIG93biBiYXNlIHNvdXJjZSAodGhlIGxvY2FsIGRpc2spLCBwcmVzZXJ2aW5nIHRoZWlyIG1vZGlmaWVkIHRpbWVzIOKAlCBzbyBhIG5ld2VyIGxvY2FsIHdyaXRlIGFsd2F5cyB3aW5zLiBTa2lwcGVkIGZvciBub0Z1bGxTeW5jIHNvdXJjZXMgKGZyb250aW5nIGEgbGFyZ2UgZGF0YWJhc2Ugd2l0aG91dCBjb3B5aW5nIGl0KTsgcmVhZHMgc3RpbGwgZG93bi1jYWNoZSBsYXppbHkuXG4gICAgcHJpdmF0ZSBhc3luYyBjb3B5U291cmNlRmlsZXMoc291cmNlSW5kZXg6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoc291cmNlSW5kZXggPT09IDApIHJldHVybjtcbiAgICAgICAgbGV0IHsgc291cmNlIH0gPSB0aGlzLnNvdXJjZXNbc291cmNlSW5kZXhdO1xuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLnNvdXJjZVN0YXRlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIGxldCBwZW5kaW5nOiB7IGtleTogc3RyaW5nOyBlbnRyeTogSW5kZXhFbnRyeSB9W10gPSBbXTtcbiAgICAgICAgbGV0IHRvdGFsQnl0ZXMgPSAwO1xuICAgICAgICBsZXQgY29waWVkU291cmNlc0xpc3RJbmRleCA9IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdChzb3VyY2VJbmRleCk7XG4gICAgICAgIGZvciAobGV0IFtrZXksIGVudHJ5XSBvZiB0aGlzLm1lbSkge1xuICAgICAgICAgICAgaWYgKGVudHJ5LnNvdXJjZXNMaXN0SW5kZXggIT09IGNvcGllZFNvdXJjZXNMaXN0SW5kZXgpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKGVudHJ5LnNpemUgPT09IDApIGNvbnRpbnVlO1xuICAgICAgICAgICAgcGVuZGluZy5wdXNoKHsga2V5LCBlbnRyeSB9KTtcbiAgICAgICAgICAgIHRvdGFsQnl0ZXMgKz0gZW50cnkuc2l6ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXBlbmRpbmcubGVuZ3RoKSByZXR1cm47XG4gICAgICAgIGxldCBhY3Rpdml0eTogU3luY0FjdGl2aXR5ID0ge1xuICAgICAgICAgICAgdHlwZTogXCJmdWxsU3luY1wiLFxuICAgICAgICAgICAgc291cmNlRGVidWdOYW1lOiBzb3VyY2UuZ2V0RGVidWdOYW1lKCksXG4gICAgICAgICAgICBzdGFydFRpbWU6IERhdGUubm93KCksXG4gICAgICAgICAgICBkb25lRmlsZXM6IDAsXG4gICAgICAgICAgICB0b3RhbEZpbGVzOiBwZW5kaW5nLmxlbmd0aCxcbiAgICAgICAgICAgIGRvbmVCeXRlczogMCxcbiAgICAgICAgICAgIHRvdGFsQnl0ZXMsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc3luY0FjdGl2aXRpZXMuYWRkKGFjdGl2aXR5KTtcbiAgICAgICAgbGV0IHByb2dyZXNzTG9nZ2VkID0gZmFsc2U7XG4gICAgICAgIGxldCBsb2dQcm9ncmVzcyA9ICgpID0+IHtcbiAgICAgICAgICAgIHByb2dyZXNzTG9nZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBGdWxsIHN5bmMgZnJvbSAke3NvdXJjZS5nZXREZWJ1Z05hbWUoKX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KTogJHthY3Rpdml0eS5kb25lRmlsZXN9LyR7cGVuZGluZy5sZW5ndGh9IGZpbGVzICgkeygoYWN0aXZpdHkuZG9uZUZpbGVzIHx8IDApIC8gcGVuZGluZy5sZW5ndGggKiAxMDApLnRvRml4ZWQoMSl9JSksICR7Zm9ybWF0TnVtYmVyKGFjdGl2aXR5LmRvbmVCeXRlcyB8fCAwKX1CLyR7Zm9ybWF0TnVtYmVyKHRvdGFsQnl0ZXMpfUIgKCR7KHRvdGFsQnl0ZXMgJiYgKGFjdGl2aXR5LmRvbmVCeXRlcyB8fCAwKSAvIHRvdGFsQnl0ZXMgKiAxMDAgfHwgMTAwKS50b0ZpeGVkKDEpfSUpYCk7XG4gICAgICAgIH07XG4gICAgICAgIGxldCBwcm9ncmVzc1RpbWVyID0gc2V0SW50ZXJ2YWwobG9nUHJvZ3Jlc3MsIFNZTkNfUFJPR1JFU1NfTE9HX0lOVEVSVkFMKTtcbiAgICAgICAgKHByb2dyZXNzVGltZXIgYXMgeyB1bnJlZj86ICgpID0+IHZvaWQgfSkudW5yZWY/LigpO1xuICAgICAgICBsZXQgc2xvd0Vycm9yVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICBsZXQgZWxhcHNlZCA9IERhdGUubm93KCkgLSBhY3Rpdml0eS5zdGFydFRpbWU7XG4gICAgICAgICAgICBsZXQgZG9uZUZpbGVzID0gYWN0aXZpdHkuZG9uZUZpbGVzIHx8IDA7XG4gICAgICAgICAgICBsZXQgZG9uZUJ5dGVzID0gYWN0aXZpdHkuZG9uZUJ5dGVzIHx8IDA7XG4gICAgICAgICAgICBsZXQgYnl0ZXNQZXJTZWNvbmQgPSBkb25lQnl0ZXMgLyAoZWxhcHNlZCAvIDEwMDApO1xuICAgICAgICAgICAgbGV0IHJlbWFpbmluZ0J5dGVzID0gdG90YWxCeXRlcyAtIGRvbmVCeXRlcztcbiAgICAgICAgICAgIGxldCBldGFUZXh0ID0gXCJ1bmtub3duIChubyBieXRlcyB0cmFuc2ZlcnJlZCB5ZXQpXCI7XG4gICAgICAgICAgICBpZiAoYnl0ZXNQZXJTZWNvbmQgPiAwKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlbWFpbmluZ01zID0gcmVtYWluaW5nQnl0ZXMgLyBieXRlc1BlclNlY29uZCAqIDEwMDA7XG4gICAgICAgICAgICAgICAgZXRhVGV4dCA9IGAke2Zvcm1hdFRpbWUocmVtYWluaW5nTXMpfSByZW1haW5pbmcsIGNvbXBsZXRpbmcgYXJvdW5kICR7bmV3IERhdGUoRGF0ZS5ub3coKSArIHJlbWFpbmluZ01zKS50b0lTT1N0cmluZygpfWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBGdWxsIHN5bmMgZnJvbSAke3NvdXJjZS5nZXREZWJ1Z05hbWUoKX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KSBoYXMgYmVlbiBydW5uaW5nIGZvciAke2Zvcm1hdFRpbWUoZWxhcHNlZCl9OiAke2RvbmVGaWxlc30vJHtwZW5kaW5nLmxlbmd0aH0gZmlsZXMgKCR7KGRvbmVGaWxlcyAvIHBlbmRpbmcubGVuZ3RoICogMTAwKS50b0ZpeGVkKDEpfSUpLCAke2Zvcm1hdE51bWJlcihkb25lQnl0ZXMpfUIvJHtmb3JtYXROdW1iZXIodG90YWxCeXRlcyl9QiAoJHsodG90YWxCeXRlcyAmJiBkb25lQnl0ZXMgLyB0b3RhbEJ5dGVzICogMTAwIHx8IDEwMCkudG9GaXhlZCgxKX0lKSwgJHtmb3JtYXROdW1iZXIoYnl0ZXNQZXJTZWNvbmQpfUIvcy4gRXN0aW1hdGVkICR7ZXRhVGV4dH0uYCk7XG4gICAgICAgIH0sIEZVTExfU1lOQ19TTE9XX0VSUk9SX0lOVEVSVkFMKTtcbiAgICAgICAgKHNsb3dFcnJvclRpbWVyIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBuZXh0SW5kZXggPSAwO1xuICAgICAgICAgICAgbGV0IGZhaWxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgbGV0IGNvcHlXb3JrZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgd2hpbGUgKCFmYWlsZWQgJiYgIXRoaXMuc3RvcHBlZC5zdG9wICYmICFzdGF0ZS5zdG9wcGVkLnN0b3ApIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGluZGV4ID0gbmV4dEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+PSBwZW5kaW5nLmxlbmd0aCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICBsZXQgeyBrZXksIGVudHJ5IH0gPSBwZW5kaW5nW2luZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvcGllZCA9IGF3YWl0IGNvcHlBcmNoaXZlRmlsZSh7IGZyb206IHNvdXJjZSwgdG86IHRoaXMuc291cmNlc1swXS5zb3VyY2UsIHBhdGg6IGtleSwgc2l6ZTogZW50cnkuc2l6ZSwgd3JpdGVUaW1lOiBlbnRyeS53cml0ZVRpbWUsIGZvcmNlU2V0SW1tdXRhYmxlOiB0cnVlLCBub0NoZWNrczogdHJ1ZSwgaW50ZXJuYWw6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb3BpZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgbW92ZSB0aGUgZW50cnkncyBzb3VyY2UgaWYgaXQgd2Fzbid0IGNoYW5nZWQgd2hpbGUgd2UgY29waWVkXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tZW0uZ2V0KGtleSkgPT09IGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRJbmRleEVudHJ5KGtleSwgeyB3cml0ZVRpbWU6IGNvcGllZC53cml0ZVRpbWUsIHNpemU6IGNvcGllZC5zaXplLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCkgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYWN0aXZpdHkuZG9uZUZpbGVzID0gKGFjdGl2aXR5LmRvbmVGaWxlcyB8fCAwKSArIDE7XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2aXR5LmRvbmVCeXRlcyA9IChhY3Rpdml0eS5kb25lQnl0ZXMgfHwgMCkgKyBlbnRyeS5zaXplO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBsZXQgd29ya2VyczogUHJvbWlzZTx2b2lkPltdID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IE1hdGgubWluKEZVTExfU1lOQ19QQVJBTExFTCwgcGVuZGluZy5sZW5ndGgpOyBpKyspIHtcbiAgICAgICAgICAgICAgICB3b3JrZXJzLnB1c2goY29weVdvcmtlcigpLmNhdGNoKChlOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBTdG9wIHRoZSBvdGhlciB3b3JrZXJzIHB1bGxpbmcgbmV3IGZpbGVzLCB0aGVuIHN1cmZhY2UgdGhlIGVycm9yXG4gICAgICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwod29ya2Vycyk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHByb2dyZXNzVGltZXIpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChzbG93RXJyb3JUaW1lcik7XG4gICAgICAgICAgICB0aGlzLnN5bmNBY3Rpdml0aWVzLmRlbGV0ZShhY3Rpdml0eSk7XG4gICAgICAgICAgICAvLyBBIHN5bmMgc2xvdyBlbm91Z2ggdG8gaGF2ZSBsb2dnZWQgcHJvZ3Jlc3MgYWxzbyBsb2dzIGl0cyBjb21wbGV0aW9uXG4gICAgICAgICAgICBpZiAocHJvZ3Jlc3NMb2dnZWQpIHtcbiAgICAgICAgICAgICAgICBsb2dQcm9ncmVzcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZmluZEluZm8gYW5kIGdldENoYW5nZXNBZnRlcjIgbGlzdCBmcm9tIHRoZSBpbmRleCwgc28gdGhleSBtdXN0IHdhaXQgZm9yIG91ciBvd24gYmFzZSBzb3VyY2UncyBpbml0aWFsIHNjYW4gKHdoaWNoIG1pZ2h0IGxhZyBtaW51dGVzKSBiZWZvcmUgdGhlIGxpc3RpbmcgaXMgdHJ1c3R3b3J0aHkuIFRoZSBiYXNlIChsb2NhbCBkaXNrKSBpcyBpbXBsaWNpdGx5IHJlcXVpcmVkIC0gcmVtb3RlIHNvdXJjZXMgYXJlIG5vdCwgdGhleSBjb21lIGFuZCBnby5cbiAgICBwcml2YXRlIGFzeW5jIHdhaXRGb3JSZXF1aXJlZFNjYW5zKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZVN0YXRlc1swXS5pbml0aWFsU2Nhbi5wcm9taXNlO1xuICAgIH1cblxuICAgIC8vIEEgcmVxdWVzdGVkIGZpbGUgaXNuJ3QgaW4gdGhlIGluZGV4OiBvdXIgb3duIGJhc2Ugc291cmNlIChpbXBsaWNpdGx5IHJlcXVpcmVkKSBpcyBjaGVja2VkIGRpcmVjdGx5IGlmIGl0cyBpbml0aWFsIHNjYW4gaGFzbid0IGZpbmlzaGVkLCBhbmQgY2hhbmdlcy1hZnRlciBzb3VyY2VzIGFyZSByZS1wb2xsZWQgKGF0IG1vc3QgZXZlcnkgNSBzZWNvbmRzKVxuICAgIHByaXZhdGUgYXN5bmMgY2hlY2tNaXNzaW5nS2V5KGtleTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNMaXZlKGkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGxldCB7IHNvdXJjZSB9ID0gdGhpcy5zb3VyY2VzW2ldO1xuICAgICAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5zb3VyY2VTdGF0ZXNbaV07XG4gICAgICAgICAgICBpZiAoaSA9PT0gMCAmJiAhc3RhdGUuc2NhbkNvbXBsZXRlKSB7XG4gICAgICAgICAgICAgICAgLy8gaW5jbHVkZVRvbWJzdG9uZXM6IGEgZGVsZXRpb24gb24gZGlzayAoYW4gZW1wdHkgZmlsZSkgbXVzdCBiZSBpbmdlc3RlZCBhcyBhIHRvbWJzdG9uZSwgd3JpdGUgdGltZSBpbmNsdWRlZFxuICAgICAgICAgICAgICAgIGxldCBpbmZvID0gYXdhaXQgc291cmNlLmdldEluZm8oa2V5LCB7IGluY2x1ZGVUb21ic3RvbmVzOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIGlmIChpbmZvKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlU2NhbkluZGV4KGksIHsgcGF0aDoga2V5LCBjcmVhdGVUaW1lOiBpbmZvLndyaXRlVGltZSwgc2l6ZTogaW5mby5zaXplIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzdGF0ZS5zdXBwb3J0c0NoYW5nZXNBZnRlciAmJiBEYXRlLm5vdygpIC0gc3RhdGUubGFzdE1pc3NDaGVjayA+IE1JU1NfQ0hFQ0tfSU5URVJWQUwpIHtcbiAgICAgICAgICAgICAgICBzdGF0ZS5sYXN0TWlzc0NoZWNrID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBvbGxDaGFuZ2VzKGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRJbmRleEVudHJ5KGtleTogc3RyaW5nKTogUHJvbWlzZTxJbmRleEVudHJ5IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIC8vIEFuIGVudHJ5IHdob3NlIGhvbGRlciBpcyBubyBsb25nZXIgaW4gdGhlIHNvdXJjZSBsaXN0IGlzIHN0aWxsIHZhbGlkIC0gZ2V0RW50cnlIb2xkZXIgcmVzb2x2ZXMgdGhlIHBlcnNpc3RlZCBVUkwgZGlyZWN0bHkgKGFuZCBnZXQyJ3MgZmFsbGJhY2sgbG9vcCBjb3ZlcnMgYSBob2xkZXIgdGhhdCBpcyBnb25lIGVudGlyZWx5KVxuICAgICAgICBsZXQgZW50cnkgPSB0aGlzLm1lbS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKGVudHJ5KSByZXR1cm4gZW50cnk7XG4gICAgICAgIGF3YWl0IHRoaXMuY2hlY2tNaXNzaW5nS2V5KGtleSk7XG4gICAgICAgIHJldHVybiB0aGlzLm1lbS5nZXQoa2V5KTtcbiAgICB9XG5cbiAgICAvLyDilIDilIAgZGF0YSBvcGVyYXRpb25zIOKUgOKUgFxuXG4gICAgcHVibGljIGFzeW5jIGdldChrZXk6IHN0cmluZywgY29uZmlnPzogR2V0Q29uZmlnKTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZ2V0MihrZXksIGNvbmZpZyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgJiYgcmVzdWx0LmRhdGEgfHwgdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXQyKGtleTogc3RyaW5nLCBjb25maWc/OiBHZXRDb25maWcpOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgIGxldCByYW5nZSA9IGNvbmZpZz8ucmFuZ2U7XG4gICAgICAgIGxldCBvdmVybGF5RW50cnkgPSB0aGlzLm92ZXJsYXkuZ2V0KGtleSk7XG4gICAgICAgIGlmIChvdmVybGF5RW50cnkpIHtcbiAgICAgICAgICAgIC8vIEFuIGVtcHR5IGZpbGUgSVMgYSBtaXNzaW5nIGZpbGUgKHRvbWJzdG9uZSlcbiAgICAgICAgICAgIGlmIChvdmVybGF5RW50cnkuZGF0YS5sZW5ndGggPT09IDApIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBsZXQgZGF0YSA9IG92ZXJsYXlFbnRyeS5kYXRhO1xuICAgICAgICAgICAgbGV0IHNpemUgPSBkYXRhLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChyYW5nZSkge1xuICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLnN1YmFycmF5KE1hdGgubWluKHJhbmdlLnN0YXJ0LCBkYXRhLmxlbmd0aCksIE1hdGgubWluKHJhbmdlLmVuZCwgZGF0YS5sZW5ndGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IGRhdGEsIHdyaXRlVGltZTogb3ZlcmxheUVudHJ5LnQsIHNpemUgfTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZW50cnkgPSBhd2FpdCB0aGlzLmdldEluZGV4RW50cnkoa2V5KTtcbiAgICAgICAgaWYgKCFlbnRyeSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGVudHJ5LnNpemUgPT09IDApIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIGVudHJ5Lmxhc3RBY2Nlc3MgPSBEYXRlLm5vdygpO1xuICAgICAgICBsZXQgaG9sZGVyQXJjaGl2ZXMgPSBhd2FpdCB0aGlzLmdldEVudHJ5SG9sZGVyKGVudHJ5KTtcbiAgICAgICAgbGV0IHJlc3VsdDogeyBkYXRhOiBCdWZmZXI7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGhvbGRlckVycm9yOiBFcnJvciB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGhvbGRlckFyY2hpdmVzKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxldCBhbnN3ZXIgPSBhd2FpdCBob2xkZXJBcmNoaXZlcy5nZXQyKGtleSwgeyByYW5nZSwgaW50ZXJuYWw6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgLy8gRW1wdHkgZGF0YSBjb3VudHMgYXMgYWJzZW50OiBhbiBlbXB0eSBmaWxlIElTIGEgZGVsZXRpb24gKGEgdG9tYnN0b25lIHN0b3JlZCBvbiBiMi9kaXNrKSwgbmV2ZXIgY29udGVudC4gTk9URTogYSByYW5nZWQgcmVhZCBvZiBhIHJlYWwgZmlsZSBjYW4gbGVnaXRpbWF0ZWx5IGJlIGVtcHR5IChyYW5nZSBwYXN0IEVPRiksIHNvIG9ubHkgdW5yYW5nZWQgZW1wdGluZXNzIG1lYW5zIGFic2VudC5cbiAgICAgICAgICAgICAgICBpZiAoYW5zd2VyICYmIGFuc3dlci5kYXRhICYmIChhbnN3ZXIuZGF0YS5sZW5ndGggfHwgcmFuZ2UgJiYgYW5zd2VyLnNpemUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHsgZGF0YTogYW5zd2VyLmRhdGEsIHdyaXRlVGltZTogYW5zd2VyLndyaXRlVGltZSwgc2l6ZTogYW5zd2VyLnNpemUgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgaG9sZGVyRXJyb3IgPSBlIGFzIEVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIC8vIFJhbmdlZCByZWFkcyBjYW4ndCBwb3B1bGF0ZSBhIGNhY2hlICh0aGV5J3JlIHBhcnRpYWwpXG4gICAgICAgICAgICBpZiAodGhpcy5zbG90Rm9yU291cmNlc0xpc3RJbmRleChlbnRyeS5zb3VyY2VzTGlzdEluZGV4KSAhPT0gMCAmJiAhcmFuZ2UpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmNhY2hlUmVhZChrZXksIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSByb3V0aW5nIGZpbGUgaXMgb25seSBldmVyIHJlYWQgb2ZmIG91ciBvd24gZGlzayAtIGZhbGxpbmcgYmFjayB0byBhbm90aGVyIHNvdXJjZSdzIGNvcHkgd291bGQgc3luY2hyb25pemUgaXQgYmV0d2VlbiBub2RlcyB0aHJvdWdoIHRoZSByZWFkIHBhdGgsIHdoaWNoIGl0IG5ldmVyIGlzXG4gICAgICAgIGlmIChrZXkgPT09IFJPVVRJTkdfRklMRSkge1xuICAgICAgICAgICAgaWYgKGhvbGRlckVycm9yKSB0aHJvdyBob2xkZXJFcnJvcjtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlIGhvbGRlciBpcyBkb3duIG9yIGxvc3QgdGhlIGZpbGUuIEFOWSBvdGhlciBzb3VyY2UncyBjb3B5IGJlYXRzIG5vIHZhbHVlIC0gZXZlbiBhbiBPTERFUiBvbmUgLSBhbmQgaXQncyBjb3BpZWQgb250byBvdXIgZGlzayBzbyB0aGUgbmV4dCByZWFkIGRvZXNuJ3QgZGVwZW5kIG9uIGx1Y2suXG4gICAgICAgIGxldCBob2xkZXJTbG90ID0gdGhpcy5zbG90Rm9yU291cmNlc0xpc3RJbmRleChlbnRyeS5zb3VyY2VzTGlzdEluZGV4KTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNvdXJjZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChpID09PSBob2xkZXJTbG90IHx8ICF0aGlzLmlzTGl2ZShpKSkgY29udGludWU7XG4gICAgICAgICAgICBsZXQgZmFsbGJhY2s6IHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxldCBhbnN3ZXIgPSBhd2FpdCB0aGlzLnNvdXJjZXNbaV0uc291cmNlLmdldDIoa2V5LCB7IGludGVybmFsOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIC8vIEVtcHR5IGRhdGEgY291bnRzIGFzIGFic2VudCAtIGEgdG9tYnN0b25lLCBub3QgY29udGVudCAodGhpcyByZWFkIGlzIHVucmFuZ2VkLCBzbyBlbXB0aW5lc3MgaXMgdW5hbWJpZ3VvdXMpXG4gICAgICAgICAgICAgICAgaWYgKGFuc3dlciAmJiBhbnN3ZXIuZGF0YSAmJiBhbnN3ZXIuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgZmFsbGJhY2sgPSB7IGRhdGE6IGFuc3dlci5kYXRhLCB3cml0ZVRpbWU6IGFuc3dlci53cml0ZVRpbWUsIHNpemU6IGFuc3dlci5zaXplIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWZhbGxiYWNrKSBjb250aW51ZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2FjaGVSZWFkKGtleSwgZmFsbGJhY2spO1xuICAgICAgICAgICAgbGV0IGRhdGEgPSBmYWxsYmFjay5kYXRhO1xuICAgICAgICAgICAgaWYgKHJhbmdlKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEuc3ViYXJyYXkoTWF0aC5taW4ocmFuZ2Uuc3RhcnQsIGRhdGEubGVuZ3RoKSwgTWF0aC5taW4ocmFuZ2UuZW5kLCBkYXRhLmxlbmd0aCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHsgZGF0YSwgd3JpdGVUaW1lOiBmYWxsYmFjay53cml0ZVRpbWUsIHNpemU6IGZhbGxiYWNrLnNpemUgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaG9sZGVyRXJyb3IpIHRocm93IGhvbGRlckVycm9yO1xuICAgICAgICAvLyBUaGUgaG9sZGVyIGFuc3dlcmVkIFwibm90IHRoZXJlXCIgYW5kIG5vIG90aGVyIHNvdXJjZSBoYXMgaXQgZWl0aGVyOiB0aGUgZW50cnkgd2FzIHN0YWxlXG4gICAgICAgIHRoaXMuZGVsZXRlSW5kZXhFbnRyeShrZXkpO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKiBJbnRlcm5hbCAoc3RvcmUtdG8tc3RvcmUpIHJlYWQ6IHB1cmVseSB0aGUgbG9jYWwgZGlzaywgY29tcGxldGVseSBzaG9ydC1jaXJjdWl0aW5nIHRoZSBpbmRleCBhbmQgaG9sZGVyIHJlc29sdXRpb24gLSB0aGUgY2FsbGVyIGlzIGFub3RoZXIgc3RvcmUsIGFuZCBjaGFzaW5nIE9VUiByZW1vdGUgaG9sZGVycyB3aGlsZSBhbnN3ZXJpbmcgaXQgaXMgaG93IGluZmluaXRlIGdldCBsb29wcyBiZXR3ZWVuIHN0b3JlcyBmb3JtLiBObyB3aW5kb3cgb3Igcm91dGUgY2hlY2tzOiBpZiB0aGUgYnl0ZXMgYXJlIG9uIG91ciBkaXNrLCB0aGUgY2FsbGVyIG1heSBoYXZlIHRoZW0uIE5vdGUgZmFzdCB3cml0ZXMgc3RpbGwgc2l0dGluZyBpbiB0aGUgb3ZlcmxheSBhcmUgaW52aXNpYmxlIGhlcmU7IHRoZSBjYWxsZXIgcmUtZmluZHMgdGhlbSBhZnRlciBvdXIgZmx1c2guICovXG4gICAgcHVibGljIGFzeW5jIGdldEludGVybmFsMihrZXk6IHN0cmluZywgY29uZmlnPzogR2V0Q29uZmlnKTogUHJvbWlzZTx7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgdGhpcy5nZXREaXNrU291cmNlKCkuZGlzay5nZXQyKGtleSwgeyByYW5nZTogY29uZmlnPy5yYW5nZSB9KTtcbiAgICAgICAgaWYgKCFyZXN1bHQgfHwgIXJlc3VsdC5kYXRhKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAvLyBBbiBlbXB0eSBmaWxlIG9uIGRpc2sgaXMgYSB0b21ic3RvbmUsIG5vdCBjb250ZW50IChhIHJhbmdlZCByZWFkIG9mIGEgcmVhbCBmaWxlIGNhbiBiZSBsZWdpdGltYXRlbHkgZW1wdHkgdGhvdWdoIC0gcmFuZ2UgcGFzdCBFT0YpXG4gICAgICAgIGlmICghcmVzdWx0LmRhdGEubGVuZ3RoICYmICEoY29uZmlnPy5yYW5nZSAmJiByZXN1bHQuc2l6ZSkpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB7IGRhdGE6IHJlc3VsdC5kYXRhLCB3cml0ZVRpbWU6IHJlc3VsdC53cml0ZVRpbWUsIHNpemU6IHJlc3VsdC5zaXplIH07XG4gICAgfVxuXG4gICAgLyoqIEludGVybmFsIChzdG9yZS10by1zdG9yZSkgd3JpdGU6IHRoZSBsb2NhbCBkaXNrIHBsdXMgb3VyIGluZGV4LCB3aXRoIE5PIGRvd25zdHJlYW0gZmFuLW91dCAtIHRoZSBwdXNoaW5nIHN0b3JlIG93bnMgcHJvcGFnYXRpb24sIGFuZCBmYW5uaW5nIGl0cyBwdXNoZXMgYmFjayBvdXQgaXMgaG93IHdyaXRlIGxvb3BzIGJldHdlZW4gc3RvcmVzIGZvcm0uIFdpbmRvdy9yb3V0ZSBhY2NlcHRhbmNlIGlzIHRoZSBjYWxsZXIncyAod3JpdGVCdWNrZXRGaWxlJ3MpIGpvYjsgb25seS10YWtlLWxhdGVzdCBzdGlsbCBhcHBsaWVzIGhlcmUuICovXG4gICAgcHVibGljIGFzeW5jIHNldEludGVybmFsKGtleTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZzogeyBsYXN0TW9kaWZpZWQ6IG51bWJlciB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBhc3NlcnRWYWxpZExhc3RNb2RpZmllZChjb25maWcubGFzdE1vZGlmaWVkKTtcbiAgICAgICAgbGV0IG92ZXJsYXlFbnRyeSA9IHRoaXMub3ZlcmxheS5nZXQoa2V5KTtcbiAgICAgICAgbGV0IGVudHJ5ID0gdGhpcy5tZW0uZ2V0KGtleSk7XG4gICAgICAgIGxldCBjdXJyZW50VGltZSA9IG92ZXJsYXlFbnRyeSAmJiBvdmVybGF5RW50cnkudCB8fCBlbnRyeSAmJiBlbnRyeS53cml0ZVRpbWUgfHwgMDtcbiAgICAgICAgaWYgKGNvbmZpZy5sYXN0TW9kaWZpZWQgPCBjdXJyZW50VGltZSkgcmV0dXJuO1xuICAgICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEEgdG9tYnN0b25lIHN0b3JlcyBub3RoaW5nIG9uIG91ciBvd24gc291cmNlIC0gdGhlIGluZGV4IGVudHJ5IGFsb25lIHJlY29yZHMgaXRcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc291cmNlc1swXS5zb3VyY2UuZGVsKGtleSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZXNbMF0uc291cmNlLnNldChrZXksIGRhdGEsIHsgbGFzdE1vZGlmaWVkOiBjb25maWcubGFzdE1vZGlmaWVkLCBmb3JjZVNldEltbXV0YWJsZTogdHJ1ZSwgbm9DaGVja3M6IHRydWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRJbmRleEVudHJ5KGtleSwgeyB3cml0ZVRpbWU6IGNvbmZpZy5sYXN0TW9kaWZpZWQsIHNpemU6IGRhdGEubGVuZ3RoLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCkgfSk7XG4gICAgfVxuXG4gICAgLy8gVGhlIHJlYWQncyBieXRlcyBjYW1lIGZyb20gYSByZW1vdGUgc291cmNlLCBzbyB3cml0ZSB0aGVtIG9udG8gb3VyIG93biBiYXNlIHNvdXJjZSAodGhlIGxvY2FsIGRpc2spLCB3aGljaCBiZWNvbWVzIHRoZSBlbnRyeSdzIG5ldyBob2xkZXIgLSByZWFkcyBvbmx5IHBheSB0aGUgcmVtb3RlIGZldGNoIG9uY2VcbiAgICBwcml2YXRlIGFzeW5jIGNhY2hlUmVhZChrZXk6IHN0cmluZywgcmVzdWx0OiB7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXIgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZXNbMF0uc291cmNlLnNldChrZXksIHJlc3VsdC5kYXRhLCB7IGxhc3RNb2RpZmllZDogcmVzdWx0LndyaXRlVGltZSwgZm9yY2VTZXRJbW11dGFibGU6IHRydWUsIG5vQ2hlY2tzOiB0cnVlIH0pO1xuICAgICAgICB0aGlzLnNldEluZGV4RW50cnkoa2V5LCB7IHdyaXRlVGltZTogcmVzdWx0LndyaXRlVGltZSwgc2l6ZTogcmVzdWx0LmRhdGEubGVuZ3RoLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCkgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldChrZXk6IHN0cmluZywgZGF0YTogQnVmZmVyLCBjb25maWc/OiBXcml0ZUNvbmZpZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGlmICghZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgc2V0IHdhcyBjYWxsZWQgd2l0aCBhbiBlbXB0eSBidWZmZXIgZm9yICR7SlNPTi5zdHJpbmdpZnkoa2V5KX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KTogYW4gZW1wdHkgZmlsZSBJUyBhIGRlbGV0aW9uIGluIHRoaXMgc3lzdGVtIGFuZCB3b3VsZCByZWFkIGJhY2sgYXMgbWlzc2luZyAtIGNhbGwgZGVsIGluc3RlYWRgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZXRPckRlbGV0ZShrZXksIGRhdGEsIGNvbmZpZyk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGRlbChrZXk6IHN0cmluZywgY29uZmlnPzogV3JpdGVDb25maWcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gRGVsZXRlcyBhcmUgdG9tYnN0b25lIHdyaXRlcyAoYW4gZW1wdHkgZmlsZSBJUyBhIG1pc3NpbmcgZmlsZSk6IHRoZSBzaXplLTAgaW5kZXggZW50cnkgaXMgb3JkZXJlZCBieSB3cml0ZSB0aW1lIGxpa2UgYW55IG90aGVyIHdyaXRlLCBwcm9wYWdhdGVzIHRocm91Z2ggc3luY2hyb25pemF0aW9uLCBhbmQgZXhwaXJlcyBhZnRlciBUT01CU1RPTkVfRVhQSVJZXG4gICAgICAgIGF3YWl0IHRoaXMuc2V0T3JEZWxldGUoa2V5LCBCdWZmZXIuYWxsb2MoMCksIGNvbmZpZyk7XG4gICAgfVxuXG4gICAgLy8gVGhlIHNoYXJlZCBlbmdpbmUgb2Ygc2V0IGFuZCBkZWw6IGFuIGVtcHR5IGJ1ZmZlciBpcyBleGFjdGx5IGEgZGVsZXRpb24gaGVyZSwgd2hpY2ggaXMgd2h5IHRoZSBlbXB0eS1idWZmZXIgcmVqZWN0aW9uIGxpdmVzIGluIHNldCAodGhlIHB1YmxpYyBBUEkpLCBub3QgaW4gdGhpcyBtYWNoaW5lcnlcbiAgICBwcml2YXRlIGFzeW5jIHNldE9yRGVsZXRlKGtleTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZz86IFdyaXRlQ29uZmlnKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgIHRoaXMuY29uZmlnPy5vbldyaXRlQ291bnRlZD8uKFwib3JpZ2luYWxcIiwgZGF0YS5sZW5ndGgpO1xuICAgICAgICBsZXQgbGFzdE1vZGlmaWVkID0gY29uZmlnPy5sYXN0TW9kaWZpZWQ7XG4gICAgICAgIGlmIChsYXN0TW9kaWZpZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFZhbGlkTGFzdE1vZGlmaWVkKGxhc3RNb2RpZmllZCk7XG4gICAgICAgICAgICBsZXQgb3ZlcmxheUVudHJ5ID0gdGhpcy5vdmVybGF5LmdldChrZXkpO1xuICAgICAgICAgICAgbGV0IGVudHJ5ID0gdGhpcy5tZW0uZ2V0KGtleSk7XG4gICAgICAgICAgICBsZXQgY3VycmVudFRpbWUgPSBvdmVybGF5RW50cnkgJiYgb3ZlcmxheUVudHJ5LnQgfHwgZW50cnkgJiYgZW50cnkud3JpdGVUaW1lIHx8IDA7XG4gICAgICAgICAgICAvLyBBbiBvbGRlciB3cml0ZSBuZXZlciBvdmVyd3JpdGVzIGEgbmV3ZXIgb25lIChzZWUgSUFyY2hpdmVzLnNldClcbiAgICAgICAgICAgIGlmIChsYXN0TW9kaWZpZWQgPCBjdXJyZW50VGltZSkgcmV0dXJuIGtleTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgd3JpdGVUaW1lID0gbGFzdE1vZGlmaWVkIHx8IERhdGUubm93KCk7XG4gICAgICAgIGlmIChjb25maWc/LmZhc3QpIHtcbiAgICAgICAgICAgIC8vIEEgd3JpdGVEZWxheSBvZiB6ZXJvIGlzIGEgcmVhbCBjaG9pY2UgKG5vIGRlbGF5IGF0IGFsbCksIHNvIG9ubHkgYW4gb21pdHRlZCBkZWxheSBnZXRzIHRoZSBkZWZhdWx0XG4gICAgICAgICAgICBsZXQgd3JpdGVEZWxheSA9IGNvbmZpZy53cml0ZURlbGF5O1xuICAgICAgICAgICAgaWYgKHdyaXRlRGVsYXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHdyaXRlRGVsYXkgPSBERUZBVUxUX0ZBU1RfV1JJVEVfREVMQVk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBUaGUgZGVsYXkgbmV2ZXIgZXh0ZW5kcyBwYXN0IG91ciBvd24gdmFsaWQgd2luZG93J3MgZW5kIChtaW51cyB0aGUgbWFyZ2luLCBzbyB0aGUgd3JpdGVzIGFyZSBvbiBkaXNrIGJlZm9yZSB0aGUgbmV4dCB3aW5kb3cncyBzb3VyY2UgdGFrZXMgb3ZlciAtIGEgZGVwbG95IHN3aXRjaG92ZXIgaXMganVzdCB0aGlzIHRvbywgc2luY2UgaXRzIHJlbWFwIGVuZHMgb3VyIHdpbmRvdykuIFBhc3QgdGhhdCBwb2ludCBmYXN0IHdyaXRlcyB3cml0ZSB0aHJvdWdoIGltbWVkaWF0ZWx5LlxuICAgICAgICAgICAgbGV0IGRlYWRsaW5lID0gdGhpcy5zb3VyY2VzWzBdLnZhbGlkV2luZG93WzFdIC0gV0lORE9XX0VORF9GTFVTSF9NQVJHSU47XG4gICAgICAgICAgICBpZiAod3JpdGVEZWxheSA+IDAgJiYgRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICAgICAgICAgICAgbGV0IGZsdXNoQXQgPSBNYXRoLm1pbihEYXRlLm5vdygpICsgd3JpdGVEZWxheSwgZGVhZGxpbmUpO1xuICAgICAgICAgICAgICAgIHRoaXMub3ZlcmxheS5zZXQoa2V5LCB7IGRhdGEsIHQ6IHdyaXRlVGltZSwgZmx1c2hBdCB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5vdmVybGF5LmRlbGV0ZShrZXkpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy53cml0ZVRvU291cmNlcyhrZXksIGRhdGEsIHdyaXRlVGltZSk7XG4gICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3ZlcmxheS5kZWxldGUoa2V5KTtcbiAgICAgICAgYXdhaXQgdGhpcy53cml0ZVRvU291cmNlcyhrZXksIGRhdGEsIHdyaXRlVGltZSk7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRXcml0YWJsZVNvdXJjZXMoY29uZmlnPzogeyBpZ25vcmVXaW5kb3c/OiBib29sZWFuIH0pOiBudW1iZXJbXSB7XG4gICAgICAgIGxldCB3cml0YWJsZTogbnVtYmVyW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNvdXJjZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0xpdmUoaSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFjb25maWc/Lmlnbm9yZVdpbmRvdyAmJiAhd2luZG93QWNjZXB0c1dyaXRlcyh0aGlzLnNvdXJjZXNbaV0udmFsaWRXaW5kb3cpKSBjb250aW51ZTtcbiAgICAgICAgICAgIHdyaXRhYmxlLnB1c2goaSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdyaXRhYmxlO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgd3JpdGVUb1NvdXJjZXMoa2V5OiBzdHJpbmcsIGRhdGE6IEJ1ZmZlciwgd3JpdGVUaW1lOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gVGhlIHJvdXRpbmcgZmlsZSBpcyBORVZFUiBzeW5jaHJvbml6ZWQgYmV0d2VlbiBzdG9yYWdlIG5vZGVzOiB0aGUgd3JpdGVyIHdyaXRlcyBpdCBkaXJlY3RseSB0byBlYWNoIG5vZGUsIHNvIHdlIHN0b3JlIGl0IG9uIG91ciBvd24gZGlzayBvbmx5IChubyB2YWxpZC13aW5kb3cgZmlsdGVyIC0gcm91dGluZy92YWxpZCB3aW5kb3dzIGNhbid0IHBvc3NpYmx5IGFwcGx5IHRvIHRoZSBmaWxlIGRlZmluaW5nIHRoZW0pIGFuZCBuZXZlciBmb3J3YXJkIGl0IHRvIG90aGVyIHNvdXJjZXMuXG4gICAgICAgIHRoaXMuY29uZmlnPy5vbldyaXRlQ291bnRlZD8uKFwiZmx1c2hlZFwiLCBkYXRhLmxlbmd0aCk7XG4gICAgICAgIGxldCBpc1JvdXRpbmcgPSBrZXkgPT09IFJPVVRJTkdfRklMRTtcbiAgICAgICAgbGV0IHdyaXRhYmxlID0gdGhpcy5nZXRXcml0YWJsZVNvdXJjZXMoeyBpZ25vcmVXaW5kb3c6IGlzUm91dGluZyB9KTtcbiAgICAgICAgbGV0IGZpcnN0ID0gd3JpdGFibGUuc2hpZnQoKTtcbiAgICAgICAgaWYgKGZpcnN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gc291cmNlIGFjY2VwdHMgd3JpdGVzIChldmVyeSBzb3VyY2UncyB2YWxpZCB3aW5kb3cgaXMgaW4gdGhlIHBhc3QpLCBzbyB3cml0ZXMgY2Fubm90IGJlIHN0b3JlZCAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pYCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT25seSBvdXIgb3duIChmaXJzdCkgc291cmNlIGJsb2NrcyB0aGUgd3JpdGUuIERvd25zdHJlYW0gc291cmNlcyBhcmUgd3JpdHRlbiBpbiB0aGUgYmFja2dyb3VuZDogYSBkb3duIGRvd25zdHJlYW0gc291cmNlIG11c3Qgbm90IGZhaWwgb3Igc3RhbGwgd3JpdGVzLCBhbmQgcmVjb25jaWxlU291cmNlIHJlLXNlbmRzIGFueXRoaW5nIHRoZXkgbWlzc2VkIG9uY2UgdGhleSBjb21lIGJhY2suXG4gICAgICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gQSB0b21ic3RvbmUgc3RvcmVzIG5vdGhpbmcgb24gb3VyIG93biBzb3VyY2UgLSB0aGUgaW5kZXggZW50cnkgYWxvbmUgcmVjb3JkcyBpdFxuICAgICAgICAgICAgYXdhaXQgdGhpcy5zb3VyY2VzW2ZpcnN0XS5zb3VyY2UuZGVsKGtleSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZXNbZmlyc3RdLnNvdXJjZS5zZXQoa2V5LCBkYXRhLCB7IGxhc3RNb2RpZmllZDogd3JpdGVUaW1lLCBub0NoZWNrczogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldEluZGV4RW50cnkoa2V5LCB7IHdyaXRlVGltZSwgc2l6ZTogZGF0YS5sZW5ndGgsIHNvdXJjZXNMaXN0SW5kZXg6IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdChmaXJzdCkgfSk7XG4gICAgICAgIGlmIChpc1JvdXRpbmcpIHJldHVybjtcbiAgICAgICAgbGV0IHJvdXRlID0gZ2V0Um91dGUoa2V5KTtcbiAgICAgICAgZm9yIChsZXQgaSBvZiB3cml0YWJsZSkge1xuICAgICAgICAgICAgaWYgKCFyb3V0ZUNvbnRhaW5zKHRoaXMuc291cmNlc1tpXS5yb3V0ZSwgcm91dGUpKSBjb250aW51ZTtcbiAgICAgICAgICAgIC8vIERlbGV0aW9ucyB0cmF2ZWwgYXMgZGVsIGNhcnJ5aW5nIHRoZSBvcmlnaW5hbCB3cml0ZSB0aW1lIChuZXZlciBhcyBlbXB0eSBzZXRzIC0gc2V0IHJlamVjdHMgZW1wdHkgYnVmZmVycykuIEJhY2tibGF6ZSBtYXRlcmlhbGl6ZXMgc3VjaCBkZWxzIGFzIHJlYWwgZW1wdHkgZmlsZXMsIHNvIGl0cyBsaXN0aW5ncyBzdGlsbCBzaG93IHRoZSBkZWxldGlvbiBmb3Igb3RoZXIgc3RvcmVzIHRvIHNjYW4gaW4gYXMgYSB0b21ic3RvbmUuXG4gICAgICAgICAgICBsZXQgcHVzaDogUHJvbWlzZTx1bmtub3duPjtcbiAgICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHB1c2ggPSB0aGlzLnNvdXJjZXNbaV0uc291cmNlLmRlbChrZXksIHsgbGFzdE1vZGlmaWVkOiB3cml0ZVRpbWUsIG5vQ2hlY2tzOiB0cnVlLCBpbnRlcm5hbDogdHJ1ZSB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcHVzaCA9IHRoaXMuc291cmNlc1tpXS5zb3VyY2Uuc2V0KGtleSwgZGF0YSwgeyBsYXN0TW9kaWZpZWQ6IHdyaXRlVGltZSwgZm9yY2VTZXRJbW11dGFibGU6IHRydWUsIG5vQ2hlY2tzOiB0cnVlLCBpbnRlcm5hbDogdHJ1ZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZvaWQgcHVzaC5jYXRjaCgoZTogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBCYWNrZ3JvdW5kIHdyaXRlIG9mICR7a2V5fSB0byBzeW5jIHNvdXJjZSAke3RoaXMuc291cmNlc1tpXS5zb3VyY2UuZ2V0RGVidWdOYW1lKCl9IGZhaWxlZDogJHtlLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRJbmZvKGtleTogc3RyaW5nLCBjb25maWc/OiBHZXRJbmZvQ29uZmlnKTogUHJvbWlzZTx7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmluaXQoKTtcbiAgICAgICAgbGV0IG92ZXJsYXlFbnRyeSA9IHRoaXMub3ZlcmxheS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKG92ZXJsYXlFbnRyeSkge1xuICAgICAgICAgICAgaWYgKCFvdmVybGF5RW50cnkuZGF0YS5sZW5ndGggJiYgIWNvbmZpZz8uaW5jbHVkZVRvbWJzdG9uZXMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICByZXR1cm4geyB3cml0ZVRpbWU6IG92ZXJsYXlFbnRyeS50LCBzaXplOiBvdmVybGF5RW50cnkuZGF0YS5sZW5ndGggfTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZW50cnkgPSBhd2FpdCB0aGlzLmdldEluZGV4RW50cnkoa2V5KTtcbiAgICAgICAgaWYgKCFlbnRyeSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCFlbnRyeS5zaXplICYmICFjb25maWc/LmluY2x1ZGVUb21ic3RvbmVzKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4geyB3cml0ZVRpbWU6IGVudHJ5LndyaXRlVGltZSwgc2l6ZTogZW50cnkuc2l6ZSB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBmaW5kSW5mbyhwcmVmaXg6IHN0cmluZywgY29uZmlnPzogeyBzaGFsbG93PzogYm9vbGVhbjsgdHlwZT86IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JSZXF1aXJlZFNjYW5zKCk7XG4gICAgICAgIGxldCBpbmZvcyA9IG5ldyBNYXA8c3RyaW5nLCBBcmNoaXZlRmlsZUluZm8+KCk7XG4gICAgICAgIGZvciAobGV0IFtrZXksIGVudHJ5XSBvZiB0aGlzLm1lbSkge1xuICAgICAgICAgICAgaWYgKCFrZXkuc3RhcnRzV2l0aChwcmVmaXgpKSBjb250aW51ZTtcbiAgICAgICAgICAgIC8vIFRvbWJzdG9uZXMgYXJlIG1pc3NpbmcgZmlsZXMsIHNvIGxpc3RpbmdzIGhpZGUgdGhlbVxuICAgICAgICAgICAgaWYgKGVudHJ5LnNpemUgPT09IDApIGNvbnRpbnVlO1xuICAgICAgICAgICAgaW5mb3Muc2V0KGtleSwgeyBwYXRoOiBrZXksIGNyZWF0ZVRpbWU6IGVudHJ5LndyaXRlVGltZSwgc2l6ZTogZW50cnkuc2l6ZSB9KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBba2V5LCBvdmVybGF5RW50cnldIG9mIHRoaXMub3ZlcmxheSkge1xuICAgICAgICAgICAgaWYgKCFrZXkuc3RhcnRzV2l0aChwcmVmaXgpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmIChvdmVybGF5RW50cnkuZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICBpbmZvcy5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGluZm9zLnNldChrZXksIHsgcGF0aDoga2V5LCBjcmVhdGVUaW1lOiBvdmVybGF5RW50cnkudCwgc2l6ZTogb3ZlcmxheUVudHJ5LmRhdGEubGVuZ3RoIH0pO1xuICAgICAgICB9XG4gICAgICAgIGxldCBmaWxlcyA9IGFwcGx5RmluZEluZm9TaGFwZShBcnJheS5mcm9tKGluZm9zLnZhbHVlcygpKSwgcHJlZml4LCBjb25maWcpO1xuICAgICAgICBzb3J0KGZpbGVzLCB4ID0+IHgucGF0aCk7XG4gICAgICAgIHJldHVybiBmaWxlcztcbiAgICB9XG5cbiAgICAvLyBBbGwgZmlsZXMgY2hhbmdlZCBhZnRlciBjb25maWcudGltZSDigJQgZmFzdCwgc3RyYWlnaHQgZnJvbSB0aGUgaW4tbWVtb3J5IGluZGV4LiBGaWx0ZXJzIG9uIHdoZW4gV0UgbGVhcm5lZCBvZiB0aGUgY2hhbmdlIChjaGFuZ2VkQXQpLCBzbyBmaWxlcyBzeW5jaHJvbml6ZWQgbGF0ZSAod2l0aCBvbGQgd3JpdGUgdGltZXMpIGFyZSBzdGlsbCByZXBvcnRlZC4gRGVsZXRpb25zIEFSRSByZXBvcnRlZCwgYXMgc2l6ZS0wIHRvbWJzdG9uZSBlbnRyaWVzIOKAlCB0aGF0J3MgaG93IHRoZXkgcHJvcGFnYXRlIHRvIHN0b3JlcyBzeW5jaW5nIGZyb20gdXMuIGNvbmZpZy5yb3V0ZXMgbGV0cyBhIHN0b3JlIHN5bmNpbmcgYSBwYXJ0aWFsIHNoYXJkIGFzayBmb3IganVzdCBpdHMgc2xpY2UuXG4gICAgcHVibGljIGFzeW5jIGdldENoYW5nZXNBZnRlcjIoY29uZmlnOiBDaGFuZ2VzQWZ0ZXJDb25maWcpOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JSZXF1aXJlZFNjYW5zKCk7XG4gICAgICAgIGxldCBpblJvdXRlcyA9IChrZXk6IHN0cmluZykgPT4gIWNvbmZpZy5yb3V0ZXMgfHwgY29uZmlnLnJvdXRlcy5zb21lKHJvdXRlID0+IHJvdXRlQ29udGFpbnMocm91dGUsIGdldFJvdXRlKGtleSkpKTtcbiAgICAgICAgbGV0IGZpbGVzOiBBcmNoaXZlRmlsZUluZm9bXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBba2V5LCBlbnRyeV0gb2YgdGhpcy5tZW0pIHtcbiAgICAgICAgICAgIGlmIChlbnRyeS5jaGFuZ2VkQXQgPD0gY29uZmlnLnRpbWUpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHRoaXMub3ZlcmxheS5oYXMoa2V5KSkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoIWluUm91dGVzKGtleSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgZmlsZXMucHVzaCh7IHBhdGg6IGtleSwgY3JlYXRlVGltZTogZW50cnkud3JpdGVUaW1lLCBzaXplOiBlbnRyeS5zaXplIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IFtrZXksIG92ZXJsYXlFbnRyeV0gb2YgdGhpcy5vdmVybGF5KSB7XG4gICAgICAgICAgICBpZiAob3ZlcmxheUVudHJ5LnQgPD0gY29uZmlnLnRpbWUpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFpblJvdXRlcyhrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGZpbGVzLnB1c2goeyBwYXRoOiBrZXksIGNyZWF0ZVRpbWU6IG92ZXJsYXlFbnRyeS50LCBzaXplOiBvdmVybGF5RW50cnkuZGF0YS5sZW5ndGggfSk7XG4gICAgICAgIH1cbiAgICAgICAgc29ydChmaWxlcywgeCA9PiB4LnBhdGgpO1xuICAgICAgICByZXR1cm4gZmlsZXM7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldFN5bmNTdGF0dXMoKTogUHJvbWlzZTxBcmNoaXZlc1N5bmNTdGF0dXM+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhbGxTY2Fuc0NvbXBsZXRlOiB0aGlzLnNvdXJjZVN0YXRlcy5ldmVyeSh4ID0+IHguc2NhbkNvbXBsZXRlKSxcbiAgICAgICAgICAgIGluZGV4U2l6ZTogdGhpcy5tZW0uc2l6ZSxcbiAgICAgICAgICAgIHNvdXJjZXM6IHRoaXMuc291cmNlcy5tYXAoKHgsIGkpID0+ICh7XG4gICAgICAgICAgICAgICAgZGVidWdOYW1lOiB4LnNvdXJjZS5nZXREZWJ1Z05hbWUoKSxcbiAgICAgICAgICAgICAgICB2YWxpZFdpbmRvdzogeC52YWxpZFdpbmRvdyxcbiAgICAgICAgICAgICAgICByb3V0ZTogeC5yb3V0ZSxcbiAgICAgICAgICAgICAgICBub0Z1bGxTeW5jOiB4Lm5vRnVsbFN5bmMsXG4gICAgICAgICAgICAgICAgc3VwcG9ydHNDaGFuZ2VzQWZ0ZXI6IHRoaXMuc291cmNlU3RhdGVzW2ldLnN1cHBvcnRzQ2hhbmdlc0FmdGVyLFxuICAgICAgICAgICAgICAgIGluaXRpYWxTY2FuQ29tcGxldGU6IHRoaXMuc291cmNlU3RhdGVzW2ldLnNjYW5Db21wbGV0ZSxcbiAgICAgICAgICAgICAgICBzY2FubmVkQ291bnQ6IHRoaXMuc291cmNlU3RhdGVzW2ldLnNjYW5uZWRDb3VudCxcbiAgICAgICAgICAgIH0pKS5maWx0ZXIoKHgsIGkpID0+IHRoaXMuaXNMaXZlKGkpKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyDilIDilIAgbGFyZ2UgdXBsb2FkcyDilIDilIBcbiAgICAvLyBMYXJnZSB1cGxvYWRzIHN0cmVhbSBvbnRvIHRoZSBsb2NhbCBkaXNrIHNvdXJjZSBkaXJlY3RseSAodGhleSBtYXkgbm90IGZpdCBpbiBtZW1vcnkpXG5cbiAgICBwcml2YXRlIGdldERpc2tTb3VyY2UoKTogeyBkaXNrOiBBcmNoaXZlc0Rpc2s7IHNvdXJjZUluZGV4OiBudW1iZXIgfSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgc291cmNlID0gdGhpcy5zb3VyY2VzW2ldLnNvdXJjZTtcbiAgICAgICAgICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBBcmNoaXZlc0Rpc2spIHJldHVybiB7IGRpc2s6IHNvdXJjZSwgc291cmNlSW5kZXg6IGkgfTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYExhcmdlIHVwbG9hZHMgcmVxdWlyZSBhbiBBcmNoaXZlc0Rpc2sgc291cmNlLCBhbmQgdGhpcyBzdG9yZSBoYXMgbm9uZSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pYCk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBzdGFydExhcmdlVXBsb2FkKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5nZXREaXNrU291cmNlKCkuZGlzay5zdGFydExhcmdlVXBsb2FkKCk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBhcHBlbmRMYXJnZVVwbG9hZChpZDogc3RyaW5nLCBkYXRhOiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXREaXNrU291cmNlKCkuZGlzay5hcHBlbmRMYXJnZVVwbG9hZChpZCwgZGF0YSk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBmaW5pc2hMYXJnZVVwbG9hZChpZDogc3RyaW5nLCBrZXk6IHN0cmluZywgbGFzdE1vZGlmaWVkPzogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCB7IGRpc2ssIHNvdXJjZUluZGV4IH0gPSB0aGlzLmdldERpc2tTb3VyY2UoKTtcbiAgICAgICAgYXdhaXQgZGlzay5maW5pc2hMYXJnZVVwbG9hZChpZCwga2V5LCBsYXN0TW9kaWZpZWQpO1xuICAgICAgICB0aGlzLm92ZXJsYXkuZGVsZXRlKGtleSk7XG4gICAgICAgIC8vIGluY2x1ZGVUb21ic3RvbmVzOiBhIHplcm8tYnl0ZSB1cGxvYWQgaXMgc3RpbGwgYSByZWFsIGZpbGUgd2hvc2UgaW5kZXggZW50cnkgbXVzdCBiZSB3cml0dGVuXG4gICAgICAgIGxldCBpbmZvID0gYXdhaXQgZGlzay5nZXRJbmZvKGtleSwgeyBpbmNsdWRlVG9tYnN0b25lczogdHJ1ZSB9KTtcbiAgICAgICAgaWYgKGluZm8pIHtcbiAgICAgICAgICAgIHRoaXMuc2V0SW5kZXhFbnRyeShrZXksIHsgd3JpdGVUaW1lOiBpbmZvLndyaXRlVGltZSwgc2l6ZTogaW5mby5zaXplLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3Qoc291cmNlSW5kZXgpIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBjYW5jZWxMYXJnZVVwbG9hZChpZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0RGlza1NvdXJjZSgpLmRpc2suY2FuY2VsTGFyZ2VVcGxvYWQoaWQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZmx1c2hPdmVybGF5KGZvcmNlPzogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBsZXQgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgZm9yIChsZXQgW2tleSwgZW50cnldIG9mIHRoaXMub3ZlcmxheSkge1xuICAgICAgICAgICAgaWYgKCFmb3JjZSAmJiBlbnRyeS5mbHVzaEF0ID4gbm93KSBjb250aW51ZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMud3JpdGVUb1NvdXJjZXMoa2V5LCBlbnRyeS5kYXRhLCBlbnRyeS50KTtcbiAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGlmIGl0IHdhc24ndCBvdmVyd3JpdHRlbiB3aGlsZSB3ZSB3ZXJlIGZsdXNoaW5nXG4gICAgICAgICAgICBpZiAodGhpcy5vdmVybGF5LmdldChrZXkpID09PSBlbnRyeSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3ZlcmxheS5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHJlYWRlckRpc2tMaW1pdDogdGhlIGRpc2sgaXMgb25seSBhIGJvdW5kZWQgcmVhZCBjYWNoZSwgc28gb25jZSBpdCBleGNlZWRzIHRoZSBsaW1pdCwgdGhlIGxlYXN0IHJlY2VudGx5IHVzZWQgZmlsZXMgYXJlIGRlbGV0ZWQgZnJvbSBpdCAtIGJ1dCBPTkxZIHdoZW4gYW5vdGhlciBzb3VyY2UgdmVyaWZpYWJseSBob2xkcyBhIHNhbWUtb3ItbmV3ZXIgY29weSAodGhlIG9ubHkgY29weSBvZiBhIGZpbGUgaXMgbmV2ZXIgZGVsZXRlZCksIGFuZCB0aGUgaW5kZXggZW50cnkgcmVwb2ludHMgdG8gdGhhdCBzb3VyY2Ugc28gcmVhZHMga2VlcCB3b3JraW5nIChyZS1jYWNoaW5nIG9uIHRoZSBuZXh0IHJlYWQpLlxuICAgIHByaXZhdGUgZXZpY3RpbmcgPSBmYWxzZTtcbiAgICBwcml2YXRlIGFzeW5jIGVuZm9yY2VEaXNrTGltaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCBsaW1pdCA9IHRoaXMuY29uZmlnPy5yZWFkZXJEaXNrTGltaXQ7XG4gICAgICAgIGlmICghbGltaXQgfHwgdGhpcy5ldmljdGluZykgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy5zb3VyY2VCeXRlQ291bnRzWzBdIDw9IGxpbWl0KSByZXR1cm47XG4gICAgICAgIHRoaXMuZXZpY3RpbmcgPSB0cnVlO1xuICAgICAgICBsZXQgZXZpY3RlZEZpbGVzID0gMDtcbiAgICAgICAgbGV0IGV2aWN0ZWRCeXRlcyA9IDA7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgYmFzZVNvdXJjZXNMaXN0SW5kZXggPSB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCk7XG4gICAgICAgICAgICBsZXQgY2FuZGlkYXRlczogeyBrZXk6IHN0cmluZzsgZW50cnk6IEluZGV4RW50cnkgfVtdID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBba2V5LCBlbnRyeV0gb2YgdGhpcy5tZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoZW50cnkuc291cmNlc0xpc3RJbmRleCAhPT0gYmFzZVNvdXJjZXNMaXN0SW5kZXggfHwgZW50cnkuc2l6ZSA9PT0gMCB8fCBrZXkgPT09IFJPVVRJTkdfRklMRSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlcy5wdXNoKHsga2V5LCBlbnRyeSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNvcnQoY2FuZGlkYXRlcywgeCA9PiB4LmVudHJ5Lmxhc3RBY2Nlc3MpO1xuICAgICAgICAgICAgZm9yIChsZXQgeyBrZXksIGVudHJ5IH0gb2YgY2FuZGlkYXRlcykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0b3BwZWQuc3RvcCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNvdXJjZUJ5dGVDb3VudHNbMF0gPD0gbGltaXQpIGJyZWFrO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm1lbS5nZXQoa2V5KSAhPT0gZW50cnkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGxldCBob2xkZXI6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHRoaXMuc291cmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNMaXZlKGkpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbmZvID0gYXdhaXQgdGhpcy5zb3VyY2VzW2ldLnNvdXJjZS5nZXRJbmZvKGtleSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5mbyAmJiBpbmZvLndyaXRlVGltZSA+PSBlbnRyeS53cml0ZVRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob2xkZXIgPSBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgZG93biBzb3VyY2UganVzdCBjYW4ndCB2b3VjaCBmb3IgdGhpcyBmaWxlIHJpZ2h0IG5vd1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChob2xkZXIgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zb3VyY2VzWzBdLnNvdXJjZS5kZWwoa2V5KTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldEluZGV4RW50cnkoa2V5LCB7IHdyaXRlVGltZTogZW50cnkud3JpdGVUaW1lLCBzaXplOiBlbnRyeS5zaXplLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoaG9sZGVyKSB9KTtcbiAgICAgICAgICAgICAgICBldmljdGVkRmlsZXMrKztcbiAgICAgICAgICAgICAgICBldmljdGVkQnl0ZXMgKz0gZW50cnkuc2l6ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMuZXZpY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChldmljdGVkRmlsZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgRGlzayBjYWNoZSBvdmVyIHJlYWRlckRpc2tMaW1pdCAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiBldmljdGVkICR7ZXZpY3RlZEZpbGVzfSBsZWFzdC1yZWNlbnRseS11c2VkIGZpbGVzICgke2Zvcm1hdE51bWJlcihldmljdGVkQnl0ZXMpfUIpLCBub3cgYXQgJHtmb3JtYXROdW1iZXIodGhpcy5zb3VyY2VCeXRlQ291bnRzWzBdKX1CLyR7Zm9ybWF0TnVtYmVyKHRoaXMuY29uZmlnPy5yZWFkZXJEaXNrTGltaXQgfHwgMCl9QmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVG9tYnN0b25lcyBvbmx5IG5lZWQgdG8gZXhpc3QgbG9uZyBlbm91Z2ggZm9yIGV2ZXJ5IHN0b3JlIHRvIGxlYXJuIG9mIHRoZSBkZWxldGlvbjsgZXhwaXJlZCBvbmVzIGNvbWUgb3V0IG9mIHRoZSBpbmRleC4gVGhlIHBoeXNpY2FsIGVtcHR5IGZpbGUgaXMgcmVtb3ZlZCBvbmx5IG9uIGJhY2tibGF6ZSBzb3VyY2VzOiByZW1vdGUgc3RvcmVzIGV4cGlyZSB0aGVpciBvd24gdG9tYnN0b25lcyAoYSBkZWwgdGhlcmUgd291bGQganVzdCBtaW50IGEgZnJlc2ggb25lKSwgYW5kIG91ciBvd24gZGlzayBuZXZlciBzdG9yZWQgYW55dGhpbmcgZm9yIGl0LlxuICAgIHByaXZhdGUgYXN5bmMgY2xlYW51cFRvbWJzdG9uZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCBjdXRvZmYgPSBEYXRlLm5vdygpIC0gVE9NQlNUT05FX0VYUElSWTtcbiAgICAgICAgZm9yIChsZXQgW2tleSwgZW50cnldIG9mIHRoaXMubWVtKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdG9wcGVkLnN0b3ApIHJldHVybjtcbiAgICAgICAgICAgIGlmIChlbnRyeS5zaXplICE9PSAwKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmIChlbnRyeS53cml0ZVRpbWUgPiBjdXRvZmYpIGNvbnRpbnVlO1xuICAgICAgICAgICAgdGhpcy5kZWxldGVJbmRleEVudHJ5KGtleSk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuc291cmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0xpdmUoaSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGxldCBzb3VyY2VFbnRyeSA9IHRoaXMuc291cmNlc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAoIXdpbmRvd0FjY2VwdHNXcml0ZXMoc291cmNlRW50cnkudmFsaWRXaW5kb3cpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBsZXQgc291cmNlID0gc291cmNlRW50cnkuc291cmNlO1xuICAgICAgICAgICAgICAgIGlmICghKHNvdXJjZSBpbnN0YW5jZW9mIEFyY2hpdmVzQmFja2JsYXplKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgdm9pZCBzb3VyY2UuZGVsKGtleSkuY2F0Y2goKGU6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFJlbW92aW5nIGV4cGlyZWQgdG9tYnN0b25lICR7a2V5fSBmcm9tICR7c291cmNlLmdldERlYnVnTmFtZSgpfSBmYWlsZWQ6ICR7ZS5zdGFjayA/PyBlfWApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIl19
|
|
1222
|
-
/* _JS_SOURCE_HASH = "
|
|
1363
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvYlN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYmxvYlN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLGdEQUF3QjtBQUN4Qix5REFBbUQ7QUFDbkQsMkRBQXNFO0FBQ3RFLG1EQUEwRTtBQUMxRSxrRUFBaUY7QUFDakYsNENBR3NCO0FBQ3RCLGtEQUFtRTtBQUNuRSw0Q0FBaUQ7QUFDakQsaURBQXVFO0FBQ3ZFLDJDQUE0QztBQUM1Qyx3RUFBdUY7QUFDdkYsb0RBQThGO0FBQzlGLCtDQUE0QztBQUU1QyxxdEJBQXF0QjtBQUV4c0IsUUFBQSx3QkFBd0IsR0FBRyxtQkFBWSxHQUFHLENBQUMsQ0FBQztBQUN6RCxNQUFNLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLG1OQUFtTjtBQUN0TSxRQUFBLHVCQUF1QixHQUFHLG1CQUFZLEdBQUcsQ0FBQyxDQUFDO0FBQ3hELG1GQUFtRjtBQUNuRixNQUFNLG9CQUFvQixHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7QUFDdkMseUVBQXlFO0FBQ3pFLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUN4QyxrUUFBa1E7QUFDbFEsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUM1QyxNQUFNLDhCQUE4QixHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUMxRCwwR0FBMEc7QUFDMUcsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQ3JDLHNHQUFzRztBQUN0RyxNQUFNLG9CQUFvQixHQUFHLG1CQUFZLENBQUM7QUFDMUMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQ25DLG9MQUFvTDtBQUNwTCxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFD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ZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGxhenkgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9jYWNoaW5nXCI7XG5pbXBvcnQgeyBydW5JbmZpbml0ZVBvbGwsIGRlbGF5IH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvYmF0Y2hpbmdcIjtcbmltcG9ydCB7IHRpbWVJbk1pbnV0ZSwgc29ydCwgcHJvbWlzZU9iaiB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL21pc2NcIjtcbmltcG9ydCB7IGZvcm1hdE51bWJlciwgZm9ybWF0VGltZSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2Zvcm1hdHRpbmcvZm9ybWF0XCI7XG5pbXBvcnQge1xuICAgIElBcmNoaXZlcywgQXJjaGl2ZUZpbGVJbmZvLCBBcmNoaXZlc1NvdXJjZSwgQXJjaGl2ZXNTeW5jU3RhdHVzLCBDaGFuZ2VzQWZ0ZXJDb25maWcsIEZpbmRDb25maWcsIEhvc3RlZENvbmZpZywgYXNzZXJ0VmFsaWRMYXN0TW9kaWZpZWQsXG4gICAgd2luZG93QWNjZXB0c1dyaXRlcywgU3luY0FjdGl2aXR5LCBGVUxMX1JPVVRFLCBTVE9SQUdFX1dST05HX1ZBTElEX1dJTkRPVywgU1RPUkFHRV9XUk9OR19ST1VURSwgY29weUFyY2hpdmVGaWxlLFxufSBmcm9tIFwiLi4vSUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBBcmNoaXZlc0Rpc2ssIGFwcGx5RmluZEluZm9TaGFwZSB9IGZyb20gXCIuLi9BcmNoaXZlc0Rpc2tcIjtcbmltcG9ydCB7IEFyY2hpdmVzQmFja2JsYXplIH0gZnJvbSBcIi4uL2JhY2tibGF6ZVwiO1xuaW1wb3J0IHsgUk9VVElOR19GSUxFLCBnZXRSb3V0ZSwgcm91dGVDb250YWlucyB9IGZyb20gXCIuL3JlbW90ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgc2VsZWN0RW50cnlBdCB9IGZyb20gXCIuL3N0b3JlUGxhblwiO1xuaW1wb3J0IHsgQnVsa0RhdGFiYXNlQmFzZSwgbm9vcFJlYWN0aXZlRGVwcyB9IGZyb20gXCIuLi9CdWxrRGF0YWJhc2UyL0J1bGtEYXRhYmFzZUJhc2VcIjtcbmltcG9ydCB7IHdyYXBIYW5kbGUsIE5vZGVKU0RpcmVjdG9yeUhhbmRsZVdyYXBwZXIsIERpcmVjdG9yeVdyYXBwZXIgfSBmcm9tIFwiLi4vRmlsZUZvbGRlckFQSVwiO1xuaW1wb3J0IHsgU291cmNlc0xpc3QgfSBmcm9tIFwiLi9zb3VyY2VzTGlzdFwiO1xuXG4vLyBUaGUgc3RvcmFnZSBlbmdpbmUgb2YgdGhlIHJlbW90ZSBzdG9yYWdlIHNlcnZlci4gRGF0YSBsaXZlcyBpbiBzeW5jaHJvbml6YXRpb24gc291cmNlcyAoYXQgbWluaW11bSBhbiBBcmNoaXZlc0Rpc2ssIHRoZSBsb2NhbCBkaXNrKTsgQmxvYlN0b3JlIGtlZXBzIGFuIGluZGV4IG9mIGV2ZXJ5IGZpbGUgKHBhdGgsIGxhc3QgbW9kaWZpZWQgdGltZSwgc2l6ZSwgYW5kIHdoaWNoIHNvdXJjZSBjdXJyZW50bHkgaG9sZHMgdGhlIGRhdGEpIGluIGEgQnVsa0RhdGFiYXNlMiwgYW5kIHN5bmNocm9uaXplcyB0aGUgaW5kZXggZnJvbSBhbGwgc291cmNlcyAoc2VlIEFyY2hpdmVzU291cmNlIGluIElBcmNoaXZlcy50cykuIEV2ZXJ5IHN0YXJ0dXAgZnVsbHkgcmVzY2FucyBlYWNoIHNvdXJjZSdzIG1ldGFkYXRhLCBzbyB0aGUgaW5kZXggc2VsZi1oZWFsczsgdGhlIGZpbGUgd2l0aCB0aGUgaGlnaGVzdCB3cml0ZSB0aW1lIHdpbnMgYWNyb3NzIGFsbCBzb3VyY2VzLCBzbyBtdWx0aXBsZSBzb3VyY2VzIG5lZWQgbm8gc3RhY2tpbmcgb3JkZXIuIFRoZSBzdG9yZSBhbHNvIGhvbGRzIGl0cyBvd24gcm91dGluZyBlbnRyaWVzICh0aGUgc2VsZiBlbnRyaWVzIG9mIHRoZSBPTkUgcm91dGUgaXQgc2VydmVzKSwgc28gaXQgdmFsaWRhdGVzIHdyaXRlcyBpdHNlbGY6IHZhbGlkIHdpbmRvd3MsIHJvdXRlcywgaW1tdXRhYmlsaXR5LCBhbmQgaW50ZXJuYWwtcHVzaCBhY2NlcHRhbmNlLlxuXG5leHBvcnQgY29uc3QgREVGQVVMVF9GQVNUX1dSSVRFX0RFTEFZID0gdGltZUluTWludXRlICogNTtcbmNvbnN0IEZBU1RfRkxVU0hfUE9MTCA9IDEwMDAgKiAxNTtcbi8vIEZhc3Qgd3JpdGVzIGFyZSBuZXZlciBkZWxheWVkIHBhc3Qgb3VyIG93biB2YWxpZCB3aW5kb3csIGFuZCB3aXRoaW4gdGhpcyBtYXJnaW4gb2YgdGhlIHdpbmRvdydzIGVuZCB0aGV5IHdyaXRlIHRocm91Z2ggaW1tZWRpYXRlbHkgLSBzbyB3aGVuIHRoZSBuZXh0IHdpbmRvdydzIHNvdXJjZSB0YWtlcyBvdmVyLCB0aGUgd3JpdGVzIGFyZSBhbHJlYWR5IG9uIGRpc2tcbmV4cG9ydCBjb25zdCBXSU5ET1dfRU5EX0ZMVVNIX01BUkdJTiA9IHRpbWVJbk1pbnV0ZSAqIDU7XG4vLyBJbmRleCBjaGFuZ2VzIGFyZSBidWZmZXJlZCBpbiBtZW1vcnkgYW5kIHdyaXR0ZW4gdG8gdGhlIEJ1bGtEYXRhYmFzZTIgaW4gYmF0Y2hlc1xuY29uc3QgSU5ERVhfRkxVU0hfSU5URVJWQUwgPSAxMDAwICogMzA7XG4vLyBTb3VyY2VzIHdpdGggYSBuYXRpdmUgKGluZGV4LWJhY2tlZCkgY2hhbmdlIGZlZWQgYXJlIHBvbGxlZCB0aGlzIG9mdGVuXG5jb25zdCBDSEFOR0VTX1BPTExfSU5URVJWQUwgPSAxMDAwICogNjA7XG4vLyBGdWxsIG1ldGFkYXRhIHJlc2NhbnMuIHN1cHBvcnRzQ2hhbmdlc0FmdGVyIGlzIHRoZSBoZXVyaXN0aWMgZm9yIFwib25lIG9mIG91ciBvd24gc3RvcmFnZSBzZXJ2ZXJzXCI6IHRoZWlyIGluZGV4LWJhY2tlZCBsaXN0aW5ncyBhcmUgY2hlYXAsIHNvIGhvdXJseSBpcyBmaW5lLiBFdmVyeXRoaW5nIGVsc2UgKGJhY2tibGF6ZSwgcGxhaW4gZGlzaykgcGF5cyB0aGUgZnVsbCBsaXN0aW5nIGNvc3QsIHNvIGl0IHJlc2NhbnMgbXVjaCBsZXNzIG9mdGVuLlxuY29uc3QgRlVMTF9SRVNDQU5fSU5URVJWQUwgPSAxMDAwICogNjAgKiA2MDtcbmNvbnN0IEZVTExfUkVTQ0FOX1VOSU5ERVhFRF9JTlRFUlZBTCA9IDEwMDAgKiA2MCAqIDYwICogNjtcbi8vIE9uIGEgcmVxdWVzdCBmb3IgYSBmaWxlIHRoZSBpbmRleCBkb2Vzbid0IGtub3csIGNoYW5nZXMtYWZ0ZXIgc291cmNlcyBhcmUgcmUtcG9sbGVkLCBhdCBtb3N0IHRoaXMgb2Z0ZW5cbmNvbnN0IE1JU1NfQ0hFQ0tfSU5URVJWQUwgPSAxMDAwICogNTtcbi8vIENoYW5nZSBwb2xscyByZS1yZXF1ZXN0IHRoaXMgbXVjaCBvdmVybGFwLCBzbyBjbG9jayBza2V3IGJldHdlZW4gdXMgYW5kIGEgc291cmNlIGNhbid0IGRyb3AgY2hhbmdlc1xuY29uc3QgQ0hBTkdFU19QT0xMX09WRVJMQVAgPSB0aW1lSW5NaW51dGU7XG5jb25zdCBTQ0FOX1JFVFJZX0RFTEFZID0gMTAwMCAqIDMwO1xuLy8gRGVsZXRlcyBhcmUgdG9tYnN0b25lcyAoYW4gZW1wdHkgZmlsZSBJUyBhIG1pc3NpbmcgZmlsZSk6IHRoZSBzaXplLTAgaW5kZXggZW50cnkgaXMgd2hhdCBsZXRzIGEgZGVsZXRpb24gcHJvcGFnYXRlL3JlY29uY2lsZSBsaWtlIGFueSBvdGhlciB3cml0ZSwgYW5kIGl0IGV4cGlyZXMgYWZ0ZXIgdGhpcyBsb25nXG5jb25zdCBUT01CU1RPTkVfRVhQSVJZID0gMTAwMCAqIDYwICogNjAgKiAyNCAqIDc7XG5jb25zdCBUT01CU1RPTkVfQ0xFQU5VUF9JTlRFUlZBTCA9IDEwMDAgKiA2MCAqIDYwO1xuLy8gV2hpbGUgYSBtZXRhZGF0YSBzY2FuIG9yIGZ1bGwgc3luYyBpcyBydW5uaW5nLCBpdHMgcHJvZ3Jlc3MgaXMgbG9nZ2VkIHRoaXMgb2Z0ZW5cbmNvbnN0IFNZTkNfUFJPR1JFU1NfTE9HX0lOVEVSVkFMID0gMTAwMCAqIDYwO1xuY29uc3QgRElTS19MSU1JVF9DSEVDS19JTlRFUlZBTCA9IDEwMDAgKiA2MDtcbi8vIEZ1bGwgc3luY3MgZG93bmxvYWQgdGhpcyBtYW55IGZpbGVzIGNvbmN1cnJlbnRseSAoaGlnaC1sYXRlbmN5IHNvdXJjZXMgbGlrZSBiYWNrYmxhemUgd291bGQgb3RoZXJ3aXNlIGNyYXdsIG9uZSByb3VuZC10cmlwIGF0IGEgdGltZSlcbmNvbnN0IEZVTExfU1lOQ19QQVJBTExFTCA9IDg7XG4vLyBBIGZ1bGwgc3luYyBydW5uaW5nIGxvbmdlciB0aGFuIHRoaXMgaXMgY29uc29sZS5lcnJvcmVkIChhbmQgYWdhaW4gZXZlcnkgaW50ZXJ2YWwgYWZ0ZXIpLCBzbyBhIHN5bmMgdGhhdCB3aWxsIHRha2UgZGF5cyBpcyBsb3VkIGluc3RlYWQgb2YgYSBxdWlldCBjb25zb2xlLmxvZyBldmVyeSBtaW51dGVcbmNvbnN0IEZVTExfU1lOQ19TTE9XX0VSUk9SX0lOVEVSVkFMID0gMTAwMCAqIDYwICogNjA7XG4vLyBBIHJlY29uY2lsZSBwYXNzIHNraXBzIGZhaWxpbmcgZmlsZXMgKG9uZSBiYWQgdmFsdWUgbXVzdCBub3Qgc3RvcCB0aGUgcmVzdCksIGJ1dCB0aGlzIG1hbnkgZmFpbHVyZXMgaW4gYSByb3cgbWVhbnMgdGhlIHRhcmdldCBpdHNlbGYgaXMgZG93biwgc28gdGhlIHBhc3MgYWJvcnRzIHVudGlsIHRoZSBuZXh0IHNjYW4gY3ljbGVcbmNvbnN0IFJFQ09OQ0lMRV9NQVhfQ09OU0VDVVRJVkVfRkFJTFVSRVMgPSA1O1xuY29uc3QgUkVDT05DSUxFX0VSUk9SX0xPR19MSU1JVCA9IDM7XG5jb25zdCBXUk9OR19UQVJHRVRfTE9HX1RIUk9UVExFID0gNjAgKiAxMDAwO1xuXG4vLyBXaGF0IHRoZSBzdG9yYWdlIHNlcnZlciBuZWVkcyBmcm9tIGEgYnVja2V0J3Mgc3RvcmUuIEJsb2JTdG9yZSBpbXBsZW1lbnRzIGl0IGZ1bGx5ICh3aXRoIHZhbGlkYXRpb24gZnJvbSBpdHMgcm91dGluZyBlbnRyaWVzKTsgUmF3RGlza1N0b3JlIGFkYXB0cyBhbiBBcmNoaXZlc0Rpc2sgZm9yIHJhd0Rpc2sgYnVja2V0cyAobm8gaW5kZXgsIG5vIHN5bmMsIG5vIHZhbGlkYXRpb24gLSByYXcgbWVhbnMgcmF3KS5cbmV4cG9ydCB0eXBlIElCdWNrZXRTdG9yZSA9IHtcbiAgICAvKiogaW50ZXJuYWwgKHN0b3JlLXRvLXN0b3JlKSByZWFkcyBhbnN3ZXIgcHVyZWx5IGZyb20gdGhlIGxvY2FsIGRpc2s7IHNlZSBHZXRDb25maWcuaW50ZXJuYWwgKi9cbiAgICBnZXQyKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9OyBpbnRlcm5hbD86IGJvb2xlYW47IGluY2x1ZGVUb21ic3RvbmVzPzogYm9vbGVhbiB9KTogUHJvbWlzZTx7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPjtcbiAgICAvKiogaW50ZXJuYWwgKHN0b3JlLXRvLXN0b3JlKSB3cml0ZXMgZ28gdG8gdGhlIGxvY2FsIGRpc2sgKyBpbmRleCB3aXRoIG5vIGZhbi1vdXQ7IHNlZSBTZXRDb25maWcuaW50ZXJuYWwgKi9cbiAgICBzZXQoY29uZmlnOiB7IHBhdGg6IHN0cmluZzsgZGF0YTogQnVmZmVyOyBsYXN0TW9kaWZpZWQ/OiBudW1iZXI7IGZvcmNlU2V0SW1tdXRhYmxlPzogYm9vbGVhbjsgaW50ZXJuYWw/OiBib29sZWFuIH0pOiBQcm9taXNlPHZvaWQ+O1xuICAgIGRlbChjb25maWc6IHsgcGF0aDogc3RyaW5nOyBsYXN0TW9kaWZpZWQ/OiBudW1iZXI7IGludGVybmFsPzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPjtcbiAgICBnZXRJbmZvKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IGluY2x1ZGVUb21ic3RvbmVzPzogYm9vbGVhbiB9KTogUHJvbWlzZTx7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD47XG4gICAgZmluZEluZm8oY29uZmlnOiBGaW5kQ29uZmlnICYgeyBwcmVmaXg6IHN0cmluZyB9KTogUHJvbWlzZTxBcmNoaXZlRmlsZUluZm9bXT47XG4gICAgZ2V0Q2hhbmdlc0FmdGVyMihjb25maWc6IENoYW5nZXNBZnRlckNvbmZpZyk6IFByb21pc2U8QXJjaGl2ZUZpbGVJbmZvW10+O1xuICAgIGdldFN5bmNTdGF0dXM/KCk6IFByb21pc2U8QXJjaGl2ZXNTeW5jU3RhdHVzPjtcbiAgICBnZXRTeW5jUHJvZ3Jlc3M/KCk6IHtcbiAgICAgICAgaW5kZXg6IHsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyIH07XG4gICAgICAgIHNvdXJjZXM6IHsgZGVidWdOYW1lOiBzdHJpbmc7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9W107XG4gICAgICAgIHJlYWRlckRpc2tMaW1pdD86IG51bWJlcjtcbiAgICAgICAgc3luY2luZzogU3luY0FjdGl2aXR5W107XG4gICAgfTtcbiAgICBjb21wdXRlSW5kZXhUb3RhbHM/KCk6IFByb21pc2U8eyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXI7IHNvdXJjZXM6IHsgZGVidWdOYW1lOiBzdHJpbmc7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9W10gfT47XG4gICAgLyoqIHBhdGgvbGFzdE1vZGlmaWVkIGxldCB0aGUgc3RvcmUgcmVqZWN0IGFuIHVwbG9hZCBpbnRvIGFuIGltbXV0YWJsZSBidWNrZXQgYmVmb3JlIGFueSBieXRlcyBtb3ZlICovXG4gICAgc3RhcnRMYXJnZVVwbG9hZChjb25maWc/OiB7IHBhdGg/OiBzdHJpbmc7IGxhc3RNb2RpZmllZD86IG51bWJlciB9KTogUHJvbWlzZTxzdHJpbmc+O1xuICAgIGFwcGVuZExhcmdlVXBsb2FkKGNvbmZpZzogeyBpZDogc3RyaW5nOyBkYXRhOiBCdWZmZXIgfSk6IFByb21pc2U8dm9pZD47XG4gICAgZmluaXNoTGFyZ2VVcGxvYWQoY29uZmlnOiB7IGlkOiBzdHJpbmc7IHBhdGg6IHN0cmluZzsgbGFzdE1vZGlmaWVkPzogbnVtYmVyIH0pOiBQcm9taXNlPHZvaWQ+O1xuICAgIGNhbmNlbExhcmdlVXBsb2FkKGNvbmZpZzogeyBpZDogc3RyaW5nIH0pOiBQcm9taXNlPHZvaWQ+O1xufTtcblxuLyoqIHJhd0Rpc2sgYnVja2V0czogdGhlIGRpc2sgSVMgdGhlIHN0b3JlLiBObyBpbmRleCwgbm8gc3luY2hyb25pemF0aW9uLCBubyB3aW5kb3cvcm91dGUvaW1tdXRhYmlsaXR5IHZhbGlkYXRpb24uICovXG5leHBvcnQgY2xhc3MgUmF3RGlza1N0b3JlIGltcGxlbWVudHMgSUJ1Y2tldFN0b3JlIHtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRpc2s6IEFyY2hpdmVzRGlzaykgeyB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0Mihjb25maWc6IHsgcGF0aDogc3RyaW5nOyByYW5nZT86IHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXIgfTsgaW50ZXJuYWw/OiBib29sZWFuOyBpbmNsdWRlVG9tYnN0b25lcz86IGJvb2xlYW4gfSk6IFByb21pc2U8eyBkYXRhOiBCdWZmZXI7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5kaXNrLmdldDIoY29uZmlnLnBhdGgsIHsgcmFuZ2U6IGNvbmZpZy5yYW5nZSwgaW5jbHVkZVRvbWJzdG9uZXM6IGNvbmZpZy5pbmNsdWRlVG9tYnN0b25lcyB9KTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIHNldChjb25maWc6IHsgcGF0aDogc3RyaW5nOyBkYXRhOiBCdWZmZXI7IGxhc3RNb2RpZmllZD86IG51bWJlcjsgZm9yY2VTZXRJbW11dGFibGU/OiBib29sZWFuOyBpbnRlcm5hbD86IGJvb2xlYW4gfSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmRpc2suc2V0KGNvbmZpZy5wYXRoLCBjb25maWcuZGF0YSwgeyBsYXN0TW9kaWZpZWQ6IGNvbmZpZy5sYXN0TW9kaWZpZWQgfSk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBkZWwoY29uZmlnOiB7IHBhdGg6IHN0cmluZzsgbGFzdE1vZGlmaWVkPzogbnVtYmVyOyBpbnRlcm5hbD86IGJvb2xlYW4gfSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoY29uZmlnLnBhdGggPT09IFJPVVRJTkdfRklMRSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgcm91dGluZyBjb25maWcgJHtKU09OLnN0cmluZ2lmeShST1VUSU5HX0ZJTEUpfSBjYW5ub3QgYmUgZGVsZXRlZCAob3ZlcndyaXRlIGl0IHRvIGNoYW5nZSB0aGUgYnVja2V0J3MgY29uZmlndXJhdGlvbilgKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLmRpc2suZGVsKGNvbmZpZy5wYXRoLCB7IGxhc3RNb2RpZmllZDogY29uZmlnLmxhc3RNb2RpZmllZCB9KTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGdldEluZm8oY29uZmlnOiB7IHBhdGg6IHN0cmluZzsgaW5jbHVkZVRvbWJzdG9uZXM/OiBib29sZWFuIH0pOiBQcm9taXNlPHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmRpc2suZ2V0SW5mbyhjb25maWcucGF0aCwgeyBpbmNsdWRlVG9tYnN0b25lczogY29uZmlnLmluY2x1ZGVUb21ic3RvbmVzIH0pO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZmluZEluZm8oY29uZmlnOiBGaW5kQ29uZmlnICYgeyBwcmVmaXg6IHN0cmluZyB9KTogUHJvbWlzZTxBcmNoaXZlRmlsZUluZm9bXT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5kaXNrLmZpbmRJbmZvKGNvbmZpZy5wcmVmaXgsIHsgc2hhbGxvdzogY29uZmlnLnNoYWxsb3csIHR5cGU6IGNvbmZpZy50eXBlIH0pO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgZ2V0Q2hhbmdlc0FmdGVyMihjb25maWc6IENoYW5nZXNBZnRlckNvbmZpZyk6IFByb21pc2U8QXJjaGl2ZUZpbGVJbmZvW10+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZGlzay5nZXRDaGFuZ2VzQWZ0ZXIyKGNvbmZpZyk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBzdGFydExhcmdlVXBsb2FkKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmRpc2suc3RhcnRMYXJnZVVwbG9hZCgpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgYXBwZW5kTGFyZ2VVcGxvYWQoY29uZmlnOiB7IGlkOiBzdHJpbmc7IGRhdGE6IEJ1ZmZlciB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuZGlzay5hcHBlbmRMYXJnZVVwbG9hZChjb25maWcuaWQsIGNvbmZpZy5kYXRhKTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGZpbmlzaExhcmdlVXBsb2FkKGNvbmZpZzogeyBpZDogc3RyaW5nOyBwYXRoOiBzdHJpbmc7IGxhc3RNb2RpZmllZD86IG51bWJlciB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuZGlzay5maW5pc2hMYXJnZVVwbG9hZChjb25maWcuaWQsIGNvbmZpZy5wYXRoLCBjb25maWcubGFzdE1vZGlmaWVkKTtcbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGNhbmNlbExhcmdlVXBsb2FkKGNvbmZpZzogeyBpZDogc3RyaW5nIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5kaXNrLmNhbmNlbExhcmdlVXBsb2FkKGNvbmZpZy5pZCk7XG4gICAgfVxufVxuXG50eXBlIE92ZXJsYXlFbnRyeSA9IHtcbiAgICAvLyBBIHplcm8tbGVuZ3RoIGJ1ZmZlciBpcyBhIHBlbmRpbmcgZGVsZXRlICh0b21ic3RvbmUpXG4gICAgZGF0YTogQnVmZmVyO1xuICAgIHQ6IG51bWJlcjtcbiAgICBmbHVzaEF0OiBudW1iZXI7XG59O1xuXG4vLyBPbmUgcm93IG9mIHRoZSBCdWxrRGF0YWJhc2UyIGluZGV4IChrZXkgaXMgdGhlIGZpbGUgcGF0aClcbnR5cGUgQmxvYkluZGV4RW50cnkgPSB7XG4gICAga2V5OiBzdHJpbmc7XG4gICAgd3JpdGVUaW1lOiBudW1iZXI7XG4gICAgc2l6ZTogbnVtYmVyO1xuICAgIC8vIFdoaWNoIHN5bmNocm9uaXphdGlvbiBzb3VyY2UgY3VycmVudGx5IGhvbGRzIHRoZSBkYXRhOiB0aGUgbGluZSBudW1iZXIgb2YgdGhlIHNvdXJjZSdzIFVSTCBpbiB0aGUgc3RvcmUncyBhcHBlbmQtb25seSBzb3VyY2VzIGxpc3QgKHNlZSBTb3VyY2VzTGlzdCkgLSBOT1QgYSBwb3NpdGlvbiBpbiB0aGUgaW4tbWVtb3J5IHNvdXJjZXMgYXJyYXksIHdoaWNoIGNoYW5nZXMgYmV0d2VlbiBydW5zXG4gICAgc291cmNlc0xpc3RJbmRleDogbnVtYmVyO1xufTtcbnR5cGUgSW5kZXhFbnRyeSA9IHtcbiAgICB3cml0ZVRpbWU6IG51bWJlcjtcbiAgICBzaXplOiBudW1iZXI7XG4gICAgc291cmNlc0xpc3RJbmRleDogbnVtYmVyO1xuICAgIC8vIFdoZW4gV0UgbGFzdCBjaGFuZ2VkIHRoaXMgZW50cnkgKG5vdCB0aGUgZmlsZSdzIHdyaXRlIHRpbWUpIOKAlCB3aGF0IGdldENoYW5nZXNBZnRlcjIgZmlsdGVycyBvbiwgc28gbGF0ZS1hcnJpdmluZyBmaWxlcyB3aXRoIG9sZCB3cml0ZSB0aW1lcyBhcmUgc3RpbGwgcmVwb3J0ZWRcbiAgICBjaGFuZ2VkQXQ6IG51bWJlcjtcbiAgICAvLyBJbi1tZW1vcnkgb25seSAobm90IHBlcnNpc3RlZCk6IHdoZW4gdGhlIGZpbGUgd2FzIGxhc3Qgc2VydmVkLCBmb3IgcmVhZGVyRGlza0xpbWl0J3MgTFJVIGV2aWN0aW9uLiBTdGFydHMgYXMgY2hhbmdlZEF0IG9uIGxvYWQuXG4gICAgbGFzdEFjY2VzczogbnVtYmVyO1xufTtcblxudHlwZSBTb3VyY2VTdGF0ZSA9IHtcbiAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcjogYm9vbGVhbjtcbiAgICBpbml0aWFsU2NhbjogUmV0dXJuVHlwZTx0eXBlb2YgcHJvbWlzZU9iaj47XG4gICAgc2NhbkNvbXBsZXRlOiBib29sZWFuO1xuICAgIC8vIEZpbGVzIHNlZW4gaW4gdGhpcyBzb3VyY2UncyBzY2FucyAvIGNoYW5nZSBwb2xscyBzbyBmYXJcbiAgICBzY2FubmVkQ291bnQ6IG51bWJlcjtcbiAgICAvLyBXYXRlcm1hcmsgZm9yIGdldENoYW5nZXNBZnRlcjIgcG9sbHNcbiAgICBjaGFuZ2VzQWZ0ZXJUaW1lOiBudW1iZXI7XG4gICAgbGFzdE1pc3NDaGVjazogbnVtYmVyO1xuICAgIC8vIFBlci1zbG90IHN0b3AgdG9rZW46IGEgcmVtb3ZlZCBzb3VyY2UncyBsb29wcyBzdG9wIHdpdGhvdXQgdG91Y2hpbmcgdGhlIHJlc3Qgb2YgdGhlIHN0b3JlXG4gICAgc3RvcHBlZDogeyBzdG9wOiBib29sZWFuIH07XG4gICAgLy8gQSByZW1vdmVkIHNvdXJjZSdzIHNsb3Qgc3RheXMgaW4gdGhlIGFycmF5cyAodGhleSBhcmUgbmV2ZXIgc3BsaWNlZCwgc28gc2xvdCBudW1iZXJzIGhlbGQgYnkgcnVubmluZyBsb29wcyBzdGF5IG1lYW5pbmdmdWwpLCBtYXJrZWQgZGVhZCAtIG5ldmVyIHNjYW5uZWQsIHdyaXR0ZW4sIG9yIHJlYWQuIEluZGV4IGVudHJpZXMgZG9uJ3QgcmVmZXJlbmNlIHNsb3RzIGF0IGFsbDsgdGhleSBwZXJzaXN0IHRoZSBzb3VyY2VzIGxpc3QncyBzb3VyY2VzTGlzdEluZGV4LlxuICAgIGRlYWQ/OiBib29sZWFuO1xufTtcblxuLy8gT25lIHNvdXJjZSBvZiBhIGxpdmUgc291cmNlLWxpc3QgdXBkYXRlOyBzZWUgQmxvYlN0b3JlLnVwZGF0ZVNvdXJjZXNcbmV4cG9ydCB0eXBlIEJsb2JTb3VyY2VTcGVjID0ge1xuICAgIC8vIE1hdGNoZWQgYWdhaW5zdCBBcmNoaXZlc1NvdXJjZS5pZGVudGl0eSAoXCJkaXNrXCIgZm9yIHRoZSBiYXNlIHNsb3QpOyBlcXVhbCBpZGVudGl0aWVzIHBhaXIgb2ZmIGluIG9yZGVyXG4gICAgaWRlbnRpdHk6IHN0cmluZztcbiAgICAvLyBTZWUgQXJjaGl2ZXNTb3VyY2UudXJsXG4gICAgdXJsOiBzdHJpbmc7XG4gICAgdmFsaWRXaW5kb3c6IFtudW1iZXIsIG51bWJlcl07XG4gICAgcm91dGU/OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIG5vRnVsbFN5bmM/OiBib29sZWFuO1xuICAgIC8vIFNlZSBBcmNoaXZlc1NvdXJjZS5pbnRlcm1lZGlhdGVcbiAgICBpbnRlcm1lZGlhdGU/OiBib29sZWFuO1xuICAgIC8vIE9ubHkgY2FsbGVkIGZvciBzb3VyY2VzIHRoYXQgZG9uJ3QgbWF0Y2ggYW4gZXhpc3RpbmcgbGl2ZSBzbG90XG4gICAgY3JlYXRlOiAoKSA9PiBJQXJjaGl2ZXM7XG59O1xuXG4vLyBXaGF0IGEgc2Nhbm5lZCBsaXN0aW5nIGVudHJ5IG1lYW50IHdoZW4gY29tcGFyZWQgYWdhaW5zdCBvdXIgaW5kZXhcbnR5cGUgU2Nhbk91dGNvbWUgPSBcImZpbHRlcmVkXCIgfCBcIm5ld1wiIHwgXCJ1cGRhdGVkXCIgfCBcInRvbWJzdG9uZVwiIHwgXCJ1bmNoYW5nZWRcIjtcbnR5cGUgU2NhblRhbGx5ID0gUmVjb3JkPFNjYW5PdXRjb21lLCBudW1iZXI+O1xuZnVuY3Rpb24gbmV3U2NhblRhbGx5KCk6IFNjYW5UYWxseSB7XG4gICAgcmV0dXJuIHsgZmlsdGVyZWQ6IDAsIG5ldzogMCwgdXBkYXRlZDogMCwgdG9tYnN0b25lOiAwLCB1bmNoYW5nZWQ6IDAgfTtcbn1cbmZ1bmN0aW9uIGZvcm1hdFNjYW5UYWxseSh0YWxseTogU2NhblRhbGx5LCB0b3RhbDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBsZXQgcGN0ID0gKG46IG51bWJlcikgPT4gYCR7TWF0aC5yb3VuZChuIC8gTWF0aC5tYXgodG90YWwsIDEpICogMTAwMCkgLyAxMH0lYDtcbiAgICByZXR1cm4gYCR7dGFsbHkubmV3fSBuZXcgcGF0aHMgKCR7cGN0KHRhbGx5Lm5ldyl9KSwgJHt0YWxseS51cGRhdGVkfSBuZXdlciB3cml0ZXMgKCR7cGN0KHRhbGx5LnVwZGF0ZWQpfSksICR7dGFsbHkudG9tYnN0b25lfSBkZWxldGlvbnMgKCR7cGN0KHRhbGx5LnRvbWJzdG9uZSl9KSwgJHt0YWxseS51bmNoYW5nZWR9IHVuY2hhbmdlZCAoJHtwY3QodGFsbHkudW5jaGFuZ2VkKX0pLCAke3RhbGx5LmZpbHRlcmVkfSBvdXRzaWRlIHJvdXRlICgke3BjdCh0YWxseS5maWx0ZXJlZCl9KWA7XG59XG5cbmZ1bmN0aW9uIG5ld1NvdXJjZVN0YXRlKCk6IFNvdXJjZVN0YXRlIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcjogZmFsc2UsXG4gICAgICAgIGluaXRpYWxTY2FuOiBwcm9taXNlT2JqKCksXG4gICAgICAgIHNjYW5Db21wbGV0ZTogZmFsc2UsXG4gICAgICAgIHNjYW5uZWRDb3VudDogMCxcbiAgICAgICAgY2hhbmdlc0FmdGVyVGltZTogMCxcbiAgICAgICAgbGFzdE1pc3NDaGVjazogMCxcbiAgICAgICAgc3RvcHBlZDogeyBzdG9wOiBmYWxzZSB9LFxuICAgIH07XG59XG5cbmxldCBsYXN0V3JvbmdUYXJnZXRMb2cgPSAwO1xuZnVuY3Rpb24gbG9nV3JvbmdUYXJnZXRSZWplY3Rpb24obWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKERhdGUubm93KCkgLSBsYXN0V3JvbmdUYXJnZXRMb2cgPCBXUk9OR19UQVJHRVRfTE9HX1RIUk9UVExFKSByZXR1cm47XG4gICAgbGFzdFdyb25nVGFyZ2V0TG9nID0gRGF0ZS5ub3coKTtcbiAgICBjb25zb2xlLmxvZyhtZXNzYWdlKTtcbn1cblxuZXhwb3J0IGNsYXNzIEJsb2JTdG9yZSBpbXBsZW1lbnRzIElCdWNrZXRTdG9yZSB7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgZm9sZGVyOiBzdHJpbmcsXG4gICAgICAgIHByaXZhdGUgc291cmNlczogQXJjaGl2ZXNTb3VyY2VbXSxcbiAgICAgICAgcHJpdmF0ZSBjb25maWc/OiB7XG4gICAgICAgICAgICAvLyBDYWxsZWQgd2hlbmV2ZXIgYSBrZXkncyBpbmRleCBlbnRyeSBjaGFuZ2VzIChvdXIgb3duIHdyaXRlcyBBTkQgZmlsZXMgcHVsbGVkIGluIHZpYSBzeW5jaHJvbml6YXRpb24pIOKAlCBob3cgdGhlIHN0b3JhZ2Ugc2VydmVyIG5vdGljZXMgcm91dGluZyBjb25maWcgdXBkYXRlcy5cbiAgICAgICAgICAgIG9uSW5kZXhDaGFuZ2VkPzogKGtleTogc3RyaW5nKSA9PiB2b2lkO1xuICAgICAgICAgICAgLy8gTFJVLWJvdW5kIHRoZSBkaXNrIChiYXNlIHNvdXJjZSkgdG8gdGhpcyBtYW55IGJ5dGVzOyBzZWUgQ29tbW9uQ29uZmlnLnJlYWRlckRpc2tMaW1pdFxuICAgICAgICAgICAgcmVhZGVyRGlza0xpbWl0PzogbnVtYmVyO1xuICAgICAgICAgICAgLy8gRXZlcnkgYWNjZXB0ZWQgd3JpdGUgKFwib3JpZ2luYWxcIikgYW5kIGV2ZXJ5IHdyaXRlIHRoYXQgYWN0dWFsbHkgcmVhY2hlZCB0aGUgc291cmNlcyAoXCJmbHVzaGVkXCIpLiBGYXN0IHdyaXRlcyBjb2FsZXNjZSwgc28gdGhlIHR3byBjb3VudHMgZGlmZmVyLlxuICAgICAgICAgICAgb25Xcml0ZUNvdW50ZWQ/OiAoa2luZDogXCJvcmlnaW5hbFwiIHwgXCJmbHVzaGVkXCIsIGJ5dGVzOiBudW1iZXIpID0+IHZvaWQ7XG4gICAgICAgICAgICAvLyBSZXNvbHZlcyBhIHBlcnNpc3RlZCBzb3VyY2UgVVJMIChzZWUgQXJjaGl2ZXNTb3VyY2UudXJsKSB0byBhIGNhY2hlZCBJQXJjaGl2ZXMsIHNvIGVudHJpZXMgd2hvc2UgaG9sZGVyIGlzIG5vIGxvbmdlciBjb25maWd1cmVkIGNhbiBzdGlsbCBiZSByZWFkXG4gICAgICAgICAgICByZXNvbHZlU291cmNlVXJsPzogKHVybDogc3RyaW5nKSA9PiBJQXJjaGl2ZXM7XG4gICAgICAgICAgICAvLyBUaGlzIHN0b3JlJ3Mgb3duIGVudHJpZXMgaW4gdGhlIHJvdXRpbmcgY29uZmlnIChhbGwgdGhlIHNhbWUgcm91dGUsIGRpZmZlcmVudCB2YWxpZCB3aW5kb3dzKS4gV2hhdCBzZXQvZGVsIHZhbGlkYXRlIGFnYWluc3Q6IHZhbGlkIHdpbmRvd3MgYW5kIHJvdXRlcyBmb3IgZnJlc2ggd3JpdGVzLCBpbW11dGFiaWxpdHksIGludGVybmFsLXB1c2ggYWNjZXB0YW5jZSwgYW5kIHRoZSBmYXN0L3dyaXRlRGVsYXkgZmxhZ3MuIEVtcHR5ID0gbm8gdmFsaWRhdGlvbiAoYSBzdG9yZSBzZXJ2aW5nIGxlZnRvdmVyIGRpc2sgZGF0YSB3aXRoIG5vIGNvbmZpZykuXG4gICAgICAgICAgICBlbnRyaWVzPzogSG9zdGVkQ29uZmlnW107XG4gICAgICAgIH1cbiAgICApIHsgfVxuXG4gICAgLy8gI3JlZ2lvbiBNYWluIGludGVyZmFjZVxuXG4gICAgcHVibGljIGluaXQgPSBsYXp5KGFzeW5jICgpID0+IHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNvdXJjZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJTbG90KGkpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMubG9hZEluZGV4KCk7XG4gICAgICAgIHRoaXMuc3luY1N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuc291cmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzTGl2ZShpKSkgY29udGludWU7XG4gICAgICAgICAgICB2b2lkIHRoaXMucnVuU291cmNlU3luYyhpKTtcbiAgICAgICAgfVxuICAgICAgICBydW5JbmZpbml0ZVBvbGwoRkFTVF9GTFVTSF9QT0xMLCAoKSA9PiB0aGlzLmZsdXNoT3ZlcmxheSgpLCB0aGlzLnN0b3BwZWQpO1xuICAgICAgICBydW5JbmZpbml0ZVBvbGwoSU5ERVhfRkxVU0hfSU5URVJWQUwsICgpID0+IHRoaXMuZmx1c2hJbmRleCgpLCB0aGlzLnN0b3BwZWQpO1xuICAgICAgICBydW5JbmZpbml0ZVBvbGwoVE9NQlNUT05FX0NMRUFOVVBfSU5URVJWQUwsICgpID0+IHRoaXMuY2xlYW51cFRvbWJzdG9uZXMoKSwgdGhpcy5zdG9wcGVkKTtcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnPy5yZWFkZXJEaXNrTGltaXQpIHtcbiAgICAgICAgICAgIHJ1bkluZmluaXRlUG9sbChESVNLX0xJTUlUX0NIRUNLX0lOVEVSVkFMLCAoKSA9PiB0aGlzLmVuZm9yY2VEaXNrTGltaXQoKSwgdGhpcy5zdG9wcGVkKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU3RvcHMgYWxsIHN5bmNocm9uaXphdGlvbiBzY2Fucy9wb2xscyBhbmQgZmx1c2hlcyBwZW5kaW5nIHdyaXRlcy4gT25seSB1c2VkIHdoZW4gdGhlIHN0b3JlIGdlbnVpbmVseSBjYW5ub3QgY29udGludWUgKHJhd0Rpc2sgZmxpcCwgcHJvY2VzcyBzaHV0ZG93bikgLSByb3V0aW5lIGNvbmZpZyBjaGFuZ2VzIGdvIHRocm91Z2ggdXBkYXRlU291cmNlcyBpbnN0ZWFkLCB3aGljaCB0aGUgc3RvcmUgc3Vydml2ZXMuXG4gICAgcHVibGljIGFzeW5jIGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuc3RvcHBlZC5zdG9wID0gdHJ1ZTtcbiAgICAgICAgZm9yIChsZXQgc3RhdGUgb2YgdGhpcy5zb3VyY2VTdGF0ZXMpIHtcbiAgICAgICAgICAgIHN0YXRlLnN0b3BwZWQuc3RvcCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5mbHVzaE92ZXJsYXkodHJ1ZSk7XG4gICAgICAgIGF3YWl0IHRoaXMuZmx1c2hJbmRleCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXQyKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9OyBpbnRlcm5hbD86IGJvb2xlYW47IGluY2x1ZGVUb21ic3RvbmVzPzogYm9vbGVhbiB9KTogUHJvbWlzZTx7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGlmIChjb25maWcuaW50ZXJuYWwpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmdldEludGVybmFsMihjb25maWcpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBsZXQga2V5ID0gY29uZmlnLnBhdGg7XG4gICAgICAgIGxldCByYW5nZSA9IGNvbmZpZy5yYW5nZTtcbiAgICAgICAgbGV0IG92ZXJsYXlFbnRyeSA9IHRoaXMub3ZlcmxheS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKG92ZXJsYXlFbnRyeSkge1xuICAgICAgICAgICAgLy8gQW4gZW1wdHkgZmlsZSBJUyBhIG1pc3NpbmcgZmlsZSAodG9tYnN0b25lKVxuICAgICAgICAgICAgaWYgKG92ZXJsYXlFbnRyeS5kYXRhLmxlbmd0aCA9PT0gMCAmJiAhY29uZmlnLmluY2x1ZGVUb21ic3RvbmVzKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgbGV0IGRhdGEgPSBvdmVybGF5RW50cnkuZGF0YTtcbiAgICAgICAgICAgIGxldCBzaXplID0gZGF0YS5sZW5ndGg7XG4gICAgICAgICAgICBpZiAocmFuZ2UpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZGF0YS5zdWJhcnJheShNYXRoLm1pbihyYW5nZS5zdGFydCwgZGF0YS5sZW5ndGgpLCBNYXRoLm1pbihyYW5nZS5lbmQsIGRhdGEubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geyBkYXRhLCB3cml0ZVRpbWU6IG92ZXJsYXlFbnRyeS50LCBzaXplIH07XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGVudHJ5ID0gYXdhaXQgdGhpcy5nZXRJbmRleEVudHJ5KGtleSk7XG4gICAgICAgIGlmICghZW50cnkpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChlbnRyeS5zaXplID09PSAwKSB7XG4gICAgICAgICAgICBpZiAoIWNvbmZpZy5pbmNsdWRlVG9tYnN0b25lcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIC8vIEEgdG9tYnN0b25lIGhhcyBubyBzdG9yZWQgYnl0ZXMgLSB0aGUgaW5kZXggZW50cnkgYWxvbmUgaXMgdGhlIGRlbGV0aW9uLCBzbyB0aGUgZmxhZy1jYWxsZXIgZ2V0cyBpdHMgd3JpdGUgdGltZSB3aXRoIGVtcHR5IGRhdGFcbiAgICAgICAgICAgIHJldHVybiB7IGRhdGE6IEJ1ZmZlci5hbGxvYygwKSwgd3JpdGVUaW1lOiBlbnRyeS53cml0ZVRpbWUsIHNpemU6IDAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbnRyeS5sYXN0QWNjZXNzID0gRGF0ZS5ub3coKTtcbiAgICAgICAgbGV0IGhvbGRlckFyY2hpdmVzID0gYXdhaXQgdGhpcy5nZXRFbnRyeUhvbGRlcihlbnRyeSk7XG4gICAgICAgIGxldCByZXN1bHQ6IHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBob2xkZXJFcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChob2xkZXJBcmNoaXZlcykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBpbmNsdWRlVG9tYnN0b25lczogdGhlIGhvbGRlciBhbnN3ZXJpbmcgXCJkZWxldGVkXCIgKGEgdG9tYnN0b25lLCB3aXRoIGl0cyB3cml0ZSB0aW1lKSBtdXN0IGJlIGRpc3Rpbmd1aXNoYWJsZSBmcm9tIFwiSSBsb3N0IHRoZSBmaWxlXCIgLSB0aGUgZm9ybWVyIGlzIGF1dGhvcml0YXRpdmUgYW5kIG11c3QgTk9UIGZhbGwgYmFjayB0byBvbGRlciBjb3BpZXMsIHdoaWNoIHdvdWxkIHJlc3VycmVjdCB0aGUgZGVsZXRpb24gZm9yIHRoaXMgcmVhZFxuICAgICAgICAgICAgICAgIGxldCBhbnN3ZXIgPSBhd2FpdCBob2xkZXJBcmNoaXZlcy5nZXQyKGtleSwgeyByYW5nZSwgaW50ZXJuYWw6IHRydWUsIGluY2x1ZGVUb21ic3RvbmVzOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIGlmIChhbnN3ZXIgJiYgYW5zd2VyLmRhdGEgJiYgIWFuc3dlci5kYXRhLmxlbmd0aCAmJiAhKHJhbmdlICYmIGFuc3dlci5zaXplKSAmJiBhbnN3ZXIud3JpdGVUaW1lID49IGVudHJ5LndyaXRlVGltZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBOT1RFOiBhIHJhbmdlZCByZWFkIG9mIGEgcmVhbCBmaWxlIGNhbiBsZWdpdGltYXRlbHkgYmUgZW1wdHkgKHJhbmdlIHBhc3QgRU9GKSwgc28gb25seSB1bnJhbmdlZCBlbXB0aW5lc3MgbWVhbnMgdG9tYnN0b25lL2Fic2VudFxuICAgICAgICAgICAgICAgIGlmIChhbnN3ZXIgJiYgYW5zd2VyLmRhdGEgJiYgKGFuc3dlci5kYXRhLmxlbmd0aCB8fCByYW5nZSAmJiBhbnN3ZXIuc2l6ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0geyBkYXRhOiBhbnN3ZXIuZGF0YSwgd3JpdGVUaW1lOiBhbnN3ZXIud3JpdGVUaW1lLCBzaXplOiBhbnN3ZXIuc2l6ZSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBob2xkZXJFcnJvciA9IGUgYXMgRXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgLy8gUmFuZ2VkIHJlYWRzIGNhbid0IHBvcHVsYXRlIGEgY2FjaGUgKHRoZXkncmUgcGFydGlhbClcbiAgICAgICAgICAgIGlmICh0aGlzLnNsb3RGb3JTb3VyY2VzTGlzdEluZGV4KGVudHJ5LnNvdXJjZXNMaXN0SW5kZXgpICE9PSAwICYmICFyYW5nZSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuY2FjaGVSZWFkKGtleSwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlIHJvdXRpbmcgZmlsZSBpcyBvbmx5IGV2ZXIgcmVhZCBvZmYgb3VyIG93biBkaXNrIC0gZmFsbGluZyBiYWNrIHRvIGFub3RoZXIgc291cmNlJ3MgY29weSB3b3VsZCBzeW5jaHJvbml6ZSBpdCBiZXR3ZWVuIG5vZGVzIHRocm91Z2ggdGhlIHJlYWQgcGF0aCwgd2hpY2ggaXQgbmV2ZXIgaXNcbiAgICAgICAgaWYgKGtleSA9PT0gUk9VVElOR19GSUxFKSB7XG4gICAgICAgICAgICBpZiAoaG9sZGVyRXJyb3IpIHRocm93IGhvbGRlckVycm9yO1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGUgaG9sZGVyIGlzIGRvd24gb3IgbG9zdCB0aGUgZmlsZS4gQU5ZIG90aGVyIHNvdXJjZSdzIGNvcHkgYmVhdHMgbm8gdmFsdWUgLSBldmVuIGFuIE9MREVSIG9uZSAtIGFuZCBpdCdzIGNvcGllZCBvbnRvIG91ciBkaXNrIHNvIHRoZSBuZXh0IHJlYWQgZG9lc24ndCBkZXBlbmQgb24gbHVjay5cbiAgICAgICAgbGV0IGhvbGRlclNsb3QgPSB0aGlzLnNsb3RGb3JTb3VyY2VzTGlzdEluZGV4KGVudHJ5LnNvdXJjZXNMaXN0SW5kZXgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuc291cmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGkgPT09IGhvbGRlclNsb3QgfHwgIXRoaXMuaXNMaXZlKGkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGxldCBmYWxsYmFjazogeyBkYXRhOiBCdWZmZXI7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IGFuc3dlciA9IGF3YWl0IHRoaXMuc291cmNlc1tpXS5zb3VyY2UuZ2V0MihrZXksIHsgaW50ZXJuYWw6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgLy8gRW1wdHkgZGF0YSBjb3VudHMgYXMgYWJzZW50IC0gYSB0b21ic3RvbmUsIG5vdCBjb250ZW50ICh0aGlzIHJlYWQgaXMgdW5yYW5nZWQsIHNvIGVtcHRpbmVzcyBpcyB1bmFtYmlndW91cylcbiAgICAgICAgICAgICAgICBpZiAoYW5zd2VyICYmIGFuc3dlci5kYXRhICYmIGFuc3dlci5kYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBmYWxsYmFjayA9IHsgZGF0YTogYW5zd2VyLmRhdGEsIHdyaXRlVGltZTogYW5zd2VyLndyaXRlVGltZSwgc2l6ZTogYW5zd2VyLnNpemUgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghZmFsbGJhY2spIGNvbnRpbnVlO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jYWNoZVJlYWQoa2V5LCBmYWxsYmFjayk7XG4gICAgICAgICAgICBsZXQgZGF0YSA9IGZhbGxiYWNrLmRhdGE7XG4gICAgICAgICAgICBpZiAocmFuZ2UpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gZGF0YS5zdWJhcnJheShNYXRoLm1pbihyYW5nZS5zdGFydCwgZGF0YS5sZW5ndGgpLCBNYXRoLm1pbihyYW5nZS5lbmQsIGRhdGEubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geyBkYXRhLCB3cml0ZVRpbWU6IGZhbGxiYWNrLndyaXRlVGltZSwgc2l6ZTogZmFsbGJhY2suc2l6ZSB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChob2xkZXJFcnJvcikgdGhyb3cgaG9sZGVyRXJyb3I7XG4gICAgICAgIC8vIFRoZSBob2xkZXIgYW5zd2VyZWQgXCJub3QgdGhlcmVcIiBhbmQgbm8gb3RoZXIgc291cmNlIGhhcyBpdCBlaXRoZXI6IHRoZSBlbnRyeSB3YXMgc3RhbGVcbiAgICAgICAgdGhpcy5kZWxldGVJbmRleEVudHJ5KGtleSk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldChjb25maWc6IHsgcGF0aDogc3RyaW5nOyBkYXRhOiBCdWZmZXI7IGxhc3RNb2RpZmllZD86IG51bWJlcjsgZm9yY2VTZXRJbW11dGFibGU/OiBib29sZWFuOyBpbnRlcm5hbD86IGJvb2xlYW4gfSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBsZXQgeyBwYXRoOiBrZXksIGRhdGEgfSA9IGNvbmZpZztcbiAgICAgICAgaWYgKCFkYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBzZXQgd2FzIGNhbGxlZCB3aXRoIGFuIGVtcHR5IGJ1ZmZlciBmb3IgJHtKU09OLnN0cmluZ2lmeShrZXkpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiBhbiBlbXB0eSBmaWxlIElTIGEgZGVsZXRpb24gaW4gdGhpcyBzeXN0ZW0gYW5kIHdvdWxkIHJlYWQgYmFjayBhcyBtaXNzaW5nIC0gY2FsbCBkZWwgaW5zdGVhZGApO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBsZXQgd3JpdGVUaW1lID0gY29uZmlnLmxhc3RNb2RpZmllZCB8fCBEYXRlLm5vdygpO1xuICAgICAgICBsZXQgcm91dGUgPSBnZXRSb3V0ZShrZXkpO1xuICAgICAgICAvLyBUaGUgcm91dGluZyBmaWxlIGRlZmluZXMgdGhlIHdpbmRvd3Mvcm91dGVzLCBzbyB0aGV5IGNhbid0IHBvc3NpYmx5IGFwcGx5IHRvIGl0IChhbmQgaXQgbmV2ZXIgZmxvd3MgdGhyb3VnaCB2YWxpZGF0aW9uKVxuICAgICAgICBpZiAoa2V5ICE9PSBST1VUSU5HX0ZJTEUgJiYgdGhpcy5lbnRyaWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCFjb25maWcubGFzdE1vZGlmaWVkKSB7XG4gICAgICAgICAgICAgICAgbGV0IHRpbWVWYWxpZCA9IHRoaXMuZW50cmllcy5maWx0ZXIoeCA9PiB3cml0ZVRpbWUgPj0geC52YWxpZFdpbmRvd1swXSAmJiB3cml0ZVRpbWUgPCB4LnZhbGlkV2luZG93WzFdKTtcbiAgICAgICAgICAgICAgICBpZiAoIXRpbWVWYWxpZC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nV3JvbmdUYXJnZXRSZWplY3Rpb24oYFJlamVjdGluZyBmcmVzaCB3cml0ZSBvZiAke0pTT04uc3RyaW5naWZ5KGtleSl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6IHdyaXRlVGltZSAke3dyaXRlVGltZX0gKCR7bmV3IERhdGUod3JpdGVUaW1lKS50b0lTT1N0cmluZygpfSkgaXMgb3V0c2lkZSBhbGwgb3VyIHZhbGlkIHdpbmRvd3MgJHtKU09OLnN0cmluZ2lmeSh0aGlzLmVudHJpZXMubWFwKHggPT4geC52YWxpZFdpbmRvdykpfSAoYSBzd2l0Y2hvdmVyIG1vdmVkIHRoZSB3cml0ZSB0YXJnZXQpYCk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtTVE9SQUdFX1dST05HX1ZBTElEX1dJTkRPV30gVGhpcyBzdG9yZSBpcyBub3QgYSB2YWxpZCB3cml0ZSB0YXJnZXQgYXQgJHt3cml0ZVRpbWV9IChvdXIgdmFsaWQgd2luZG93czogJHtKU09OLnN0cmluZ2lmeSh0aGlzLmVudHJpZXMubWFwKHggPT4geC52YWxpZFdpbmRvdykpfSwgc3RvcmUgJHt0aGlzLmZvbGRlcn0pLiBSZS1yZXNvbHZlIHRoZSBjdXJyZW50bHkgdmFsaWQgc291cmNlIGFuZCByZXRyeS5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCF0aW1lVmFsaWQuc29tZSh4ID0+IHJvdXRlQ29udGFpbnMoeC5yb3V0ZSwgcm91dGUpKSkge1xuICAgICAgICAgICAgICAgICAgICBsb2dXcm9uZ1RhcmdldFJlamVjdGlvbihgUmVqZWN0aW5nIGZyZXNoIHdyaXRlIG9mICR7SlNPTi5zdHJpbmdpZnkoa2V5KX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KTogcm91dGUgJHtyb3V0ZX0gaXMgb3V0c2lkZSBvdXIgcm91dGVzICR7SlNPTi5zdHJpbmdpZnkodGltZVZhbGlkLm1hcCh4ID0+IHgucm91dGUgfHwgRlVMTF9ST1VURSkpfSBhdCB3cml0ZVRpbWUgJHt3cml0ZVRpbWV9ICh0aGUgY2xpZW50J3Mgc2hhcmQgY29uZmlnIGlzIHN0YWxlKWApO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7U1RPUkFHRV9XUk9OR19ST1VURX0gVGhpcyBzdG9yZSBkb2VzIG5vdCBoYW5kbGUgcm91dGUgJHtyb3V0ZX0gKGtleSAke0pTT04uc3RyaW5naWZ5KGtleSl9LCBvdXIgcm91dGVzIGF0IHRoaXMgdGltZTogJHtKU09OLnN0cmluZ2lmeSh0aW1lVmFsaWQubWFwKHggPT4geC5yb3V0ZSB8fCBGVUxMX1JPVVRFKSl9LCBzdG9yZSAke3RoaXMuZm9sZGVyfSkuIFJlLXJlc29sdmUgdGhlIHNvdXJjZSBmb3IgdGhpcyBrZXkgYW5kIHJldHJ5LmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjb25maWcuZm9yY2VTZXRJbW11dGFibGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbmZpZy5sYXN0TW9kaWZpZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmb3JjZVNldEltbXV0YWJsZSByZXF1aXJlcyBsYXN0TW9kaWZpZWQgKHN5bmNocm9uaXphdGlvbiB3cml0ZXMgYXJlIG9yZGVyZWQgYnkgdGhlaXIgd3JpdGUgdGltZSksIHdyaXRpbmcgJHtKU09OLnN0cmluZ2lmeShrZXkpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEltbXV0YWJpbGl0eSB3aW5zOiBhbiBleGlzdGluZyBwYXRoIGlzIGtlcHQgaW5zdGVhZCBvZiB0aGUgcHVzaCB0aHJvd2luZyAoc2VlIFNldENvbmZpZy5mb3JjZVNldEltbXV0YWJsZSlcbiAgICAgICAgICAgICAgICBsZXQgc2VsZiA9IHNlbGVjdEVudHJ5QXQodGhpcy5lbnRyaWVzLCB3cml0ZVRpbWUsIHJvdXRlKTtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZj8uaW1tdXRhYmxlICYmIGF3YWl0IHRoaXMuZ2V0SW5mbyh7IHBhdGg6IGtleSB9KSkgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmFzc2VydE11dGFibGUoa2V5LCB3cml0ZVRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb25maWcuaW50ZXJuYWwpIHtcbiAgICAgICAgICAgIGlmICghY29uZmlnLmxhc3RNb2RpZmllZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW50ZXJuYWwgd3JpdGVzIG11c3QgY2FycnkgbGFzdE1vZGlmaWVkICh0aGV5IGFyZSBzeW5jaHJvbml6YXRpb24gcHVzaGVzLCBvcmRlcmVkIGJ5IHRoZWlyIHdyaXRlIHRpbWUpLCB3cml0aW5nICR7SlNPTi5zdHJpbmdpZnkoa2V5KX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hc3NlcnRJbnRlcm5hbFdyaXRlQWNjZXB0ZWQoa2V5LCBjb25maWcubGFzdE1vZGlmaWVkLCByb3V0ZSk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNldEludGVybmFsKGtleSwgZGF0YSwgeyBsYXN0TW9kaWZpZWQ6IGNvbmZpZy5sYXN0TW9kaWZpZWQgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzLmVudHJpZXMubGVuZ3RoICYmIHNlbGVjdEVudHJ5QXQodGhpcy5lbnRyaWVzLCB3cml0ZVRpbWUsIHJvdXRlKSB8fCB1bmRlZmluZWQ7XG4gICAgICAgIGF3YWl0IHRoaXMuc2V0T3JEZWxldGUoa2V5LCBkYXRhLCB7IGZhc3Q6IHNlbGY/LmZhc3QsIHdyaXRlRGVsYXk6IHNlbGY/LndyaXRlRGVsYXksIGxhc3RNb2RpZmllZDogY29uZmlnLmxhc3RNb2RpZmllZCB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZGVsKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IGxhc3RNb2RpZmllZD86IG51bWJlcjsgaW50ZXJuYWw/OiBib29sZWFuIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IGtleSA9IGNvbmZpZy5wYXRoO1xuICAgICAgICBpZiAoa2V5ID09PSBST1VUSU5HX0ZJTEUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHJvdXRpbmcgY29uZmlnICR7SlNPTi5zdHJpbmdpZnkoUk9VVElOR19GSUxFKX0gY2Fubm90IGJlIGRlbGV0ZWQgKG92ZXJ3cml0ZSBpdCB0byBjaGFuZ2UgdGhlIGJ1Y2tldCdzIGNvbmZpZ3VyYXRpb24pYCk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgIGlmIChjb25maWcuaW50ZXJuYWwpIHtcbiAgICAgICAgICAgIGlmICghY29uZmlnLmxhc3RNb2RpZmllZCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW50ZXJuYWwgZGVsZXRpb25zIG11c3QgY2FycnkgbGFzdE1vZGlmaWVkICh0aGV5IGFyZSBzeW5jaHJvbml6YXRpb24gcHVzaGVzLCBvcmRlcmVkIGJ5IHRoZWlyIHdyaXRlIHRpbWUpLCBkZWxldGluZyAke0pTT04uc3RyaW5naWZ5KGtleSl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSlgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYXNzZXJ0SW50ZXJuYWxXcml0ZUFjY2VwdGVkKGtleSwgY29uZmlnLmxhc3RNb2RpZmllZCwgZ2V0Um91dGUoa2V5KSk7XG4gICAgICAgICAgICAvLyBzZXRJbnRlcm5hbCB0cmVhdHMgYW4gZW1wdHkgYnVmZmVyIGFzIGV4YWN0bHkgYSBkZWxldGlvbjogZGlzayByZW1vdmFsIHBsdXMgYSB0b21ic3RvbmUgaW5kZXggZW50cnksIG5vIGZhbi1vdXRcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2V0SW50ZXJuYWwoa2V5LCBCdWZmZXIuYWxsb2MoMCksIHsgbGFzdE1vZGlmaWVkOiBjb25maWcubGFzdE1vZGlmaWVkIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIERlbGV0ZXMgYXJlIHRvbWJzdG9uZSB3cml0ZXMgKGFuIGVtcHR5IGZpbGUgSVMgYSBtaXNzaW5nIGZpbGUpOiB0aGUgc2l6ZS0wIGluZGV4IGVudHJ5IGlzIG9yZGVyZWQgYnkgd3JpdGUgdGltZSBsaWtlIGFueSBvdGhlciB3cml0ZSwgcHJvcGFnYXRlcyB0aHJvdWdoIHN5bmNocm9uaXphdGlvbiwgYW5kIGV4cGlyZXMgYWZ0ZXIgVE9NQlNUT05FX0VYUElSWVxuICAgICAgICBsZXQgd3JpdGVUaW1lID0gY29uZmlnLmxhc3RNb2RpZmllZCB8fCBEYXRlLm5vdygpO1xuICAgICAgICBsZXQgc2VsZiA9IHRoaXMuZW50cmllcy5sZW5ndGggJiYgc2VsZWN0RW50cnlBdCh0aGlzLmVudHJpZXMsIHdyaXRlVGltZSwgZ2V0Um91dGUoa2V5KSkgfHwgdW5kZWZpbmVkO1xuICAgICAgICBhd2FpdCB0aGlzLnNldE9yRGVsZXRlKGtleSwgQnVmZmVyLmFsbG9jKDApLCB7IGZhc3Q6IHNlbGY/LmZhc3QsIHdyaXRlRGVsYXk6IHNlbGY/LndyaXRlRGVsYXksIGxhc3RNb2RpZmllZDogY29uZmlnLmxhc3RNb2RpZmllZCB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0SW5mbyhjb25maWc6IHsgcGF0aDogc3RyaW5nOyBpbmNsdWRlVG9tYnN0b25lcz86IGJvb2xlYW4gfSk6IFByb21pc2U8eyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgIGxldCBrZXkgPSBjb25maWcucGF0aDtcbiAgICAgICAgbGV0IG92ZXJsYXlFbnRyeSA9IHRoaXMub3ZlcmxheS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKG92ZXJsYXlFbnRyeSkge1xuICAgICAgICAgICAgaWYgKCFvdmVybGF5RW50cnkuZGF0YS5sZW5ndGggJiYgIWNvbmZpZy5pbmNsdWRlVG9tYnN0b25lcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHJldHVybiB7IHdyaXRlVGltZTogb3ZlcmxheUVudHJ5LnQsIHNpemU6IG92ZXJsYXlFbnRyeS5kYXRhLmxlbmd0aCB9O1xuICAgICAgICB9XG4gICAgICAgIGxldCBlbnRyeSA9IGF3YWl0IHRoaXMuZ2V0SW5kZXhFbnRyeShrZXkpO1xuICAgICAgICBpZiAoIWVudHJ5KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoIWVudHJ5LnNpemUgJiYgIWNvbmZpZy5pbmNsdWRlVG9tYnN0b25lcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHsgd3JpdGVUaW1lOiBlbnRyeS53cml0ZVRpbWUsIHNpemU6IGVudHJ5LnNpemUgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZmluZEluZm8oY29uZmlnOiBGaW5kQ29uZmlnICYgeyBwcmVmaXg6IHN0cmluZyB9KTogUHJvbWlzZTxBcmNoaXZlRmlsZUluZm9bXT4ge1xuICAgICAgICBhd2FpdCB0aGlzLmluaXQoKTtcbiAgICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yUmVxdWlyZWRTY2FucygpO1xuICAgICAgICBsZXQgcHJlZml4ID0gY29uZmlnLnByZWZpeDtcbiAgICAgICAgbGV0IGluZm9zID0gbmV3IE1hcDxzdHJpbmcsIEFyY2hpdmVGaWxlSW5mbz4oKTtcbiAgICAgICAgZm9yIChsZXQgW2tleSwgZW50cnldIG9mIHRoaXMubWVtKSB7XG4gICAgICAgICAgICBpZiAoIWtleS5zdGFydHNXaXRoKHByZWZpeCkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgLy8gVG9tYnN0b25lcyBhcmUgbWlzc2luZyBmaWxlcywgc28gbGlzdGluZ3MgaGlkZSB0aGVtXG4gICAgICAgICAgICBpZiAoZW50cnkuc2l6ZSA9PT0gMCkgY29udGludWU7XG4gICAgICAgICAgICBpbmZvcy5zZXQoa2V5LCB7IHBhdGg6IGtleSwgY3JlYXRlVGltZTogZW50cnkud3JpdGVUaW1lLCBzaXplOiBlbnRyeS5zaXplIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IFtrZXksIG92ZXJsYXlFbnRyeV0gb2YgdGhpcy5vdmVybGF5KSB7XG4gICAgICAgICAgICBpZiAoIWtleS5zdGFydHNXaXRoKHByZWZpeCkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKG92ZXJsYXlFbnRyeS5kYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGluZm9zLmRlbGV0ZShrZXkpO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5mb3Muc2V0KGtleSwgeyBwYXRoOiBrZXksIGNyZWF0ZVRpbWU6IG92ZXJsYXlFbnRyeS50LCBzaXplOiBvdmVybGF5RW50cnkuZGF0YS5sZW5ndGggfSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGZpbGVzID0gYXBwbHlGaW5kSW5mb1NoYXBlKEFycmF5LmZyb20oaW5mb3MudmFsdWVzKCkpLCBwcmVmaXgsIHsgc2hhbGxvdzogY29uZmlnLnNoYWxsb3csIHR5cGU6IGNvbmZpZy50eXBlIH0pO1xuICAgICAgICBzb3J0KGZpbGVzLCB4ID0+IHgucGF0aCk7XG4gICAgICAgIHJldHVybiBmaWxlcztcbiAgICB9XG5cbiAgICAvLyBBbGwgZmlsZXMgY2hhbmdlZCBhZnRlciBjb25maWcudGltZSDigJQgZmFzdCwgc3RyYWlnaHQgZnJvbSB0aGUgaW4tbWVtb3J5IGluZGV4LiBGaWx0ZXJzIG9uIHdoZW4gV0UgbGVhcm5lZCBvZiB0aGUgY2hhbmdlIChjaGFuZ2VkQXQpLCBzbyBmaWxlcyBzeW5jaHJvbml6ZWQgbGF0ZSAod2l0aCBvbGQgd3JpdGUgdGltZXMpIGFyZSBzdGlsbCByZXBvcnRlZC4gRGVsZXRpb25zIEFSRSByZXBvcnRlZCwgYXMgc2l6ZS0wIHRvbWJzdG9uZSBlbnRyaWVzIOKAlCB0aGF0J3MgaG93IHRoZXkgcHJvcGFnYXRlIHRvIHN0b3JlcyBzeW5jaW5nIGZyb20gdXMuIGNvbmZpZy5yb3V0ZXMgbGV0cyBhIHN0b3JlIHN5bmNpbmcgYSBwYXJ0aWFsIHNoYXJkIGFzayBmb3IganVzdCBpdHMgc2xpY2UuXG4gICAgcHVibGljIGFzeW5jIGdldENoYW5nZXNBZnRlcjIoY29uZmlnOiBDaGFuZ2VzQWZ0ZXJDb25maWcpOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JSZXF1aXJlZFNjYW5zKCk7XG4gICAgICAgIGxldCBpblJvdXRlcyA9IChrZXk6IHN0cmluZykgPT4gIWNvbmZpZy5yb3V0ZXMgfHwgY29uZmlnLnJvdXRlcy5zb21lKHJvdXRlID0+IHJvdXRlQ29udGFpbnMocm91dGUsIGdldFJvdXRlKGtleSkpKTtcbiAgICAgICAgbGV0IGZpbGVzOiBBcmNoaXZlRmlsZUluZm9bXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBba2V5LCBlbnRyeV0gb2YgdGhpcy5tZW0pIHtcbiAgICAgICAgICAgIGlmIChlbnRyeS5jaGFuZ2VkQXQgPD0gY29uZmlnLnRpbWUpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHRoaXMub3ZlcmxheS5oYXMoa2V5KSkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoIWluUm91dGVzKGtleSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgZmlsZXMucHVzaCh7IHBhdGg6IGtleSwgY3JlYXRlVGltZTogZW50cnkud3JpdGVUaW1lLCBzaXplOiBlbnRyeS5zaXplIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IFtrZXksIG92ZXJsYXlFbnRyeV0gb2YgdGhpcy5vdmVybGF5KSB7XG4gICAgICAgICAgICBpZiAob3ZlcmxheUVudHJ5LnQgPD0gY29uZmlnLnRpbWUpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFpblJvdXRlcyhrZXkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGZpbGVzLnB1c2goeyBwYXRoOiBrZXksIGNyZWF0ZVRpbWU6IG92ZXJsYXlFbnRyeS50LCBzaXplOiBvdmVybGF5RW50cnkuZGF0YS5sZW5ndGggfSk7XG4gICAgICAgIH1cbiAgICAgICAgc29ydChmaWxlcywgeCA9PiB4LnBhdGgpO1xuICAgICAgICByZXR1cm4gZmlsZXM7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldFN5bmNTdGF0dXMoKTogUHJvbWlzZTxBcmNoaXZlc1N5bmNTdGF0dXM+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhbGxTY2Fuc0NvbXBsZXRlOiB0aGlzLnNvdXJjZVN0YXRlcy5ldmVyeSh4ID0+IHguc2NhbkNvbXBsZXRlKSxcbiAgICAgICAgICAgIGluZGV4U2l6ZTogdGhpcy5tZW0uc2l6ZSxcbiAgICAgICAgICAgIHNvdXJjZXM6IHRoaXMuc291cmNlcy5tYXAoKHgsIGkpID0+ICh7XG4gICAgICAgICAgICAgICAgZGVidWdOYW1lOiB4LnNvdXJjZS5nZXREZWJ1Z05hbWUoKSxcbiAgICAgICAgICAgICAgICB2YWxpZFdpbmRvdzogeC52YWxpZFdpbmRvdyxcbiAgICAgICAgICAgICAgICByb3V0ZTogeC5yb3V0ZSxcbiAgICAgICAgICAgICAgICBub0Z1bGxTeW5jOiB4Lm5vRnVsbFN5bmMsXG4gICAgICAgICAgICAgICAgc3VwcG9ydHNDaGFuZ2VzQWZ0ZXI6IHRoaXMuc291cmNlU3RhdGVzW2ldLnN1cHBvcnRzQ2hhbmdlc0FmdGVyLFxuICAgICAgICAgICAgICAgIGluaXRpYWxTY2FuQ29tcGxldGU6IHRoaXMuc291cmNlU3RhdGVzW2ldLnNjYW5Db21wbGV0ZSxcbiAgICAgICAgICAgICAgICBzY2FubmVkQ291bnQ6IHRoaXMuc291cmNlU3RhdGVzW2ldLnNjYW5uZWRDb3VudCxcbiAgICAgICAgICAgIH0pKS5maWx0ZXIoKHgsIGkpID0+IHRoaXMuaXNMaXZlKGkpKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKiogVGhlIGNoZWFwIGFsd2F5cy1jdXJyZW50IHRvdGFscyBwbHVzIGFueSBpbi1wcm9ncmVzcyBiYWNrZ3JvdW5kIHN5bmNocm9uaXphdGlvbi4gKi9cbiAgICBwdWJsaWMgZ2V0U3luY1Byb2dyZXNzKCk6IHtcbiAgICAgICAgaW5kZXg6IHsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyIH07XG4gICAgICAgIHNvdXJjZXM6IHsgZGVidWdOYW1lOiBzdHJpbmc7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9W107XG4gICAgICAgIHJlYWRlckRpc2tMaW1pdD86IG51bWJlcjtcbiAgICAgICAgc3luY2luZzogU3luY0FjdGl2aXR5W107XG4gICAgfSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpbmRleDogeyBmaWxlQ291bnQ6IHRoaXMuaW5kZXhGaWxlQ291bnQsIGJ5dGVDb3VudDogdGhpcy5pbmRleEJ5dGVDb3VudCB9LFxuICAgICAgICAgICAgc291cmNlczogdGhpcy5zb3VyY2VzLm1hcCgoeCwgaSkgPT4gKHtcbiAgICAgICAgICAgICAgICBkZWJ1Z05hbWU6IHguc291cmNlLmdldERlYnVnTmFtZSgpLFxuICAgICAgICAgICAgICAgIGZpbGVDb3VudDogdGhpcy5zb3VyY2VGaWxlQ291bnRzW2ldLFxuICAgICAgICAgICAgICAgIGJ5dGVDb3VudDogdGhpcy5zb3VyY2VCeXRlQ291bnRzW2ldLFxuICAgICAgICAgICAgfSkpLmZpbHRlcigoeCwgaSkgPT4gdGhpcy5pc0xpdmUoaSkpLFxuICAgICAgICAgICAgcmVhZGVyRGlza0xpbWl0OiB0aGlzLmNvbmZpZz8ucmVhZGVyRGlza0xpbWl0LFxuICAgICAgICAgICAgc3luY2luZzogWy4uLnRoaXMuc3luY0FjdGl2aXRpZXNdLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKiBXYWxrcyB0aGUgd2hvbGUgaW5kZXggZm9yIGV4YWN0IHRvdGFscyAtIG1vcmUgZXhwZW5zaXZlIHRoYW4gZ2V0U3luY1Byb2dyZXNzLCBidXQgaW1tdW5lIHRvIGFueSBkcmlmdCBpbiB0aGUgbWFpbnRhaW5lZCBjb3VudGVycyAoYW5kIGxvYWRzIHRoZSBpbmRleCBmaXJzdCwgc28gaXQncyBuZXZlciBjb2xkIHplcm9zKS4gKi9cbiAgICBwdWJsaWMgYXN5bmMgY29tcHV0ZUluZGV4VG90YWxzKCk6IFByb21pc2U8e1xuICAgICAgICBmaWxlQ291bnQ6IG51bWJlcjtcbiAgICAgICAgYnl0ZUNvdW50OiBudW1iZXI7XG4gICAgICAgIHNvdXJjZXM6IHsgZGVidWdOYW1lOiBzdHJpbmc7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9W107XG4gICAgfT4ge1xuICAgICAgICBhd2FpdCB0aGlzLmluaXQoKTtcbiAgICAgICAgbGV0IGZpbGVDb3VudCA9IDA7XG4gICAgICAgIGxldCBieXRlQ291bnQgPSAwO1xuICAgICAgICBsZXQgc291cmNlcyA9IHRoaXMuc291cmNlcy5tYXAoeCA9PiAoeyBkZWJ1Z05hbWU6IHguc291cmNlLmdldERlYnVnTmFtZSgpLCBmaWxlQ291bnQ6IDAsIGJ5dGVDb3VudDogMCB9KSk7XG4gICAgICAgIGZvciAobGV0IGVudHJ5IG9mIHRoaXMubWVtLnZhbHVlcygpKSB7XG4gICAgICAgICAgICBpZiAoZW50cnkuc2l6ZSA9PT0gMCkgY29udGludWU7XG4gICAgICAgICAgICBmaWxlQ291bnQrKztcbiAgICAgICAgICAgIGJ5dGVDb3VudCArPSBlbnRyeS5zaXplO1xuICAgICAgICAgICAgbGV0IHNsb3QgPSB0aGlzLnNsb3RGb3JTb3VyY2VzTGlzdEluZGV4KGVudHJ5LnNvdXJjZXNMaXN0SW5kZXgpO1xuICAgICAgICAgICAgaWYgKHNsb3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHNvdXJjZXNbc2xvdF0uZmlsZUNvdW50Kys7XG4gICAgICAgICAgICAgICAgc291cmNlc1tzbG90XS5ieXRlQ291bnQgKz0gZW50cnkuc2l6ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBmaWxlQ291bnQsIGJ5dGVDb3VudCwgc291cmNlczogc291cmNlcy5maWx0ZXIoKHgsIGkpID0+IHRoaXMuaXNMaXZlKGkpKSB9O1xuICAgIH1cblxuICAgIC8qKiBBcHBsaWVzIGEgY29uZmlnIGNoYW5nZSB0byB0aGUgUlVOTklORyBzdG9yZTogd2luZG93cy9yb3V0ZXMgdXBkYXRlIGluIHBsYWNlLCBuZXcgc291cmNlcyBhcmUgYWRkZWQgKHRoZWlyIHN5bmMgc3RhcnRzIGltbWVkaWF0ZWx5KSwgYW5kIHJlbW92ZWQgc291cmNlcycgc2xvdHMgZ28gZGVhZCAodGhlaXIgc2NhbnMgc3RvcCwgdGhlaXIgaW5kZXggZW50cmllcyBkcm9wKS4gVGhlIHN0b3JlIHN1cnZpdmVzIGV2ZXJ5IHJvdXRpbmUgY29uZmlnIGV2b2x1dGlvbiAtIGl0IGlzIG5ldmVyIGRlc3Ryb3llZCBmb3IgYSBzb3VyY2UtbGlzdCBjaGFuZ2UsIG9ubHkgZm9yIHN0cnVjdHVyYWwgZmxpcHMgaXQgY2Fubm90IGV4cHJlc3MgKHJhd0Rpc2spLiBQZW5kaW5nIGZhc3Qgd3JpdGVzIGFyZSByZS1jYXBwZWQgdG8gdGhlIG5ldyBmbHVzaCBkZWFkbGluZSAoZmx1c2hpbmcgaW1tZWRpYXRlbHkgd2hlbiBpdCBoYXMgYWxyZWFkeSBwYXNzZWQpLiAqL1xuICAgIHB1YmxpYyB1cGRhdGVTb3VyY2VzKHNwZWNzOiBCbG9iU291cmNlU3BlY1tdLCBlbnRyaWVzPzogSG9zdGVkQ29uZmlnW10pOiB2b2lkIHtcbiAgICAgICAgaWYgKCFzcGVjcy5sZW5ndGggfHwgc3BlY3NbMF0uaWRlbnRpdHkgIT09IFwiZGlza1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVwZGF0ZVNvdXJjZXMgZXhwZWN0cyB0aGUgZGlzayBzb3VyY2UgZmlyc3QgKGlkZW50aXR5IFwiZGlza1wiKSwgZ290ICR7SlNPTi5zdHJpbmdpZnkoc3BlY3MubWFwKHggPT4geC5pZGVudGl0eSkpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVudHJpZXMpIHtcbiAgICAgICAgICAgIHRoaXMuZW50cmllcyA9IGVudHJpZXM7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHNldFdpbmRvdyA9IChpOiBudW1iZXIsIHdpbmRvdzogW251bWJlciwgbnVtYmVyXSkgPT4ge1xuICAgICAgICAgICAgbGV0IG9sZCA9IHRoaXMuc291cmNlc1tpXS52YWxpZFdpbmRvdztcbiAgICAgICAgICAgIGlmIChvbGRbMF0gPT09IHdpbmRvd1swXSAmJiBvbGRbMV0gPT09IHdpbmRvd1sxXSkgcmV0dXJuO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFZhbGlkIHdpbmRvdyBjaGFuZ2VkIGZvciAke3RoaXMuc291cmNlc1tpXS5zb3VyY2UuZ2V0RGVidWdOYW1lKCl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6IFske29sZC5qb2luKFwiLCBcIil9XSAtPiBbJHt3aW5kb3cuam9pbihcIiwgXCIpfV1gKTtcbiAgICAgICAgICAgIHRoaXMuc291cmNlc1tpXS52YWxpZFdpbmRvdyA9IHdpbmRvdztcbiAgICAgICAgfTtcbiAgICAgICAgc2V0V2luZG93KDAsIHNwZWNzWzBdLnZhbGlkV2luZG93KTtcbiAgICAgICAgLy8gTGl2ZSBzbG90cyBwYWlyIHdpdGggc3BlY3MgYnkgaWRlbnRpdHksIGluIG9yZGVyICh0aGUgc2FtZSBlbmRwb2ludCBjYW4gYXBwZWFyIHNldmVyYWwgdGltZXMsIGUuZy4gb25lIGVudHJ5IHBlciB3aW5kb3cpXG4gICAgICAgIGxldCBsaXZlQnlJZGVudGl0eSA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXJbXT4oKTtcbiAgICAgICAgbGV0IG9yaWdpbmFsTGVuZ3RoID0gdGhpcy5zb3VyY2VzLmxlbmd0aDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBvcmlnaW5hbExlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNMaXZlKGkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGxldCBpZCA9IHRoaXMuc291cmNlc1tpXS5pZGVudGl0eTtcbiAgICAgICAgICAgIGlmIChpZCA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgICAgICAgIGxldCBsaXN0ID0gbGl2ZUJ5SWRlbnRpdHkuZ2V0KGlkKTtcbiAgICAgICAgICAgIGlmICghbGlzdCkge1xuICAgICAgICAgICAgICAgIGxpc3QgPSBbXTtcbiAgICAgICAgICAgICAgICBsaXZlQnlJZGVudGl0eS5zZXQoaWQsIGxpc3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGlzdC5wdXNoKGkpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBtYXRjaGVkID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgICAgIGZvciAobGV0IHNwZWMgb2Ygc3BlY3Muc2xpY2UoMSkpIHtcbiAgICAgICAgICAgIGxldCBzbG90ID0gbGl2ZUJ5SWRlbnRpdHkuZ2V0KHNwZWMuaWRlbnRpdHkpPy5zaGlmdCgpO1xuICAgICAgICAgICAgaWYgKHNsb3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG1hdGNoZWQuYWRkKHNsb3QpO1xuICAgICAgICAgICAgICAgIHNldFdpbmRvdyhzbG90LCBzcGVjLnZhbGlkV2luZG93KTtcbiAgICAgICAgICAgICAgICBsZXQgZXhpc3RpbmcgPSB0aGlzLnNvdXJjZXNbc2xvdF07XG4gICAgICAgICAgICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KGV4aXN0aW5nLnJvdXRlKSAhPT0gSlNPTi5zdHJpbmdpZnkoc3BlYy5yb3V0ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFJvdXRlIGNoYW5nZWQgZm9yICR7ZXhpc3Rpbmcuc291cmNlLmdldERlYnVnTmFtZSgpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiAke0pTT04uc3RyaW5naWZ5KGV4aXN0aW5nLnJvdXRlKX0gLT4gJHtKU09OLnN0cmluZ2lmeShzcGVjLnJvdXRlKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgZXhpc3Rpbmcucm91dGUgPSBzcGVjLnJvdXRlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBleGlzdGluZy5ub0Z1bGxTeW5jID0gc3BlYy5ub0Z1bGxTeW5jO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHNvdXJjZSA9IHNwZWMuY3JlYXRlKCk7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZXMucHVzaCh7IHNvdXJjZSwgdXJsOiBzcGVjLnVybCwgdmFsaWRXaW5kb3c6IHNwZWMudmFsaWRXaW5kb3csIHJvdXRlOiBzcGVjLnJvdXRlLCBub0Z1bGxTeW5jOiBzcGVjLm5vRnVsbFN5bmMsIGludGVybWVkaWF0ZTogc3BlYy5pbnRlcm1lZGlhdGUsIGlkZW50aXR5OiBzcGVjLmlkZW50aXR5IH0pO1xuICAgICAgICAgICAgdGhpcy5zb3VyY2VTdGF0ZXMucHVzaChuZXdTb3VyY2VTdGF0ZSgpKTtcbiAgICAgICAgICAgIHRoaXMuc291cmNlRmlsZUNvdW50cy5wdXNoKDApO1xuICAgICAgICAgICAgdGhpcy5zb3VyY2VCeXRlQ291bnRzLnB1c2goMCk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgQWRkZWQgc3luYyBzb3VyY2UgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSlgKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN5bmNTdGFydGVkKSB7XG4gICAgICAgICAgICAgICAgdm9pZCB0aGlzLnJ1blNvdXJjZVN5bmModGhpcy5zb3VyY2VzLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgb3JpZ2luYWxMZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzTGl2ZShpKSB8fCBtYXRjaGVkLmhhcyhpKSkgY29udGludWU7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZVNvdXJjZShpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZGVhZGxpbmUgPSB0aGlzLnNvdXJjZXNbMF0udmFsaWRXaW5kb3dbMV0gLSBXSU5ET1dfRU5EX0ZMVVNIX01BUkdJTjtcbiAgICAgICAgbGV0IHJlY2FwcGVkID0gMDtcbiAgICAgICAgZm9yIChsZXQgZW50cnkgb2YgdGhpcy5vdmVybGF5LnZhbHVlcygpKSB7XG4gICAgICAgICAgICBpZiAoZW50cnkuZmx1c2hBdCA8PSBkZWFkbGluZSkgY29udGludWU7XG4gICAgICAgICAgICBlbnRyeS5mbHVzaEF0ID0gZGVhZGxpbmU7XG4gICAgICAgICAgICByZWNhcHBlZCsrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZWNhcHBlZCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFJlLWNhcHBlZCAke3JlY2FwcGVkfSBwZW5kaW5nIGZhc3Qgd3JpdGVzIHRvIHRoZSBuZXcgZmx1c2ggZGVhZGxpbmUgJHtuZXcgRGF0ZShkZWFkbGluZSkudG9JU09TdHJpbmcoKX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KWApO1xuICAgICAgICAgICAgaWYgKGRlYWRsaW5lIDw9IERhdGUubm93KCkpIHtcbiAgICAgICAgICAgICAgICB2b2lkIHRoaXMuZmx1c2hPdmVybGF5KCkuY2F0Y2goKGU6IEVycm9yKSA9PiBjb25zb2xlLmVycm9yKGBGbHVzaGluZyBmYXN0IHdyaXRlcyBhZnRlciBhIHZhbGlkIHdpbmRvdyBjaGFuZ2UgZmFpbGVkIChzdG9yZSAke3RoaXMuZm9sZGVyfSk6ICR7ZS5zdGFjayA/PyBlfWApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBSZXNjYW5zIG91ciBvd24gZGlzaydzIG1ldGFkYXRhIGludG8gdGhlIGluZGV4IC0gdXNlZCBhcm91bmQgdmFsaWQgd2luZG93IGhhbmRvZmZzLCB3aGVyZSBhbm90aGVyIHByb2Nlc3Mgd3JvdGUgZmlsZXMgdG8gdGhlIHNoYXJlZCBmb2xkZXIgdGhhdCBvdXIgaW5kZXggaGFzbid0IHNlZW4uICovXG4gICAgcHVibGljIGFzeW5jIHJlc2NhbkJhc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBhd2FpdCB0aGlzLnNjYW5Tb3VyY2UoMCk7XG4gICAgfVxuXG4gICAgLyoqIEEgYm91bmRhcnkgc2NhbiBvZiB0aGUgbm9kZSB0aGF0IG93bmVkIChwYXJ0IG9mKSBvdXIgcm91dGUgaW4gdGhlIHZhbGlkIHdpbmRvdyBiZWZvcmUgb3Vycywgd2hlbiB0aGF0IG5vZGUgaXMgZGlmZmVyZW50IHN0b3JhZ2UgKGEgZGlzayByZXNjYW4gY2FuJ3Qgc2VlIGl0cyB3cml0ZXMpOiBqdXN0IGl0cyBjaGFuZ2VzIHNpbmNlIHRoZSBib3VuZGFyeSBuZWlnaGJvcmhvb2QsIHdpdGggbWF0Y2hpbmcgdmFsdWVzIHB1bGxlZCBvbnRvIG91ciBvd24gZGlzay4gKi9cbiAgICBwdWJsaWMgYXN5bmMgYm91bmRhcnlTY2FuUmVtb3RlKHNvdXJjZTogSUFyY2hpdmVzLCBjb25maWc6IHsgc2luY2U6IG51bWJlcjsgcm91dGU/OiBbbnVtYmVyLCBudW1iZXJdIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbml0KCk7XG4gICAgICAgIGxldCBzY2FuU3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICBjb25zb2xlLmxvZyhgQm91bmRhcnkgc2NhbiBvZiAke3NvdXJjZS5nZXREZWJ1Z05hbWUoKX0gc3RhcnRpbmc6IGNoYW5nZXMgc2luY2UgJHtuZXcgRGF0ZShjb25maWcuc2luY2UpLnRvSVNPU3RyaW5nKCl9LCByb3V0ZSAke0pTT04uc3RyaW5naWZ5KGNvbmZpZy5yb3V0ZSB8fCBGVUxMX1JPVVRFKX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KWApO1xuICAgICAgICBsZXQgY2hhbmdlcyA9IGF3YWl0IHNvdXJjZS5nZXRDaGFuZ2VzQWZ0ZXIyKHsgdGltZTogY29uZmlnLnNpbmNlLCByb3V0ZXM6IGNvbmZpZy5yb3V0ZSAmJiBbY29uZmlnLnJvdXRlXSB8fCB1bmRlZmluZWQgfSk7XG4gICAgICAgIGxldCB0YWxseSA9IG5ld1NjYW5UYWxseSgpO1xuICAgICAgICBmb3IgKGxldCBmaWxlIG9mIGNoYW5nZXMpIHtcbiAgICAgICAgICAgIGlmIChmaWxlLnBhdGggPT09IFJPVVRJTkdfRklMRSkge1xuICAgICAgICAgICAgICAgIHRhbGx5LmZpbHRlcmVkKys7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgb3ZlcmxheUVudHJ5ID0gdGhpcy5vdmVybGF5LmdldChmaWxlLnBhdGgpO1xuICAgICAgICAgICAgbGV0IGVudHJ5ID0gdGhpcy5tZW0uZ2V0KGZpbGUucGF0aCk7XG4gICAgICAgICAgICBsZXQgY3VycmVudFRpbWUgPSBvdmVybGF5RW50cnkgJiYgb3ZlcmxheUVudHJ5LnQgfHwgZW50cnkgJiYgZW50cnkud3JpdGVUaW1lIHx8IDA7XG4gICAgICAgICAgICBpZiAoZmlsZS5jcmVhdGVUaW1lIDw9IGN1cnJlbnRUaW1lKSB7XG4gICAgICAgICAgICAgICAgdGFsbHkudW5jaGFuZ2VkKys7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZmlsZS5zaXplID09PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gQSB0b21ic3RvbmUgc3RvcmVzIG5vdGhpbmcgb24gb3VyIG93biBzb3VyY2UgLSB0aGUgaW5kZXggZW50cnkgYWxvbmUgcmVjb3JkcyBpdFxuICAgICAgICAgICAgICAgIHRoaXMuc2V0SW5kZXhFbnRyeShmaWxlLnBhdGgsIHsgd3JpdGVUaW1lOiBmaWxlLmNyZWF0ZVRpbWUsIHNpemU6IDAsIHNvdXJjZXNMaXN0SW5kZXg6IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdCgwKSB9KTtcbiAgICAgICAgICAgICAgICB0YWxseS50b21ic3RvbmUrKztcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBjb3BpZWQgPSBhd2FpdCBjb3B5QXJjaGl2ZUZpbGUoeyBmcm9tOiBzb3VyY2UsIHRvOiB0aGlzLnNvdXJjZXNbMF0uc291cmNlLCBwYXRoOiBmaWxlLnBhdGgsIHNpemU6IGZpbGUuc2l6ZSwgd3JpdGVUaW1lOiBmaWxlLmNyZWF0ZVRpbWUsIGZvcmNlU2V0SW1tdXRhYmxlOiB0cnVlLCBub0NoZWNrczogdHJ1ZSwgaW50ZXJuYWw6IHRydWUgfSk7XG4gICAgICAgICAgICBpZiAoIWNvcGllZCkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoY29waWVkLnNpemUgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldEluZGV4RW50cnkoZmlsZS5wYXRoLCB7IHdyaXRlVGltZTogY29waWVkLndyaXRlVGltZSwgc2l6ZTogMCwgc291cmNlc0xpc3RJbmRleDogdGhpcy5zb3VyY2VzTGlzdEluZGV4T2ZTbG90KDApIH0pO1xuICAgICAgICAgICAgICAgIHRhbGx5LnRvbWJzdG9uZSsrO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRJbmRleEVudHJ5KGZpbGUucGF0aCwgeyB3cml0ZVRpbWU6IGNvcGllZC53cml0ZVRpbWUsIHNpemU6IGNvcGllZC5zaXplLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCkgfSk7XG4gICAgICAgICAgICBpZiAoZW50cnkgfHwgb3ZlcmxheUVudHJ5KSB7XG4gICAgICAgICAgICAgICAgdGFsbHkudXBkYXRlZCsrO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0YWxseS5uZXcrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZyhgQm91bmRhcnkgc2NhbiBvZiAke3NvdXJjZS5nZXREZWJ1Z05hbWUoKX0gZmluaXNoZWQgaW4gJHtNYXRoLnJvdW5kKChEYXRlLm5vdygpIC0gc2NhblN0YXJ0KSAvIDEwMDApfXMgKHN0b3JlICR7dGhpcy5mb2xkZXJ9KTogJHtjaGFuZ2VzLmxlbmd0aH0gY2hhbmdlczogJHtmb3JtYXRTY2FuVGFsbHkodGFsbHksIGNoYW5nZXMubGVuZ3RoKX1gKTtcbiAgICB9XG5cbiAgICAvLyBMYXJnZSB1cGxvYWRzIHN0cmVhbSBvbnRvIHRoZSBsb2NhbCBkaXNrIHNvdXJjZSBkaXJlY3RseSAodGhleSBtYXkgbm90IGZpdCBpbiBtZW1vcnkpXG4gICAgcHVibGljIGFzeW5jIHN0YXJ0TGFyZ2VVcGxvYWQoY29uZmlnPzogeyBwYXRoPzogc3RyaW5nOyBsYXN0TW9kaWZpZWQ/OiBudW1iZXIgfSk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBpZiAoY29uZmlnPy5wYXRoKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmFzc2VydE11dGFibGUoY29uZmlnLnBhdGgsIGNvbmZpZy5sYXN0TW9kaWZpZWQgfHwgRGF0ZS5ub3coKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2V0RGlza1NvdXJjZSgpLmRpc2suc3RhcnRMYXJnZVVwbG9hZCgpO1xuICAgIH1cbiAgICBwdWJsaWMgYXN5bmMgYXBwZW5kTGFyZ2VVcGxvYWQoY29uZmlnOiB7IGlkOiBzdHJpbmc7IGRhdGE6IEJ1ZmZlciB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuZ2V0RGlza1NvdXJjZSgpLmRpc2suYXBwZW5kTGFyZ2VVcGxvYWQoY29uZmlnLmlkLCBjb25maWcuZGF0YSk7XG4gICAgfVxuICAgIHB1YmxpYyBhc3luYyBmaW5pc2hMYXJnZVVwbG9hZChjb25maWc6IHsgaWQ6IHN0cmluZzsgcGF0aDogc3RyaW5nOyBsYXN0TW9kaWZpZWQ/OiBudW1iZXIgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBsZXQgeyBkaXNrLCBzb3VyY2VJbmRleCB9ID0gdGhpcy5nZXREaXNrU291cmNlKCk7XG4gICAgICAgIGF3YWl0IGRpc2suZmluaXNoTGFyZ2VVcGxvYWQoY29uZmlnLmlkLCBjb25maWcucGF0aCwgY29uZmlnLmxhc3RNb2RpZmllZCk7XG4gICAgICAgIHRoaXMub3ZlcmxheS5kZWxldGUoY29uZmlnLnBhdGgpO1xuICAgICAgICAvLyBpbmNsdWRlVG9tYnN0b25lczogYSB6ZXJvLWJ5dGUgdXBsb2FkIGlzIHN0aWxsIGEgcmVhbCBmaWxlIHdob3NlIGluZGV4IGVudHJ5IG11c3QgYmUgd3JpdHRlblxuICAgICAgICBsZXQgaW5mbyA9IGF3YWl0IGRpc2suZ2V0SW5mbyhjb25maWcucGF0aCwgeyBpbmNsdWRlVG9tYnN0b25lczogdHJ1ZSB9KTtcbiAgICAgICAgaWYgKGluZm8pIHtcbiAgICAgICAgICAgIHRoaXMuc2V0SW5kZXhFbnRyeShjb25maWcucGF0aCwgeyB3cml0ZVRpbWU6IGluZm8ud3JpdGVUaW1lLCBzaXplOiBpbmZvLnNpemUsIHNvdXJjZXNMaXN0SW5kZXg6IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdChzb3VyY2VJbmRleCkgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHVibGljIGFzeW5jIGNhbmNlbExhcmdlVXBsb2FkKGNvbmZpZzogeyBpZDogc3RyaW5nIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXREaXNrU291cmNlKCkuZGlzay5jYW5jZWxMYXJnZVVwbG9hZChjb25maWcuaWQpO1xuICAgIH1cblxuICAgIC8vICNlbmRyZWdpb25cblxuICAgIC8vICNyZWdpb24gSW50ZXJuYWxzXG5cbiAgICBwcml2YXRlIHN0b3BwZWQgPSB7IHN0b3A6IGZhbHNlIH07XG5cbiAgICAvLyBUaGUgaW5kZXgncyBCdWxrRGF0YWJhc2UyIGZpbGVzIGxpdmUgdW5kZXIgPGZvbGRlcj4vaW5kZXguIFwiYmxvYkluZGV4MlwiOiB0aGUgXCJibG9iSW5kZXhcIiBnZW5lcmF0aW9uIHBlcnNpc3RlZCBzb3VyY2VzLWFycmF5IHBvc2l0aW9ucyBhcyB0aGUgaG9sZGluZyBzb3VyY2UsIHdoaWNoIGFyZSBub3Qgc3RhYmxlIGFjcm9zcyBydW5zIC0gaXRzIGVudHJpZXMgYXJlIHVudXNhYmxlLCBzbyBpdCBpcyBzaW1wbHkgbmV2ZXIgcmVhZCBhZ2Fpbi5cbiAgICBwcml2YXRlIGluZGV4ID0gbmV3IEJ1bGtEYXRhYmFzZUJhc2U8QmxvYkluZGV4RW50cnk+KFwiYmxvYkluZGV4MlwiLCBub29wUmVhY3RpdmVEZXBzLCBhc3luYyAocDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGxldCBiYXNlOiBEaXJlY3RvcnlXcmFwcGVyID0gbmV3IE5vZGVKU0RpcmVjdG9yeUhhbmRsZVdyYXBwZXIocGF0aC5qb2luKHRoaXMuZm9sZGVyLCBcImluZGV4XCIpKTtcbiAgICAgICAgZm9yIChsZXQgcGFydCBvZiBwLnNwbGl0KFwiL1wiKSkge1xuICAgICAgICAgICAgaWYgKHBhcnQpIGJhc2UgPSBhd2FpdCBiYXNlLmdldERpcmVjdG9yeUhhbmRsZShwYXJ0LCB7IGNyZWF0ZTogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gd3JhcEhhbmRsZShiYXNlKTtcbiAgICB9KTtcbiAgICAvLyBUaGUgaW4tbWVtb3J5IGNvcHkgb2YgdGhlIGluZGV4LiBBbGwgcmVhZHMgYXJlIHNlcnZlZCBmcm9tIGl0OyBjaGFuZ2VzIGFyZSBidWZmZXJlZCBpbiBkaXJ0eSBhbmQgZmx1c2hlZCB0byB0aGUgQnVsa0RhdGFiYXNlMiBpbiBiYXRjaGVzICh1bmRlZmluZWQgPSBkZWxldGUpLlxuICAgIHByaXZhdGUgbWVtID0gbmV3IE1hcDxzdHJpbmcsIEluZGV4RW50cnk+KCk7XG4gICAgLy8gTGl2ZSB0b3RhbHMgb3ZlciBtZW0gKHRvbWJzdG9uZXMgZXhjbHVkZWQpLCBhZGp1c3RlZCBvbiBldmVyeSBtdXRhdGlvbiBhbmQgcmVjb21wdXRlZCBvbiBsb2FkIC0gc28gYW55IGRyaWZ0IGhlYWxzIG9uIHJlc3RhcnQuIGNvbXB1dGVJbmRleFRvdGFscyBnaXZlcyB0aGUgd2Fsay10aGUtaW5kZXggdHJ1dGguXG4gICAgcHJpdmF0ZSBpbmRleEZpbGVDb3VudCA9IDA7XG4gICAgcHJpdmF0ZSBpbmRleEJ5dGVDb3VudCA9IDA7XG4gICAgLy8gVGhlIHNhbWUgdG90YWxzIHBlciBob2xkaW5nIHNvdXJjZSAoaW5kZXggMCA9IG91ciBkaXNrLCB3aGljaCByZWFkZXJEaXNrTGltaXQgYm91bmRzKVxuICAgIHByaXZhdGUgc291cmNlRmlsZUNvdW50cyA9IHRoaXMuc291cmNlcy5tYXAoKCkgPT4gMCk7XG4gICAgcHJpdmF0ZSBzb3VyY2VCeXRlQ291bnRzID0gdGhpcy5zb3VyY2VzLm1hcCgoKSA9PiAwKTtcbiAgICAvLyBCYWNrZ3JvdW5kIHNjYW5zIC8gZnVsbCBzeW5jcyBjdXJyZW50bHkgaW4gcHJvZ3Jlc3MgKGEgU2V0IC0gb25lIHNvdXJjZSBjYW4gaGF2ZSBhIGNoYW5nZSBwb2xsJ3MgZnVsbCBzeW5jIGFuZCBhIHJlc2NhbiBvdmVybGFwcGluZylcbiAgICBwcml2YXRlIHN5bmNBY3Rpdml0aWVzID0gbmV3IFNldDxTeW5jQWN0aXZpdHk+KCk7XG4gICAgcHJpdmF0ZSBkaXJ0eSA9IG5ldyBNYXA8c3RyaW5nLCBJbmRleEVudHJ5IHwgdW5kZWZpbmVkPigpO1xuICAgIHByaXZhdGUgb3ZlcmxheSA9IG5ldyBNYXA8c3RyaW5nLCBPdmVybGF5RW50cnk+KCk7XG4gICAgcHJpdmF0ZSBzb3VyY2VTdGF0ZXMgPSB0aGlzLnNvdXJjZXMubWFwKCgpID0+IG5ld1NvdXJjZVN0YXRlKCkpO1xuICAgIHByaXZhdGUgc3luY1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIGVudHJpZXMgPSB0aGlzLmNvbmZpZz8uZW50cmllcyB8fCBbXTtcbiAgICAvLyBUaGUgcGVyc2lzdGVudCBpZGVudGl0aWVzIGJlaGluZCBJbmRleEVudHJ5LnNvdXJjZXNMaXN0SW5kZXggKHNlZSBTb3VyY2VzTGlzdClcbiAgICBwcml2YXRlIHNvdXJjZXNMaXN0ID0gbmV3IFNvdXJjZXNMaXN0KHBhdGguam9pbih0aGlzLmZvbGRlciwgXCJpbmRleFwiLCBcInNvdXJjZXNMaXN0LnR4dFwiKSk7XG4gICAgLy8gUGVyIHNsb3Q6IHRoZSBwZXJzaXN0ZW50IHNvdXJjZXNMaXN0SW5kZXggb2YgdGhhdCBzbG90J3MgVVJMLCBmaWxsZWQgYnkgcmVnaXN0ZXJTbG90IGJlZm9yZSB0aGUgc2xvdCdzIHN5bmMgcnVuc1xuICAgIHByaXZhdGUgc2xvdFNvdXJjZXNMaXN0SW5kZXhlczogbnVtYmVyW10gPSBbXTtcbiAgICBwcml2YXRlIHNsb3RSZWdpc3RyYXRpb25zOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcblxuICAgIHByaXZhdGUgaXNMaXZlKHNvdXJjZUluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5zb3VyY2VzW3NvdXJjZUluZGV4XSAmJiAhdGhpcy5zb3VyY2VTdGF0ZXNbc291cmNlSW5kZXhdLmRlYWQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWdpc3RlclNsb3Qoc2xvdDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCBleGlzdGluZyA9IHRoaXMuc2xvdFJlZ2lzdHJhdGlvbnNbc2xvdF07XG4gICAgICAgIGlmIChleGlzdGluZykgcmV0dXJuIGV4aXN0aW5nO1xuICAgICAgICBsZXQgcmVnaXN0cmF0aW9uID0gdGhpcy5zb3VyY2VzTGlzdC5lbnN1cmUodGhpcy5zb3VyY2VzW3Nsb3RdLnVybCkudGhlbihpbmRleCA9PiB7XG4gICAgICAgICAgICB0aGlzLnNsb3RTb3VyY2VzTGlzdEluZGV4ZXNbc2xvdF0gPSBpbmRleDtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2xvdFJlZ2lzdHJhdGlvbnNbc2xvdF0gPSByZWdpc3RyYXRpb247XG4gICAgICAgIHJldHVybiByZWdpc3RyYXRpb247XG4gICAgfVxuXG4gICAgLy8gVGhlIHBlcnNpc3RlbnQgc291cmNlc0xpc3RJbmRleCBvZiBhIHNsb3QgLSBvbmx5IHZhbGlkIG9uY2UgdGhlIHNsb3QncyByZWdpc3RyYXRpb24gcmVzb2x2ZWQgKGluaXQgYW5kIHJ1blNvdXJjZVN5bmMgZ3VhcmFudGVlIHRoYXQgYmVmb3JlIGFueSBpbmRleGluZyBoYXBwZW5zKVxuICAgIHByaXZhdGUgc291cmNlc0xpc3RJbmRleE9mU2xvdChzbG90OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBsZXQgaW5kZXggPSB0aGlzLnNsb3RTb3VyY2VzTGlzdEluZGV4ZXNbc2xvdF07XG4gICAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNvdXJjZSBzbG90ICR7c2xvdH0gKCR7dGhpcy5zb3VyY2VzW3Nsb3RdPy51cmx9KSBoYXMgbm8gcmVnaXN0ZXJlZCBzb3VyY2VzTGlzdEluZGV4IHlldCAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cblxuICAgIC8vIFRoZSBsaXZlIHNsb3QgY3VycmVudGx5IHNlcnZpbmcgYSBwZXJzaXN0ZW50IHNvdXJjZXNMaXN0SW5kZXgsIG9yIHVuZGVmaW5lZCB3aGVuIG5vIGNvbmZpZ3VyZWQgc291cmNlIGhhcyB0aGF0IFVSTCBhbnltb3JlLiBMaW5lYXIsIGJ1dCB0aGUgc291cmNlcyBsaXN0IGlzIHRpbnkgYW5kIHRoaXMgaXMgYWx3YXlzIGN1cnJlbnQgKHNsb3RzIGR5aW5nLCBvciBzZXZlcmFsIHNsb3RzIHNoYXJpbmcgb25lIFVSTCBhY3Jvc3MgdmFsaWQgd2luZG93cywgbmVlZCBubyBib29ra2VlcGluZykuXG4gICAgcHJpdmF0ZSBzbG90Rm9yU291cmNlc0xpc3RJbmRleChzb3VyY2VzTGlzdEluZGV4OiBudW1iZXIpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuc2xvdFNvdXJjZXNMaXN0SW5kZXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2xvdFNvdXJjZXNMaXN0SW5kZXhlc1tpXSA9PT0gc291cmNlc0xpc3RJbmRleCAmJiB0aGlzLmlzTGl2ZShpKSkgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyBUaGUgSUFyY2hpdmVzIGN1cnJlbnRseSBob2xkaW5nIGFuIGVudHJ5J3MgYnl0ZXM6IHRoZSBsaXZlIHNsb3Qgd2hlbiB0aGUgaG9sZGVyIGlzIHN0aWxsIGNvbmZpZ3VyZWQsIG90aGVyd2lzZSByZXNvbHZlZCAoY2FjaGVkKSBzdHJhaWdodCBmcm9tIGl0cyBwZXJzaXN0ZWQgVVJMIC0gd2luZG93cy9yb3V0ZXMgZGVjaWRlIHdoZW4gYSBzb3VyY2UgaXMgc2Nhbm5lZCBvciB3cml0dGVuLCBidXQgZm9yIHJlYWRpbmcgYnl0ZXMgd2Uga25vdyBpdCBob2xkcywgdGhlIFVSTCBhbG9uZSBpcyBlbm91Z2hcbiAgICBwcml2YXRlIGFzeW5jIGdldEVudHJ5SG9sZGVyKGVudHJ5OiBJbmRleEVudHJ5KTogUHJvbWlzZTxJQXJjaGl2ZXMgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgbGV0IHNsb3QgPSB0aGlzLnNsb3RGb3JTb3VyY2VzTGlzdEluZGV4KGVudHJ5LnNvdXJjZXNMaXN0SW5kZXgpO1xuICAgICAgICBpZiAoc2xvdCAhPT0gdW5kZWZpbmVkKSByZXR1cm4gdGhpcy5zb3VyY2VzW3Nsb3RdLnNvdXJjZTtcbiAgICAgICAgbGV0IHVybCA9IHRoaXMuc291cmNlc0xpc3QuZ2V0VXJsKGVudHJ5LnNvdXJjZXNMaXN0SW5kZXgpIHx8IGF3YWl0IHRoaXMuc291cmNlc0xpc3QuZ2V0VXJsUmVsb2FkaW5nKGVudHJ5LnNvdXJjZXNMaXN0SW5kZXgpO1xuICAgICAgICBpZiAoIXVybCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnPy5yZXNvbHZlU291cmNlVXJsPy4odXJsKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGxvYWRJbmRleCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IFt3cml0ZVRpbWVzLCBzaXplcywgc291cmNlc0xpc3RJbmRleGVzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIHRoaXMuaW5kZXguZ2V0Q29sdW1uKFwid3JpdGVUaW1lXCIpLFxuICAgICAgICAgICAgdGhpcy5pbmRleC5nZXRDb2x1bW4oXCJzaXplXCIpLFxuICAgICAgICAgICAgdGhpcy5pbmRleC5nZXRDb2x1bW4oXCJzb3VyY2VzTGlzdEluZGV4XCIpLFxuICAgICAgICBdKTtcbiAgICAgICAgbGV0IHNpemVNYXAgPSBuZXcgTWFwKHNpemVzLm1hcCh4ID0+IFt4LmtleSwgeC52YWx1ZV0pKTtcbiAgICAgICAgbGV0IHNvdXJjZXNMaXN0SW5kZXhNYXAgPSBuZXcgTWFwKHNvdXJjZXNMaXN0SW5kZXhlcy5tYXAoeCA9PiBbeC5rZXksIHgudmFsdWVdKSk7XG4gICAgICAgIGZvciAobGV0IGVudHJ5IG9mIHdyaXRlVGltZXMpIHtcbiAgICAgICAgICAgIGxldCBzaXplID0gc2l6ZU1hcC5nZXQoZW50cnkua2V5KTtcbiAgICAgICAgICAgIGxldCBzb3VyY2VzTGlzdEluZGV4ID0gc291cmNlc0xpc3RJbmRleE1hcC5nZXQoZW50cnkua2V5KTtcbiAgICAgICAgICAgIC8vIEV4cGxpY2l0IGNoZWNrcywgYXMgMCBpcyBhIHZhbGlkIHNpemUgYW5kIGEgdmFsaWQgc291cmNlc0xpc3RJbmRleFxuICAgICAgICAgICAgaWYgKHNpemUgPT09IHVuZGVmaW5lZCB8fCBzb3VyY2VzTGlzdEluZGV4ID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgICAgICAgLy8gVGhlIHJvdXRpbmcgY29uZmlnIGlzIG9ubHkgZXZlciByZWFkIG9mZiBvdXIgb3duIGRpc2sgKHNlZSB1cGRhdGVTY2FuSW5kZXgpLCBhbmQgYSBsb2FkZWQgYnVja2V0IGFsd2F5cyBoYXMgaXQgdGhlcmUgLSBhIHBlcnNpc3RlZCBlbnRyeSBwb2ludGluZyBlbHNld2hlcmUgaXMgc3RhbGVcbiAgICAgICAgICAgIGlmIChlbnRyeS5rZXkgPT09IFJPVVRJTkdfRklMRSkge1xuICAgICAgICAgICAgICAgIHNvdXJjZXNMaXN0SW5kZXggPSB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgZnVsbDogSW5kZXhFbnRyeSA9IHsgd3JpdGVUaW1lOiBlbnRyeS52YWx1ZSwgc2l6ZSwgc291cmNlc0xpc3RJbmRleCwgY2hhbmdlZEF0OiBlbnRyeS50aW1lLCBsYXN0QWNjZXNzOiBlbnRyeS50aW1lIH07XG4gICAgICAgICAgICB0aGlzLm1lbS5zZXQoZW50cnkua2V5LCBmdWxsKTtcbiAgICAgICAgICAgIHRoaXMuY291bnRFbnRyeShmdWxsLCAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY291bnRFbnRyeShlbnRyeTogSW5kZXhFbnRyeSB8IHVuZGVmaW5lZCwgZGlyZWN0aW9uOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgaWYgKCFlbnRyeSB8fCBlbnRyeS5zaXplID09PSAwKSByZXR1cm47XG4gICAgICAgIHRoaXMuaW5kZXhGaWxlQ291bnQgKz0gZGlyZWN0aW9uO1xuICAgICAgICB0aGlzLmluZGV4Qnl0ZUNvdW50ICs9IGVudHJ5LnNpemUgKiBkaXJlY3Rpb247XG4gICAgICAgIC8vIEVudHJpZXMgY2FuIHJlZmVyZW5jZSBhIHNvdXJjZSBubyBsb25nZXIgY29uZmlndXJlZCAocmVhZGFibGUgdmlhIGdldEVudHJ5SG9sZGVyLCBidXQgd2l0aCBubyBzbG90IHRvIGNvdW50IHVuZGVyKVxuICAgICAgICBsZXQgc2xvdCA9IHRoaXMuc2xvdEZvclNvdXJjZXNMaXN0SW5kZXgoZW50cnkuc291cmNlc0xpc3RJbmRleCk7XG4gICAgICAgIGlmIChzbG90ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuc291cmNlRmlsZUNvdW50c1tzbG90XSArPSBkaXJlY3Rpb247XG4gICAgICAgICAgICB0aGlzLnNvdXJjZUJ5dGVDb3VudHNbc2xvdF0gKz0gZW50cnkuc2l6ZSAqIGRpcmVjdGlvbjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2V0SW5kZXhFbnRyeShrZXk6IHN0cmluZywgZW50cnk6IHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlcjsgc291cmNlc0xpc3RJbmRleDogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICAgICAgbGV0IGZ1bGw6IEluZGV4RW50cnkgPSB7IC4uLmVudHJ5LCBjaGFuZ2VkQXQ6IERhdGUubm93KCksIGxhc3RBY2Nlc3M6IERhdGUubm93KCkgfTtcbiAgICAgICAgdGhpcy5jb3VudEVudHJ5KHRoaXMubWVtLmdldChrZXkpLCAtMSk7XG4gICAgICAgIHRoaXMuY291bnRFbnRyeShmdWxsLCAxKTtcbiAgICAgICAgdGhpcy5tZW0uc2V0KGtleSwgZnVsbCk7XG4gICAgICAgIHRoaXMuZGlydHkuc2V0KGtleSwgZnVsbCk7XG4gICAgICAgIHRoaXMuY29uZmlnPy5vbkluZGV4Q2hhbmdlZD8uKGtleSk7XG4gICAgfVxuICAgIHByaXZhdGUgZGVsZXRlSW5kZXhFbnRyeShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBsZXQgZXhpc3RpbmcgPSB0aGlzLm1lbS5nZXQoa2V5KTtcbiAgICAgICAgaWYgKCFleGlzdGluZykgcmV0dXJuO1xuICAgICAgICB0aGlzLmNvdW50RW50cnkoZXhpc3RpbmcsIC0xKTtcbiAgICAgICAgdGhpcy5tZW0uZGVsZXRlKGtleSk7XG4gICAgICAgIHRoaXMuZGlydHkuc2V0KGtleSwgdW5kZWZpbmVkKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgc2xvdCBzdGF5cyBpbiB0aGUgYXJyYXlzIGZvcmV2ZXIgKGluZGV4IGVudHJpZXMgcmVmZXJlbmNlIHNvdXJjZXMgYnkgc2xvdCBudW1iZXIpOyBpdCBqdXN0IGdvZXMgZGVhZCAtIGxvb3BzIHN0b3AsIGFuZCBpdHMgaW5kZXggZW50cmllcyBkcm9wIChvdGhlciBzb3VyY2VzJyBzY2FucyByZS1maW5kIGFueSBjb3B5IHRoYXQncyBzdGlsbCByZWFjaGFibGUgdGhyb3VnaCB0aGUgbmV3IGNvbmZpZylcbiAgICBwcml2YXRlIHJlbW92ZVNvdXJjZShzb3VyY2VJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuc291cmNlU3RhdGVzW3NvdXJjZUluZGV4XTtcbiAgICAgICAgbGV0IHNvdXJjZSA9IHRoaXMuc291cmNlc1tzb3VyY2VJbmRleF0uc291cmNlO1xuICAgICAgICBzdGF0ZS5kZWFkID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUuc3RvcHBlZC5zdG9wID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUuc2NhbkNvbXBsZXRlID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUuaW5pdGlhbFNjYW4ucmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICBsZXQgc291cmNlc0xpc3RJbmRleCA9IHRoaXMuc2xvdFNvdXJjZXNMaXN0SW5kZXhlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIC8vIFRoZSBzYW1lIFVSTCBjYW4gYmUgYW5vdGhlciBsaXZlIHNsb3QgKG9uZSBlbnRyeSBwZXIgdmFsaWQgd2luZG93KSAtIHRoZSBlbmRwb2ludCBpcyBzdGlsbCBjb25maWd1cmVkLCBzbyBpdHMgZW50cmllcyBzdGF5XG4gICAgICAgIGlmIChzb3VyY2VzTGlzdEluZGV4ICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zbG90Rm9yU291cmNlc0xpc3RJbmRleChzb3VyY2VzTGlzdEluZGV4KSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsZXQgZHJvcHBlZCA9IDA7XG4gICAgICAgICAgICBmb3IgKGxldCBba2V5LCBlbnRyeV0gb2YgdGhpcy5tZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoZW50cnkuc291cmNlc0xpc3RJbmRleCAhPT0gc291cmNlc0xpc3RJbmRleCkgY29udGludWU7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVJbmRleEVudHJ5KGtleSk7XG4gICAgICAgICAgICAgICAgZHJvcHBlZCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5sb2coYFJlbW92ZWQgc3luYyBzb3VyY2UgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6IGl0cyBzY2FucyBhcmUgc3RvcHBlZCBhbmQgJHtkcm9wcGVkfSBpbmRleCBlbnRyaWVzIGl0IGhlbGQgd2VyZSBkcm9wcGVkYCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc29sZS5sb2coYFJlbW92ZWQgc3luYyBzb3VyY2UgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6IGl0cyBzY2FucyBhcmUgc3RvcHBlZCAoaXRzIFVSTCBpcyBzdGlsbCBzZXJ2ZWQgYnkgYW5vdGhlciBzbG90LCBzbyBpdHMgaW5kZXggZW50cmllcyBzdGF5KWApO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZmx1c2hJbmRleCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKCF0aGlzLmRpcnR5LnNpemUpIHJldHVybjtcbiAgICAgICAgbGV0IGRpcnR5ID0gdGhpcy5kaXJ0eTtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IG5ldyBNYXAoKTtcbiAgICAgICAgbGV0IHdyaXRlczogQmxvYkluZGV4RW50cnlbXSA9IFtdO1xuICAgICAgICBsZXQgZGVsZXRlczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgW2tleSwgZW50cnldIG9mIGRpcnR5KSB7XG4gICAgICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICAgICAgICB3cml0ZXMucHVzaCh7IGtleSwgd3JpdGVUaW1lOiBlbnRyeS53cml0ZVRpbWUsIHNpemU6IGVudHJ5LnNpemUsIHNvdXJjZXNMaXN0SW5kZXg6IGVudHJ5LnNvdXJjZXNMaXN0SW5kZXggfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRlbGV0ZXMucHVzaChrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh3cml0ZXMubGVuZ3RoKSBhd2FpdCB0aGlzLmluZGV4LndyaXRlQmF0Y2god3JpdGVzKTtcbiAgICAgICAgaWYgKGRlbGV0ZXMubGVuZ3RoKSBhd2FpdCB0aGlzLmluZGV4LmRlbGV0ZUJhdGNoKGRlbGV0ZXMpO1xuICAgIH1cblxuICAgIC8vIOKUgOKUgCB2YWxpZGF0aW9uIChmcm9tIHRoaXMgc3RvcmUncyBvd24gcm91dGluZyBlbnRyaWVzKSDilIDilIBcblxuICAgIHByaXZhdGUgYXN5bmMgYXNzZXJ0TXV0YWJsZShrZXk6IHN0cmluZywgd3JpdGVUaW1lOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKCF0aGlzLmVudHJpZXMubGVuZ3RoKSByZXR1cm47XG4gICAgICAgIGxldCBzZWxmID0gc2VsZWN0RW50cnlBdCh0aGlzLmVudHJpZXMsIHdyaXRlVGltZSwgZ2V0Um91dGUoa2V5KSk7XG4gICAgICAgIGlmICghc2VsZj8uaW1tdXRhYmxlKSByZXR1cm47XG4gICAgICAgIGlmIChhd2FpdCB0aGlzLmdldEluZm8oeyBwYXRoOiBrZXkgfSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhpcyBzdG9yZSBpcyBpbW11dGFibGUgKGF0IHdyaXRlIHRpbWUgJHt3cml0ZVRpbWV9KSBhbmQgJHtKU09OLnN0cmluZ2lmeShrZXkpfSBhbHJlYWR5IGV4aXN0cywgc28gaXQgY2Fubm90IGJlIHdyaXR0ZW4gdG8gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gU2VlIFNldENvbmZpZy5pbnRlcm5hbDogdGhlIHN0YW1wIG11c3QgbGFuZCBpbnNpZGUgU09NRSB3aW5kb3crcm91dGUgdGhpcyBzdG9yZSBpcyBjb25maWd1cmVkIGZvciAoYW55IHdpbmRvdywgaW5jbHVkaW5nIHBhc3Qgb25lcyAtIHN5bmNocm9uaXphdGlvbiBtb3ZlcyBvbGQgZGF0YSksIHNvIGEgY29uZnVzZWQgcGVlciBjYW4ndCBzdHVmZiBkYXRhIG9udG8gYSBzdG9yZSB0aGF0IHdhcyBuZXZlciBtZWFudCB0byBob2xkIGl0XG4gICAgcHJpdmF0ZSBhc3NlcnRJbnRlcm5hbFdyaXRlQWNjZXB0ZWQoa2V5OiBzdHJpbmcsIHdyaXRlVGltZTogbnVtYmVyLCByb3V0ZTogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5lbnRyaWVzLmxlbmd0aCkgcmV0dXJuO1xuICAgICAgICBsZXQgY292ZXJlZCA9IHRoaXMuZW50cmllcy5zb21lKHggPT4gd3JpdGVUaW1lID49IHgudmFsaWRXaW5kb3dbMF0gJiYgd3JpdGVUaW1lIDwgeC52YWxpZFdpbmRvd1sxXSAmJiByb3V0ZUNvbnRhaW5zKHgucm91dGUsIHJvdXRlKSk7XG4gICAgICAgIGlmICghY292ZXJlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnRlcm5hbCB3cml0ZSBvZiAke0pTT04uc3RyaW5naWZ5KGtleSl9IHJlamVjdGVkOiB3cml0ZVRpbWUgJHt3cml0ZVRpbWV9ICgke25ldyBEYXRlKHdyaXRlVGltZSkudG9JU09TdHJpbmcoKX0pIGF0IHJvdXRlICR7cm91dGV9IGlzIG91dHNpZGUgZXZlcnkgd2luZG93L3JvdXRlIHRoaXMgc3RvcmUgaXMgY29uZmlndXJlZCBmb3I6ICR7SlNPTi5zdHJpbmdpZnkodGhpcy5lbnRyaWVzLm1hcCh4ID0+ICh7IHZhbGlkV2luZG93OiB4LnZhbGlkV2luZG93LCByb3V0ZTogeC5yb3V0ZSB8fCBGVUxMX1JPVVRFIH0pKSl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSlgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIOKUgOKUgCBzeW5jaHJvbml6YXRpb24g4pSA4pSAXG5cbiAgICBwcml2YXRlIGFzeW5jIHJ1blNvdXJjZVN5bmMoc291cmNlSW5kZXg6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyU2xvdChzb3VyY2VJbmRleCk7XG4gICAgICAgIGxldCB7IHNvdXJjZSB9ID0gdGhpcy5zb3VyY2VzW3NvdXJjZUluZGV4XTtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5zb3VyY2VTdGF0ZXNbc291cmNlSW5kZXhdO1xuICAgICAgICAvLyBSZWFkIGxpdmUgZm9yIGV2ZXJ5IHBhc3MsIG5vdCBjYXB0dXJlZCAtIHVwZGF0ZVNvdXJjZXMgY2FuIGNoYW5nZSBpdCB3aGlsZSBsb29wcyBydW5cbiAgICAgICAgbGV0IG5vRnVsbFN5bmMgPSAoKSA9PiB0aGlzLnNvdXJjZXNbc291cmNlSW5kZXhdLm5vRnVsbFN5bmM7XG4gICAgICAgIGxldCBpbnRlcm1lZGlhdGUgPSB0aGlzLnNvdXJjZXNbc291cmNlSW5kZXhdLmludGVybWVkaWF0ZTtcbiAgICAgICAgbGV0IGxpc3Rpbmc6IE1hcDxzdHJpbmcsIG51bWJlcj4gfCB1bmRlZmluZWQ7XG4gICAgICAgIHdoaWxlICghdGhpcy5zdG9wcGVkLnN0b3AgJiYgIXN0YXRlLnN0b3BwZWQuc3RvcCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNEZWFkSW50ZXJtZWRpYXRlKHNvdXJjZUluZGV4KSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBOb3Qgc2Nhbm5pbmcgc3luYyBzb3VyY2UgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6IGl0IGlzIGFuIGludGVybWVkaWF0ZSB3aG9zZSB3aW5kb3cgYWxyZWFkeSBlbmRlZGApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXQgY29uZmlnID0gYXdhaXQgc291cmNlLmdldENvbmZpZygpO1xuICAgICAgICAgICAgICAgIHN0YXRlLnN1cHBvcnRzQ2hhbmdlc0FmdGVyID0gISFjb25maWcuc3VwcG9ydHNDaGFuZ2VzQWZ0ZXI7XG4gICAgICAgICAgICAgICAgbGlzdGluZyA9IGF3YWl0IHRoaXMuc2NhblNvdXJjZShzb3VyY2VJbmRleCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGludGVybWVkaWF0ZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBJbml0aWFsIHNjYW4gb2YgaW50ZXJtZWRpYXRlIHN5bmMgc291cmNlICR7c291cmNlLmdldERlYnVnTmFtZSgpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pIGZhaWxlZDsgbm90IHJldHJ5aW5nIChpbnRlcm1lZGlhdGVzIGFyZSB0ZW1wb3Jhcnkgc3dpdGNob3ZlciBwb3J0cyk6ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBJbml0aWFsIHNjYW4gb2Ygc3luYyBzb3VyY2UgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IGZhaWxlZCwgcmV0cnlpbmc6YCwgZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgZGVsYXkoU0NBTl9SRVRSWV9ERUxBWSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUuc2NhbkNvbXBsZXRlID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUuaW5pdGlhbFNjYW4ucmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICBpZiAodGhpcy5zdG9wcGVkLnN0b3AgfHwgc3RhdGUuc3RvcHBlZC5zdG9wKSByZXR1cm47XG4gICAgICAgIC8vIEFuIGludGVybWVkaWF0ZSB0aGF0IG5ldmVyIHByb2R1Y2VkIGEgbGlzdGluZyBpcyBkZWFkIG9yIGR5aW5nIC0gcG9sbGluZyBhbmQgY29weWluZyBmcm9tIGl0IHdvdWxkIG9ubHkgbG9nIGVycm9yc1xuICAgICAgICBpZiAoaW50ZXJtZWRpYXRlICYmICFsaXN0aW5nKSByZXR1cm47XG4gICAgICAgIGlmIChsaXN0aW5nKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlY29uY2lsZVNvdXJjZShzb3VyY2VJbmRleCwgbGlzdGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFub0Z1bGxTeW5jKCkpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5jb3B5U291cmNlRmlsZXMoc291cmNlSW5kZXgpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYENvcHlpbmcgZmlsZXMgZnJvbSBzeW5jIHNvdXJjZSAke3NvdXJjZS5nZXREZWJ1Z05hbWUoKX0gZmFpbGVkOmAsIGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZS5zdXBwb3J0c0NoYW5nZXNBZnRlcikge1xuICAgICAgICAgICAgcnVuSW5maW5pdGVQb2xsKENIQU5HRVNfUE9MTF9JTlRFUlZBTCwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzRGVhZEludGVybWVkaWF0ZShzb3VyY2VJbmRleCkpIHJldHVybjtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBvbGxDaGFuZ2VzKHNvdXJjZUluZGV4KTtcbiAgICAgICAgICAgICAgICBpZiAoIW5vRnVsbFN5bmMoKSkgYXdhaXQgdGhpcy5jb3B5U291cmNlRmlsZXMoc291cmNlSW5kZXgpO1xuICAgICAgICAgICAgfSwgc3RhdGUuc3RvcHBlZCk7XG4gICAgICAgICAgICAvLyBDaGFuZ2UgcG9sbHMgb25seSBzaG93IHdoYXQgdGhlIHNvdXJjZSBIQVMsIG5ldmVyIHdoYXQgaXQncyBtaXNzaW5nLCBzbyBwdXNoZXMgcnVuIG9uIHRoZSBmdWxsLXJlc2NhbiBjYWRlbmNlIChmaW5kSW5mbyBvbiBhbiBpbmRleC1iYWNrZWQgc291cmNlIGlzIGNoZWFwKVxuICAgICAgICAgICAgcnVuSW5maW5pdGVQb2xsKEZVTExfUkVTQ0FOX0lOVEVSVkFMLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNEZWFkSW50ZXJtZWRpYXRlKHNvdXJjZUluZGV4KSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGxldCBmaWxlcyA9IGF3YWl0IHNvdXJjZS5maW5kSW5mbyhcIlwiKTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlY29uY2lsZVNvdXJjZShzb3VyY2VJbmRleCwgbmV3IE1hcChmaWxlcy5tYXAoeCA9PiBbeC5wYXRoLCB4LmNyZWF0ZVRpbWVdKSkpO1xuICAgICAgICAgICAgfSwgc3RhdGUuc3RvcHBlZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBydW5JbmZpbml0ZVBvbGwoRlVMTF9SRVNDQU5fVU5JTkRFWEVEX0lOVEVSVkFMLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNEZWFkSW50ZXJtZWRpYXRlKHNvdXJjZUluZGV4KSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGxldCByZXNjYW4gPSBhd2FpdCB0aGlzLnNjYW5Tb3VyY2Uoc291cmNlSW5kZXgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVjb25jaWxlU291cmNlKHNvdXJjZUluZGV4LCByZXNjYW4pO1xuICAgICAgICAgICAgICAgIGlmICghbm9GdWxsU3luYygpKSBhd2FpdCB0aGlzLmNvcHlTb3VyY2VGaWxlcyhzb3VyY2VJbmRleCk7XG4gICAgICAgICAgICB9LCBzdGF0ZS5zdG9wcGVkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFuIGludGVybWVkaWF0ZSBpcyBhIGRlcGxveSBzd2l0Y2hvdmVyJ3MgdGVtcG9yYXJ5IGFsdGVybmF0ZSBwb3J0OiBvbmNlIGl0cyB3aW5kb3cgaXMgcGFzdCwgdGhlIHBvcnQgaXMgZ29uZSBmb3IgZ29vZCwgc28gc2Nhbm5pbmcgaXQgKG9yIHJldHJ5aW5nIGEgZmFpbGVkIHNjYW4pIGNhbiBuZXZlciBzdWNjZWVkIC0gaXQgd291bGQganVzdCBsb2cgZXJyb3JzIGZvcmV2ZXJcbiAgICBwcml2YXRlIGlzRGVhZEludGVybWVkaWF0ZShzb3VyY2VJbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCB7IGludGVybWVkaWF0ZSwgdmFsaWRXaW5kb3cgfSA9IHRoaXMuc291cmNlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIHJldHVybiAhIWludGVybWVkaWF0ZSAmJiB2YWxpZFdpbmRvd1sxXSA8PSBEYXRlLm5vdygpO1xuICAgIH1cblxuICAgIC8vIEZ1bGwgbWV0YWRhdGEgc2NhbiAoc2l6ZSwgd3JpdGVUaW1lLCBwYXRoKSBvZiBvbmUgc291cmNlLCBhcHBsaWVkIHRvIHRoZSBpbmRleC4gUmV0dXJucyB0aGUgc291cmNlJ3MgbGlzdGluZyAocGF0aCAtPiB3cml0ZSB0aW1lKSwgd2hpY2ggcmVjb25jaWxlU291cmNlIHVzZXMgZm9yIHRoZSBwdXNoIGRpcmVjdGlvbi5cbiAgICBwcml2YXRlIGFzeW5jIHNjYW5Tb3VyY2Uoc291cmNlSW5kZXg6IG51bWJlcik6IFByb21pc2U8TWFwPHN0cmluZywgbnVtYmVyPj4ge1xuICAgICAgICBsZXQgeyBzb3VyY2UsIHJvdXRlIH0gPSB0aGlzLnNvdXJjZXNbc291cmNlSW5kZXhdO1xuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLnNvdXJjZVN0YXRlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIGxldCBzY2FuU3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICBsZXQgYWN0aXZpdHk6IFN5bmNBY3Rpdml0eSA9IHsgdHlwZTogXCJtZXRhZGF0YVNjYW5cIiwgc291cmNlRGVidWdOYW1lOiBzb3VyY2UuZ2V0RGVidWdOYW1lKCksIHN0YXJ0VGltZTogc2NhblN0YXJ0IH07XG4gICAgICAgIHRoaXMuc3luY0FjdGl2aXRpZXMuYWRkKGFjdGl2aXR5KTtcbiAgICAgICAgY29uc29sZS5sb2coYE1ldGFkYXRhIHNjYW4gb2YgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IHN0YXJ0aW5nIChzdG9yZSAke3RoaXMuZm9sZGVyfSlgKTtcbiAgICAgICAgbGV0IHByb2dyZXNzVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgTWV0YWRhdGEgc2NhbiBvZiAke3NvdXJjZS5nZXREZWJ1Z05hbWUoKX0gc3RpbGwgcnVubmluZyAoJHtNYXRoLnJvdW5kKChEYXRlLm5vdygpIC0gc2NhblN0YXJ0KSAvIDEwMDApfXMsIHN0b3JlICR7dGhpcy5mb2xkZXJ9KWApO1xuICAgICAgICB9LCBTWU5DX1BST0dSRVNTX0xPR19JTlRFUlZBTCk7XG4gICAgICAgIChwcm9ncmVzc1RpbWVyIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgICAgICAgLy8gVGhlIGxpc3RpbmcgcmVxdWVzdCBkZWxpYmVyYXRlbHkgdGFrZXMgbm8gdGltZSBvciByb3V0ZSBmaWx0ZXJzOiBvdXIgc2xvd2VzdCBzb3VyY2VzIChiYWNrYmxhemUpIHN1cHBvcnQgbmVpdGhlciwgc28gZmlsdGVyaW5nIHdvdWxkIGhhcHBlbiBhZnRlciB0aGUgZnVsbCBmZXRjaCBhbnl3YXkgLSBsaXR0bGUgYmVuZWZpdCwgbW9yZSByb29tIGZvciBkZXN5bmNocm9uaXphdGlvbi4gQW5kIGlmIGEgZnVsbCBsaXN0aW5nIGV2ZXIgYmVjb21lcyB0b28gYmlnIHRvIHNlbmQgb3ZlciB0aGUgbmV0d29yaywgaXQgaXMgYWxzbyB0b28gYmlnIGZvciB0aGUgcmVjZWl2aW5nIHByb2Nlc3MgdG8gaG9sZCBpbiBtZW1vcnkgLSB0aGUgZml4IGlzIG1vcmUgcm91dGluZyBzaGFyZHMgKGVhY2ggc3RvcmluZyBhbmQgc2VuZGluZyBsZXNzKSwgbm90IGZpbHRlcmluZy5cbiAgICAgICAgbGV0IGZpbGVzOiBBcmNoaXZlRmlsZUluZm9bXTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZpbGVzID0gYXdhaXQgc291cmNlLmZpbmRJbmZvKFwiXCIpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwcm9ncmVzc1RpbWVyKTtcbiAgICAgICAgICAgIHRoaXMuc3luY0FjdGl2aXRpZXMuZGVsZXRlKGFjdGl2aXR5KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGUgc291cmNlIG1heSBoYXZlIGJlZW4gcmVtb3ZlZCB3aGlsZSB0aGUgbGlzdGluZyB3YXMgaW4gZmxpZ2h0OyBpdHMgcmVzdWx0cyBhcmUgZGVhZFxuICAgICAgICBpZiAoc3RhdGUuc3RvcHBlZC5zdG9wKSByZXR1cm4gbmV3IE1hcCgpO1xuICAgICAgICBsZXQgaW5kZXhTaXplQmVmb3JlID0gdGhpcy5tZW0uc2l6ZTtcbiAgICAgICAgbGV0IHNlZW4gPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgICAgICBsZXQgdGFsbHkgPSBuZXdTY2FuVGFsbHkoKTtcbiAgICAgICAgbGV0IG5ld1BhdGhzID0gMDtcbiAgICAgICAgZm9yIChsZXQgZmlsZSBvZiBmaWxlcykge1xuICAgICAgICAgICAgc2Vlbi5zZXQoZmlsZS5wYXRoLCBmaWxlLmNyZWF0ZVRpbWUpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLm1lbS5oYXMoZmlsZS5wYXRoKSkge1xuICAgICAgICAgICAgICAgIG5ld1BhdGhzKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0YWxseVt0aGlzLnVwZGF0ZVNjYW5JbmRleChzb3VyY2VJbmRleCwgZmlsZSldKys7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUuc2Nhbm5lZENvdW50ID0gZmlsZXMubGVuZ3RoO1xuICAgICAgICAvLyBJbmRleCBlbnRyaWVzIHRoaXMgc291cmNlIHdhcyB0aGUgaG9sZGVyIG9mLCBidXQgdGhhdCB2YW5pc2hlZCBmcm9tIGl0IChlLmcuIGRlbGV0ZWQgd2hpbGUgd2Ugd2VyZSBvZmZsaW5lKSwgY29tZSBvdXQgb2YgdGhlIGluZGV4LiBFbnRyaWVzIGNoYW5nZWQgYWZ0ZXIgdGhlIHNjYW4gc3RhcnRlZCBhcmUga2VwdCDigJQgdGhlIHNjYW4gbGlzdGluZyBtYXkgc2ltcGx5IHByZWRhdGUgdGhlbS4gVG9tYnN0b25lcyBoYXZlIG5vIHBoeXNpY2FsIGZpbGUgZm9yIGEgbGlzdGluZyB0byB2b3VjaCBmb3IsIHNvIHRoZXkncmUgZXhlbXB0IChjbGVhbnVwVG9tYnN0b25lcyBleHBpcmVzIHRoZW0gaW5zdGVhZCkuXG4gICAgICAgIGxldCByZW1vdmVkRnJvbUluZGV4ID0gMDtcbiAgICAgICAgbGV0IG1pc3NpbmdPblNvdXJjZSA9IDA7XG4gICAgICAgIGxldCBzY2FubmVkU291cmNlc0xpc3RJbmRleCA9IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdChzb3VyY2VJbmRleCk7XG4gICAgICAgIGZvciAobGV0IFtrZXksIGVudHJ5XSBvZiB0aGlzLm1lbSkge1xuICAgICAgICAgICAgaWYgKHNlZW4uaGFzKGtleSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKGVudHJ5LnNvdXJjZXNMaXN0SW5kZXggPT09IHNjYW5uZWRTb3VyY2VzTGlzdEluZGV4ICYmIGVudHJ5LnNpemUgIT09IDAgJiYgZW50cnkuY2hhbmdlZEF0IDwgc2NhblN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVJbmRleEVudHJ5KGtleSk7XG4gICAgICAgICAgICAgICAgcmVtb3ZlZEZyb21JbmRleCsrO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQ291bnRlZCBvbmx5IHdoZW4gdGhlIHNvdXJjZSBTSE9VTEQgaG9sZCB0aGUgZW50cnkgKGl0cyByb3V0ZSBtYXRjaGVzKSAtIHRoZXNlIGFyZSB3aGF0IHRoZSByZWNvbmNpbGUgcGFzcyBwdXNoZXMgdG8gaXQgKHdoaWNoIGFsc28gaWdub3JlcyB0aGUgdmFsaWQgd2luZG93OiBzeW5jaHJvbml6YXRpb24gbW92ZXMgZXhpc3RpbmcgdmFsdWVzLCB0aGUgd2luZG93IG9ubHkgcm91dGVzIGZyZXNoIHdyaXRlcylcbiAgICAgICAgICAgIGlmIChlbnRyeS5zaXplID09PSAwIHx8IGtleSA9PT0gUk9VVElOR19GSUxFKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmICghcm91dGVDb250YWlucyhyb3V0ZSwgZ2V0Um91dGUoa2V5KSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgbWlzc2luZ09uU291cmNlKys7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUGVyY2VudGFnZXMgYXJlIG9mIHRoZSB1bmlvbiBvZiBib3RoIHNpZGVzIChvdXIgaW5kZXggKyB0aGVpciBsaXN0aW5nKSwgc28gZXZlcnkgY291bnQgaGFzIGEgc3RhYmxlIGRlbm9taW5hdG9yXG4gICAgICAgIGxldCB1bmlvbiA9IGluZGV4U2l6ZUJlZm9yZSArIG5ld1BhdGhzO1xuICAgICAgICBsZXQgcGN0ID0gKG46IG51bWJlcikgPT4gYCR7TWF0aC5yb3VuZChuIC8gTWF0aC5tYXgodW5pb24sIDEpICogMTAwMCkgLyAxMH0lYDtcbiAgICAgICAgY29uc29sZS5sb2coYE1ldGFkYXRhIHNjYW4gb2YgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IGZpbmlzaGVkIGluICR7TWF0aC5yb3VuZCgoRGF0ZS5ub3coKSAtIHNjYW5TdGFydCkgLyAxMDAwKX1zIChzdG9yZSAke3RoaXMuZm9sZGVyfSk6ICR7ZmlsZXMubGVuZ3RofSBsaXN0ZWQgdnMgJHtpbmRleFNpemVCZWZvcmV9IGluZGV4ZWQgKHVuaW9uICR7dW5pb259KTogJHtmb3JtYXRTY2FuVGFsbHkodGFsbHksIHVuaW9uKX0sICR7bWlzc2luZ09uU291cmNlfSBpbiBpbmRleCBidXQgbWlzc2luZyBvbiBzb3VyY2UgKCR7cGN0KG1pc3NpbmdPblNvdXJjZSl9KSwgJHtyZW1vdmVkRnJvbUluZGV4fSByZW1vdmVkIGZyb20gaW5kZXggKCR7cGN0KHJlbW92ZWRGcm9tSW5kZXgpfSlgKTtcbiAgICAgICAgc3RhdGUuY2hhbmdlc0FmdGVyVGltZSA9IE1hdGgubWF4KHN0YXRlLmNoYW5nZXNBZnRlclRpbWUsIHNjYW5TdGFydCAtIENIQU5HRVNfUE9MTF9PVkVSTEFQKTtcbiAgICAgICAgcmV0dXJuIHNlZW47XG4gICAgfVxuXG4gICAgLy8gVGhlIHB1c2ggZGlyZWN0aW9uIG9mIHN5bmNocm9uaXphdGlvbjogZXZlcnl0aGluZyB3ZSBrbm93IHRoYXQgdGhlIHNvdXJjZSBpcyBtaXNzaW5nIChvciBob2xkcyBhbiBvbGRlciBjb3B5IG9mKSBpcyB3cml0dGVuIHRvIGl0IOKAlCBpbmNsdWRpbmcgZGVsZXRpb25zLCBhcyB0b21ic3RvbmUgd3JpdGVzLiBUaGlzIGlzIHdoYXQgaGVhbHMgYSBzb3VyY2Ugd2hvc2UgYmFja2dyb3VuZCB3cml0ZXMgZmFpbGVkIChlLmcuIGl0IHdhcyBkb3duKTogdGhlIG5leHQgc2NhbiBzZWVzIHdoYXQncyBtaXNzaW5nIGFuZCByZS1zZW5kcyBpdC4gQSBmYWlsaW5nIGZpbGUgaXMgc2tpcHBlZCwgbm90IGZhdGFsIChpbW11dGFibGUgdGFyZ2V0cyBhcmUgaGFuZGxlZCBieSBmb3JjZVNldEltbXV0YWJsZSwgYW5kIG9uZSB1bnJlYWRhYmxlIHZhbHVlIG11c3Qgbm90IHN0b3AgdGhlIHJlc3Qgb2YgdGhlIHBhc3MpIC0gb25seSBhIHJ1biBvZiBjb25zZWN1dGl2ZSBmYWlsdXJlcyAodGhlIHNvdXJjZSBpdHNlbGYgaXMgZG93bikgYWJvcnRzIHVudGlsIHRoZSBuZXh0IHNjYW4gY3ljbGUuXG4gICAgcHJpdmF0ZSBhc3luYyByZWNvbmNpbGVTb3VyY2Uoc291cmNlSW5kZXg6IG51bWJlciwgbGlzdGluZzogTWFwPHN0cmluZywgbnVtYmVyPik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBsZXQgeyBzb3VyY2UsIHZhbGlkV2luZG93LCByb3V0ZSB9ID0gdGhpcy5zb3VyY2VzW3NvdXJjZUluZGV4XTtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5zb3VyY2VTdGF0ZXNbc291cmNlSW5kZXhdO1xuICAgICAgICBsZXQgYWNjZXB0c1dyaXRlcyA9IHdpbmRvd0FjY2VwdHNXcml0ZXModmFsaWRXaW5kb3cpO1xuICAgICAgICBsZXQgdGFyZ2V0U291cmNlc0xpc3RJbmRleCA9IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdChzb3VyY2VJbmRleCk7XG4gICAgICAgIGxldCBwdXNoZWQgPSAwO1xuICAgICAgICBsZXQgZmFpbGVkID0gMDtcbiAgICAgICAgbGV0IGNvbnNlY3V0aXZlRmFpbHVyZXMgPSAwO1xuICAgICAgICBsZXQgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBsZXQgYWJvcnRlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBba2V5LCBlbnRyeV0gb2YgdGhpcy5tZW0pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0b3BwZWQuc3RvcCB8fCBzdGF0ZS5zdG9wcGVkLnN0b3ApIHJldHVybjtcbiAgICAgICAgICAgIGlmIChlbnRyeS5zb3VyY2VzTGlzdEluZGV4ID09PSB0YXJnZXRTb3VyY2VzTGlzdEluZGV4KSBjb250aW51ZTtcbiAgICAgICAgICAgIC8vIFRoZSByb3V0aW5nIGZpbGUgaXMgTkVWRVIgc3luY2hyb25pemVkIGJldHdlZW4gc3RvcmFnZSBub2RlcyAtIGl0IGlzIG9ubHkgZXZlciB3cml0dGVuIGRpcmVjdGx5IHRvIGVhY2ggbm9kZSwgYW5kIG9ubHkgZXZlciByZWFkIG9mZiBvdXIgb3duIGRpc2tcbiAgICAgICAgICAgIGlmIChrZXkgPT09IFJPVVRJTkdfRklMRSkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoIWFjY2VwdHNXcml0ZXMpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFyb3V0ZUNvbnRhaW5zKHJvdXRlLCBnZXRSb3V0ZShrZXkpKSkgY29udGludWU7XG4gICAgICAgICAgICBsZXQgdGhlaXJUaW1lID0gbGlzdGluZy5nZXQoa2V5KTtcbiAgICAgICAgICAgIGlmICh0aGVpclRpbWUgIT09IHVuZGVmaW5lZCAmJiB0aGVpclRpbWUgPj0gZW50cnkud3JpdGVUaW1lKSBjb250aW51ZTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKGVudHJ5LnNpemUgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQSBkZWxldGlvbiBvbmx5IG5lZWRzIHB1c2hpbmcgd2hpbGUgdGhlIHNvdXJjZSBzdGlsbCBob2xkcyBhbiBvbGRlciBjb3B5LiBJdCB0cmF2ZWxzIGFzIGRlbCAobmV2ZXIgYXMgYW4gZW1wdHkgc2V0IC0gc2V0IHJlamVjdHMgZW1wdHkgYnVmZmVycyksIHdpdGggdGhlIE9SSUdJTkFMIGRlbGV0aW9uIHRpbWUgc28gb3JkZXJpbmcgc3Vydml2ZXMuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGVpclRpbWUgPT09IHVuZGVmaW5lZCkgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHNvdXJjZS5kZWwoa2V5LCB7IGxhc3RNb2RpZmllZDogZW50cnkud3JpdGVUaW1lLCBub0NoZWNrczogdHJ1ZSwgaW50ZXJuYWw6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgICAgIHB1c2hlZCsrO1xuICAgICAgICAgICAgICAgICAgICBjb25zZWN1dGl2ZUZhaWx1cmVzID0gMDtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBob2xkZXIgPSBhd2FpdCB0aGlzLmdldEVudHJ5SG9sZGVyKGVudHJ5KTtcbiAgICAgICAgICAgICAgICBpZiAoIWhvbGRlcikgY29udGludWU7XG4gICAgICAgICAgICAgICAgbGV0IGNvcGllZCA9IGF3YWl0IGNvcHlBcmNoaXZlRmlsZSh7IGZyb206IGhvbGRlciwgdG86IHNvdXJjZSwgcGF0aDoga2V5LCBzaXplOiBlbnRyeS5zaXplLCB3cml0ZVRpbWU6IGVudHJ5LndyaXRlVGltZSwgZm9yY2VTZXRJbW11dGFibGU6IHRydWUsIG5vQ2hlY2tzOiB0cnVlLCBpbnRlcm5hbDogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICBpZiAoIWNvcGllZCkgY29udGludWU7XG4gICAgICAgICAgICAgICAgcHVzaGVkKys7XG4gICAgICAgICAgICAgICAgY29uc2VjdXRpdmVGYWlsdXJlcyA9IDA7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgZmFpbGVkKys7XG4gICAgICAgICAgICAgICAgY29uc2VjdXRpdmVGYWlsdXJlcysrO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcnMubGVuZ3RoIDwgUkVDT05DSUxFX0VSUk9SX0xPR19MSU1JVCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChgJHtrZXl9OiAkeyhlIGFzIEVycm9yKS5zdGFjayA/PyBlfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoY29uc2VjdXRpdmVGYWlsdXJlcyA+PSBSRUNPTkNJTEVfTUFYX0NPTlNFQ1VUSVZFX0ZBSUxVUkVTKSB7XG4gICAgICAgICAgICAgICAgICAgIGFib3J0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZhaWxlZCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgUmVjb25jaWxpbmcgc3luYyBzb3VyY2UgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6IHB1c2hlZCAke3B1c2hlZH0gZmlsZXMsICR7ZmFpbGVkfSBmYWlsZWQke2Fib3J0ZWQgJiYgYCBiZWZvcmUgYWJvcnRpbmcgdGhlIHBhc3MgKCR7Y29uc2VjdXRpdmVGYWlsdXJlc30gY29uc2VjdXRpdmUgZmFpbHVyZXMgLSB0aGUgc291cmNlIGxvb2tzIGRvd247IHRoZSBuZXh0IHNjYW4gY3ljbGUgcmV0cmllcylgIHx8IFwiXCJ9LiBGaXJzdCBlcnJvcnM6ICR7ZXJyb3JzLmpvaW4oXCIgfCBcIil9YCk7XG4gICAgICAgIH0gZWxzZSBpZiAocHVzaGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgUmVjb25jaWxlZCBzeW5jIHNvdXJjZSAke3NvdXJjZS5nZXREZWJ1Z05hbWUoKX0gKHN0b3JlICR7dGhpcy5mb2xkZXJ9KTogcHVzaGVkICR7cHVzaGVkfSBmaWxlcyBpdCB3YXMgbWlzc2luZyBvciBoZWxkIG9sZGVyIGNvcGllcyBvZmApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVTY2FuSW5kZXgoc291cmNlSW5kZXg6IG51bWJlciwgZmlsZTogQXJjaGl2ZUZpbGVJbmZvKTogU2Nhbk91dGNvbWUge1xuICAgICAgICAvLyBBbiBpbi1mbGlnaHQgc2NhbiBjYW4gb3V0bGl2ZSBpdHMgc291cmNlJ3MgcmVtb3ZhbDsgaXRzIHJlc3VsdHMgYXJlIGRlYWRcbiAgICAgICAgaWYgKCF0aGlzLmlzTGl2ZShzb3VyY2VJbmRleCkpIHJldHVybiBcImZpbHRlcmVkXCI7XG4gICAgICAgIGlmIChmaWxlLnBhdGggPT09IFJPVVRJTkdfRklMRSkge1xuICAgICAgICAgICAgLy8gVGhlIHJvdXRpbmcgY29uZmlnIGlzIE5FVkVSIHB1bGxlZCBmcm9tIG90aGVyIHNvdXJjZXMgLSBpdCBvbmx5IGV2ZXIgYXJyaXZlcyBhcyBhbiBleHBsaWNpdCwgdmVyc2lvbi12YWxpZGF0ZWQgd3JpdGUsIGFuZCBpcyBvbmx5IGV2ZXIgcmVhZCBvZmYgb3VyIG93biBkaXNrLiBSb3V0ZSBhbmQgdmFsaWQtd2luZG93IGZpbHRlcnMgY2FuJ3QgcG9zc2libHkgYXBwbHkgdG8gaXQgZWl0aGVyOiBpdCBpcyB0aGUgZmlsZSBERUZJTklORyB0aGVtLCBzbyBmaWx0ZXJpbmcgaXQgd291bGQgbWVhbiBjZXJ0YWluIHNvdXJjZXMgY291bGQgbmV2ZXIgaGF2ZSB0aGVpciByb3V0aW5nIGNvbmZpZyB1cGRhdGVkLCBldmVyLlxuICAgICAgICAgICAgaWYgKHNvdXJjZUluZGV4ICE9PSAwKSByZXR1cm4gXCJmaWx0ZXJlZFwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gVGhlIHZhbGlkIHdpbmRvdyBpcyBkZWxpYmVyYXRlbHkgTk9UIGFwcGxpZWQgaGVyZTogaXQgZGVjaWRlcyB3aGVyZSBXUklURVMgcm91dGUsIGJ1dCBhIHNjYW4gaXMgdXMgYXNraW5nIGEgc291cmNlIHdoYXQgaXQgYWxyZWFkeSBob2xkcyAtIGV4aXN0aW5nIHZhbHVlcyBzeW5jaHJvbml6ZSByZWdhcmRsZXNzIG9mIHRoZSB3aW5kb3cgKHRoZSBzYW1lIHJlYXNvbmluZyB0aGF0IGxldHMgc3luY2hyb25pemF0aW9uIGlnbm9yZSB0aGUgaW1tdXRhYmxlIGZsYWcpLiBPbmx5IHRoZSByb3V0ZSBmaWx0ZXJzOiBhIHBhcnRpYWxseS1vdmVybGFwcGluZyBzaGFyZCdzIGxpc3RpbmcgbGVnaXRpbWF0ZWx5IGluY2x1ZGVzIGtleXMgdGhhdCBhcmVuJ3Qgb3Vycy5cbiAgICAgICAgICAgIGxldCB7IHJvdXRlIH0gPSB0aGlzLnNvdXJjZXNbc291cmNlSW5kZXhdO1xuICAgICAgICAgICAgaWYgKCFyb3V0ZUNvbnRhaW5zKHJvdXRlLCBnZXRSb3V0ZShmaWxlLnBhdGgpKSkgcmV0dXJuIFwiZmlsdGVyZWRcIjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZXhpc3RpbmcgPSB0aGlzLm1lbS5nZXQoZmlsZS5wYXRoKTtcbiAgICAgICAgLy8gVGhlIGhpZ2hlc3Qgd3JpdGUgdGltZSB3aW5zIGFjcm9zcyBhbGwgc291cmNlcyAodGllcyBrZWVwIHRoZSBleGlzdGluZyBlbnRyeSlcbiAgICAgICAgaWYgKGV4aXN0aW5nICYmIGZpbGUuY3JlYXRlVGltZSA8PSBleGlzdGluZy53cml0ZVRpbWUpIHJldHVybiBcInVuY2hhbmdlZFwiO1xuICAgICAgICB0aGlzLnNldEluZGV4RW50cnkoZmlsZS5wYXRoLCB7IHdyaXRlVGltZTogZmlsZS5jcmVhdGVUaW1lLCBzaXplOiBmaWxlLnNpemUsIHNvdXJjZXNMaXN0SW5kZXg6IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdChzb3VyY2VJbmRleCkgfSk7XG4gICAgICAgIGlmIChmaWxlLnNpemUgPT09IDApIHJldHVybiBcInRvbWJzdG9uZVwiO1xuICAgICAgICBpZiAoZXhpc3RpbmcpIHJldHVybiBcInVwZGF0ZWRcIjtcbiAgICAgICAgcmV0dXJuIFwibmV3XCI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBwb2xsQ2hhbmdlcyhzb3VyY2VJbmRleDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCB7IHNvdXJjZSwgcm91dGUgfSA9IHRoaXMuc291cmNlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuc291cmNlU3RhdGVzW3NvdXJjZUluZGV4XTtcbiAgICAgICAgbGV0IHBvbGxTdGFydCA9IERhdGUubm93KCk7XG4gICAgICAgIGxldCBjaGFuZ2VzID0gYXdhaXQgc291cmNlLmdldENoYW5nZXNBZnRlcjIoeyB0aW1lOiBzdGF0ZS5jaGFuZ2VzQWZ0ZXJUaW1lLCByb3V0ZXM6IHJvdXRlICYmIFtyb3V0ZV0gfHwgdW5kZWZpbmVkIH0pO1xuICAgICAgICBsZXQgdGFsbHkgPSBuZXdTY2FuVGFsbHkoKTtcbiAgICAgICAgZm9yIChsZXQgZmlsZSBvZiBjaGFuZ2VzKSB7XG4gICAgICAgICAgICB0YWxseVt0aGlzLnVwZGF0ZVNjYW5JbmRleChzb3VyY2VJbmRleCwgZmlsZSldKys7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUG9sbHMgcnVuIGNvbnN0YW50bHksIHNvIG9ubHkgdGhlIG9uZXMgdGhhdCBhY3R1YWxseSBjaGFuZ2VkIHRoZSBpbmRleCBnZXQgYSBsaW5lXG4gICAgICAgIGlmICh0YWxseS5uZXcgfHwgdGFsbHkudXBkYXRlZCB8fCB0YWxseS50b21ic3RvbmUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDaGFuZ2VzIHBvbGwgb2YgJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6ICR7Y2hhbmdlcy5sZW5ndGh9IGNoYW5nZXM6ICR7Zm9ybWF0U2NhblRhbGx5KHRhbGx5LCBjaGFuZ2VzLmxlbmd0aCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUuc2Nhbm5lZENvdW50ICs9IGNoYW5nZXMubGVuZ3RoO1xuICAgICAgICBzdGF0ZS5jaGFuZ2VzQWZ0ZXJUaW1lID0gcG9sbFN0YXJ0IC0gQ0hBTkdFU19QT0xMX09WRVJMQVA7XG4gICAgfVxuXG4gICAgLy8gRG93bmxvYWRzIHRoZSBmaWxlcyBhIHNvdXJjZSBjdXJyZW50bHkgaG9sZHMgb250byBvdXIgb3duIGJhc2Ugc291cmNlICh0aGUgbG9jYWwgZGlzayksIHByZXNlcnZpbmcgdGhlaXIgbW9kaWZpZWQgdGltZXMg4oCUIHNvIGEgbmV3ZXIgbG9jYWwgd3JpdGUgYWx3YXlzIHdpbnMuIFNraXBwZWQgZm9yIG5vRnVsbFN5bmMgc291cmNlcyAoZnJvbnRpbmcgYSBsYXJnZSBkYXRhYmFzZSB3aXRob3V0IGNvcHlpbmcgaXQpOyByZWFkcyBzdGlsbCBkb3duLWNhY2hlIGxhemlseS5cbiAgICBwcml2YXRlIGFzeW5jIGNvcHlTb3VyY2VGaWxlcyhzb3VyY2VJbmRleDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChzb3VyY2VJbmRleCA9PT0gMCkgcmV0dXJuO1xuICAgICAgICBsZXQgeyBzb3VyY2UgfSA9IHRoaXMuc291cmNlc1tzb3VyY2VJbmRleF07XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuc291cmNlU3RhdGVzW3NvdXJjZUluZGV4XTtcbiAgICAgICAgbGV0IHBlbmRpbmc6IHsga2V5OiBzdHJpbmc7IGVudHJ5OiBJbmRleEVudHJ5IH1bXSA9IFtdO1xuICAgICAgICBsZXQgdG90YWxCeXRlcyA9IDA7XG4gICAgICAgIGxldCBjb3BpZWRTb3VyY2VzTGlzdEluZGV4ID0gdGhpcy5zb3VyY2VzTGlzdEluZGV4T2ZTbG90KHNvdXJjZUluZGV4KTtcbiAgICAgICAgZm9yIChsZXQgW2tleSwgZW50cnldIG9mIHRoaXMubWVtKSB7XG4gICAgICAgICAgICBpZiAoZW50cnkuc291cmNlc0xpc3RJbmRleCAhPT0gY29waWVkU291cmNlc0xpc3RJbmRleCkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoZW50cnkuc2l6ZSA9PT0gMCkgY29udGludWU7XG4gICAgICAgICAgICBwZW5kaW5nLnB1c2goeyBrZXksIGVudHJ5IH0pO1xuICAgICAgICAgICAgdG90YWxCeXRlcyArPSBlbnRyeS5zaXplO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcGVuZGluZy5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgbGV0IGFjdGl2aXR5OiBTeW5jQWN0aXZpdHkgPSB7XG4gICAgICAgICAgICB0eXBlOiBcImZ1bGxTeW5jXCIsXG4gICAgICAgICAgICBzb3VyY2VEZWJ1Z05hbWU6IHNvdXJjZS5nZXREZWJ1Z05hbWUoKSxcbiAgICAgICAgICAgIHN0YXJ0VGltZTogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIGRvbmVGaWxlczogMCxcbiAgICAgICAgICAgIHRvdGFsRmlsZXM6IHBlbmRpbmcubGVuZ3RoLFxuICAgICAgICAgICAgZG9uZUJ5dGVzOiAwLFxuICAgICAgICAgICAgdG90YWxCeXRlcyxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zeW5jQWN0aXZpdGllcy5hZGQoYWN0aXZpdHkpO1xuICAgICAgICBsZXQgcHJvZ3Jlc3NMb2dnZWQgPSBmYWxzZTtcbiAgICAgICAgbGV0IGxvZ1Byb2dyZXNzID0gKCkgPT4ge1xuICAgICAgICAgICAgcHJvZ3Jlc3NMb2dnZWQgPSB0cnVlO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYEZ1bGwgc3luYyBmcm9tICR7c291cmNlLmdldERlYnVnTmFtZSgpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pOiAke2FjdGl2aXR5LmRvbmVGaWxlc30vJHtwZW5kaW5nLmxlbmd0aH0gZmlsZXMgKCR7KChhY3Rpdml0eS5kb25lRmlsZXMgfHwgMCkgLyBwZW5kaW5nLmxlbmd0aCAqIDEwMCkudG9GaXhlZCgxKX0lKSwgJHtmb3JtYXROdW1iZXIoYWN0aXZpdHkuZG9uZUJ5dGVzIHx8IDApfUIvJHtmb3JtYXROdW1iZXIodG90YWxCeXRlcyl9QiAoJHsodG90YWxCeXRlcyAmJiAoYWN0aXZpdHkuZG9uZUJ5dGVzIHx8IDApIC8gdG90YWxCeXRlcyAqIDEwMCB8fCAxMDApLnRvRml4ZWQoMSl9JSlgKTtcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IHByb2dyZXNzVGltZXIgPSBzZXRJbnRlcnZhbChsb2dQcm9ncmVzcywgU1lOQ19QUk9HUkVTU19MT0dfSU5URVJWQUwpO1xuICAgICAgICAocHJvZ3Jlc3NUaW1lciBhcyB7IHVucmVmPzogKCkgPT4gdm9pZCB9KS51bnJlZj8uKCk7XG4gICAgICAgIGxldCBzbG93RXJyb3JUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBlbGFwc2VkID0gRGF0ZS5ub3coKSAtIGFjdGl2aXR5LnN0YXJ0VGltZTtcbiAgICAgICAgICAgIGxldCBkb25lRmlsZXMgPSBhY3Rpdml0eS5kb25lRmlsZXMgfHwgMDtcbiAgICAgICAgICAgIGxldCBkb25lQnl0ZXMgPSBhY3Rpdml0eS5kb25lQnl0ZXMgfHwgMDtcbiAgICAgICAgICAgIGxldCBieXRlc1BlclNlY29uZCA9IGRvbmVCeXRlcyAvIChlbGFwc2VkIC8gMTAwMCk7XG4gICAgICAgICAgICBsZXQgcmVtYWluaW5nQnl0ZXMgPSB0b3RhbEJ5dGVzIC0gZG9uZUJ5dGVzO1xuICAgICAgICAgICAgbGV0IGV0YVRleHQgPSBcInVua25vd24gKG5vIGJ5dGVzIHRyYW5zZmVycmVkIHlldClcIjtcbiAgICAgICAgICAgIGlmIChieXRlc1BlclNlY29uZCA+IDApIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVtYWluaW5nTXMgPSByZW1haW5pbmdCeXRlcyAvIGJ5dGVzUGVyU2Vjb25kICogMTAwMDtcbiAgICAgICAgICAgICAgICBldGFUZXh0ID0gYCR7Zm9ybWF0VGltZShyZW1haW5pbmdNcyl9IHJlbWFpbmluZywgY29tcGxldGluZyBhcm91bmQgJHtuZXcgRGF0ZShEYXRlLm5vdygpICsgcmVtYWluaW5nTXMpLnRvSVNPU3RyaW5nKCl9YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEZ1bGwgc3luYyBmcm9tICR7c291cmNlLmdldERlYnVnTmFtZSgpfSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pIGhhcyBiZWVuIHJ1bm5pbmcgZm9yICR7Zm9ybWF0VGltZShlbGFwc2VkKX06ICR7ZG9uZUZpbGVzfS8ke3BlbmRpbmcubGVuZ3RofSBmaWxlcyAoJHsoZG9uZUZpbGVzIC8gcGVuZGluZy5sZW5ndGggKiAxMDApLnRvRml4ZWQoMSl9JSksICR7Zm9ybWF0TnVtYmVyKGRvbmVCeXRlcyl9Qi8ke2Zvcm1hdE51bWJlcih0b3RhbEJ5dGVzKX1CICgkeyh0b3RhbEJ5dGVzICYmIGRvbmVCeXRlcyAvIHRvdGFsQnl0ZXMgKiAxMDAgfHwgMTAwKS50b0ZpeGVkKDEpfSUpLCAke2Zvcm1hdE51bWJlcihieXRlc1BlclNlY29uZCl9Qi9zLiBFc3RpbWF0ZWQgJHtldGFUZXh0fS5gKTtcbiAgICAgICAgfSwgRlVMTF9TWU5DX1NMT1dfRVJST1JfSU5URVJWQUwpO1xuICAgICAgICAoc2xvd0Vycm9yVGltZXIgYXMgeyB1bnJlZj86ICgpID0+IHZvaWQgfSkudW5yZWY/LigpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IG5leHRJbmRleCA9IDA7XG4gICAgICAgICAgICBsZXQgZmFpbGVkID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgY29weVdvcmtlciA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICB3aGlsZSAoIWZhaWxlZCAmJiAhdGhpcy5zdG9wcGVkLnN0b3AgJiYgIXN0YXRlLnN0b3BwZWQuc3RvcCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSBuZXh0SW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID49IHBlbmRpbmcubGVuZ3RoKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIGxldCB7IGtleSwgZW50cnkgfSA9IHBlbmRpbmdbaW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICBsZXQgY29waWVkID0gYXdhaXQgY29weUFyY2hpdmVGaWxlKHsgZnJvbTogc291cmNlLCB0bzogdGhpcy5zb3VyY2VzWzBdLnNvdXJjZSwgcGF0aDoga2V5LCBzaXplOiBlbnRyeS5zaXplLCB3cml0ZVRpbWU6IGVudHJ5LndyaXRlVGltZSwgZm9yY2VTZXRJbW11dGFibGU6IHRydWUsIG5vQ2hlY2tzOiB0cnVlLCBpbnRlcm5hbDogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvcGllZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBtb3ZlIHRoZSBlbnRyeSdzIHNvdXJjZSBpZiBpdCB3YXNuJ3QgY2hhbmdlZCB3aGlsZSB3ZSBjb3BpZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm1lbS5nZXQoa2V5KSA9PT0gZW50cnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEluZGV4RW50cnkoa2V5LCB7IHdyaXRlVGltZTogY29waWVkLndyaXRlVGltZSwgc2l6ZTogY29waWVkLnNpemUsIHNvdXJjZXNMaXN0SW5kZXg6IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdCgwKSB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhY3Rpdml0eS5kb25lRmlsZXMgPSAoYWN0aXZpdHkuZG9uZUZpbGVzIHx8IDApICsgMTtcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZpdHkuZG9uZUJ5dGVzID0gKGFjdGl2aXR5LmRvbmVCeXRlcyB8fCAwKSArIGVudHJ5LnNpemU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGxldCB3b3JrZXJzOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTWF0aC5taW4oRlVMTF9TWU5DX1BBUkFMTEVMLCBwZW5kaW5nLmxlbmd0aCk7IGkrKykge1xuICAgICAgICAgICAgICAgIHdvcmtlcnMucHVzaChjb3B5V29ya2VyKCkuY2F0Y2goKGU6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0b3AgdGhlIG90aGVyIHdvcmtlcnMgcHVsbGluZyBuZXcgZmlsZXMsIHRoZW4gc3VyZmFjZSB0aGUgZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgZmFpbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbCh3b3JrZXJzKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwocHJvZ3Jlc3NUaW1lcik7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHNsb3dFcnJvclRpbWVyKTtcbiAgICAgICAgICAgIHRoaXMuc3luY0FjdGl2aXRpZXMuZGVsZXRlKGFjdGl2aXR5KTtcbiAgICAgICAgICAgIC8vIEEgc3luYyBzbG93IGVub3VnaCB0byBoYXZlIGxvZ2dlZCBwcm9ncmVzcyBhbHNvIGxvZ3MgaXRzIGNvbXBsZXRpb25cbiAgICAgICAgICAgIGlmIChwcm9ncmVzc0xvZ2dlZCkge1xuICAgICAgICAgICAgICAgIGxvZ1Byb2dyZXNzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBmaW5kSW5mbyBhbmQgZ2V0Q2hhbmdlc0FmdGVyMiBsaXN0IGZyb20gdGhlIGluZGV4LCBzbyB0aGV5IG11c3Qgd2FpdCBmb3Igb3VyIG93biBiYXNlIHNvdXJjZSdzIGluaXRpYWwgc2NhbiAod2hpY2ggbWlnaHQgbGFnIG1pbnV0ZXMpIGJlZm9yZSB0aGUgbGlzdGluZyBpcyB0cnVzdHdvcnRoeS4gVGhlIGJhc2UgKGxvY2FsIGRpc2spIGlzIGltcGxpY2l0bHkgcmVxdWlyZWQgLSByZW1vdGUgc291cmNlcyBhcmUgbm90LCB0aGV5IGNvbWUgYW5kIGdvLlxuICAgIHByaXZhdGUgYXN5bmMgd2FpdEZvclJlcXVpcmVkU2NhbnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuc291cmNlU3RhdGVzWzBdLmluaXRpYWxTY2FuLnByb21pc2U7XG4gICAgfVxuXG4gICAgLy8gQSByZXF1ZXN0ZWQgZmlsZSBpc24ndCBpbiB0aGUgaW5kZXg6IG91ciBvd24gYmFzZSBzb3VyY2UgKGltcGxpY2l0bHkgcmVxdWlyZWQpIGlzIGNoZWNrZWQgZGlyZWN0bHkgaWYgaXRzIGluaXRpYWwgc2NhbiBoYXNuJ3QgZmluaXNoZWQsIGFuZCBjaGFuZ2VzLWFmdGVyIHNvdXJjZXMgYXJlIHJlLXBvbGxlZCAoYXQgbW9zdCBldmVyeSA1IHNlY29uZHMpXG4gICAgcHJpdmF0ZSBhc3luYyBjaGVja01pc3NpbmdLZXkoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnNvdXJjZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0xpdmUoaSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgbGV0IHsgc291cmNlIH0gPSB0aGlzLnNvdXJjZXNbaV07XG4gICAgICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLnNvdXJjZVN0YXRlc1tpXTtcbiAgICAgICAgICAgIGlmIChpID09PSAwICYmICFzdGF0ZS5zY2FuQ29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICAvLyBpbmNsdWRlVG9tYnN0b25lczogYSBkZWxldGlvbiBvbiBkaXNrIChhbiBlbXB0eSBmaWxlKSBtdXN0IGJlIGluZ2VzdGVkIGFzIGEgdG9tYnN0b25lLCB3cml0ZSB0aW1lIGluY2x1ZGVkXG4gICAgICAgICAgICAgICAgbGV0IGluZm8gPSBhd2FpdCBzb3VyY2UuZ2V0SW5mbyhrZXksIHsgaW5jbHVkZVRvbWJzdG9uZXM6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGluZm8pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVTY2FuSW5kZXgoaSwgeyBwYXRoOiBrZXksIGNyZWF0ZVRpbWU6IGluZm8ud3JpdGVUaW1lLCBzaXplOiBpbmZvLnNpemUgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN0YXRlLnN1cHBvcnRzQ2hhbmdlc0FmdGVyICYmIERhdGUubm93KCkgLSBzdGF0ZS5sYXN0TWlzc0NoZWNrID4gTUlTU19DSEVDS19JTlRFUlZBTCkge1xuICAgICAgICAgICAgICAgIHN0YXRlLmxhc3RNaXNzQ2hlY2sgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucG9sbENoYW5nZXMoaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGdldEluZGV4RW50cnkoa2V5OiBzdHJpbmcpOiBQcm9taXNlPEluZGV4RW50cnkgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgLy8gQW4gZW50cnkgd2hvc2UgaG9sZGVyIGlzIG5vIGxvbmdlciBpbiB0aGUgc291cmNlIGxpc3QgaXMgc3RpbGwgdmFsaWQgLSBnZXRFbnRyeUhvbGRlciByZXNvbHZlcyB0aGUgcGVyc2lzdGVkIFVSTCBkaXJlY3RseSAoYW5kIGdldDIncyBmYWxsYmFjayBsb29wIGNvdmVycyBhIGhvbGRlciB0aGF0IGlzIGdvbmUgZW50aXJlbHkpXG4gICAgICAgIGxldCBlbnRyeSA9IHRoaXMubWVtLmdldChrZXkpO1xuICAgICAgICBpZiAoZW50cnkpIHJldHVybiBlbnRyeTtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja01pc3NpbmdLZXkoa2V5KTtcbiAgICAgICAgcmV0dXJuIHRoaXMubWVtLmdldChrZXkpO1xuICAgIH1cblxuICAgIC8qKiBJbnRlcm5hbCAoc3RvcmUtdG8tc3RvcmUpIHJlYWQ6IHB1cmVseSB0aGUgbG9jYWwgZGlzaywgY29tcGxldGVseSBzaG9ydC1jaXJjdWl0aW5nIHRoZSBpbmRleCBhbmQgaG9sZGVyIHJlc29sdXRpb24gLSB0aGUgY2FsbGVyIGlzIGFub3RoZXIgc3RvcmUsIGFuZCBjaGFzaW5nIE9VUiByZW1vdGUgaG9sZGVycyB3aGlsZSBhbnN3ZXJpbmcgaXQgaXMgaG93IGluZmluaXRlIGdldCBsb29wcyBiZXR3ZWVuIHN0b3JlcyBmb3JtLiBObyB3aW5kb3cgb3Igcm91dGUgY2hlY2tzOiBpZiB0aGUgYnl0ZXMgYXJlIG9uIG91ciBkaXNrLCB0aGUgY2FsbGVyIG1heSBoYXZlIHRoZW0uIE5vdGUgZmFzdCB3cml0ZXMgc3RpbGwgc2l0dGluZyBpbiB0aGUgb3ZlcmxheSBhcmUgaW52aXNpYmxlIGhlcmU7IHRoZSBjYWxsZXIgcmUtZmluZHMgdGhlbSBhZnRlciBvdXIgZmx1c2guICovXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRJbnRlcm5hbDIoY29uZmlnOiB7IHBhdGg6IHN0cmluZzsgcmFuZ2U/OiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH07IGluY2x1ZGVUb21ic3RvbmVzPzogYm9vbGVhbiB9KTogUHJvbWlzZTx7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICAvLyBpbmNsdWRlVG9tYnN0b25lcyBmb3J3YXJkcyB0byB0aGUgZGlzazogYSBmbGFnLWNhbGxlciAoYSBwZWVyIHN0b3JlJ3Mgc3luY2hyb25pemF0aW9uKSBuZWVkcyB0byBzZWUgb3VyIGRlbGV0aW9ucywgbm90IGp1c3Qgb3VyIGNvbnRlbnQuIEEgdG9tYnN0b25lIGRlbGV0ZWQgZnJvbSBkaXNrIGVudGlyZWx5IG9ubHkgbGl2ZXMgaW4gb3VyIGluZGV4LCBzbyBmYWxsIGJhY2sgdG8gdGhhdC5cbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZ2V0RGlza1NvdXJjZSgpLmRpc2suZ2V0Mihjb25maWcucGF0aCwgeyByYW5nZTogY29uZmlnLnJhbmdlLCBpbmNsdWRlVG9tYnN0b25lczogY29uZmlnLmluY2x1ZGVUb21ic3RvbmVzIH0pO1xuICAgICAgICBpZiAoIXJlc3VsdCB8fCAhcmVzdWx0LmRhdGEpIHtcbiAgICAgICAgICAgIGlmIChjb25maWcuaW5jbHVkZVRvbWJzdG9uZXMpIHtcbiAgICAgICAgICAgICAgICBsZXQgZW50cnkgPSB0aGlzLm1lbS5nZXQoY29uZmlnLnBhdGgpO1xuICAgICAgICAgICAgICAgIGlmIChlbnRyeSAmJiAhZW50cnkuc2l6ZSkgcmV0dXJuIHsgZGF0YTogQnVmZmVyLmFsbG9jKDApLCB3cml0ZVRpbWU6IGVudHJ5LndyaXRlVGltZSwgc2l6ZTogMCB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBkYXRhOiByZXN1bHQuZGF0YSwgd3JpdGVUaW1lOiByZXN1bHQud3JpdGVUaW1lLCBzaXplOiByZXN1bHQuc2l6ZSB9O1xuICAgIH1cblxuICAgIC8qKiBJbnRlcm5hbCAoc3RvcmUtdG8tc3RvcmUpIHdyaXRlOiB0aGUgbG9jYWwgZGlzayBwbHVzIG91ciBpbmRleCwgd2l0aCBOTyBkb3duc3RyZWFtIGZhbi1vdXQgLSB0aGUgcHVzaGluZyBzdG9yZSBvd25zIHByb3BhZ2F0aW9uLCBhbmQgZmFubmluZyBpdHMgcHVzaGVzIGJhY2sgb3V0IGlzIGhvdyB3cml0ZSBsb29wcyBiZXR3ZWVuIHN0b3JlcyBmb3JtLiBPbmx5LXRha2UtbGF0ZXN0IHN0aWxsIGFwcGxpZXMgaGVyZS4gKi9cbiAgICBwcml2YXRlIGFzeW5jIHNldEludGVybmFsKGtleTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZzogeyBsYXN0TW9kaWZpZWQ6IG51bWJlciB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5pdCgpO1xuICAgICAgICBhc3NlcnRWYWxpZExhc3RNb2RpZmllZChjb25maWcubGFzdE1vZGlmaWVkKTtcbiAgICAgICAgbGV0IG92ZXJsYXlFbnRyeSA9IHRoaXMub3ZlcmxheS5nZXQoa2V5KTtcbiAgICAgICAgbGV0IGVudHJ5ID0gdGhpcy5tZW0uZ2V0KGtleSk7XG4gICAgICAgIGxldCBjdXJyZW50VGltZSA9IG92ZXJsYXlFbnRyeSAmJiBvdmVybGF5RW50cnkudCB8fCBlbnRyeSAmJiBlbnRyeS53cml0ZVRpbWUgfHwgMDtcbiAgICAgICAgaWYgKGNvbmZpZy5sYXN0TW9kaWZpZWQgPCBjdXJyZW50VGltZSkgcmV0dXJuO1xuICAgICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEEgdG9tYnN0b25lIHN0b3JlcyBub3RoaW5nIG9uIG91ciBvd24gc291cmNlIC0gdGhlIGluZGV4IGVudHJ5IGFsb25lIHJlY29yZHMgaXRcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc291cmNlc1swXS5zb3VyY2UuZGVsKGtleSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZXNbMF0uc291cmNlLnNldChrZXksIGRhdGEsIHsgbGFzdE1vZGlmaWVkOiBjb25maWcubGFzdE1vZGlmaWVkLCBmb3JjZVNldEltbXV0YWJsZTogdHJ1ZSwgbm9DaGVja3M6IHRydWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRJbmRleEVudHJ5KGtleSwgeyB3cml0ZVRpbWU6IGNvbmZpZy5sYXN0TW9kaWZpZWQsIHNpemU6IGRhdGEubGVuZ3RoLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCkgfSk7XG4gICAgfVxuXG4gICAgLy8gVGhlIHJlYWQncyBieXRlcyBjYW1lIGZyb20gYSByZW1vdGUgc291cmNlLCBzbyB3cml0ZSB0aGVtIG9udG8gb3VyIG93biBiYXNlIHNvdXJjZSAodGhlIGxvY2FsIGRpc2spLCB3aGljaCBiZWNvbWVzIHRoZSBlbnRyeSdzIG5ldyBob2xkZXIgLSByZWFkcyBvbmx5IHBheSB0aGUgcmVtb3RlIGZldGNoIG9uY2VcbiAgICBwcml2YXRlIGFzeW5jIGNhY2hlUmVhZChrZXk6IHN0cmluZywgcmVzdWx0OiB7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXIgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZXNbMF0uc291cmNlLnNldChrZXksIHJlc3VsdC5kYXRhLCB7IGxhc3RNb2RpZmllZDogcmVzdWx0LndyaXRlVGltZSwgZm9yY2VTZXRJbW11dGFibGU6IHRydWUsIG5vQ2hlY2tzOiB0cnVlIH0pO1xuICAgICAgICB0aGlzLnNldEluZGV4RW50cnkoa2V5LCB7IHdyaXRlVGltZTogcmVzdWx0LndyaXRlVGltZSwgc2l6ZTogcmVzdWx0LmRhdGEubGVuZ3RoLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoMCkgfSk7XG4gICAgfVxuXG4gICAgLy8gVGhlIHNoYXJlZCBlbmdpbmUgb2Ygc2V0IGFuZCBkZWw6IGFuIGVtcHR5IGJ1ZmZlciBpcyBleGFjdGx5IGEgZGVsZXRpb24gaGVyZSwgd2hpY2ggaXMgd2h5IHRoZSBlbXB0eS1idWZmZXIgcmVqZWN0aW9uIGxpdmVzIGluIHNldCAodGhlIHB1YmxpYyBBUEkpLCBub3QgaW4gdGhpcyBtYWNoaW5lcnlcbiAgICBwcml2YXRlIGFzeW5jIHNldE9yRGVsZXRlKGtleTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZzogeyBmYXN0PzogYm9vbGVhbjsgd3JpdGVEZWxheT86IG51bWJlcjsgbGFzdE1vZGlmaWVkPzogbnVtYmVyIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5jb25maWc/Lm9uV3JpdGVDb3VudGVkPy4oXCJvcmlnaW5hbFwiLCBkYXRhLmxlbmd0aCk7XG4gICAgICAgIGxldCBsYXN0TW9kaWZpZWQgPSBjb25maWcubGFzdE1vZGlmaWVkO1xuICAgICAgICBpZiAobGFzdE1vZGlmaWVkKSB7XG4gICAgICAgICAgICBhc3NlcnRWYWxpZExhc3RNb2RpZmllZChsYXN0TW9kaWZpZWQpO1xuICAgICAgICAgICAgbGV0IG92ZXJsYXlFbnRyeSA9IHRoaXMub3ZlcmxheS5nZXQoa2V5KTtcbiAgICAgICAgICAgIGxldCBlbnRyeSA9IHRoaXMubWVtLmdldChrZXkpO1xuICAgICAgICAgICAgbGV0IGN1cnJlbnRUaW1lID0gb3ZlcmxheUVudHJ5ICYmIG92ZXJsYXlFbnRyeS50IHx8IGVudHJ5ICYmIGVudHJ5LndyaXRlVGltZSB8fCAwO1xuICAgICAgICAgICAgLy8gQW4gb2xkZXIgd3JpdGUgbmV2ZXIgb3ZlcndyaXRlcyBhIG5ld2VyIG9uZSAoc2VlIElBcmNoaXZlcy5zZXQpXG4gICAgICAgICAgICBpZiAobGFzdE1vZGlmaWVkIDwgY3VycmVudFRpbWUpIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgd3JpdGVUaW1lID0gbGFzdE1vZGlmaWVkIHx8IERhdGUubm93KCk7XG4gICAgICAgIGlmIChjb25maWcuZmFzdCkge1xuICAgICAgICAgICAgLy8gQSB3cml0ZURlbGF5IG9mIHplcm8gaXMgYSByZWFsIGNob2ljZSAobm8gZGVsYXkgYXQgYWxsKSwgc28gb25seSBhbiBvbWl0dGVkIGRlbGF5IGdldHMgdGhlIGRlZmF1bHRcbiAgICAgICAgICAgIGxldCB3cml0ZURlbGF5ID0gY29uZmlnLndyaXRlRGVsYXk7XG4gICAgICAgICAgICBpZiAod3JpdGVEZWxheSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgd3JpdGVEZWxheSA9IERFRkFVTFRfRkFTVF9XUklURV9ERUxBWTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRoZSBkZWxheSBuZXZlciBleHRlbmRzIHBhc3Qgb3VyIG93biB2YWxpZCB3aW5kb3cncyBlbmQgKG1pbnVzIHRoZSBtYXJnaW4sIHNvIHRoZSB3cml0ZXMgYXJlIG9uIGRpc2sgYmVmb3JlIHRoZSBuZXh0IHdpbmRvdydzIHNvdXJjZSB0YWtlcyBvdmVyIC0gYSBkZXBsb3kgc3dpdGNob3ZlciBpcyBqdXN0IHRoaXMgdG9vLCBzaW5jZSBpdHMgcmVtYXAgZW5kcyBvdXIgd2luZG93KS4gUGFzdCB0aGF0IHBvaW50IGZhc3Qgd3JpdGVzIHdyaXRlIHRocm91Z2ggaW1tZWRpYXRlbHkuXG4gICAgICAgICAgICBsZXQgZGVhZGxpbmUgPSB0aGlzLnNvdXJjZXNbMF0udmFsaWRXaW5kb3dbMV0gLSBXSU5ET1dfRU5EX0ZMVVNIX01BUkdJTjtcbiAgICAgICAgICAgIGlmICh3cml0ZURlbGF5ID4gMCAmJiBEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgZmx1c2hBdCA9IE1hdGgubWluKERhdGUubm93KCkgKyB3cml0ZURlbGF5LCBkZWFkbGluZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5vdmVybGF5LnNldChrZXksIHsgZGF0YSwgdDogd3JpdGVUaW1lLCBmbHVzaEF0IH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm92ZXJsYXkuZGVsZXRlKGtleSk7XG4gICAgICAgIGF3YWl0IHRoaXMud3JpdGVUb1NvdXJjZXMoa2V5LCBkYXRhLCB3cml0ZVRpbWUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0V3JpdGFibGVTb3VyY2VzKGNvbmZpZz86IHsgaWdub3JlV2luZG93PzogYm9vbGVhbiB9KTogbnVtYmVyW10ge1xuICAgICAgICBsZXQgd3JpdGFibGU6IG51bWJlcltdID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNMaXZlKGkpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmICghY29uZmlnPy5pZ25vcmVXaW5kb3cgJiYgIXdpbmRvd0FjY2VwdHNXcml0ZXModGhpcy5zb3VyY2VzW2ldLnZhbGlkV2luZG93KSkgY29udGludWU7XG4gICAgICAgICAgICB3cml0YWJsZS5wdXNoKGkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB3cml0YWJsZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHdyaXRlVG9Tb3VyY2VzKGtleTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIHdyaXRlVGltZTogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIC8vIFRoZSByb3V0aW5nIGZpbGUgaXMgTkVWRVIgc3luY2hyb25pemVkIGJldHdlZW4gc3RvcmFnZSBub2RlczogdGhlIHdyaXRlciB3cml0ZXMgaXQgZGlyZWN0bHkgdG8gZWFjaCBub2RlLCBzbyB3ZSBzdG9yZSBpdCBvbiBvdXIgb3duIGRpc2sgb25seSAobm8gdmFsaWQtd2luZG93IGZpbHRlciAtIHJvdXRpbmcvdmFsaWQgd2luZG93cyBjYW4ndCBwb3NzaWJseSBhcHBseSB0byB0aGUgZmlsZSBkZWZpbmluZyB0aGVtKSBhbmQgbmV2ZXIgZm9yd2FyZCBpdCB0byBvdGhlciBzb3VyY2VzLlxuICAgICAgICB0aGlzLmNvbmZpZz8ub25Xcml0ZUNvdW50ZWQ/LihcImZsdXNoZWRcIiwgZGF0YS5sZW5ndGgpO1xuICAgICAgICBsZXQgaXNSb3V0aW5nID0ga2V5ID09PSBST1VUSU5HX0ZJTEU7XG4gICAgICAgIGxldCB3cml0YWJsZSA9IHRoaXMuZ2V0V3JpdGFibGVTb3VyY2VzKHsgaWdub3JlV2luZG93OiBpc1JvdXRpbmcgfSk7XG4gICAgICAgIGxldCBmaXJzdCA9IHdyaXRhYmxlLnNoaWZ0KCk7XG4gICAgICAgIGlmIChmaXJzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHNvdXJjZSBhY2NlcHRzIHdyaXRlcyAoZXZlcnkgc291cmNlJ3MgdmFsaWQgd2luZG93IGlzIGluIHRoZSBwYXN0KSwgc28gd3JpdGVzIGNhbm5vdCBiZSBzdG9yZWQgKHN0b3JlICR7dGhpcy5mb2xkZXJ9KWApO1xuICAgICAgICB9XG4gICAgICAgIC8vIE9ubHkgb3VyIG93biAoZmlyc3QpIHNvdXJjZSBibG9ja3MgdGhlIHdyaXRlLiBEb3duc3RyZWFtIHNvdXJjZXMgYXJlIHdyaXR0ZW4gaW4gdGhlIGJhY2tncm91bmQ6IGEgZG93biBkb3duc3RyZWFtIHNvdXJjZSBtdXN0IG5vdCBmYWlsIG9yIHN0YWxsIHdyaXRlcywgYW5kIHJlY29uY2lsZVNvdXJjZSByZS1zZW5kcyBhbnl0aGluZyB0aGV5IG1pc3NlZCBvbmNlIHRoZXkgY29tZSBiYWNrLlxuICAgICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEEgdG9tYnN0b25lIHN0b3JlcyBub3RoaW5nIG9uIG91ciBvd24gc291cmNlIC0gdGhlIGluZGV4IGVudHJ5IGFsb25lIHJlY29yZHMgaXRcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc291cmNlc1tmaXJzdF0uc291cmNlLmRlbChrZXkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5zb3VyY2VzW2ZpcnN0XS5zb3VyY2Uuc2V0KGtleSwgZGF0YSwgeyBsYXN0TW9kaWZpZWQ6IHdyaXRlVGltZSwgbm9DaGVja3M6IHRydWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRJbmRleEVudHJ5KGtleSwgeyB3cml0ZVRpbWUsIHNpemU6IGRhdGEubGVuZ3RoLCBzb3VyY2VzTGlzdEluZGV4OiB0aGlzLnNvdXJjZXNMaXN0SW5kZXhPZlNsb3QoZmlyc3QpIH0pO1xuICAgICAgICBpZiAoaXNSb3V0aW5nKSByZXR1cm47XG4gICAgICAgIGxldCByb3V0ZSA9IGdldFJvdXRlKGtleSk7XG4gICAgICAgIGZvciAobGV0IGkgb2Ygd3JpdGFibGUpIHtcbiAgICAgICAgICAgIGlmICghcm91dGVDb250YWlucyh0aGlzLnNvdXJjZXNbaV0ucm91dGUsIHJvdXRlKSkgY29udGludWU7XG4gICAgICAgICAgICAvLyBEZWxldGlvbnMgdHJhdmVsIGFzIGRlbCBjYXJyeWluZyB0aGUgb3JpZ2luYWwgd3JpdGUgdGltZSAobmV2ZXIgYXMgZW1wdHkgc2V0cyAtIHNldCByZWplY3RzIGVtcHR5IGJ1ZmZlcnMpLiBCYWNrYmxhemUgbWF0ZXJpYWxpemVzIHN1Y2ggZGVscyBhcyByZWFsIGVtcHR5IGZpbGVzLCBzbyBpdHMgbGlzdGluZ3Mgc3RpbGwgc2hvdyB0aGUgZGVsZXRpb24gZm9yIG90aGVyIHN0b3JlcyB0byBzY2FuIGluIGFzIGEgdG9tYnN0b25lLlxuICAgICAgICAgICAgbGV0IHB1c2g6IFByb21pc2U8dW5rbm93bj47XG4gICAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICBwdXNoID0gdGhpcy5zb3VyY2VzW2ldLnNvdXJjZS5kZWwoa2V5LCB7IGxhc3RNb2RpZmllZDogd3JpdGVUaW1lLCBub0NoZWNrczogdHJ1ZSwgaW50ZXJuYWw6IHRydWUgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHB1c2ggPSB0aGlzLnNvdXJjZXNbaV0uc291cmNlLnNldChrZXksIGRhdGEsIHsgbGFzdE1vZGlmaWVkOiB3cml0ZVRpbWUsIGZvcmNlU2V0SW1tdXRhYmxlOiB0cnVlLCBub0NoZWNrczogdHJ1ZSwgaW50ZXJuYWw6IHRydWUgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2b2lkIHB1c2guY2F0Y2goKGU6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQmFja2dyb3VuZCB3cml0ZSBvZiAke2tleX0gdG8gc3luYyBzb3VyY2UgJHt0aGlzLnNvdXJjZXNbaV0uc291cmNlLmdldERlYnVnTmFtZSgpfSBmYWlsZWQ6ICR7ZS5zdGFjayA/PyBlfWApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERpc2tTb3VyY2UoKTogeyBkaXNrOiBBcmNoaXZlc0Rpc2s7IHNvdXJjZUluZGV4OiBudW1iZXIgfSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgc291cmNlID0gdGhpcy5zb3VyY2VzW2ldLnNvdXJjZTtcbiAgICAgICAgICAgIGlmIChzb3VyY2UgaW5zdGFuY2VvZiBBcmNoaXZlc0Rpc2spIHJldHVybiB7IGRpc2s6IHNvdXJjZSwgc291cmNlSW5kZXg6IGkgfTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYExhcmdlIHVwbG9hZHMgcmVxdWlyZSBhbiBBcmNoaXZlc0Rpc2sgc291cmNlLCBhbmQgdGhpcyBzdG9yZSBoYXMgbm9uZSAoc3RvcmUgJHt0aGlzLmZvbGRlcn0pYCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBmbHVzaE92ZXJsYXkoZm9yY2U/OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICBmb3IgKGxldCBba2V5LCBlbnRyeV0gb2YgdGhpcy5vdmVybGF5KSB7XG4gICAgICAgICAgICBpZiAoIWZvcmNlICYmIGVudHJ5LmZsdXNoQXQgPiBub3cpIGNvbnRpbnVlO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy53cml0ZVRvU291cmNlcyhrZXksIGVudHJ5LmRhdGEsIGVudHJ5LnQpO1xuICAgICAgICAgICAgLy8gT25seSByZW1vdmUgaWYgaXQgd2Fzbid0IG92ZXJ3cml0dGVuIHdoaWxlIHdlIHdlcmUgZmx1c2hpbmdcbiAgICAgICAgICAgIGlmICh0aGlzLm92ZXJsYXkuZ2V0KGtleSkgPT09IGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vdmVybGF5LmRlbGV0ZShrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gcmVhZGVyRGlza0xpbWl0OiB0aGUgZGlzayBpcyBvbmx5IGEgYm91bmRlZCByZWFkIGNhY2hlLCBzbyBvbmNlIGl0IGV4Y2VlZHMgdGhlIGxpbWl0LCB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZCBmaWxlcyBhcmUgZGVsZXRlZCBmcm9tIGl0IC0gYnV0IE9OTFkgd2hlbiBhbm90aGVyIHNvdXJjZSB2ZXJpZmlhYmx5IGhvbGRzIGEgc2FtZS1vci1uZXdlciBjb3B5ICh0aGUgb25seSBjb3B5IG9mIGEgZmlsZSBpcyBuZXZlciBkZWxldGVkKSwgYW5kIHRoZSBpbmRleCBlbnRyeSByZXBvaW50cyB0byB0aGF0IHNvdXJjZSBzbyByZWFkcyBrZWVwIHdvcmtpbmcgKHJlLWNhY2hpbmcgb24gdGhlIG5leHQgcmVhZCkuXG4gICAgcHJpdmF0ZSBldmljdGluZyA9IGZhbHNlO1xuICAgIHByaXZhdGUgYXN5bmMgZW5mb3JjZURpc2tMaW1pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IGxpbWl0ID0gdGhpcy5jb25maWc/LnJlYWRlckRpc2tMaW1pdDtcbiAgICAgICAgaWYgKCFsaW1pdCB8fCB0aGlzLmV2aWN0aW5nKSByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLnNvdXJjZUJ5dGVDb3VudHNbMF0gPD0gbGltaXQpIHJldHVybjtcbiAgICAgICAgdGhpcy5ldmljdGluZyA9IHRydWU7XG4gICAgICAgIGxldCBldmljdGVkRmlsZXMgPSAwO1xuICAgICAgICBsZXQgZXZpY3RlZEJ5dGVzID0gMDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBiYXNlU291cmNlc0xpc3RJbmRleCA9IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdCgwKTtcbiAgICAgICAgICAgIGxldCBjYW5kaWRhdGVzOiB7IGtleTogc3RyaW5nOyBlbnRyeTogSW5kZXhFbnRyeSB9W10gPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IFtrZXksIGVudHJ5XSBvZiB0aGlzLm1lbSkge1xuICAgICAgICAgICAgICAgIGlmIChlbnRyeS5zb3VyY2VzTGlzdEluZGV4ICE9PSBiYXNlU291cmNlc0xpc3RJbmRleCB8fCBlbnRyeS5zaXplID09PSAwIHx8IGtleSA9PT0gUk9VVElOR19GSUxFKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBjYW5kaWRhdGVzLnB1c2goeyBrZXksIGVudHJ5IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc29ydChjYW5kaWRhdGVzLCB4ID0+IHguZW50cnkubGFzdEFjY2Vzcyk7XG4gICAgICAgICAgICBmb3IgKGxldCB7IGtleSwgZW50cnkgfSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RvcHBlZC5zdG9wKSByZXR1cm47XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc291cmNlQnl0ZUNvdW50c1swXSA8PSBsaW1pdCkgYnJlYWs7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubWVtLmdldChrZXkpICE9PSBlbnRyeSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgbGV0IGhvbGRlcjogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgdGhpcy5zb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0xpdmUoaSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGluZm8gPSBhd2FpdCB0aGlzLnNvdXJjZXNbaV0uc291cmNlLmdldEluZm8oa2V5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmZvICYmIGluZm8ud3JpdGVUaW1lID49IGVudHJ5LndyaXRlVGltZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGRlciA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSBkb3duIHNvdXJjZSBqdXN0IGNhbid0IHZvdWNoIGZvciB0aGlzIGZpbGUgcmlnaHQgbm93XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGhvbGRlciA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZXNbMF0uc291cmNlLmRlbChrZXkpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0SW5kZXhFbnRyeShrZXksIHsgd3JpdGVUaW1lOiBlbnRyeS53cml0ZVRpbWUsIHNpemU6IGVudHJ5LnNpemUsIHNvdXJjZXNMaXN0SW5kZXg6IHRoaXMuc291cmNlc0xpc3RJbmRleE9mU2xvdChob2xkZXIpIH0pO1xuICAgICAgICAgICAgICAgIGV2aWN0ZWRGaWxlcysrO1xuICAgICAgICAgICAgICAgIGV2aWN0ZWRCeXRlcyArPSBlbnRyeS5zaXplO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5ldmljdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGV2aWN0ZWRGaWxlcykge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBEaXNrIGNhY2hlIG92ZXIgcmVhZGVyRGlza0xpbWl0IChzdG9yZSAke3RoaXMuZm9sZGVyfSk6IGV2aWN0ZWQgJHtldmljdGVkRmlsZXN9IGxlYXN0LXJlY2VudGx5LXVzZWQgZmlsZXMgKCR7Zm9ybWF0TnVtYmVyKGV2aWN0ZWRCeXRlcyl9QiksIG5vdyBhdCAke2Zvcm1hdE51bWJlcih0aGlzLnNvdXJjZUJ5dGVDb3VudHNbMF0pfUIvJHtmb3JtYXROdW1iZXIodGhpcy5jb25maWc/LnJlYWRlckRpc2tMaW1pdCB8fCAwKX1CYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUb21ic3RvbmVzIG9ubHkgbmVlZCB0byBleGlzdCBsb25nIGVub3VnaCBmb3IgZXZlcnkgc3RvcmUgdG8gbGVhcm4gb2YgdGhlIGRlbGV0aW9uOyBleHBpcmVkIG9uZXMgY29tZSBvdXQgb2YgdGhlIGluZGV4LiBUaGUgcGh5c2ljYWwgZW1wdHkgZmlsZSBpcyByZW1vdmVkIG9ubHkgb24gYmFja2JsYXplIHNvdXJjZXM6IHJlbW90ZSBzdG9yZXMgZXhwaXJlIHRoZWlyIG93biB0b21ic3RvbmVzIChhIGRlbCB0aGVyZSB3b3VsZCBqdXN0IG1pbnQgYSBmcmVzaCBvbmUpLCBhbmQgb3VyIG93biBkaXNrIG5ldmVyIHN0b3JlZCBhbnl0aGluZyBmb3IgaXQuXG4gICAgcHJpdmF0ZSBhc3luYyBjbGVhbnVwVG9tYnN0b25lcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IGN1dG9mZiA9IERhdGUubm93KCkgLSBUT01CU1RPTkVfRVhQSVJZO1xuICAgICAgICBmb3IgKGxldCBba2V5LCBlbnRyeV0gb2YgdGhpcy5tZW0pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0b3BwZWQuc3RvcCkgcmV0dXJuO1xuICAgICAgICAgICAgaWYgKGVudHJ5LnNpemUgIT09IDApIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKGVudHJ5LndyaXRlVGltZSA+IGN1dG9mZikgY29udGludWU7XG4gICAgICAgICAgICB0aGlzLmRlbGV0ZUluZGV4RW50cnkoa2V5KTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzTGl2ZShpKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgbGV0IHNvdXJjZUVudHJ5ID0gdGhpcy5zb3VyY2VzW2ldO1xuICAgICAgICAgICAgICAgIGlmICghd2luZG93QWNjZXB0c1dyaXRlcyhzb3VyY2VFbnRyeS52YWxpZFdpbmRvdykpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGxldCBzb3VyY2UgPSBzb3VyY2VFbnRyeS5zb3VyY2U7XG4gICAgICAgICAgICAgICAgaWYgKCEoc291cmNlIGluc3RhbmNlb2YgQXJjaGl2ZXNCYWNrYmxhemUpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB2b2lkIHNvdXJjZS5kZWwoa2V5KS5jYXRjaCgoZTogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgUmVtb3ZpbmcgZXhwaXJlZCB0b21ic3RvbmUgJHtrZXl9IGZyb20gJHtzb3VyY2UuZ2V0RGVidWdOYW1lKCl9IGZhaWxlZDogJHtlLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAjZW5kcmVnaW9uXG59XG4iXX0=
|
|
1364
|
+
/* _JS_SOURCE_HASH = "1a8210ad608550d6d7c44b55d09d9e0b16b4839245ec59008055c6d4a72a675c"; */
|