sliftutils 1.7.89 → 1.7.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +36 -81
- package/misc/https/dist/cloudflareHelpers.ts.cache +2 -2
- package/misc/https/dist/dns.ts.cache +2 -2
- package/package.json +1 -1
- 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/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/dist/ArchivesDisk.ts.cache +2 -2
- package/storage/dist/IArchives.ts.cache +2 -2
- package/storage/dist/archiveHelpers.ts.cache +87 -0
- package/storage/dist/backblaze.ts.cache +2 -2
- package/storage/remoteStorage/accessStats.d.ts +12 -0
- package/storage/remoteStorage/accessStats.ts +47 -0
- package/storage/remoteStorage/blobStore.d.ts +3 -1
- package/storage/remoteStorage/blobStore.ts +5 -0
- package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +2 -2
- package/storage/remoteStorage/dist/accessStats.ts.cache +42 -3
- package/storage/remoteStorage/dist/blobStore.ts.cache +7 -4
- package/storage/remoteStorage/dist/createArchives.ts.cache +2 -2
- package/storage/remoteStorage/dist/intermediateManagement.ts.cache +56 -50
- package/storage/remoteStorage/dist/storageController.ts.cache +47 -58
- package/storage/remoteStorage/dist/storageServerState.ts.cache +119 -248
- package/storage/remoteStorage/dist/storeConfig.ts.cache +2 -2
- package/storage/remoteStorage/dist/storePlan.ts.cache +4 -56
- package/storage/remoteStorage/dist/storeSync.ts.cache +6 -5
- package/storage/remoteStorage/intermediateManagement.d.ts +2 -3
- package/storage/remoteStorage/intermediateManagement.ts +53 -46
- package/storage/remoteStorage/storageController.ts +35 -44
- package/storage/remoteStorage/storageServerState.d.ts +17 -57
- package/storage/remoteStorage/storageServerState.ts +112 -279
- package/storage/remoteStorage/storeConfig.d.ts +2 -0
- package/storage/remoteStorage/storeConfig.ts +2 -0
- package/storage/remoteStorage/storePlan.d.ts +0 -20
- package/storage/remoteStorage/storePlan.ts +1 -69
|
@@ -1,47 +1,86 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
3
|
-
//exports.
|
|
3
|
+
//exports.debugListAccountBuckets = exports.activateBucket = exports.debugGetActiveBucket = exports.getActiveBucketKeys = exports.writeRoutingConfig = exports.resolveSourceArchives = exports.debugBucketIndexTotals = exports.bucketSyncStatus = exports.getBucketArchivesConfig = exports.readBucketInternal = exports.getBucketStores = exports.findBucketStore = exports.getStore = void 0;
|
|
4
4
|
const blobStore_1 = require("./blobStore");
|
|
5
5
|
const remoteConfig_1 = require("./remoteConfig");
|
|
6
6
|
const storeSources_1 = require("./storeSources");
|
|
7
7
|
const storageController_1 = require("./storageController");
|
|
8
8
|
const serverConfig_1 = require("./serverConfig");
|
|
9
|
+
const validation_1 = require("./validation");
|
|
9
10
|
const bucketDisk_1 = require("./bucketDisk");
|
|
10
11
|
const intermediateManagement_1 = require("./intermediateManagement");
|
|
11
12
|
const storePlan_1 = require("./storePlan");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const accessStats_1 = require("./accessStats");
|
|
14
|
+
/**
|
|
15
|
+
* What this server HAS: the stores, by name (getStore) - made once, self-configuring from there -
|
|
16
|
+
* and the three entry points a request resolves through (findBucketStore, readBucketInternal,
|
|
17
|
+
* writeRoutingConfig). There is no cached bucket state: a bucket is nothing but the stores whose
|
|
18
|
+
* folders share its name, listed off the disk when something genuinely needs all of them.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Every store this process runs, by folder - which IS the store's identity: account, name, bucket.
|
|
22
|
+
* A store is made once, configures itself from the routing config it holds, and stays; nothing here
|
|
23
|
+
* decides what it is, only that it exists.
|
|
24
|
+
*/
|
|
25
|
+
const stores = new Map();
|
|
26
|
+
// The opened stores of each `${account}/${bucketName}`, by name - which buckets are ACTIVE (something touched them), for deploy handoffs and the debug pages. Purely a registry of what getStore already made.
|
|
27
|
+
const activeStores = new Map();
|
|
28
|
+
function getStore(account, bucketName, name) {
|
|
29
|
+
// The one place a name becomes a folder, so the one place it is validated (it can come straight off the wire)
|
|
30
|
+
(0, validation_1.assertValidSourceName)(name);
|
|
31
|
+
let folder = (0, bucketDisk_1.getBucketFolder)(name, account, bucketName);
|
|
32
|
+
let existing = stores.get(folder);
|
|
33
|
+
if (existing)
|
|
34
|
+
return existing;
|
|
35
|
+
console.log(`Opening store ${JSON.stringify(name)} of bucket ${account}/${bucketName} (folder ${folder}) - created on this first use if it never existed`);
|
|
36
|
+
let store = new blobStore_1.BlobStore(folder, name, {
|
|
37
|
+
// Which entries in ITS routing config are this server's copy of it
|
|
38
|
+
isSelf: source => (0, storePlan_1.isSelfSource)(source, account, bucketName),
|
|
39
|
+
createSource: config => (0, storeSources_1.createStoreSource)({ sourceConfig: config.sourceConfig, folder, writeDelay: config.writeDelay }),
|
|
40
|
+
applySource: (source, sourceConfig, writeDelay) => (0, storeSources_1.applySourceConfig)(source, sourceConfig, writeDelay),
|
|
41
|
+
onWriteCounted: (kind, bytes) => (0, accessStats_1.countBucketWrite)(`${account}/${bucketName}`, kind, bytes),
|
|
42
|
+
resolveSourceUrl: resolveSourceArchives,
|
|
43
|
+
// The store is the one that knows when a config landed, and a config with upcoming windows is what boundary scans are armed from
|
|
44
|
+
onRoutingApplied: routing => (0, intermediateManagement_1.scheduleBoundaryWork)(account, bucketName, routing),
|
|
45
|
+
});
|
|
46
|
+
stores.set(folder, store);
|
|
47
|
+
let key = `${account}/${bucketName}`;
|
|
48
|
+
let byName = activeStores.get(key);
|
|
49
|
+
if (!byName) {
|
|
50
|
+
byName = new Map();
|
|
51
|
+
activeStores.set(key, byName);
|
|
17
52
|
}
|
|
18
|
-
|
|
53
|
+
byName.set(name, store);
|
|
54
|
+
// Lazy init would leave a store nothing has touched sitting inert - no index loaded, no config applied, nothing synchronizing - while its folder is full of files
|
|
55
|
+
void store.init().catch((e) => { var _a; return console.error(`Initializing store ${JSON.stringify(name)} of bucket ${account}/${bucketName} failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`); });
|
|
56
|
+
return store;
|
|
19
57
|
}
|
|
20
|
-
exports.
|
|
21
|
-
/** The store serving a request: the one the client's selected entry NAMES.
|
|
22
|
-
|
|
23
|
-
let bucket = await requireBucket(account, bucketName);
|
|
58
|
+
exports.getStore = getStore;
|
|
59
|
+
/** The store serving a request: the one the client's selected entry NAMES. Account, name, and bucket ARE the folder, so this is a direct lookup, never a search of what exists - and a name this server has never seen is CREATED, never rejected, because asking for a name is the instruction to have that store (one name, one folder, one index; it configures itself once the routing config lands in it). Nothing else about the request is compared - not the window, not the route, not the flags - which is the whole point of naming it: a client a config version behind on some flag still reaches the right store. */
|
|
60
|
+
function findBucketStore(account, bucketName, sourceConfig) {
|
|
24
61
|
if (!sourceConfig) {
|
|
25
|
-
throw new Error(`No remote source configuration was provided for bucket ${account}/${bucketName}: every request must say which configured source it selected
|
|
26
|
-
}
|
|
27
|
-
let store = bucket.stores.find(x => x.name === sourceConfig.name);
|
|
28
|
-
if (store)
|
|
29
|
-
return store;
|
|
30
|
-
// The loaded bucket is a snapshot of the disk from when it loaded; a store created since (a new name in a rewritten routing config) is on the disk but not in the snapshot, so a miss re-reads the disk once before it is believed
|
|
31
|
-
let previousNames = bucket.stores.map(x => x.name);
|
|
32
|
-
let reloaded = await reloadBucket(account, bucketName);
|
|
33
|
-
store = reloaded === null || reloaded === void 0 ? void 0 : reloaded.stores.find(x => x.name === sourceConfig.name);
|
|
34
|
-
if (store) {
|
|
35
|
-
console.log(`Reloaded bucket ${account}/${bucketName} to find store ${JSON.stringify(sourceConfig.name)}: its stores changed from ${JSON.stringify(previousNames)} to ${JSON.stringify(reloaded === null || reloaded === void 0 ? void 0 : reloaded.stores.map(x => x.name))}`);
|
|
36
|
-
return store;
|
|
62
|
+
throw new Error(`No remote source configuration was provided for bucket ${account}/${bucketName}: every request must say which configured source it selected`);
|
|
37
63
|
}
|
|
38
|
-
|
|
64
|
+
return getStore(account, bucketName, sourceConfig.name);
|
|
39
65
|
}
|
|
40
66
|
exports.findBucketStore = findBucketStore;
|
|
67
|
+
/** The stores of a bucket as the DISK records them (a bucket is nothing more than the store folders sharing its name), opened - so the ones that weren't running yet start synchronizing. Empty when the bucket does not exist here. */
|
|
68
|
+
async function getBucketStores(account, bucketName) {
|
|
69
|
+
let folders = await (0, bucketDisk_1.listBucketStoreFolders)(account, bucketName);
|
|
70
|
+
return folders.map(x => ({ name: x.name, store: getStore(account, bucketName, x.name) }));
|
|
71
|
+
}
|
|
72
|
+
exports.getBucketStores = getBucketStores;
|
|
73
|
+
async function requireBucketStores(account, bucketName) {
|
|
74
|
+
let list = await getBucketStores(account, bucketName);
|
|
75
|
+
if (!list.length) {
|
|
76
|
+
throw new Error(`Bucket ${account}/${bucketName} does not exist on this server. Write its routing config to ${JSON.stringify(remoteConfig_1.ROUTING_FILE)} to create it.`);
|
|
77
|
+
}
|
|
78
|
+
return list;
|
|
79
|
+
}
|
|
41
80
|
/** Internal (store-to-store) reads skip store selection entirely: the caller is another store whose index says this MACHINE holds the bytes - the persisted holder identity is just a URL, which cannot name a store. Whichever store's folder has the newest copy answers. */
|
|
42
81
|
async function readBucketInternal(account, bucketName, config) {
|
|
43
|
-
let
|
|
44
|
-
let results = await Promise.all(
|
|
82
|
+
let bucketStores = await requireBucketStores(account, bucketName);
|
|
83
|
+
let results = await Promise.all(bucketStores.map(s => s.store.get2({ path: config.path, range: config.range, includeTombstones: config.includeTombstones, internal: true })));
|
|
45
84
|
let best;
|
|
46
85
|
for (let result of results) {
|
|
47
86
|
if (result && (!best || result.writeTime > best.writeTime)) {
|
|
@@ -51,13 +90,13 @@ async function readBucketInternal(account, bucketName, config) {
|
|
|
51
90
|
return best;
|
|
52
91
|
}
|
|
53
92
|
exports.readBucketInternal = readBucketInternal;
|
|
54
|
-
function
|
|
93
|
+
function aggregateArchivesConfig(bucketStores, routing) {
|
|
55
94
|
let index = { fileCount: 0, byteCount: 0 };
|
|
56
95
|
let indexSources = [];
|
|
57
96
|
let syncing = [];
|
|
58
97
|
let readerDiskLimit;
|
|
59
|
-
for (let
|
|
60
|
-
let progress =
|
|
98
|
+
for (let store of bucketStores) {
|
|
99
|
+
let progress = store.getSyncProgress();
|
|
61
100
|
index.fileCount += progress.index.fileCount;
|
|
62
101
|
index.byteCount += progress.index.byteCount;
|
|
63
102
|
indexSources.push(...progress.sources);
|
|
@@ -67,16 +106,22 @@ function getBucketConfig(bucket) {
|
|
|
67
106
|
return {
|
|
68
107
|
// Every store is index-backed, so the change feed is always native
|
|
69
108
|
supportsChangesAfter: true,
|
|
70
|
-
remoteConfig:
|
|
109
|
+
remoteConfig: routing,
|
|
71
110
|
index,
|
|
72
111
|
indexSources,
|
|
73
112
|
readerDiskLimit,
|
|
74
113
|
syncing,
|
|
75
114
|
};
|
|
76
115
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
let
|
|
116
|
+
async function getBucketArchivesConfig(account, bucketName) {
|
|
117
|
+
let bucketStores = await requireBucketStores(account, bucketName);
|
|
118
|
+
let routing = await (0, bucketDisk_1.readRoutingFromDisk)(account, bucketName);
|
|
119
|
+
return aggregateArchivesConfig(bucketStores.map(x => x.store), routing);
|
|
120
|
+
}
|
|
121
|
+
exports.getBucketArchivesConfig = getBucketArchivesConfig;
|
|
122
|
+
async function bucketSyncStatus(account, bucketName) {
|
|
123
|
+
let bucketStores = await requireBucketStores(account, bucketName);
|
|
124
|
+
let statuses = await Promise.all(bucketStores.map(s => s.store.getSyncStatus()));
|
|
80
125
|
return {
|
|
81
126
|
allScansComplete: statuses.every(x => x.allScansComplete),
|
|
82
127
|
indexSize: statuses.reduce((sum, x) => sum + x.indexSize, 0),
|
|
@@ -84,23 +129,16 @@ async function bucketSyncStatus(bucket) {
|
|
|
84
129
|
};
|
|
85
130
|
}
|
|
86
131
|
exports.bucketSyncStatus = bucketSyncStatus;
|
|
87
|
-
async function
|
|
88
|
-
let
|
|
132
|
+
async function debugBucketIndexTotals(account, bucketName) {
|
|
133
|
+
let bucketStores = await requireBucketStores(account, bucketName);
|
|
134
|
+
let totals = await Promise.all(bucketStores.map(s => s.store.computeIndexTotals()));
|
|
89
135
|
return {
|
|
90
136
|
fileCount: totals.reduce((sum, x) => sum + x.fileCount, 0),
|
|
91
137
|
byteCount: totals.reduce((sum, x) => sum + x.byteCount, 0),
|
|
92
138
|
sources: totals.flatMap(x => x.sources),
|
|
93
139
|
};
|
|
94
140
|
}
|
|
95
|
-
exports.
|
|
96
|
-
const buckets = new Map();
|
|
97
|
-
// The resolved ones, for the code that walks buckets rather than asking for one (see getBucketStates)
|
|
98
|
-
const loadedBuckets = new Map();
|
|
99
|
-
/** The bucket states currently in memory - what the switchover machinery walks. Only what is loaded: loading a bucket starts its synchronization, and a bucket nothing has touched has no in-flight writes to hand over anyway. */
|
|
100
|
-
function getBucketStates() {
|
|
101
|
-
return [...loadedBuckets.values()];
|
|
102
|
-
}
|
|
103
|
-
exports.getBucketStates = getBucketStates;
|
|
141
|
+
exports.debugBucketIndexTotals = debugBucketIndexTotals;
|
|
104
142
|
const resolvedSourceArchives = new Map();
|
|
105
143
|
/** A cached IArchives for a persisted source identity: a routing URL (hosted/backblaze) or a disk folder path - the form BlobStore's sources list stores. Configuration (valid windows, routes) decides WHEN a source should be used; for reading bytes the index says a source holds, the URL alone is enough - even for sources no longer in any config. */
|
|
106
144
|
function resolveSourceArchives(url) {
|
|
@@ -117,87 +155,6 @@ function resolveSourceArchives(url) {
|
|
|
117
155
|
return archives;
|
|
118
156
|
}
|
|
119
157
|
exports.resolveSourceArchives = resolveSourceArchives;
|
|
120
|
-
/** What an index entry records as the holder of its bytes (see ArchivesSource.url), so it must name the endpoint FOREVER. An intermediate is a switchover's temporary alternate port onto another source, and that port is gone for good once its window passes - so it is recorded as the source it was split out of, which holds the same bucket and outlives it. */
|
|
121
|
-
function sourcePersistentUrl(sourceConfig, folder) {
|
|
122
|
-
if (!sourceConfig)
|
|
123
|
-
return folder;
|
|
124
|
-
return sourceConfig.intermediate || sourceConfig.url;
|
|
125
|
-
}
|
|
126
|
-
/** The fast-write policy this store writes under: its own configuration decides it (fast/writeDelay are OUR settings, not the peer's), and each source then holds writes for as long as sourceWriteDelay says. */
|
|
127
|
-
/**
|
|
128
|
-
* Every store this process runs, by folder - which IS the store's identity: account, name, bucket.
|
|
129
|
-
* A store is made once, configures itself from the routing config it holds, and stays; nothing here
|
|
130
|
-
* decides what it is, only that it exists.
|
|
131
|
-
*/
|
|
132
|
-
const stores = new Map();
|
|
133
|
-
function getStore(account, bucketName, name) {
|
|
134
|
-
let folder = (0, bucketDisk_1.getBucketFolder)(name, account, bucketName);
|
|
135
|
-
let existing = stores.get(folder);
|
|
136
|
-
if (existing)
|
|
137
|
-
return existing;
|
|
138
|
-
let store = new blobStore_1.BlobStore(folder, name, {
|
|
139
|
-
// Which entries in ITS routing config are this server's copy of it
|
|
140
|
-
isSelf: source => (0, storePlan_1.isSelfSource)(source, account, bucketName),
|
|
141
|
-
createSource: config => (0, storeSources_1.createStoreSource)({ sourceConfig: config.sourceConfig, folder, writeDelay: config.writeDelay }),
|
|
142
|
-
applySource: (source, sourceConfig, writeDelay) => (0, storeSources_1.applySourceConfig)(source, sourceConfig, writeDelay),
|
|
143
|
-
onWriteCounted: (kind, bytes) => countBucketWrite(`${account}/${bucketName}`, kind, bytes),
|
|
144
|
-
resolveSourceUrl: resolveSourceArchives,
|
|
145
|
-
});
|
|
146
|
-
stores.set(folder, store);
|
|
147
|
-
// Lazy init would leave a store nothing has touched sitting inert - no index loaded, no config applied, nothing synchronizing - while its folder is full of files
|
|
148
|
-
void store.init().catch((e) => { var _a; return console.error(`Initializing store ${JSON.stringify(name)} of bucket ${account}/${bucketName} failed: ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`); });
|
|
149
|
-
return store;
|
|
150
|
-
}
|
|
151
|
-
exports.getStore = getStore;
|
|
152
|
-
/** The bucket as this server has it: the stores whose folders exist, plus whatever the newest of their configs says about us. Names come from the DISK, not from the config - a store we hold keeps being served whether or not the current config still mentions it. */
|
|
153
|
-
function buildBucket(account, bucketName, names, routing) {
|
|
154
|
-
let plan = routing && (0, storePlan_1.planSelfStores)(account, bucketName, routing) || undefined;
|
|
155
|
-
let entriesByName = new Map();
|
|
156
|
-
for (let selfStore of (plan === null || plan === void 0 ? void 0 : plan.stores) || []) {
|
|
157
|
-
entriesByName.set(selfStore.name, selfStore.entries);
|
|
158
|
-
}
|
|
159
|
-
// Each store reads its own copy of the config and decides what it is - see BlobStore.applyRoutingConfig. Nothing here configures anything.
|
|
160
|
-
let stores = names.map(name => ({
|
|
161
|
-
name,
|
|
162
|
-
entries: entriesByName.get(name) || [],
|
|
163
|
-
folder: (0, bucketDisk_1.getBucketFolder)(name, account, bucketName),
|
|
164
|
-
store: getStore(account, bucketName, name),
|
|
165
|
-
}));
|
|
166
|
-
let loaded = { account, bucketName, routing, selfEntries: (plan === null || plan === void 0 ? void 0 : plan.selfEntries) || [], self: plan === null || plan === void 0 ? void 0 : plan.self, stores };
|
|
167
|
-
loadedBuckets.set(`${account}/${bucketName}`, loaded);
|
|
168
|
-
(0, intermediateManagement_1.scheduleBoundaryWork)(loaded);
|
|
169
|
-
return loaded;
|
|
170
|
-
}
|
|
171
|
-
// A bucket exists here when it has at least one store folder - the disk IS the record. Its config is the newest copy among those stores; with none at all it has no config yet, which is a perfectly good state for a store nobody has configured.
|
|
172
|
-
async function loadBucket(account, bucketName) {
|
|
173
|
-
let folders = await (0, bucketDisk_1.listBucketStoreFolders)(account, bucketName);
|
|
174
|
-
if (!folders.length)
|
|
175
|
-
return undefined;
|
|
176
|
-
let routing = await (0, bucketDisk_1.readRoutingFromDisk)(account, bucketName);
|
|
177
|
-
return buildBucket(account, bucketName, folders.map(x => x.name), routing);
|
|
178
|
-
}
|
|
179
|
-
function getLoadedBucket(account, bucketName) {
|
|
180
|
-
let key = `${account}/${bucketName}`;
|
|
181
|
-
return buckets.get(key) || reloadBucket(account, bucketName);
|
|
182
|
-
}
|
|
183
|
-
exports.getLoadedBucket = getLoadedBucket;
|
|
184
|
-
/** Re-reads the bucket off the disk, replacing the cached snapshot: what a routing-config write calls, because that write can CREATE a store (a new name gets a new folder) and the snapshot would keep answering with the stores it saw at load time. Existing stores are reused (getStore caches by folder), so this only picks up folder changes - it never restarts a store. */
|
|
185
|
-
async function reloadBucket(account, bucketName) {
|
|
186
|
-
let key = `${account}/${bucketName}`;
|
|
187
|
-
let loaded = loadBucket(account, bucketName);
|
|
188
|
-
buckets.set(key, loaded);
|
|
189
|
-
void loaded.then(bucket => {
|
|
190
|
-
if (!bucket && buckets.get(key) === loaded) {
|
|
191
|
-
buckets.delete(key);
|
|
192
|
-
}
|
|
193
|
-
}, () => {
|
|
194
|
-
if (buckets.get(key) === loaded) {
|
|
195
|
-
buckets.delete(key);
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
return await loaded;
|
|
199
|
-
}
|
|
200
|
-
exports.reloadBucket = reloadBucket;
|
|
201
158
|
/**
|
|
202
159
|
* Writing the routing config is a write like any other: it goes into a store, and the store applies
|
|
203
160
|
* it to itself and lets its peers pull it. The only thing that happens here is picking WHICH store,
|
|
@@ -208,97 +165,58 @@ exports.reloadBucket = reloadBucket;
|
|
|
208
165
|
* cancel it mid-flight.
|
|
209
166
|
*/
|
|
210
167
|
async function writeRoutingConfig(account, bucketName, name, data, config) {
|
|
211
|
-
var _a;
|
|
212
168
|
(0, serverConfig_1.assertWritesAllowed)();
|
|
213
169
|
let store = getStore(account, bucketName, name);
|
|
214
170
|
let incoming = (0, remoteConfig_1.parseRoutingData)(data);
|
|
215
|
-
let current =
|
|
171
|
+
let current = await (0, bucketDisk_1.readRoutingFromDisk)(account, bucketName);
|
|
216
172
|
let stored = (0, intermediateManagement_1.reinjectIntermediates)(current, incoming);
|
|
217
173
|
await store.set({ path: remoteConfig_1.ROUTING_FILE, data: Buffer.from((0, remoteConfig_1.serializeRemoteConfig)(stored)), lastModified: config === null || config === void 0 ? void 0 : config.lastModified });
|
|
218
|
-
// The write may have CREATED the store (a new name gets a new folder), and the loaded bucket is a snapshot of the disk - so it is re-read, or every data write naming the new store is rejected until a restart
|
|
219
|
-
await reloadBucket(account, bucketName);
|
|
220
174
|
(0, storageController_1.broadcastRoutingChanged)();
|
|
221
175
|
}
|
|
222
176
|
exports.writeRoutingConfig = writeRoutingConfig;
|
|
223
|
-
/** Which buckets this process currently has
|
|
177
|
+
/** Which buckets this process currently has active (some store of theirs was opened) - what a deploy successor asks its predecessor for, so it activates exactly the buckets that are actually in use. */
|
|
224
178
|
function getActiveBucketKeys() {
|
|
225
|
-
return [...
|
|
179
|
+
return [...activeStores.keys()].map(key => {
|
|
226
180
|
let slash = key.indexOf("/");
|
|
227
181
|
return { account: key.slice(0, slash), bucketName: key.slice(slash + 1) };
|
|
228
182
|
});
|
|
229
183
|
}
|
|
230
184
|
exports.getActiveBucketKeys = getActiveBucketKeys;
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
// One of its stores' folders - a bucket no longer has a folder of its own, it has one per store
|
|
235
|
-
folder: ((_a = loaded.stores[0]) === null || _a === void 0 ? void 0 : _a.folder) || "",
|
|
236
|
-
routing: loaded.routing,
|
|
237
|
-
selfEntries: loaded.selfEntries,
|
|
238
|
-
self: loaded.self,
|
|
239
|
-
config: getBucketConfig(loaded),
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
/** The live in-memory state of ONE bucket, answered without touching the disk (no routing file read, no statfs, no stored write stats). Returns an error string when the bucket is not loaded here, which is the normal state for a bucket nothing has accessed since startup. */
|
|
243
|
-
async function getActiveBucket(account, bucketName) {
|
|
244
|
-
var _a;
|
|
185
|
+
/** The state of ONE active bucket. Returns an error string when the bucket is not active here, which is the normal state for a bucket nothing has accessed since startup. */
|
|
186
|
+
async function debugGetActiveBucket(account, bucketName) {
|
|
245
187
|
let key = `${account}/${bucketName}`;
|
|
246
|
-
let
|
|
247
|
-
if (!
|
|
248
|
-
return `Bucket ${key} is not
|
|
188
|
+
let opened = activeStores.get(key);
|
|
189
|
+
if (!opened || !opened.size) {
|
|
190
|
+
return `Bucket ${key} is not active on this server (a bucket activates on first access)`;
|
|
249
191
|
}
|
|
250
|
-
let
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
catch (e) {
|
|
255
|
-
return `Bucket ${key} failed to load on this server: ${String((_a = e.stack) !== null && _a !== void 0 ? _a : e).slice(0, 500)}`;
|
|
256
|
-
}
|
|
257
|
-
if (!loaded) {
|
|
258
|
-
return `Bucket ${key} does not exist on this server`;
|
|
259
|
-
}
|
|
260
|
-
return toActiveBucketInfo(loaded);
|
|
192
|
+
let bucketStores = [...opened.values()];
|
|
193
|
+
let routing = await (0, bucketDisk_1.readRoutingFromDisk)(account, bucketName);
|
|
194
|
+
return { folder: bucketStores[0].folder, routing, config: aggregateArchivesConfig(bucketStores, routing) };
|
|
261
195
|
}
|
|
262
|
-
exports.
|
|
263
|
-
/** Loads a bucket that exists on this server's disk into memory, which starts
|
|
196
|
+
exports.debugGetActiveBucket = debugGetActiveBucket;
|
|
197
|
+
/** Loads every store of a bucket that exists on this server's disk into memory, which starts their synchronization and window timers, and returns the bucket's state. Nothing is written and no other server is contacted - unlike building an ArchivesChain for it, which would probe every source and could write the routing config. Already-active buckets just return their state. */
|
|
264
198
|
async function activateBucket(account, bucketName) {
|
|
265
|
-
var _a;
|
|
266
199
|
let key = `${account}/${bucketName}`;
|
|
267
|
-
let
|
|
268
|
-
let
|
|
269
|
-
|
|
270
|
-
loaded = await getLoadedBucket(account, bucketName);
|
|
271
|
-
}
|
|
272
|
-
catch (e) {
|
|
273
|
-
return `Bucket ${key} failed to load on this server: ${String((_a = e.stack) !== null && _a !== void 0 ? _a : e).slice(0, 500)}`;
|
|
274
|
-
}
|
|
275
|
-
if (!loaded) {
|
|
200
|
+
let wasActive = activeStores.has(key);
|
|
201
|
+
let bucketStores = await getBucketStores(account, bucketName);
|
|
202
|
+
if (!bucketStores.length) {
|
|
276
203
|
return `Bucket ${key} does not exist on this server (it has no store folders under ${(0, bucketDisk_1.getBucketFolder)("<name>", account, bucketName)})`;
|
|
277
204
|
}
|
|
278
205
|
// Wait for the indexes to load, so the totals we return are the real ones rather than zeroes from stores that have not read their index yet. The source scans keep running in the background.
|
|
279
|
-
for (let s of
|
|
206
|
+
for (let s of bucketStores) {
|
|
280
207
|
await s.store.init();
|
|
281
208
|
}
|
|
282
|
-
if (!
|
|
283
|
-
console.log(`Activated bucket ${key} on request:
|
|
209
|
+
if (!wasActive) {
|
|
210
|
+
console.log(`Activated bucket ${key} on request: its ${bucketStores.length} store(s) are now loaded and synchronizing`);
|
|
284
211
|
}
|
|
285
|
-
|
|
212
|
+
let routing = await (0, bucketDisk_1.readRoutingFromDisk)(account, bucketName);
|
|
213
|
+
return { folder: bucketStores[0].store.folder, routing, config: aggregateArchivesConfig(bucketStores.map(x => x.store), routing) };
|
|
286
214
|
}
|
|
287
215
|
exports.activateBucket = activateBucket;
|
|
288
|
-
async function
|
|
216
|
+
async function debugListAccountBuckets(account) {
|
|
289
217
|
let start = Date.now();
|
|
290
|
-
let timings = new Map();
|
|
291
|
-
async function timed(name, run) {
|
|
292
|
-
let began = Date.now();
|
|
293
|
-
try {
|
|
294
|
-
return await run();
|
|
295
|
-
}
|
|
296
|
-
finally {
|
|
297
|
-
timings.set(name, (timings.get(name) || 0) + (Date.now() - began));
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
218
|
// The disk is the record: a bucket exists here when it has at least one store folder, and several names for one bucket are still one bucket
|
|
301
|
-
let folders = await
|
|
219
|
+
let folders = await (0, bucketDisk_1.listAccountStoreFolders)(account);
|
|
302
220
|
let byBucket = new Map();
|
|
303
221
|
for (let store of folders) {
|
|
304
222
|
if (byBucket.has(store.bucketName))
|
|
@@ -311,31 +229,23 @@ async function listAccountBuckets(account) {
|
|
|
311
229
|
var _a, _b;
|
|
312
230
|
let key = `${account}/${bucketName}`;
|
|
313
231
|
let folder = byBucket.get(bucketName) || "";
|
|
314
|
-
let base = { bucketName, active:
|
|
315
|
-
base.disk = await
|
|
232
|
+
let base = { bucketName, active: activeStores.has(key), folder };
|
|
233
|
+
base.disk = await (0, bucketDisk_1.getDiskInfo)(folder).catch((e) => {
|
|
316
234
|
var _a;
|
|
317
235
|
base.diskError = String((_a = e.stack) !== null && _a !== void 0 ? _a : e).slice(0, 500);
|
|
318
236
|
return undefined;
|
|
319
237
|
});
|
|
320
|
-
base.writeStats = getBucketWriteStats(key);
|
|
321
|
-
const loadedPromise = buckets.get(key);
|
|
322
|
-
if (loadedPromise) {
|
|
323
|
-
try {
|
|
324
|
-
let loaded = await timed("awaitLoaded", () => loadedPromise);
|
|
325
|
-
if (loaded) {
|
|
326
|
-
return { ...base, active: true, config: getBucketConfig(loaded) };
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
catch (e) {
|
|
330
|
-
return { ...base, active: true, error: String((_a = e.stack) !== null && _a !== void 0 ? _a : e).slice(0, 500) };
|
|
331
|
-
}
|
|
332
|
-
}
|
|
238
|
+
base.writeStats = (0, accessStats_1.getBucketWriteStats)(key);
|
|
333
239
|
try {
|
|
334
|
-
|
|
335
|
-
if (
|
|
240
|
+
let routing = await (0, bucketDisk_1.readRoutingFromDisk)(account, bucketName);
|
|
241
|
+
if (base.active) {
|
|
242
|
+
let opened = [...(((_a = activeStores.get(key)) === null || _a === void 0 ? void 0 : _a.values()) || [])];
|
|
243
|
+
return { ...base, config: aggregateArchivesConfig(opened, routing) };
|
|
244
|
+
}
|
|
245
|
+
if (!routing) {
|
|
336
246
|
return { ...base, error: `No routing file (${remoteConfig_1.ROUTING_FILE}) in any of its stores` };
|
|
337
247
|
}
|
|
338
|
-
return { ...base, config: { remoteConfig:
|
|
248
|
+
return { ...base, config: { remoteConfig: routing } };
|
|
339
249
|
}
|
|
340
250
|
catch (e) {
|
|
341
251
|
return { ...base, error: String((_b = e.stack) !== null && _b !== void 0 ? _b : e).slice(0, 500) };
|
|
@@ -343,48 +253,9 @@ async function listAccountBuckets(account) {
|
|
|
343
253
|
}));
|
|
344
254
|
}
|
|
345
255
|
finally {
|
|
346
|
-
|
|
347
|
-
let parts = [...timings].map(([name, ms]) => `${name} ${ms}ms`).join(", ");
|
|
348
|
-
console.log(`listAccountBuckets(${account}) took ${Date.now() - start}ms for ${names.length} buckets: ${parts}`);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
exports.listAccountBuckets = listAccountBuckets;
|
|
352
|
-
function emptyWriteStats() {
|
|
353
|
-
return { originalWrites: 0, originalBytes: 0, flushedWrites: 0, flushedBytes: 0 };
|
|
354
|
-
}
|
|
355
|
-
// In memory only: totals since this process started (or the last clearWriteStats). Persisting them to disk was more machinery than the numbers were worth.
|
|
356
|
-
const writeStats = new Map();
|
|
357
|
-
function countBucketWrite(key, kind, bytes) {
|
|
358
|
-
let stats = writeStats.get(key);
|
|
359
|
-
if (!stats) {
|
|
360
|
-
stats = emptyWriteStats();
|
|
361
|
-
writeStats.set(key, stats);
|
|
362
|
-
}
|
|
363
|
-
if (kind === "original") {
|
|
364
|
-
stats.originalWrites++;
|
|
365
|
-
stats.originalBytes += bytes;
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
stats.flushedWrites++;
|
|
369
|
-
stats.flushedBytes += bytes;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
function getBucketWriteStats(key) {
|
|
373
|
-
return writeStats.get(key) || emptyWriteStats();
|
|
374
|
-
}
|
|
375
|
-
/** Zeroes the write statistics of every bucket in the account. */
|
|
376
|
-
function clearAccountWriteStats(account) {
|
|
377
|
-
let prefix = `${account}/`;
|
|
378
|
-
let cleared = 0;
|
|
379
|
-
for (let key of [...writeStats.keys()]) {
|
|
380
|
-
if (!key.startsWith(prefix))
|
|
381
|
-
continue;
|
|
382
|
-
writeStats.delete(key);
|
|
383
|
-
cleared++;
|
|
256
|
+
console.log(`debugListAccountBuckets(${account}) took ${Date.now() - start}ms for ${names.length} buckets`);
|
|
384
257
|
}
|
|
385
|
-
console.log(`Cleared the write statistics of ${cleared} buckets in account ${account}`);
|
|
386
|
-
return cleared;
|
|
387
258
|
}
|
|
388
|
-
exports.
|
|
389
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZVNlcnZlclN0YXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3RvcmFnZVNlcnZlclN0YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLDJDQUF3QztBQUl4QyxpREFBd0c7QUFDeEcsaURBQXNFO0FBQ3RFLDJEQUE4RDtBQUM5RCxpREFBNkU7QUFDN0UsNkNBQWtKO0FBQ2xKLHFFQUF1RjtBQUN2RiwyQ0FBd0U7QUFrQ3hFLDBNQUEwTTtBQUNuTSxLQUFLLFVBQVUsYUFBYSxDQUFDLE9BQWUsRUFBRSxVQUFrQjtJQUNuRSxJQUFJLE1BQU0sR0FBRyxNQUFNLGVBQWUsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDeEQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1YsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLE9BQU8sSUFBSSxVQUFVLCtEQUErRCxJQUFJLENBQUMsU0FBUyxDQUFDLDJCQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNoSyxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQztBQU5ELHNDQU1DO0FBRUQsa1pBQWtaO0FBQzNZLEtBQUssVUFBVSxlQUFlLENBQUMsT0FBZSxFQUFFLFVBQWtCLEVBQUUsWUFBc0M7SUFDN0csSUFBSSxNQUFNLEdBQUcsTUFBTSxhQUFhLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3RELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLDBEQUEwRCxPQUFPLElBQUksVUFBVSxrRkFBa0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN2TyxDQUFDO0lBQ0QsSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJ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O0lBQ0QsSUFBSSxJQUFJLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDdEIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxhQUFhLElBQUksS0FBSyxDQUFDO0lBQ2pDLENBQUM7U0FBTSxDQUFDO1FBQ0osS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3RCLEtBQUssQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDO0lBQ2hDLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxHQUFXO0lBQ3BDLE9BQU8sVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxlQUFlLEVBQUUsQ0FBQztBQUNwRCxDQUFDO0FBRUQsa0VBQWtFO0FBQ2xFLFNBQWdCLHNCQUFzQixDQUFDLE9BQWU7SUFDbEQsSUFBSSxNQUFNLEdBQUcsR0FBRyxPQUFPLEdBQUcsQ0FBQztJQUMzQixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7SUFDaEIsS0FBSyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNyQyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFBRSxTQUFTO1FBQ3RDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkIsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQ0FBbUMsT0FBTyx1QkFBdUIsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUN4RixPQUFPLE9BQU8sQ0FBQztBQUNuQixDQUFDO0FBVkQsd0RBVUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgQmxvYlN0b3JlIH0gZnJvbSBcIi4vYmxvYlN0b3JlXCI7XG5pbXBvcnQge1xuICAgIFJlbW90ZUNvbmZpZywgSG9zdGVkQ29uZmlnLCBTb3VyY2VDb25maWcsIElBcmNoaXZlcywgQXJjaGl2ZXNDb25maWcsIEFyY2hpdmVzU3luY1N0YXR1cywgU3luY0FjdGl2aXR5LFxufSBmcm9tIFwiLi4vSUFyY2hpdmVzXCI7XG5pbXBvcnQgeyBST1VUSU5HX0ZJTEUsIHBhcnNlUm91dGluZ0RhdGEsIHNlcmlhbGl6ZVJlbW90ZUNvbmZpZywgbm9ybWFsaXplU291cmNlIH0gZnJvbSBcIi4vcmVtb3RlQ29uZmlnXCI7XG5pbXBvcnQgeyBjcmVhdGVTdG9yZVNvdXJjZSwgYXBwbHlTb3VyY2VDb25maWcgfSBmcm9tIFwiLi9zdG9yZVNvdXJjZXNcIjtcbmltcG9ydCB7IGJyb2FkY2FzdFJvdXRpbmdDaGFuZ2VkIH0gZnJvbSBcIi4vc3RvcmFnZUNvbnRyb2xsZXJcIjtcbmltcG9ydCB7IGdldFN0b3JhZ2VTZXJ2ZXJDb25maWcsIGFzc2VydFdyaXRlc0FsbG93ZWQgfSBmcm9tIFwiLi9zZXJ2ZXJDb25maWdcIjtcbmltcG9ydCB7IGdldEJ1Y2tldEZvbGRlciwgbGlzdEFjY291bnRTdG9yZUZvbGRlcnMsIGxpc3RCdWNrZXRTdG9yZUZvbGRlcnMsIHJlYWRSb3V0aW5nRnJvbURpc2ssIGdldERpc2tJbmZvLCBCdWNrZXREaXNrSW5mbyB9IGZyb20gXCIuL2J1Y2tldERpc2tcIjtcbmltcG9ydCB7IHNjaGVkdWxlQm91bmRhcnlXb3JrLCByZWluamVjdEludGVybWVkaWF0ZXMgfSBmcm9tIFwiLi9pbnRlcm1lZGlhdGVNYW5hZ2VtZW50XCI7XG5pbXBvcnQgeyBwbGFuU2VsZlN0b3JlcywgaXNTZWxmU291cmNlLCBTZWxmU3VtbWFyeSB9IGZyb20gXCIuL3N0b3JlUGxhblwiO1xuXG4vKipcbiAqIFdoYXQgdGhpcyBzZXJ2ZXIgSEFTLCBhcyBvcHBvc2VkIHRvIHdoYXQgYW55IG9mIGl0IGRvZXMuIEZvdXIgdGhpbmdzLCBhbmQgbm90aGluZyBlbHNlOlxuICpcbiAqIC0gdGhlIHN0b3JlcywgYnkgZm9sZGVyIChnZXRTdG9yZSkgLSBtYWRlIG9uY2UsIGFuZCBzZWxmLWNvbmZpZ3VyaW5nIGZyb20gdGhlcmVcbiAqIC0gd2hpY2ggb2YgdGhlbSBhIHJlcXVlc3QgbWVhbnMgKGZpbmRCdWNrZXRTdG9yZSksIHdoaWNoIGlzIG9ubHkgZXZlciBhIG5hbWVcbiAqIC0gd2hhdCBleGlzdHMgb24gZGlzaywgZm9yIGxpc3RpbmdzIGFuZCBmb3IgdGhlIHBhZ2VzIHRoYXQgcmVwb3J0IGl0XG4gKlxuICogSXQgZGVjaWRlcyBub3RoaW5nIGFib3V0IHJvdXRlcywgd2luZG93cyBvciBwZWVycyAtIGEgc3RvcmUgcmVhZHMgaXRzIG93biBjb25maWcgYW5kIHdvcmtzIHRoYXRcbiAqIG91dCBpdHNlbGYgKEJsb2JTdG9yZS5hcHBseVJvdXRpbmdDb25maWcpIC0gYW5kIGl0IHNjaGVkdWxlcyBub3RoaW5nOiBzd2l0Y2hvdmVycyBhbmQgdGhlIGhhbmRvdmVyc1xuICogdGhleSBjYXVzZSBsaXZlIGluIGludGVybWVkaWF0ZU1hbmFnZW1lbnQuXG4gKi9cblxuZXhwb3J0IHR5cGUgTG9hZGVkU3RvcmUgPSB7XG4gICAgLy8gVGhlIG5hbWUgaXRzIGVudHJpZXMgZ2F2ZSBpdCAoc2VlIENvbW1vbkNvbmZpZy5uYW1lKSAtIGl0cyBpZGVudGl0eSBoZXJlLCBpdHMgZm9sZGVyIG9uIGRpc2ssIGFuZCBob3cgYSByZXF1ZXN0IGZpbmRzIGl0XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIC8vIFRoZSBleGFjdCBzZWxmIGVudHJpZXMgdGhpcyBzdG9yZSBzZXJ2ZXMgKHNhbWUgcm91dGUsIGRpZmZlcmVudCB2YWxpZCB3aW5kb3dzKS4gRW1wdHkgd2hlbiB3ZSBhcmUgbm90IGluIHRoZSBjb25maWcgYnV0IHN0aWxsIHNlcnZlIG91ciBkaXNrIGRhdGEuXG4gICAgZW50cmllczogSG9zdGVkQ29uZmlnW107XG4gICAgZm9sZGVyOiBzdHJpbmc7XG4gICAgc3RvcmU6IEJsb2JTdG9yZTtcbn07XG5cbi8vIEEgYnVja2V0IGxvYWRlZCBvbiB0aGlzIHNlcnZlcjogdGhlIHN0b3JlcyBpdCBoYXMgaGVyZSwgYW5kIHdoYXQgdGhlIG5ld2VzdCBvZiB0aGVpciBjb25maWdzIHNheXMgYWJvdXQgdXMuIFB1cmUgZGF0YSAtIHRoZSBzdG9yZXMgdGhlbXNlbHZlcyBkbyB0aGUgd29yaywgaW5jbHVkaW5nIGNvbmZpZ3VyaW5nIHRoZW1zZWx2ZXMuXG5leHBvcnQgdHlwZSBCdWNrZXRTdGF0ZSA9IHtcbiAgICBhY2NvdW50OiBzdHJpbmc7XG4gICAgYnVja2V0TmFtZTogc3RyaW5nO1xuICAgIC8vIFRoZSBuZXdlc3Qgcm91dGluZyBjb25maWcgYW1vbmcgaXRzIHN0b3Jlcywgb3IgYWJzZW50IHdoZW4gbm9uZSBvZiB0aGVtIGhhcyBvbmUgeWV0XG4gICAgcm91dGluZz86IFJlbW90ZUNvbmZpZztcbiAgICBzZWxmRW50cmllczogSG9zdGVkQ29uZmlnW107XG4gICAgc2VsZjogU2VsZlN1bW1hcnkgfCB1bmRlZmluZWQ7XG4gICAgc3RvcmVzOiBMb2FkZWRTdG9yZVtdO1xufTtcblxuLyoqIFRoZSBsb2FkZWQgYnVja2V0LCBsb2FkaW5nIGl0ICh3aGljaCBpbnN0YW50aWF0ZXMgaXRzIHN0b3JlcyBhbmQgc3RhcnRzIHRoZWlyIHN5bmNocm9uaXphdGlvbikgaWYgbmVlZGVkLiBBIGJ1Y2tldCB0aGF0IGRvZXMgbm90IGV4aXN0IG9uIHRoaXMgc2VydmVyIHRocm93cyAtIGNhbGxlcnMgbmV2ZXIgc2VlIHVuZGVmaW5lZCBidWNrZXRzLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcXVpcmVCdWNrZXQoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEJ1Y2tldFN0YXRlPiB7XG4gICAgbGV0IGJ1Y2tldCA9IGF3YWl0IGdldExvYWRlZEJ1Y2tldChhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBpZiAoIWJ1Y2tldCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEJ1Y2tldCAke2FjY291bnR9LyR7YnVja2V0TmFtZX0gZG9lcyBub3QgZXhpc3Qgb24gdGhpcyBzZXJ2ZXIuIFdyaXRlIGl0cyByb3V0aW5nIGNvbmZpZyB0byAke0pTT04uc3RyaW5naWZ5KFJPVVRJTkdfRklMRSl9IHRvIGNyZWF0ZSBpdC5gKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1Y2tldDtcbn1cblxuLyoqIFRoZSBzdG9yZSBzZXJ2aW5nIGEgcmVxdWVzdDogdGhlIG9uZSB0aGUgY2xpZW50J3Mgc2VsZWN0ZWQgZW50cnkgTkFNRVMuIE5vdGhpbmcgZWxzZSBpcyBjb21wYXJlZCAtIG5vdCB0aGUgd2luZG93LCBub3QgdGhlIHJvdXRlLCBub3QgdGhlIGZsYWdzIC0gYmVjYXVzZSB0aGUgbmFtZSBpcyB3aGF0IHNheXMgd2hpY2ggc3RvcmFnZSB0aGlzIGlzLCBhbmQgZXZlcnl0aGluZyBlbHNlIGlzIHBvbGljeSB0aGUgc3RvcmUgaXRzZWxmIGFwcGxpZXMgdG8gdGhlIHJlcXVlc3QuIEEgY2xpZW50IGEgY29uZmlnIHZlcnNpb24gYmVoaW5kIG9uIHNvbWUgZmxhZyB0aGVyZWZvcmUgc3RpbGwgcmVhY2hlcyB0aGUgcmlnaHQgc3RvcmUsIHdoaWNoIGlzIHRoZSB3aG9sZSBwb2ludCBvZiBuYW1pbmcgaXQuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmluZEJ1Y2tldFN0b3JlKGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nLCBzb3VyY2VDb25maWc6IFNvdXJjZUNvbmZpZyB8IHVuZGVmaW5lZCk6IFByb21pc2U8TG9hZGVkU3RvcmU+IHtcbiAgICBsZXQgYnVja2V0ID0gYXdhaXQgcmVxdWlyZUJ1Y2tldChhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBpZiAoIXNvdXJjZUNvbmZpZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHJlbW90ZSBzb3VyY2UgY29uZmlndXJhdGlvbiB3YXMgcHJvdmlkZWQgZm9yIGJ1Y2tldCAke2FjY291bnR9LyR7YnVja2V0TmFtZX06IGV2ZXJ5IHJlcXVlc3QgbXVzdCBzYXkgd2hpY2ggY29uZmlndXJlZCBzb3VyY2UgaXQgc2VsZWN0ZWQuIFRoaXMgc2VydmVyIGhhczogJHtKU09OLnN0cmluZ2lmeShidWNrZXQuc3RvcmVzLm1hcCh4ID0+IHgubmFtZSkpfWApO1xuICAgIH1cbiAgICBsZXQgc3RvcmUgPSBidWNrZXQuc3RvcmVzLmZpbmQoeCA9PiB4Lm5hbWUgPT09IHNvdXJjZUNvbmZpZy5uYW1lKTtcbiAgICBpZiAoc3RvcmUpIHJldHVybiBzdG9yZTtcbiAgICAvLyBUaGUgbG9hZGVkIGJ1Y2tldCBpcyBhIHNuYXBzaG90IG9mIHRoZSBkaXNrIGZyb20gd2hlbiBpdCBsb2FkZWQ7IGEgc3RvcmUgY3JlYXRlZCBzaW5jZSAoYSBuZXcgbmFtZSBpbiBhIHJld3JpdHRlbiByb3V0aW5nIGNvbmZpZykgaXMgb24gdGhlIGRpc2sgYnV0IG5vdCBpbiB0aGUgc25hcHNob3QsIHNvIGEgbWlzcyByZS1yZWFkcyB0aGUgZGlzayBvbmNlIGJlZm9yZSBpdCBpcyBiZWxpZXZlZFxuICAgIGxldCBwcmV2aW91c05hbWVzID0gYnVja2V0LnN0b3Jlcy5tYXAoeCA9PiB4Lm5hbWUpO1xuICAgIGxldCByZWxvYWRlZCA9IGF3YWl0IHJlbG9hZEJ1Y2tldChhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBzdG9yZSA9IHJlbG9hZGVkPy5zdG9yZXMuZmluZCh4ID0+IHgubmFtZSA9PT0gc291cmNlQ29uZmlnLm5hbWUpO1xuICAgIGlmIChzdG9yZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgUmVsb2FkZWQgYnVja2V0ICR7YWNjb3VudH0vJHtidWNrZXROYW1lfSB0byBmaW5kIHN0b3JlICR7SlNPTi5zdHJpbmdpZnkoc291cmNlQ29uZmlnLm5hbWUpfTogaXRzIHN0b3JlcyBjaGFuZ2VkIGZyb20gJHtKU09OLnN0cmluZ2lmeShwcmV2aW91c05hbWVzKX0gdG8gJHtKU09OLnN0cmluZ2lmeShyZWxvYWRlZD8uc3RvcmVzLm1hcCh4ID0+IHgubmFtZSkpfWApO1xuICAgICAgICByZXR1cm4gc3RvcmU7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgVGhpcyBzZXJ2ZXIgaGFzIG5vIHN0b3JlIG5hbWVkICR7SlNPTi5zdHJpbmdpZnkoc291cmNlQ29uZmlnLm5hbWUpfSBmb3IgYnVja2V0ICR7YWNjb3VudH0vJHtidWNrZXROYW1lfSAoaXQgaGFzOiAke0pTT04uc3RyaW5naWZ5KChyZWxvYWRlZCB8fCBidWNrZXQpLnN0b3Jlcy5tYXAoeCA9PiB4Lm5hbWUpKX0pLiBSZXF1ZXN0ZWQ6ICR7SlNPTi5zdHJpbmdpZnkoc291cmNlQ29uZmlnKX1gKTtcbn1cblxuLyoqIEludGVybmFsIChzdG9yZS10by1zdG9yZSkgcmVhZHMgc2tpcCBzdG9yZSBzZWxlY3Rpb24gZW50aXJlbHk6IHRoZSBjYWxsZXIgaXMgYW5vdGhlciBzdG9yZSB3aG9zZSBpbmRleCBzYXlzIHRoaXMgTUFDSElORSBob2xkcyB0aGUgYnl0ZXMgLSB0aGUgcGVyc2lzdGVkIGhvbGRlciBpZGVudGl0eSBpcyBqdXN0IGEgVVJMLCB3aGljaCBjYW5ub3QgbmFtZSBhIHN0b3JlLiBXaGljaGV2ZXIgc3RvcmUncyBmb2xkZXIgaGFzIHRoZSBuZXdlc3QgY29weSBhbnN3ZXJzLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRCdWNrZXRJbnRlcm5hbChhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgY29uZmlnOiB7IHBhdGg6IHN0cmluZzsgcmFuZ2U/OiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH07IGluY2x1ZGVUb21ic3RvbmVzPzogYm9vbGVhbiB9KTogUHJvbWlzZTx7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgbGV0IGJ1Y2tldCA9IGF3YWl0IHJlcXVpcmVCdWNrZXQoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChidWNrZXQuc3RvcmVzLm1hcChzID0+IHMuc3RvcmUuZ2V0Mih7IHBhdGg6IGNvbmZpZy5wYXRoLCByYW5nZTogY29uZmlnLnJhbmdlLCBpbmNsdWRlVG9tYnN0b25lczogY29uZmlnLmluY2x1ZGVUb21ic3RvbmVzLCBpbnRlcm5hbDogdHJ1ZSB9KSkpO1xuICAgIGxldCBiZXN0OiB7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkO1xuICAgIGZvciAobGV0IHJlc3VsdCBvZiByZXN1bHRzKSB7XG4gICAgICAgIGlmIChyZXN1bHQgJiYgKCFiZXN0IHx8IHJlc3VsdC53cml0ZVRpbWUgPiBiZXN0LndyaXRlVGltZSkpIHtcbiAgICAgICAgICAgIGJlc3QgPSByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGJlc3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCdWNrZXRDb25maWcoYnVja2V0OiBCdWNrZXRTdGF0ZSk6IEFyY2hpdmVzQ29uZmlnIHtcbiAgICBsZXQgaW5kZXggPSB7IGZpbGVDb3VudDogMCwgYnl0ZUNvdW50OiAwIH07XG4gICAgbGV0IGluZGV4U291cmNlczogeyBkZWJ1Z05hbWU6IHN0cmluZzsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyIH1bXSA9IFtdO1xuICAgIGxldCBzeW5jaW5nOiBTeW5jQWN0aXZpdHlbXSA9IFtdO1xuICAgIGxldCByZWFkZXJEaXNrTGltaXQ6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBmb3IgKGxldCBzIG9mIGJ1Y2tldC5zdG9yZXMpIHtcbiAgICAgICAgbGV0IHByb2dyZXNzID0gcy5zdG9yZS5nZXRTeW5jUHJvZ3Jlc3MoKTtcbiAgICAgICAgaW5kZXguZmlsZUNvdW50ICs9IHByb2dyZXNzLmluZGV4LmZpbGVDb3VudDtcbiAgICAgICAgaW5kZXguYnl0ZUNvdW50ICs9IHByb2dyZXNzLmluZGV4LmJ5dGVDb3VudDtcbiAgICAgICAgaW5kZXhTb3VyY2VzLnB1c2goLi4ucHJvZ3Jlc3Muc291cmNlcyk7XG4gICAgICAgIHN5bmNpbmcucHVzaCguLi5wcm9ncmVzcy5zeW5jaW5nKTtcbiAgICAgICAgcmVhZGVyRGlza0xpbWl0ID0gcmVhZGVyRGlza0xpbWl0IHx8IHByb2dyZXNzLnJlYWRlckRpc2tMaW1pdDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgLy8gRXZlcnkgc3RvcmUgaXMgaW5kZXgtYmFja2VkLCBzbyB0aGUgY2hhbmdlIGZlZWQgaXMgYWx3YXlzIG5hdGl2ZVxuICAgICAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcjogdHJ1ZSxcbiAgICAgICAgcmVtb3RlQ29uZmlnOiBidWNrZXQucm91dGluZyxcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIGluZGV4U291cmNlcyxcbiAgICAgICAgcmVhZGVyRGlza0xpbWl0LFxuICAgICAgICBzeW5jaW5nLFxuICAgIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBidWNrZXRTeW5jU3RhdHVzKGJ1Y2tldDogQnVja2V0U3RhdGUpOiBQcm9taXNlPEFyY2hpdmVzU3luY1N0YXR1cz4ge1xuICAgIGxldCBzdGF0dXNlcyA9IGF3YWl0IFByb21pc2UuYWxsKGJ1Y2tldC5zdG9yZXMubWFwKHMgPT4gcy5zdG9yZS5nZXRTeW5jU3RhdHVzKCkpKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBhbGxTY2Fuc0NvbXBsZXRlOiBzdGF0dXNlcy5ldmVyeSh4ID0+IHguYWxsU2NhbnNDb21wbGV0ZSksXG4gICAgICAgIGluZGV4U2l6ZTogc3RhdHVzZXMucmVkdWNlKChzdW0sIHgpID0+IHN1bSArIHguaW5kZXhTaXplLCAwKSxcbiAgICAgICAgc291cmNlczogc3RhdHVzZXMuZmxhdE1hcCh4ID0+IHguc291cmNlcyksXG4gICAgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJ1Y2tldEluZGV4VG90YWxzKGJ1Y2tldDogQnVja2V0U3RhdGUpOiBQcm9taXNlPHsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyOyBzb3VyY2VzOiB7IGRlYnVnTmFtZTogc3RyaW5nOyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXIgfVtdIH0+IHtcbiAgICBsZXQgdG90YWxzID0gYXdhaXQgUHJvbWlzZS5hbGwoYnVja2V0LnN0b3Jlcy5tYXAocyA9PiBzLnN0b3JlLmNvbXB1dGVJbmRleFRvdGFscygpKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZmlsZUNvdW50OiB0b3RhbHMucmVkdWNlKChzdW0sIHgpID0+IHN1bSArIHguZmlsZUNvdW50LCAwKSxcbiAgICAgICAgYnl0ZUNvdW50OiB0b3RhbHMucmVkdWNlKChzdW0sIHgpID0+IHN1bSArIHguYnl0ZUNvdW50LCAwKSxcbiAgICAgICAgc291cmNlczogdG90YWxzLmZsYXRNYXAoeCA9PiB4LnNvdXJjZXMpLFxuICAgIH07XG59XG5cbmNvbnN0IGJ1Y2tldHMgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxCdWNrZXRTdGF0ZSB8IHVuZGVmaW5lZD4+KCk7XG4vLyBUaGUgcmVzb2x2ZWQgb25lcywgZm9yIHRoZSBjb2RlIHRoYXQgd2Fsa3MgYnVja2V0cyByYXRoZXIgdGhhbiBhc2tpbmcgZm9yIG9uZSAoc2VlIGdldEJ1Y2tldFN0YXRlcylcbmNvbnN0IGxvYWRlZEJ1Y2tldHMgPSBuZXcgTWFwPHN0cmluZywgQnVja2V0U3RhdGU+KCk7XG5cbi8qKiBUaGUgYnVja2V0IHN0YXRlcyBjdXJyZW50bHkgaW4gbWVtb3J5IC0gd2hhdCB0aGUgc3dpdGNob3ZlciBtYWNoaW5lcnkgd2Fsa3MuIE9ubHkgd2hhdCBpcyBsb2FkZWQ6IGxvYWRpbmcgYSBidWNrZXQgc3RhcnRzIGl0cyBzeW5jaHJvbml6YXRpb24sIGFuZCBhIGJ1Y2tldCBub3RoaW5nIGhhcyB0b3VjaGVkIGhhcyBubyBpbi1mbGlnaHQgd3JpdGVzIHRvIGhhbmQgb3ZlciBhbnl3YXkuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QnVja2V0U3RhdGVzKCk6IEJ1Y2tldFN0YXRlW10ge1xuICAgIHJldHVybiBbLi4ubG9hZGVkQnVja2V0cy52YWx1ZXMoKV07XG59XG5cbmNvbnN0IHJlc29sdmVkU291cmNlQXJjaGl2ZXMgPSBuZXcgTWFwPHN0cmluZywgSUFyY2hpdmVzPigpO1xuLyoqIEEgY2FjaGVkIElBcmNoaXZlcyBmb3IgYSBwZXJzaXN0ZWQgc291cmNlIGlkZW50aXR5OiBhIHJvdXRpbmcgVVJMIChob3N0ZWQvYmFja2JsYXplKSBvciBhIGRpc2sgZm9sZGVyIHBhdGggLSB0aGUgZm9ybSBCbG9iU3RvcmUncyBzb3VyY2VzIGxpc3Qgc3RvcmVzLiBDb25maWd1cmF0aW9uICh2YWxpZCB3aW5kb3dzLCByb3V0ZXMpIGRlY2lkZXMgV0hFTiBhIHNvdXJjZSBzaG91bGQgYmUgdXNlZDsgZm9yIHJlYWRpbmcgYnl0ZXMgdGhlIGluZGV4IHNheXMgYSBzb3VyY2UgaG9sZHMsIHRoZSBVUkwgYWxvbmUgaXMgZW5vdWdoIC0gZXZlbiBmb3Igc291cmNlcyBubyBsb25nZXIgaW4gYW55IGNvbmZpZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlU291cmNlQXJjaGl2ZXModXJsOiBzdHJpbmcpOiBJQXJjaGl2ZXMge1xuICAgIGxldCBleGlzdGluZyA9IHJlc29sdmVkU291cmNlQXJjaGl2ZXMuZ2V0KHVybCk7XG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3Rpbmc7XG4gICAgbGV0IHNvdXJjZUNvbmZpZzogU291cmNlQ29uZmlnIHwgdW5kZWZpbmVkO1xuICAgIGlmICh1cmwuc3RhcnRzV2l0aChcImh0dHBzOi8vXCIpKSB7XG4gICAgICAgIC8vIFRoZSBjb25maWcgaXMgZmFicmljYXRlZCBmcm9tIHRoZSBiYXJlIFVSTCBhbmQgY2FuIG5ldmVyIGV4YWN0LW1hdGNoIGEgc2VydmVyJ3MgZW50cmllcyAtIHdoaWNoIGlzIGZpbmUsIGJlY2F1c2UgaG9sZGVyIHJlYWRzIGFyZSBpbnRlcm5hbCByZWFkcywgYW5kIGludGVybmFsIHJlYWRzIG5ldmVyIHNlbGVjdCBhIHN0b3JlIChzZWUgcmVhZEJ1Y2tldEludGVybmFsKVxuICAgICAgICBzb3VyY2VDb25maWcgPSBub3JtYWxpemVTb3VyY2UodXJsKTtcbiAgICB9XG4gICAgbGV0IGFyY2hpdmVzID0gY3JlYXRlU3RvcmVTb3VyY2UoeyBzb3VyY2VDb25maWcsIGZvbGRlcjogdXJsIH0pO1xuICAgIHJlc29sdmVkU291cmNlQXJjaGl2ZXMuc2V0KHVybCwgYXJjaGl2ZXMpO1xuICAgIHJldHVybiBhcmNoaXZlcztcbn1cblxuLyoqIFdoYXQgYW4gaW5kZXggZW50cnkgcmVjb3JkcyBhcyB0aGUgaG9sZGVyIG9mIGl0cyBieXRlcyAoc2VlIEFyY2hpdmVzU291cmNlLnVybCksIHNvIGl0IG11c3QgbmFtZSB0aGUgZW5kcG9pbnQgRk9SRVZFUi4gQW4gaW50ZXJtZWRpYXRlIGlzIGEgc3dpdGNob3ZlcidzIHRlbXBvcmFyeSBhbHRlcm5hdGUgcG9ydCBvbnRvIGFub3RoZXIgc291cmNlLCBhbmQgdGhhdCBwb3J0IGlzIGdvbmUgZm9yIGdvb2Qgb25jZSBpdHMgd2luZG93IHBhc3NlcyAtIHNvIGl0IGlzIHJlY29yZGVkIGFzIHRoZSBzb3VyY2UgaXQgd2FzIHNwbGl0IG91dCBvZiwgd2hpY2ggaG9sZHMgdGhlIHNhbWUgYnVja2V0IGFuZCBvdXRsaXZlcyBpdC4gKi9cbmZ1bmN0aW9uIHNvdXJjZVBlcnNpc3RlbnRVcmwoc291cmNlQ29uZmlnOiBTb3VyY2VDb25maWcgfCB1bmRlZmluZWQsIGZvbGRlcjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXNvdXJjZUNvbmZpZykgcmV0dXJuIGZvbGRlcjtcbiAgICByZXR1cm4gc291cmNlQ29uZmlnLmludGVybWVkaWF0ZSB8fCBzb3VyY2VDb25maWcudXJsO1xufVxuXG4vKiogVGhlIGZhc3Qtd3JpdGUgcG9saWN5IHRoaXMgc3RvcmUgd3JpdGVzIHVuZGVyOiBpdHMgb3duIGNvbmZpZ3VyYXRpb24gZGVjaWRlcyBpdCAoZmFzdC93cml0ZURlbGF5IGFyZSBPVVIgc2V0dGluZ3MsIG5vdCB0aGUgcGVlcidzKSwgYW5kIGVhY2ggc291cmNlIHRoZW4gaG9sZHMgd3JpdGVzIGZvciBhcyBsb25nIGFzIHNvdXJjZVdyaXRlRGVsYXkgc2F5cy4gKi9cbi8qKlxuICogRXZlcnkgc3RvcmUgdGhpcyBwcm9jZXNzIHJ1bnMsIGJ5IGZvbGRlciAtIHdoaWNoIElTIHRoZSBzdG9yZSdzIGlkZW50aXR5OiBhY2NvdW50LCBuYW1lLCBidWNrZXQuXG4gKiBBIHN0b3JlIGlzIG1hZGUgb25jZSwgY29uZmlndXJlcyBpdHNlbGYgZnJvbSB0aGUgcm91dGluZyBjb25maWcgaXQgaG9sZHMsIGFuZCBzdGF5czsgbm90aGluZyBoZXJlXG4gKiBkZWNpZGVzIHdoYXQgaXQgaXMsIG9ubHkgdGhhdCBpdCBleGlzdHMuXG4gKi9cbmNvbnN0IHN0b3JlcyA9IG5ldyBNYXA8c3RyaW5nLCBCbG9iU3RvcmU+KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdG9yZShhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nKTogQmxvYlN0b3JlIHtcbiAgICBsZXQgZm9sZGVyID0gZ2V0QnVja2V0Rm9sZGVyKG5hbWUsIGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGxldCBleGlzdGluZyA9IHN0b3Jlcy5nZXQoZm9sZGVyKTtcbiAgICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZztcbiAgICBsZXQgc3RvcmUgPSBuZXcgQmxvYlN0b3JlKGZvbGRlciwgbmFtZSwge1xuICAgICAgICAvLyBXaGljaCBlbnRyaWVzIGluIElUUyByb3V0aW5nIGNvbmZpZyBhcmUgdGhpcyBzZXJ2ZXIncyBjb3B5IG9mIGl0XG4gICAgICAgIGlzU2VsZjogc291cmNlID0+IGlzU2VsZlNvdXJjZShzb3VyY2UsIGFjY291bnQsIGJ1Y2tldE5hbWUpLFxuICAgICAgICBjcmVhdGVTb3VyY2U6IGNvbmZpZyA9PiBjcmVhdGVTdG9yZVNvdXJjZSh7IHNvdXJjZUNvbmZpZzogY29uZmlnLnNvdXJjZUNvbmZpZywgZm9sZGVyLCB3cml0ZURlbGF5OiBjb25maWcud3JpdGVEZWxheSB9KSxcbiAgICAgICAgYXBwbHlTb3VyY2U6IChzb3VyY2UsIHNvdXJjZUNvbmZpZywgd3JpdGVEZWxheSkgPT4gYXBwbHlTb3VyY2VDb25maWcoc291cmNlLCBzb3VyY2VDb25maWcsIHdyaXRlRGVsYXkpLFxuICAgICAgICBvbldyaXRlQ291bnRlZDogKGtpbmQsIGJ5dGVzKSA9PiBjb3VudEJ1Y2tldFdyaXRlKGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gLCBraW5kLCBieXRlcyksXG4gICAgICAgIHJlc29sdmVTb3VyY2VVcmw6IHJlc29sdmVTb3VyY2VBcmNoaXZlcyxcbiAgICB9KTtcbiAgICBzdG9yZXMuc2V0KGZvbGRlciwgc3RvcmUpO1xuICAgIC8vIExhenkgaW5pdCB3b3VsZCBsZWF2ZSBhIHN0b3JlIG5vdGhpbmcgaGFzIHRvdWNoZWQgc2l0dGluZyBpbmVydCAtIG5vIGluZGV4IGxvYWRlZCwgbm8gY29uZmlnIGFwcGxpZWQsIG5vdGhpbmcgc3luY2hyb25pemluZyAtIHdoaWxlIGl0cyBmb2xkZXIgaXMgZnVsbCBvZiBmaWxlc1xuICAgIHZvaWQgc3RvcmUuaW5pdCgpLmNhdGNoKChlOiBFcnJvcikgPT4gY29uc29sZS5lcnJvcihgSW5pdGlhbGl6aW5nIHN0b3JlICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IG9mIGJ1Y2tldCAke2FjY291bnR9LyR7YnVja2V0TmFtZX0gZmFpbGVkOiAke2Uuc3RhY2sgPz8gZX1gKSk7XG4gICAgcmV0dXJuIHN0b3JlO1xufVxuXG4vKiogVGhlIGJ1Y2tldCBhcyB0aGlzIHNlcnZlciBoYXMgaXQ6IHRoZSBzdG9yZXMgd2hvc2UgZm9sZGVycyBleGlzdCwgcGx1cyB3aGF0ZXZlciB0aGUgbmV3ZXN0IG9mIHRoZWlyIGNvbmZpZ3Mgc2F5cyBhYm91dCB1cy4gTmFtZXMgY29tZSBmcm9tIHRoZSBESVNLLCBub3QgZnJvbSB0aGUgY29uZmlnIC0gYSBzdG9yZSB3ZSBob2xkIGtlZXBzIGJlaW5nIHNlcnZlZCB3aGV0aGVyIG9yIG5vdCB0aGUgY3VycmVudCBjb25maWcgc3RpbGwgbWVudGlvbnMgaXQuICovXG5mdW5jdGlvbiBidWlsZEJ1Y2tldChhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgbmFtZXM6IHN0cmluZ1tdLCByb3V0aW5nOiBSZW1vdGVDb25maWcgfCB1bmRlZmluZWQpOiBCdWNrZXRTdGF0ZSB7XG4gICAgbGV0IHBsYW4gPSByb3V0aW5nICYmIHBsYW5TZWxmU3RvcmVzKGFjY291bnQsIGJ1Y2tldE5hbWUsIHJvdXRpbmcpIHx8IHVuZGVmaW5lZDtcbiAgICBsZXQgZW50cmllc0J5TmFtZSA9IG5ldyBNYXA8c3RyaW5nLCBIb3N0ZWRDb25maWdbXT4oKTtcbiAgICBmb3IgKGxldCBzZWxmU3RvcmUgb2YgcGxhbj8uc3RvcmVzIHx8IFtdKSB7XG4gICAgICAgIGVudHJpZXNCeU5hbWUuc2V0KHNlbGZTdG9yZS5uYW1lLCBzZWxmU3RvcmUuZW50cmllcyk7XG4gICAgfVxuICAgIC8vIEVhY2ggc3RvcmUgcmVhZHMgaXRzIG93biBjb3B5IG9mIHRoZSBjb25maWcgYW5kIGRlY2lkZXMgd2hhdCBpdCBpcyAtIHNlZSBCbG9iU3RvcmUuYXBwbHlSb3V0aW5nQ29uZmlnLiBOb3RoaW5nIGhlcmUgY29uZmlndXJlcyBhbnl0aGluZy5cbiAgICBsZXQgc3RvcmVzOiBMb2FkZWRTdG9yZVtdID0gbmFtZXMubWFwKG5hbWUgPT4gKHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgZW50cmllczogZW50cmllc0J5TmFtZS5nZXQobmFtZSkgfHwgW10sXG4gICAgICAgIGZvbGRlcjogZ2V0QnVja2V0Rm9sZGVyKG5hbWUsIGFjY291bnQsIGJ1Y2tldE5hbWUpLFxuICAgICAgICBzdG9yZTogZ2V0U3RvcmUoYWNjb3VudCwgYnVja2V0TmFtZSwgbmFtZSksXG4gICAgfSkpO1xuICAgIGxldCBsb2FkZWQ6IEJ1Y2tldFN0YXRlID0geyBhY2NvdW50LCBidWNrZXROYW1lLCByb3V0aW5nLCBzZWxmRW50cmllczogcGxhbj8uc2VsZkVudHJpZXMgfHwgW10sIHNlbGY6IHBsYW4/LnNlbGYsIHN0b3JlcyB9O1xuICAgIGxvYWRlZEJ1Y2tldHMuc2V0KGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gLCBsb2FkZWQpO1xuICAgIHNjaGVkdWxlQm91bmRhcnlXb3JrKGxvYWRlZCk7XG4gICAgcmV0dXJuIGxvYWRlZDtcbn1cblxuLy8gQSBidWNrZXQgZXhpc3RzIGhlcmUgd2hlbiBpdCBoYXMgYXQgbGVhc3Qgb25lIHN0b3JlIGZvbGRlciAtIHRoZSBkaXNrIElTIHRoZSByZWNvcmQuIEl0cyBjb25maWcgaXMgdGhlIG5ld2VzdCBjb3B5IGFtb25nIHRob3NlIHN0b3Jlczsgd2l0aCBub25lIGF0IGFsbCBpdCBoYXMgbm8gY29uZmlnIHlldCwgd2hpY2ggaXMgYSBwZXJmZWN0bHkgZ29vZCBzdGF0ZSBmb3IgYSBzdG9yZSBub2JvZHkgaGFzIGNvbmZpZ3VyZWQuXG5hc3luYyBmdW5jdGlvbiBsb2FkQnVja2V0KGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nKTogUHJvbWlzZTxCdWNrZXRTdGF0ZSB8IHVuZGVmaW5lZD4ge1xuICAgIGxldCBmb2xkZXJzID0gYXdhaXQgbGlzdEJ1Y2tldFN0b3JlRm9sZGVycyhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBpZiAoIWZvbGRlcnMubGVuZ3RoKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGxldCByb3V0aW5nID0gYXdhaXQgcmVhZFJvdXRpbmdGcm9tRGlzayhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICByZXR1cm4gYnVpbGRCdWNrZXQoYWNjb3VudCwgYnVja2V0TmFtZSwgZm9sZGVycy5tYXAoeCA9PiB4Lm5hbWUpLCByb3V0aW5nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExvYWRlZEJ1Y2tldChhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZyk6IFByb21pc2U8QnVja2V0U3RhdGUgfCB1bmRlZmluZWQ+IHtcbiAgICBsZXQga2V5ID0gYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWA7XG4gICAgcmV0dXJuIGJ1Y2tldHMuZ2V0KGtleSkgfHwgcmVsb2FkQnVja2V0KGFjY291bnQsIGJ1Y2tldE5hbWUpO1xufVxuXG4vKiogUmUtcmVhZHMgdGhlIGJ1Y2tldCBvZmYgdGhlIGRpc2ssIHJlcGxhY2luZyB0aGUgY2FjaGVkIHNuYXBzaG90OiB3aGF0IGEgcm91dGluZy1jb25maWcgd3JpdGUgY2FsbHMsIGJlY2F1c2UgdGhhdCB3cml0ZSBjYW4gQ1JFQVRFIGEgc3RvcmUgKGEgbmV3IG5hbWUgZ2V0cyBhIG5ldyBmb2xkZXIpIGFuZCB0aGUgc25hcHNob3Qgd291bGQga2VlcCBhbnN3ZXJpbmcgd2l0aCB0aGUgc3RvcmVzIGl0IHNhdyBhdCBsb2FkIHRpbWUuIEV4aXN0aW5nIHN0b3JlcyBhcmUgcmV1c2VkIChnZXRTdG9yZSBjYWNoZXMgYnkgZm9sZGVyKSwgc28gdGhpcyBvbmx5IHBpY2tzIHVwIGZvbGRlciBjaGFuZ2VzIC0gaXQgbmV2ZXIgcmVzdGFydHMgYSBzdG9yZS4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWxvYWRCdWNrZXQoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEJ1Y2tldFN0YXRlIHwgdW5kZWZpbmVkPiB7XG4gICAgbGV0IGtleSA9IGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gO1xuICAgIGxldCBsb2FkZWQgPSBsb2FkQnVja2V0KGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGJ1Y2tldHMuc2V0KGtleSwgbG9hZGVkKTtcbiAgICB2b2lkIGxvYWRlZC50aGVuKGJ1Y2tldCA9PiB7XG4gICAgICAgIGlmICghYnVja2V0ICYmIGJ1Y2tldHMuZ2V0KGtleSkgPT09IGxvYWRlZCkge1xuICAgICAgICAgICAgYnVja2V0cy5kZWxldGUoa2V5KTtcbiAgICAgICAgfVxuICAgIH0sICgpID0+IHtcbiAgICAgICAgaWYgKGJ1Y2tldHMuZ2V0KGtleSkgPT09IGxvYWRlZCkge1xuICAgICAgICAgICAgYnVja2V0cy5kZWxldGUoa2V5KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBhd2FpdCBsb2FkZWQ7XG59XG5cbi8qKlxuICogV3JpdGluZyB0aGUgcm91dGluZyBjb25maWcgaXMgYSB3cml0ZSBsaWtlIGFueSBvdGhlcjogaXQgZ29lcyBpbnRvIGEgc3RvcmUsIGFuZCB0aGUgc3RvcmUgYXBwbGllc1xuICogaXQgdG8gaXRzZWxmIGFuZCBsZXRzIGl0cyBwZWVycyBwdWxsIGl0LiBUaGUgb25seSB0aGluZyB0aGF0IGhhcHBlbnMgaGVyZSBpcyBwaWNraW5nIFdISUNIIHN0b3JlLFxuICogYmVjYXVzZSB0aGUgd3JpdGVyIG5hbWVzIGEgc291cmNlIGFuZCBhIHNvdXJjZSBuYW1lcyBhIHN0b3JlLlxuICpcbiAqIEluLWZsaWdodCBzd2l0Y2hvdmVyIHdpbmRvd3MgYXJlIHJlLWluamVjdGVkIGZpcnN0IChzZWUgaW50ZXJtZWRpYXRlTWFuYWdlbWVudCk6IGFuIG9wZXJhdG9yJ3NcbiAqIGNvbmZpZyBrbm93cyBub3RoaW5nIGFib3V0IGEgc3dpdGNob3ZlciB0aGF0IGlzIGhhcHBlbmluZyByaWdodCBub3csIGFuZCB3cml0aW5nIGl0IGFzLWlzIHdvdWxkXG4gKiBjYW5jZWwgaXQgbWlkLWZsaWdodC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlUm91dGluZ0NvbmZpZyhhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZz86IHsgbGFzdE1vZGlmaWVkPzogbnVtYmVyIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhc3NlcnRXcml0ZXNBbGxvd2VkKCk7XG4gICAgbGV0IHN0b3JlID0gZ2V0U3RvcmUoYWNjb3VudCwgYnVja2V0TmFtZSwgbmFtZSk7XG4gICAgbGV0IGluY29taW5nID0gcGFyc2VSb3V0aW5nRGF0YShkYXRhKTtcbiAgICBsZXQgY3VycmVudCA9IChhd2FpdCBnZXRMb2FkZWRCdWNrZXQoYWNjb3VudCwgYnVja2V0TmFtZSkpPy5yb3V0aW5nO1xuICAgIGxldCBzdG9yZWQgPSByZWluamVjdEludGVybWVkaWF0ZXMoY3VycmVudCwgaW5jb21pbmcpO1xuICAgIGF3YWl0IHN0b3JlLnNldCh7IHBhdGg6IFJPVVRJTkdfRklMRSwgZGF0YTogQnVmZmVyLmZyb20oc2VyaWFsaXplUmVtb3RlQ29uZmlnKHN0b3JlZCkpLCBsYXN0TW9kaWZpZWQ6IGNvbmZpZz8ubGFzdE1vZGlmaWVkIH0pO1xuICAgIC8vIFRoZSB3cml0ZSBtYXkgaGF2ZSBDUkVBVEVEIHRoZSBzdG9yZSAoYSBuZXcgbmFtZSBnZXRzIGEgbmV3IGZvbGRlciksIGFuZCB0aGUgbG9hZGVkIGJ1Y2tldCBpcyBhIHNuYXBzaG90IG9mIHRoZSBkaXNrIC0gc28gaXQgaXMgcmUtcmVhZCwgb3IgZXZlcnkgZGF0YSB3cml0ZSBuYW1pbmcgdGhlIG5ldyBzdG9yZSBpcyByZWplY3RlZCB1bnRpbCBhIHJlc3RhcnRcbiAgICBhd2FpdCByZWxvYWRCdWNrZXQoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgYnJvYWRjYXN0Um91dGluZ0NoYW5nZWQoKTtcbn1cblxuLyoqIFdoaWNoIGJ1Y2tldHMgdGhpcyBwcm9jZXNzIGN1cnJlbnRseSBoYXMgbG9hZGVkIC0gd2hhdCBhIGRlcGxveSBzdWNjZXNzb3IgYXNrcyBpdHMgcHJlZGVjZXNzb3IgZm9yLCBzbyBpdCBhY3RpdmF0ZXMgZXhhY3RseSB0aGUgYnVja2V0cyB0aGF0IGFyZSBhY3R1YWxseSBpbiB1c2UuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aXZlQnVja2V0S2V5cygpOiB7IGFjY291bnQ6IHN0cmluZzsgYnVja2V0TmFtZTogc3RyaW5nIH1bXSB7XG4gICAgcmV0dXJuIFsuLi5idWNrZXRzLmtleXMoKV0ubWFwKGtleSA9PiB7XG4gICAgICAgIGxldCBzbGFzaCA9IGtleS5pbmRleE9mKFwiL1wiKTtcbiAgICAgICAgcmV0dXJuIHsgYWNjb3VudDoga2V5LnNsaWNlKDAsIHNsYXNoKSwgYnVja2V0TmFtZToga2V5LnNsaWNlKHNsYXNoICsgMSkgfTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IHR5cGUgU2VydmVyQnVja2V0SW5mbyA9IHtcbiAgICBidWNrZXROYW1lOiBzdHJpbmc7XG4gICAgYWN0aXZlOiBib29sZWFuO1xuICAgIC8qKiBXaGVyZSB0aGUgYnVja2V0J3MgZGF0YSBsaXZlcyBvbiB0aGlzIHNlcnZlciAqL1xuICAgIGZvbGRlcjogc3RyaW5nO1xuICAgIC8qKiBUaGUgZHJpdmUgdGhhdCBmb2xkZXIgaXMgb24uIEJ1Y2tldHMgc2hhcmluZyBhIGRyaXZlIHJlcG9ydCB0aGUgc2FtZSBudW1iZXJzLiAqL1xuICAgIGRpc2s/OiBCdWNrZXREaXNrSW5mbztcbiAgICBkaXNrRXJyb3I/OiBzdHJpbmc7XG4gICAgd3JpdGVTdGF0cz86IEJ1Y2tldFdyaXRlU3RhdHM7XG4gICAgY29uZmlnPzogQXJjaGl2ZXNDb25maWc7XG4gICAgZXJyb3I/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgdHlwZSBBY3RpdmVCdWNrZXRJbmZvID0ge1xuICAgIGZvbGRlcjogc3RyaW5nO1xuICAgIC8qKiBUaGUgcm91dGluZyBjb25maWcgdGhlIGJ1Y2tldCBpcyBSVU5OSU5HIG9uLCBzdHJhaWdodCBmcm9tIG1lbW9yeSAtIGluY2x1ZGluZyBzd2l0Y2hvdmVyIHdpbmRvd3Mgd3JpdHRlbiBzaW5jZSBpdCBsb2FkZWQuIEFic2VudCB3aGVuIG5vbmUgb2YgaXRzIHN0b3JlcyBoYXMgb25lIHlldC4gKi9cbiAgICByb3V0aW5nPzogUmVtb3RlQ29uZmlnO1xuICAgIC8qKiBPdXIgb3duIGVudHJpZXMgaW4gdGhhdCBjb25maWcsIGFuZCB0aGVpciBzdW1tYXJpemVkIGN1cnJlbnQgcm9sZSAocm91dGVzIHVuaW9uICsgZmxhZ3MpICovXG4gICAgc2VsZkVudHJpZXM6IEhvc3RlZENvbmZpZ1tdO1xuICAgIHNlbGY/OiBTZWxmU3VtbWFyeTtcbiAgICBjb25maWc6IEFyY2hpdmVzQ29uZmlnO1xufTtcblxuZnVuY3Rpb24gdG9BY3RpdmVCdWNrZXRJbmZvKGxvYWRlZDogQnVja2V0U3RhdGUpOiBBY3RpdmVCdWNrZXRJbmZvIHtcbiAgICByZXR1cm4ge1xuICAgICAgICAvLyBPbmUgb2YgaXRzIHN0b3JlcycgZm9sZGVycyAtIGEgYnVja2V0IG5vIGxvbmdlciBoYXMgYSBmb2xkZXIgb2YgaXRzIG93biwgaXQgaGFzIG9uZSBwZXIgc3RvcmVcbiAgICAgICAgZm9sZGVyOiBsb2FkZWQuc3RvcmVzWzBdPy5mb2xkZXIgfHwgXCJcIixcbiAgICAgICAgcm91dGluZzogbG9hZGVkLnJvdXRpbmcsXG4gICAgICAgIHNlbGZFbnRyaWVzOiBsb2FkZWQuc2VsZkVudHJpZXMsXG4gICAgICAgIHNlbGY6IGxvYWRlZC5zZWxmLFxuICAgICAgICBjb25maWc6IGdldEJ1Y2tldENvbmZpZyhsb2FkZWQpLFxuICAgIH07XG59XG5cbi8qKiBUaGUgbGl2ZSBpbi1tZW1vcnkgc3RhdGUgb2YgT05FIGJ1Y2tldCwgYW5zd2VyZWQgd2l0aG91dCB0b3VjaGluZyB0aGUgZGlzayAobm8gcm91dGluZyBmaWxlIHJlYWQsIG5vIHN0YXRmcywgbm8gc3RvcmVkIHdyaXRlIHN0YXRzKS4gUmV0dXJucyBhbiBlcnJvciBzdHJpbmcgd2hlbiB0aGUgYnVja2V0IGlzIG5vdCBsb2FkZWQgaGVyZSwgd2hpY2ggaXMgdGhlIG5vcm1hbCBzdGF0ZSBmb3IgYSBidWNrZXQgbm90aGluZyBoYXMgYWNjZXNzZWQgc2luY2Ugc3RhcnR1cC4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRBY3RpdmVCdWNrZXQoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEFjdGl2ZUJ1Y2tldEluZm8gfCBzdHJpbmc+IHtcbiAgICBsZXQga2V5ID0gYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWA7XG4gICAgbGV0IGxvYWRlZFByb21pc2UgPSBidWNrZXRzLmdldChrZXkpO1xuICAgIGlmICghbG9hZGVkUHJvbWlzZSkge1xuICAgICAgICByZXR1cm4gYEJ1Y2tldCAke2tleX0gaXMgbm90IGxvYWRlZCBvbiB0aGlzIHNlcnZlciwgc28gaXQgaGFzIG5vIGxpdmUgc3RhdGUgKGl0IGxvYWRzIG9uIGZpcnN0IGFjY2VzcylgO1xuICAgIH1cbiAgICBsZXQgbG9hZGVkOiBCdWNrZXRTdGF0ZSB8IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgICBsb2FkZWQgPSBhd2FpdCBsb2FkZWRQcm9taXNlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGBCdWNrZXQgJHtrZXl9IGZhaWxlZCB0byBsb2FkIG9uIHRoaXMgc2VydmVyOiAke1N0cmluZygoZSBhcyBFcnJvcikuc3RhY2sgPz8gZSkuc2xpY2UoMCwgNTAwKX1gO1xuICAgIH1cbiAgICBpZiAoIWxvYWRlZCkge1xuICAgICAgICByZXR1cm4gYEJ1Y2tldCAke2tleX0gZG9lcyBub3QgZXhpc3Qgb24gdGhpcyBzZXJ2ZXJgO1xuICAgIH1cbiAgICByZXR1cm4gdG9BY3RpdmVCdWNrZXRJbmZvKGxvYWRlZCk7XG59XG5cbi8qKiBMb2FkcyBhIGJ1Y2tldCB0aGF0IGV4aXN0cyBvbiB0aGlzIHNlcnZlcidzIGRpc2sgaW50byBtZW1vcnksIHdoaWNoIHN0YXJ0cyBpdHMgc3luY2hyb25pemF0aW9uIGFuZCB3aW5kb3cgdGltZXJzLCBhbmQgcmV0dXJucyBpdHMgbGl2ZSBzdGF0ZS4gTm90aGluZyBpcyB3cml0dGVuIGFuZCBubyBvdGhlciBzZXJ2ZXIgaXMgY29udGFjdGVkIC0gdW5saWtlIGJ1aWxkaW5nIGFuIEFyY2hpdmVzQ2hhaW4gZm9yIGl0LCB3aGljaCB3b3VsZCBwcm9iZSBldmVyeSBzb3VyY2UgYW5kIGNvdWxkIHdyaXRlIHRoZSByb3V0aW5nIGNvbmZpZy4gQWxyZWFkeS1sb2FkZWQgYnVja2V0cyBqdXN0IHJldHVybiB0aGVpciBzdGF0ZS4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhY3RpdmF0ZUJ1Y2tldChhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZyk6IFByb21pc2U8QWN0aXZlQnVja2V0SW5mbyB8IHN0cmluZz4ge1xuICAgIGxldCBrZXkgPSBgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9YDtcbiAgICBsZXQgd2FzTG9hZGVkID0gYnVja2V0cy5oYXMoa2V5KTtcbiAgICBsZXQgbG9hZGVkOiBCdWNrZXRTdGF0ZSB8IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgICBsb2FkZWQgPSBhd2FpdCBnZXRMb2FkZWRCdWNrZXQoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gYEJ1Y2tldCAke2tleX0gZmFpbGVkIHRvIGxvYWQgb24gdGhpcyBzZXJ2ZXI6ICR7U3RyaW5nKChlIGFzIEVycm9yKS5zdGFjayA/PyBlKS5zbGljZSgwLCA1MDApfWA7XG4gICAgfVxuICAgIGlmICghbG9hZGVkKSB7XG4gICAgICAgIHJldHVybiBgQnVja2V0ICR7a2V5fSBkb2VzIG5vdCBleGlzdCBvbiB0aGlzIHNlcnZlciAoaXQgaGFzIG5vIHN0b3JlIGZvbGRlcnMgdW5kZXIgJHtnZXRCdWNrZXRGb2xkZXIoXCI8bmFtZT5cIiwgYWNjb3VudCwgYnVja2V0TmFtZSl9KWA7XG4gICAgfVxuICAgIC8vIFdhaXQgZm9yIHRoZSBpbmRleGVzIHRvIGxvYWQsIHNvIHRoZSB0b3RhbHMgd2UgcmV0dXJuIGFyZSB0aGUgcmVhbCBvbmVzIHJhdGhlciB0aGFuIHplcm9lcyBmcm9tIHN0b3JlcyB0aGF0IGhhdmUgbm90IHJlYWQgdGhlaXIgaW5kZXggeWV0LiBUaGUgc291cmNlIHNjYW5zIGtlZXAgcnVubmluZyBpbiB0aGUgYmFja2dyb3VuZC5cbiAgICBmb3IgKGxldCBzIG9mIGxvYWRlZC5zdG9yZXMpIHtcbiAgICAgICAgYXdhaXQgcy5zdG9yZS5pbml0KCk7XG4gICAgfVxuICAgIGlmICghd2FzTG9hZGVkKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBBY3RpdmF0ZWQgYnVja2V0ICR7a2V5fSBvbiByZXF1ZXN0OiBpdCBpcyBub3cgbG9hZGVkIGFuZCBzeW5jaHJvbml6aW5nYCk7XG4gICAgfVxuICAgIHJldHVybiB0b0FjdGl2ZUJ1Y2tldEluZm8obG9hZGVkKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RBY2NvdW50QnVja2V0cyhhY2NvdW50OiBzdHJpbmcpOiBQcm9taXNlPFNlcnZlckJ1Y2tldEluZm9bXT4ge1xuICAgIGxldCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgbGV0IHRpbWluZ3MgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgIGFzeW5jIGZ1bmN0aW9uIHRpbWVkPFQ+KG5hbWU6IHN0cmluZywgcnVuOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgICAgIGxldCBiZWdhbiA9IERhdGUubm93KCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgcnVuKCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0aW1pbmdzLnNldChuYW1lLCAodGltaW5ncy5nZXQobmFtZSkgfHwgMCkgKyAoRGF0ZS5ub3coKSAtIGJlZ2FuKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gVGhlIGRpc2sgaXMgdGhlIHJlY29yZDogYSBidWNrZXQgZXhpc3RzIGhlcmUgd2hlbiBpdCBoYXMgYXQgbGVhc3Qgb25lIHN0b3JlIGZvbGRlciwgYW5kIHNldmVyYWwgbmFtZXMgZm9yIG9uZSBidWNrZXQgYXJlIHN0aWxsIG9uZSBidWNrZXRcbiAgICBsZXQgZm9sZGVycyA9IGF3YWl0IHRpbWVkKFwicmVhZGRpclwiLCAoKSA9PiBsaXN0QWNjb3VudFN0b3JlRm9sZGVycyhhY2NvdW50KSk7XG4gICAgbGV0IGJ5QnVja2V0ID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICBmb3IgKGxldCBzdG9yZSBvZiBmb2xkZXJzKSB7XG4gICAgICAgIGlmIChieUJ1Y2tldC5oYXMoc3RvcmUuYnVja2V0TmFtZSkpIGNvbnRpbnVlO1xuICAgICAgICBieUJ1Y2tldC5zZXQoc3RvcmUuYnVja2V0TmFtZSwgc3RvcmUuZm9sZGVyKTtcbiAgICB9XG4gICAgbGV0IG5hbWVzID0gWy4uLmJ5QnVja2V0LmtleXMoKV07XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKG5hbWVzLm1hcChhc3luYyBidWNrZXROYW1lID0+IHtcbiAgICAgICAgICAgIGxldCBrZXkgPSBgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9YDtcbiAgICAgICAgICAgIGxldCBmb2xkZXIgPSBieUJ1Y2tldC5nZXQoYnVja2V0TmFtZSkgfHwgXCJcIjtcbiAgICAgICAgICAgIGxldCBiYXNlOiBTZXJ2ZXJCdWNrZXRJbmZvID0geyBidWNrZXROYW1lLCBhY3RpdmU6IGZhbHNlLCBmb2xkZXIgfTtcbiAgICAgICAgICAgIGJhc2UuZGlzayA9IGF3YWl0IHRpbWVkKFwic3RhdGZzXCIsICgpID0+IGdldERpc2tJbmZvKGZvbGRlcikpLmNhdGNoKChlOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGJhc2UuZGlza0Vycm9yID0gU3RyaW5nKGUuc3RhY2sgPz8gZSkuc2xpY2UoMCwgNTAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBiYXNlLndyaXRlU3RhdHMgPSBnZXRCdWNrZXRXcml0ZVN0YXRzKGtleSk7XG4gICAgICAgICAgICBjb25zdCBsb2FkZWRQcm9taXNlID0gYnVja2V0cy5nZXQoa2V5KTtcbiAgICAgICAgICAgIGlmIChsb2FkZWRQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGxvYWRlZCA9IGF3YWl0IHRpbWVkKFwiYXdhaXRMb2FkZWRcIiwgKCkgPT4gbG9hZGVkUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb2FkZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLmJhc2UsIGFjdGl2ZTogdHJ1ZSwgY29uZmlnOiBnZXRCdWNrZXRDb25maWcobG9hZGVkKSB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyAuLi5iYXNlLCBhY3RpdmU6IHRydWUsIGVycm9yOiBTdHJpbmcoKGUgYXMgRXJyb3IpLnN0YWNrID8/IGUpLnNsaWNlKDAsIDUwMCkgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IGF3YWl0IHRpbWVkKFwicmVhZFJvdXRpbmdGaWxlXCIsICgpID0+IHJlYWRSb3V0aW5nRnJvbURpc2soYWNjb3VudCwgYnVja2V0TmFtZSkpO1xuICAgICAgICAgICAgICAgIGlmICghcGFyc2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLmJhc2UsIGVycm9yOiBgTm8gcm91dGluZyBmaWxlICgke1JPVVRJTkdfRklMRX0pIGluIGFueSBvZiBpdHMgc3RvcmVzYCB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4geyAuLi5iYXNlLCBjb25maWc6IHsgcmVtb3RlQ29uZmlnOiBwYXJzZWQgfSB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLmJhc2UsIGVycm9yOiBTdHJpbmcoKGUgYXMgRXJyb3IpLnN0YWNrID8/IGUpLnNsaWNlKDAsIDUwMCkgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIC8vIFRoZSBwYXJ0cyBydW4gY29uY3VycmVudGx5LCBzbyB0aGVzZSBhcmUgc3VtbWVkIHdhbGwgdGltZXMgcGVyIHBhcnQsIG5vdCBhIGJyZWFrZG93biBvZiB0aGUgdG90YWxcbiAgICAgICAgbGV0IHBhcnRzID0gWy4uLnRpbWluZ3NdLm1hcCgoW25hbWUsIG1zXSkgPT4gYCR7bmFtZX0gJHttc31tc2ApLmpvaW4oXCIsIFwiKTtcbiAgICAgICAgY29uc29sZS5sb2coYGxpc3RBY2NvdW50QnVja2V0cygke2FjY291bnR9KSB0b29rICR7RGF0ZS5ub3coKSAtIHN0YXJ0fW1zIGZvciAke25hbWVzLmxlbmd0aH0gYnVja2V0czogJHtwYXJ0c31gKTtcbiAgICB9XG59XG5cbmV4cG9ydCB0eXBlIEJ1Y2tldFdyaXRlU3RhdHMgPSB7XG4gICAgLyoqIEV2ZXJ5IHNldCBjYWxsIHRoZSBidWNrZXQgYWNjZXB0ZWQgKi9cbiAgICBvcmlnaW5hbFdyaXRlczogbnVtYmVyO1xuICAgIG9yaWdpbmFsQnl0ZXM6IG51bWJlcjtcbiAgICAvKiogV2hhdCBhY3R1YWxseSByZWFjaGVkIHRoZSBzb3VyY2VzLiBGYXN0IHdyaXRlcyBjb2FsZXNjZSByZXBlYXRlZCB3cml0ZXMgdG8gdGhlIHNhbWUga2V5LCBzbyB0aGlzIGlzIGxvd2VyIHRoYW4gdGhlIG9yaWdpbmFsIGNvdW50cyAoYW5kIGlzIHdoYXQgdGhlIGRpc2sgYWN0dWFsbHkgZGlkKS4gKi9cbiAgICBmbHVzaGVkV3JpdGVzOiBudW1iZXI7XG4gICAgZmx1c2hlZEJ5dGVzOiBudW1iZXI7XG59O1xuZnVuY3Rpb24gZW1wdHlXcml0ZVN0YXRzKCk6IEJ1Y2tldFdyaXRlU3RhdHMge1xuICAgIHJldHVybiB7IG9yaWdpbmFsV3JpdGVzOiAwLCBvcmlnaW5hbEJ5dGVzOiAwLCBmbHVzaGVkV3JpdGVzOiAwLCBmbHVzaGVkQnl0ZXM6IDAgfTtcbn1cblxuLy8gSW4gbWVtb3J5IG9ubHk6IHRvdGFscyBzaW5jZSB0aGlzIHByb2Nlc3Mgc3RhcnRlZCAob3IgdGhlIGxhc3QgY2xlYXJXcml0ZVN0YXRzKS4gUGVyc2lzdGluZyB0aGVtIHRvIGRpc2sgd2FzIG1vcmUgbWFjaGluZXJ5IHRoYW4gdGhlIG51bWJlcnMgd2VyZSB3b3J0aC5cbmNvbnN0IHdyaXRlU3RhdHMgPSBuZXcgTWFwPHN0cmluZywgQnVja2V0V3JpdGVTdGF0cz4oKTtcblxuZnVuY3Rpb24gY291bnRCdWNrZXRXcml0ZShrZXk6IHN0cmluZywga2luZDogXCJvcmlnaW5hbFwiIHwgXCJmbHVzaGVkXCIsIGJ5dGVzOiBudW1iZXIpOiB2b2lkIHtcbiAgICBsZXQgc3RhdHMgPSB3cml0ZVN0YXRzLmdldChrZXkpO1xuICAgIGlmICghc3RhdHMpIHtcbiAgICAgICAgc3RhdHMgPSBlbXB0eVdyaXRlU3RhdHMoKTtcbiAgICAgICAgd3JpdGVTdGF0cy5zZXQoa2V5LCBzdGF0cyk7XG4gICAgfVxuICAgIGlmIChraW5kID09PSBcIm9yaWdpbmFsXCIpIHtcbiAgICAgICAgc3RhdHMub3JpZ2luYWxXcml0ZXMrKztcbiAgICAgICAgc3RhdHMub3JpZ2luYWxCeXRlcyArPSBieXRlcztcbiAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0cy5mbHVzaGVkV3JpdGVzKys7XG4gICAgICAgIHN0YXRzLmZsdXNoZWRCeXRlcyArPSBieXRlcztcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldEJ1Y2tldFdyaXRlU3RhdHMoa2V5OiBzdHJpbmcpOiBCdWNrZXRXcml0ZVN0YXRzIHtcbiAgICByZXR1cm4gd3JpdGVTdGF0cy5nZXQoa2V5KSB8fCBlbXB0eVdyaXRlU3RhdHMoKTtcbn1cblxuLyoqIFplcm9lcyB0aGUgd3JpdGUgc3RhdGlzdGljcyBvZiBldmVyeSBidWNrZXQgaW4gdGhlIGFjY291bnQuICovXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJBY2NvdW50V3JpdGVTdGF0cyhhY2NvdW50OiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGxldCBwcmVmaXggPSBgJHthY2NvdW50fS9gO1xuICAgIGxldCBjbGVhcmVkID0gMDtcbiAgICBmb3IgKGxldCBrZXkgb2YgWy4uLndyaXRlU3RhdHMua2V5cygpXSkge1xuICAgICAgICBpZiAoIWtleS5zdGFydHNXaXRoKHByZWZpeCkpIGNvbnRpbnVlO1xuICAgICAgICB3cml0ZVN0YXRzLmRlbGV0ZShrZXkpO1xuICAgICAgICBjbGVhcmVkKys7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBDbGVhcmVkIHRoZSB3cml0ZSBzdGF0aXN0aWNzIG9mICR7Y2xlYXJlZH0gYnVja2V0cyBpbiBhY2NvdW50ICR7YWNjb3VudH1gKTtcbiAgICByZXR1cm4gY2xlYXJlZDtcbn1cbiJdfQ==
|
|
390
|
-
/* _JS_SOURCE_HASH = "
|
|
259
|
+
exports.debugListAccountBuckets = debugListAccountBuckets;
|
|
260
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZVNlcnZlclN0YXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3RvcmFnZVNlcnZlclN0YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUF3QztBQUl4QyxpREFBd0c7QUFDeEcsaURBQXNFO0FBQ3RFLDJEQUE4RDtBQUM5RCxpREFBcUQ7QUFDckQsNkNBQXFEO0FBQ3JELDZDQUFrSjtBQUNsSixxRUFBdUY7QUFDdkYsMkNBQTJDO0FBQzNDLCtDQUF3RjtBQUV4Rjs7Ozs7R0FLRztBQUVIOzs7O0dBSUc7QUFDSCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQztBQUM1QywrTUFBK007QUFDL00sTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQWtDLENBQUM7QUFFL0QsU0FBZ0IsUUFBUSxDQUFDLE9BQWUsRUFBRSxVQUFrQixFQUFFLElBQVk7SUFDdEUsOEdBQThHO0lBQzlHLElBQUEsa0NBQXFCLEVBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUIsSUFBSSxNQUFNLEdBQUcsSUFBQSw0QkFBZSxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDeEQsSUFBSSxRQUFRLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNsQyxJQUFJLFFBQVE7UUFBRSxPQUFPLFFBQVEsQ0FBQztJQUM5QixPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxjQUFjLE9BQU8sSUFBSSxVQUFVLFlBQVksTUFBTSxtREFBbUQsQ0FBQyxDQUFDO0lBQzNKLElBQUksS0FBSyxHQUFHLElBQUkscUJBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFO1FBQ3BDLG1FQUFtRTtRQUNuRSxNQUFNLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFBLHdCQUFZLEVBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUM7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QUUsS0FBSyxFQUFFLG9CQUFvQiwyQkFBWSx3QkFBd0IsRUFBRSxDQUFDO2dCQUN4RixDQUFDO2dCQUNELE9BQU8sRUFBRSxHQUFHLElBQUksRUFBRSxNQUFNLEVBQUUsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQztZQUMxRCxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDVCxPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxNQUFDLENBQVcsQ0FBQyxLQUFLLG1DQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM3RSxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNSLENBQUM7WUFBUyxDQUFDO1FBQ1AsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsT0FBTyxVQUFVLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLFVBQVUsS0FBSyxDQUFDLE1BQU0sVUFBVSxDQUFDLENBQUM7SUFDaEgsQ0FBQztBQUNMLENBQUM7QUFyQ0QsMERBcUNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmxvYlN0b3JlIH0gZnJvbSBcIi4vYmxvYlN0b3JlXCI7XG5pbXBvcnQge1xuICAgIFJlbW90ZUNvbmZpZywgU291cmNlQ29uZmlnLCBJQXJjaGl2ZXMsIEFyY2hpdmVzQ29uZmlnLCBBcmNoaXZlc1N5bmNTdGF0dXMsIFN5bmNBY3Rpdml0eSxcbn0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHsgUk9VVElOR19GSUxFLCBwYXJzZVJvdXRpbmdEYXRhLCBzZXJpYWxpemVSZW1vdGVDb25maWcsIG5vcm1hbGl6ZVNvdXJjZSB9IGZyb20gXCIuL3JlbW90ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgY3JlYXRlU3RvcmVTb3VyY2UsIGFwcGx5U291cmNlQ29uZmlnIH0gZnJvbSBcIi4vc3RvcmVTb3VyY2VzXCI7XG5pbXBvcnQgeyBicm9hZGNhc3RSb3V0aW5nQ2hhbmdlZCB9IGZyb20gXCIuL3N0b3JhZ2VDb250cm9sbGVyXCI7XG5pbXBvcnQgeyBhc3NlcnRXcml0ZXNBbGxvd2VkIH0gZnJvbSBcIi4vc2VydmVyQ29uZmlnXCI7XG5pbXBvcnQgeyBhc3NlcnRWYWxpZFNvdXJjZU5hbWUgfSBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBnZXRCdWNrZXRGb2xkZXIsIGxpc3RBY2NvdW50U3RvcmVGb2xkZXJzLCBsaXN0QnVja2V0U3RvcmVGb2xkZXJzLCByZWFkUm91dGluZ0Zyb21EaXNrLCBnZXREaXNrSW5mbywgQnVja2V0RGlza0luZm8gfSBmcm9tIFwiLi9idWNrZXREaXNrXCI7XG5pbXBvcnQgeyBzY2hlZHVsZUJvdW5kYXJ5V29yaywgcmVpbmplY3RJbnRlcm1lZGlhdGVzIH0gZnJvbSBcIi4vaW50ZXJtZWRpYXRlTWFuYWdlbWVudFwiO1xuaW1wb3J0IHsgaXNTZWxmU291cmNlIH0gZnJvbSBcIi4vc3RvcmVQbGFuXCI7XG5pbXBvcnQgeyBjb3VudEJ1Y2tldFdyaXRlLCBnZXRCdWNrZXRXcml0ZVN0YXRzLCBCdWNrZXRXcml0ZVN0YXRzIH0gZnJvbSBcIi4vYWNjZXNzU3RhdHNcIjtcblxuLyoqXG4gKiBXaGF0IHRoaXMgc2VydmVyIEhBUzogdGhlIHN0b3JlcywgYnkgbmFtZSAoZ2V0U3RvcmUpIC0gbWFkZSBvbmNlLCBzZWxmLWNvbmZpZ3VyaW5nIGZyb20gdGhlcmUgLVxuICogYW5kIHRoZSB0aHJlZSBlbnRyeSBwb2ludHMgYSByZXF1ZXN0IHJlc29sdmVzIHRocm91Z2ggKGZpbmRCdWNrZXRTdG9yZSwgcmVhZEJ1Y2tldEludGVybmFsLFxuICogd3JpdGVSb3V0aW5nQ29uZmlnKS4gVGhlcmUgaXMgbm8gY2FjaGVkIGJ1Y2tldCBzdGF0ZTogYSBidWNrZXQgaXMgbm90aGluZyBidXQgdGhlIHN0b3JlcyB3aG9zZVxuICogZm9sZGVycyBzaGFyZSBpdHMgbmFtZSwgbGlzdGVkIG9mZiB0aGUgZGlzayB3aGVuIHNvbWV0aGluZyBnZW51aW5lbHkgbmVlZHMgYWxsIG9mIHRoZW0uXG4gKi9cblxuLyoqXG4gKiBFdmVyeSBzdG9yZSB0aGlzIHByb2Nlc3MgcnVucywgYnkgZm9sZGVyIC0gd2hpY2ggSVMgdGhlIHN0b3JlJ3MgaWRlbnRpdHk6IGFjY291bnQsIG5hbWUsIGJ1Y2tldC5cbiAqIEEgc3RvcmUgaXMgbWFkZSBvbmNlLCBjb25maWd1cmVzIGl0c2VsZiBmcm9tIHRoZSByb3V0aW5nIGNvbmZpZyBpdCBob2xkcywgYW5kIHN0YXlzOyBub3RoaW5nIGhlcmVcbiAqIGRlY2lkZXMgd2hhdCBpdCBpcywgb25seSB0aGF0IGl0IGV4aXN0cy5cbiAqL1xuY29uc3Qgc3RvcmVzID0gbmV3IE1hcDxzdHJpbmcsIEJsb2JTdG9yZT4oKTtcbi8vIFRoZSBvcGVuZWQgc3RvcmVzIG9mIGVhY2ggYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWAsIGJ5IG5hbWUgLSB3aGljaCBidWNrZXRzIGFyZSBBQ1RJVkUgKHNvbWV0aGluZyB0b3VjaGVkIHRoZW0pLCBmb3IgZGVwbG95IGhhbmRvZmZzIGFuZCB0aGUgZGVidWcgcGFnZXMuIFB1cmVseSBhIHJlZ2lzdHJ5IG9mIHdoYXQgZ2V0U3RvcmUgYWxyZWFkeSBtYWRlLlxuY29uc3QgYWN0aXZlU3RvcmVzID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIEJsb2JTdG9yZT4+KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdG9yZShhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nKTogQmxvYlN0b3JlIHtcbiAgICAvLyBUaGUgb25lIHBsYWNlIGEgbmFtZSBiZWNvbWVzIGEgZm9sZGVyLCBzbyB0aGUgb25lIHBsYWNlIGl0IGlzIHZhbGlkYXRlZCAoaXQgY2FuIGNvbWUgc3RyYWlnaHQgb2ZmIHRoZSB3aXJlKVxuICAgIGFzc2VydFZhbGlkU291cmNlTmFtZShuYW1lKTtcbiAgICBsZXQgZm9sZGVyID0gZ2V0QnVja2V0Rm9sZGVyKG5hbWUsIGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGxldCBleGlzdGluZyA9IHN0b3Jlcy5nZXQoZm9sZGVyKTtcbiAgICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZztcbiAgICBjb25zb2xlLmxvZyhgT3BlbmluZyBzdG9yZSAke0pTT04uc3RyaW5naWZ5KG5hbWUpfSBvZiBidWNrZXQgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9IChmb2xkZXIgJHtmb2xkZXJ9KSAtIGNyZWF0ZWQgb24gdGhpcyBmaXJzdCB1c2UgaWYgaXQgbmV2ZXIgZXhpc3RlZGApO1xuICAgIGxldCBzdG9yZSA9IG5ldyBCbG9iU3RvcmUoZm9sZGVyLCBuYW1lLCB7XG4gICAgICAgIC8vIFdoaWNoIGVudHJpZXMgaW4gSVRTIHJvdXRpbmcgY29uZmlnIGFyZSB0aGlzIHNlcnZlcidzIGNvcHkgb2YgaXRcbiAgICAgICAgaXNTZWxmOiBzb3VyY2UgPT4gaXNTZWxmU291cmNlKHNvdXJjZSwgYWNjb3VudCwgYnVja2V0TmFtZSksXG4gICAgICAgIGNyZWF0ZVNvdXJjZTogY29uZmlnID0+IGNyZWF0ZVN0b3JlU291cmNlKHsgc291cmNlQ29uZmlnOiBjb25maWcuc291cmNlQ29uZmlnLCBmb2xkZXIsIHdyaXRlRGVsYXk6IGNvbmZpZy53cml0ZURlbGF5IH0pLFxuICAgICAgICBhcHBseVNvdXJjZTogKHNvdXJjZSwgc291cmNlQ29uZmlnLCB3cml0ZURlbGF5KSA9PiBhcHBseVNvdXJjZUNvbmZpZyhzb3VyY2UsIHNvdXJjZUNvbmZpZywgd3JpdGVEZWxheSksXG4gICAgICAgIG9uV3JpdGVDb3VudGVkOiAoa2luZCwgYnl0ZXMpID0+IGNvdW50QnVja2V0V3JpdGUoYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWAsIGtpbmQsIGJ5dGVzKSxcbiAgICAgICAgcmVzb2x2ZVNvdXJjZVVybDogcmVzb2x2ZVNvdXJjZUFyY2hpdmVzLFxuICAgICAgICAvLyBUaGUgc3RvcmUgaXMgdGhlIG9uZSB0aGF0IGtub3dzIHdoZW4gYSBjb25maWcgbGFuZGVkLCBhbmQgYSBjb25maWcgd2l0aCB1cGNvbWluZyB3aW5kb3dzIGlzIHdoYXQgYm91bmRhcnkgc2NhbnMgYXJlIGFybWVkIGZyb21cbiAgICAgICAgb25Sb3V0aW5nQXBwbGllZDogcm91dGluZyA9PiBzY2hlZHVsZUJvdW5kYXJ5V29yayhhY2NvdW50LCBidWNrZXROYW1lLCByb3V0aW5nKSxcbiAgICB9KTtcbiAgICBzdG9yZXMuc2V0KGZvbGRlciwgc3RvcmUpO1xuICAgIGxldCBrZXkgPSBgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9YDtcbiAgICBsZXQgYnlOYW1lID0gYWN0aXZlU3RvcmVzLmdldChrZXkpO1xuICAgIGlmICghYnlOYW1lKSB7XG4gICAgICAgIGJ5TmFtZSA9IG5ldyBNYXAoKTtcbiAgICAgICAgYWN0aXZlU3RvcmVzLnNldChrZXksIGJ5TmFtZSk7XG4gICAgfVxuICAgIGJ5TmFtZS5zZXQobmFtZSwgc3RvcmUpO1xuICAgIC8vIExhenkgaW5pdCB3b3VsZCBsZWF2ZSBhIHN0b3JlIG5vdGhpbmcgaGFzIHRvdWNoZWQgc2l0dGluZyBpbmVydCAtIG5vIGluZGV4IGxvYWRlZCwgbm8gY29uZmlnIGFwcGxpZWQsIG5vdGhpbmcgc3luY2hyb25pemluZyAtIHdoaWxlIGl0cyBmb2xkZXIgaXMgZnVsbCBvZiBmaWxlc1xuICAgIHZvaWQgc3RvcmUuaW5pdCgpLmNhdGNoKChlOiBFcnJvcikgPT4gY29uc29sZS5lcnJvcihgSW5pdGlhbGl6aW5nIHN0b3JlICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IG9mIGJ1Y2tldCAke2FjY291bnR9LyR7YnVja2V0TmFtZX0gZmFpbGVkOiAke2Uuc3RhY2sgPz8gZX1gKSk7XG4gICAgcmV0dXJuIHN0b3JlO1xufVxuXG4vKiogVGhlIHN0b3JlIHNlcnZpbmcgYSByZXF1ZXN0OiB0aGUgb25lIHRoZSBjbGllbnQncyBzZWxlY3RlZCBlbnRyeSBOQU1FUy4gQWNjb3VudCwgbmFtZSwgYW5kIGJ1Y2tldCBBUkUgdGhlIGZvbGRlciwgc28gdGhpcyBpcyBhIGRpcmVjdCBsb29rdXAsIG5ldmVyIGEgc2VhcmNoIG9mIHdoYXQgZXhpc3RzIC0gYW5kIGEgbmFtZSB0aGlzIHNlcnZlciBoYXMgbmV2ZXIgc2VlbiBpcyBDUkVBVEVELCBuZXZlciByZWplY3RlZCwgYmVjYXVzZSBhc2tpbmcgZm9yIGEgbmFtZSBpcyB0aGUgaW5zdHJ1Y3Rpb24gdG8gaGF2ZSB0aGF0IHN0b3JlIChvbmUgbmFtZSwgb25lIGZvbGRlciwgb25lIGluZGV4OyBpdCBjb25maWd1cmVzIGl0c2VsZiBvbmNlIHRoZSByb3V0aW5nIGNvbmZpZyBsYW5kcyBpbiBpdCkuIE5vdGhpbmcgZWxzZSBhYm91dCB0aGUgcmVxdWVzdCBpcyBjb21wYXJlZCAtIG5vdCB0aGUgd2luZG93LCBub3QgdGhlIHJvdXRlLCBub3QgdGhlIGZsYWdzIC0gd2hpY2ggaXMgdGhlIHdob2xlIHBvaW50IG9mIG5hbWluZyBpdDogYSBjbGllbnQgYSBjb25maWcgdmVyc2lvbiBiZWhpbmQgb24gc29tZSBmbGFnIHN0aWxsIHJlYWNoZXMgdGhlIHJpZ2h0IHN0b3JlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRCdWNrZXRTdG9yZShhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgc291cmNlQ29uZmlnOiBTb3VyY2VDb25maWcgfCB1bmRlZmluZWQpOiBCbG9iU3RvcmUge1xuICAgIGlmICghc291cmNlQ29uZmlnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gcmVtb3RlIHNvdXJjZSBjb25maWd1cmF0aW9uIHdhcyBwcm92aWRlZCBmb3IgYnVja2V0ICR7YWNjb3VudH0vJHtidWNrZXROYW1lfTogZXZlcnkgcmVxdWVzdCBtdXN0IHNheSB3aGljaCBjb25maWd1cmVkIHNvdXJjZSBpdCBzZWxlY3RlZGApO1xuICAgIH1cbiAgICByZXR1cm4gZ2V0U3RvcmUoYWNjb3VudCwgYnVja2V0TmFtZSwgc291cmNlQ29uZmlnLm5hbWUpO1xufVxuXG4vKiogVGhlIHN0b3JlcyBvZiBhIGJ1Y2tldCBhcyB0aGUgRElTSyByZWNvcmRzIHRoZW0gKGEgYnVja2V0IGlzIG5vdGhpbmcgbW9yZSB0aGFuIHRoZSBzdG9yZSBmb2xkZXJzIHNoYXJpbmcgaXRzIG5hbWUpLCBvcGVuZWQgLSBzbyB0aGUgb25lcyB0aGF0IHdlcmVuJ3QgcnVubmluZyB5ZXQgc3RhcnQgc3luY2hyb25pemluZy4gRW1wdHkgd2hlbiB0aGUgYnVja2V0IGRvZXMgbm90IGV4aXN0IGhlcmUuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0QnVja2V0U3RvcmVzKGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IG5hbWU6IHN0cmluZzsgc3RvcmU6IEJsb2JTdG9yZSB9W10+IHtcbiAgICBsZXQgZm9sZGVycyA9IGF3YWl0IGxpc3RCdWNrZXRTdG9yZUZvbGRlcnMoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgcmV0dXJuIGZvbGRlcnMubWFwKHggPT4gKHsgbmFtZTogeC5uYW1lLCBzdG9yZTogZ2V0U3RvcmUoYWNjb3VudCwgYnVja2V0TmFtZSwgeC5uYW1lKSB9KSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlcXVpcmVCdWNrZXRTdG9yZXMoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgbmFtZTogc3RyaW5nOyBzdG9yZTogQmxvYlN0b3JlIH1bXT4ge1xuICAgIGxldCBsaXN0ID0gYXdhaXQgZ2V0QnVja2V0U3RvcmVzKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGlmICghbGlzdC5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBCdWNrZXQgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9IGRvZXMgbm90IGV4aXN0IG9uIHRoaXMgc2VydmVyLiBXcml0ZSBpdHMgcm91dGluZyBjb25maWcgdG8gJHtKU09OLnN0cmluZ2lmeShST1VUSU5HX0ZJTEUpfSB0byBjcmVhdGUgaXQuYCk7XG4gICAgfVxuICAgIHJldHVybiBsaXN0O1xufVxuXG4vKiogSW50ZXJuYWwgKHN0b3JlLXRvLXN0b3JlKSByZWFkcyBza2lwIHN0b3JlIHNlbGVjdGlvbiBlbnRpcmVseTogdGhlIGNhbGxlciBpcyBhbm90aGVyIHN0b3JlIHdob3NlIGluZGV4IHNheXMgdGhpcyBNQUNISU5FIGhvbGRzIHRoZSBieXRlcyAtIHRoZSBwZXJzaXN0ZWQgaG9sZGVyIGlkZW50aXR5IGlzIGp1c3QgYSBVUkwsIHdoaWNoIGNhbm5vdCBuYW1lIGEgc3RvcmUuIFdoaWNoZXZlciBzdG9yZSdzIGZvbGRlciBoYXMgdGhlIG5ld2VzdCBjb3B5IGFuc3dlcnMuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZEJ1Y2tldEludGVybmFsKGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nLCBjb25maWc6IHsgcGF0aDogc3RyaW5nOyByYW5nZT86IHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXIgfTsgaW5jbHVkZVRvbWJzdG9uZXM/OiBib29sZWFuIH0pOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+IHtcbiAgICBsZXQgYnVja2V0U3RvcmVzID0gYXdhaXQgcmVxdWlyZUJ1Y2tldFN0b3JlcyhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKGJ1Y2tldFN0b3Jlcy5tYXAocyA9PiBzLnN0b3JlLmdldDIoeyBwYXRoOiBjb25maWcucGF0aCwgcmFuZ2U6IGNvbmZpZy5yYW5nZSwgaW5jbHVkZVRvbWJzdG9uZXM6IGNvbmZpZy5pbmNsdWRlVG9tYnN0b25lcywgaW50ZXJuYWw6IHRydWUgfSkpKTtcbiAgICBsZXQgYmVzdDogeyBkYXRhOiBCdWZmZXI7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZDtcbiAgICBmb3IgKGxldCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgICAgICBpZiAocmVzdWx0ICYmICghYmVzdCB8fCByZXN1bHQud3JpdGVUaW1lID4gYmVzdC53cml0ZVRpbWUpKSB7XG4gICAgICAgICAgICBiZXN0ID0gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBiZXN0O1xufVxuXG5mdW5jdGlvbiBhZ2dyZWdhdGVBcmNoaXZlc0NvbmZpZyhidWNrZXRTdG9yZXM6IEJsb2JTdG9yZVtdLCByb3V0aW5nOiBSZW1vdGVDb25maWcgfCB1bmRlZmluZWQpOiBBcmNoaXZlc0NvbmZpZyB7XG4gICAgbGV0IGluZGV4ID0geyBmaWxlQ291bnQ6IDAsIGJ5dGVDb3VudDogMCB9O1xuICAgIGxldCBpbmRleFNvdXJjZXM6IHsgZGVidWdOYW1lOiBzdHJpbmc7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9W10gPSBbXTtcbiAgICBsZXQgc3luY2luZzogU3luY0FjdGl2aXR5W10gPSBbXTtcbiAgICBsZXQgcmVhZGVyRGlza0xpbWl0OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgc3RvcmUgb2YgYnVja2V0U3RvcmVzKSB7XG4gICAgICAgIGxldCBwcm9ncmVzcyA9IHN0b3JlLmdldFN5bmNQcm9ncmVzcygpO1xuICAgICAgICBpbmRleC5maWxlQ291bnQgKz0gcHJvZ3Jlc3MuaW5kZXguZmlsZUNvdW50O1xuICAgICAgICBpbmRleC5ieXRlQ291bnQgKz0gcHJvZ3Jlc3MuaW5kZXguYnl0ZUNvdW50O1xuICAgICAgICBpbmRleFNvdXJjZXMucHVzaCguLi5wcm9ncmVzcy5zb3VyY2VzKTtcbiAgICAgICAgc3luY2luZy5wdXNoKC4uLnByb2dyZXNzLnN5bmNpbmcpO1xuICAgICAgICByZWFkZXJEaXNrTGltaXQgPSByZWFkZXJEaXNrTGltaXQgfHwgcHJvZ3Jlc3MucmVhZGVyRGlza0xpbWl0O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICAvLyBFdmVyeSBzdG9yZSBpcyBpbmRleC1iYWNrZWQsIHNvIHRoZSBjaGFuZ2UgZmVlZCBpcyBhbHdheXMgbmF0aXZlXG4gICAgICAgIHN1cHBvcnRzQ2hhbmdlc0FmdGVyOiB0cnVlLFxuICAgICAgICByZW1vdGVDb25maWc6IHJvdXRpbmcsXG4gICAgICAgIGluZGV4LFxuICAgICAgICBpbmRleFNvdXJjZXMsXG4gICAgICAgIHJlYWRlckRpc2tMaW1pdCxcbiAgICAgICAgc3luY2luZyxcbiAgICB9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0QnVja2V0QXJjaGl2ZXNDb25maWcoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEFyY2hpdmVzQ29uZmlnPiB7XG4gICAgbGV0IGJ1Y2tldFN0b3JlcyA9IGF3YWl0IHJlcXVpcmVCdWNrZXRTdG9yZXMoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgbGV0IHJvdXRpbmcgPSBhd2FpdCByZWFkUm91dGluZ0Zyb21EaXNrKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIHJldHVybiBhZ2dyZWdhdGVBcmNoaXZlc0NvbmZpZyhidWNrZXRTdG9yZXMubWFwKHggPT4geC5zdG9yZSksIHJvdXRpbmcpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYnVja2V0U3luY1N0YXR1cyhhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZyk6IFByb21pc2U8QXJjaGl2ZXNTeW5jU3RhdHVzPiB7XG4gICAgbGV0IGJ1Y2tldFN0b3JlcyA9IGF3YWl0IHJlcXVpcmVCdWNrZXRTdG9yZXMoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgbGV0IHN0YXR1c2VzID0gYXdhaXQgUHJvbWlzZS5hbGwoYnVja2V0U3RvcmVzLm1hcChzID0+IHMuc3RvcmUuZ2V0U3luY1N0YXR1cygpKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYWxsU2NhbnNDb21wbGV0ZTogc3RhdHVzZXMuZXZlcnkoeCA9PiB4LmFsbFNjYW5zQ29tcGxldGUpLFxuICAgICAgICBpbmRleFNpemU6IHN0YXR1c2VzLnJlZHVjZSgoc3VtLCB4KSA9PiBzdW0gKyB4LmluZGV4U2l6ZSwgMCksXG4gICAgICAgIHNvdXJjZXM6IHN0YXR1c2VzLmZsYXRNYXAoeCA9PiB4LnNvdXJjZXMpLFxuICAgIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWJ1Z0J1Y2tldEluZGV4VG90YWxzKGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlcjsgc291cmNlczogeyBkZWJ1Z05hbWU6IHN0cmluZzsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyIH1bXSB9PiB7XG4gICAgbGV0IGJ1Y2tldFN0b3JlcyA9IGF3YWl0IHJlcXVpcmVCdWNrZXRTdG9yZXMoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgbGV0IHRvdGFscyA9IGF3YWl0IFByb21pc2UuYWxsKGJ1Y2tldFN0b3Jlcy5tYXAocyA9PiBzLnN0b3JlLmNvbXB1dGVJbmRleFRvdGFscygpKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZmlsZUNvdW50OiB0b3RhbHMucmVkdWNlKChzdW0sIHgpID0+IHN1bSArIHguZmlsZUNvdW50LCAwKSxcbiAgICAgICAgYnl0ZUNvdW50OiB0b3RhbHMucmVkdWNlKChzdW0sIHgpID0+IHN1bSArIHguYnl0ZUNvdW50LCAwKSxcbiAgICAgICAgc291cmNlczogdG90YWxzLmZsYXRNYXAoeCA9PiB4LnNvdXJjZXMpLFxuICAgIH07XG59XG5cbmNvbnN0IHJlc29sdmVkU291cmNlQXJjaGl2ZXMgPSBuZXcgTWFwPHN0cmluZywgSUFyY2hpdmVzPigpO1xuLyoqIEEgY2FjaGVkIElBcmNoaXZlcyBmb3IgYSBwZXJzaXN0ZWQgc291cmNlIGlkZW50aXR5OiBhIHJvdXRpbmcgVVJMIChob3N0ZWQvYmFja2JsYXplKSBvciBhIGRpc2sgZm9sZGVyIHBhdGggLSB0aGUgZm9ybSBCbG9iU3RvcmUncyBzb3VyY2VzIGxpc3Qgc3RvcmVzLiBDb25maWd1cmF0aW9uICh2YWxpZCB3aW5kb3dzLCByb3V0ZXMpIGRlY2lkZXMgV0hFTiBhIHNvdXJjZSBzaG91bGQgYmUgdXNlZDsgZm9yIHJlYWRpbmcgYnl0ZXMgdGhlIGluZGV4IHNheXMgYSBzb3VyY2UgaG9sZHMsIHRoZSBVUkwgYWxvbmUgaXMgZW5vdWdoIC0gZXZlbiBmb3Igc291cmNlcyBubyBsb25nZXIgaW4gYW55IGNvbmZpZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlU291cmNlQXJjaGl2ZXModXJsOiBzdHJpbmcpOiBJQXJjaGl2ZXMge1xuICAgIGxldCBleGlzdGluZyA9IHJlc29sdmVkU291cmNlQXJjaGl2ZXMuZ2V0KHVybCk7XG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3Rpbmc7XG4gICAgbGV0IHNvdXJjZUNvbmZpZzogU291cmNlQ29uZmlnIHwgdW5kZWZpbmVkO1xuICAgIGlmICh1cmwuc3RhcnRzV2l0aChcImh0dHBzOi8vXCIpKSB7XG4gICAgICAgIC8vIFRoZSBjb25maWcgaXMgZmFicmljYXRlZCBmcm9tIHRoZSBiYXJlIFVSTCBhbmQgY2FuIG5ldmVyIGV4YWN0LW1hdGNoIGEgc2VydmVyJ3MgZW50cmllcyAtIHdoaWNoIGlzIGZpbmUsIGJlY2F1c2UgaG9sZGVyIHJlYWRzIGFyZSBpbnRlcm5hbCByZWFkcywgYW5kIGludGVybmFsIHJlYWRzIG5ldmVyIHNlbGVjdCBhIHN0b3JlIChzZWUgcmVhZEJ1Y2tldEludGVybmFsKVxuICAgICAgICBzb3VyY2VDb25maWcgPSBub3JtYWxpemVTb3VyY2UodXJsKTtcbiAgICB9XG4gICAgbGV0IGFyY2hpdmVzID0gY3JlYXRlU3RvcmVTb3VyY2UoeyBzb3VyY2VDb25maWcsIGZvbGRlcjogdXJsIH0pO1xuICAgIHJlc29sdmVkU291cmNlQXJjaGl2ZXMuc2V0KHVybCwgYXJjaGl2ZXMpO1xuICAgIHJldHVybiBhcmNoaXZlcztcbn1cblxuLyoqXG4gKiBXcml0aW5nIHRoZSByb3V0aW5nIGNvbmZpZyBpcyBhIHdyaXRlIGxpa2UgYW55IG90aGVyOiBpdCBnb2VzIGludG8gYSBzdG9yZSwgYW5kIHRoZSBzdG9yZSBhcHBsaWVzXG4gKiBpdCB0byBpdHNlbGYgYW5kIGxldHMgaXRzIHBlZXJzIHB1bGwgaXQuIFRoZSBvbmx5IHRoaW5nIHRoYXQgaGFwcGVucyBoZXJlIGlzIHBpY2tpbmcgV0hJQ0ggc3RvcmUsXG4gKiBiZWNhdXNlIHRoZSB3cml0ZXIgbmFtZXMgYSBzb3VyY2UgYW5kIGEgc291cmNlIG5hbWVzIGEgc3RvcmUuXG4gKlxuICogSW4tZmxpZ2h0IHN3aXRjaG92ZXIgd2luZG93cyBhcmUgcmUtaW5qZWN0ZWQgZmlyc3QgKHNlZSBpbnRlcm1lZGlhdGVNYW5hZ2VtZW50KTogYW4gb3BlcmF0b3Inc1xuICogY29uZmlnIGtub3dzIG5vdGhpbmcgYWJvdXQgYSBzd2l0Y2hvdmVyIHRoYXQgaXMgaGFwcGVuaW5nIHJpZ2h0IG5vdywgYW5kIHdyaXRpbmcgaXQgYXMtaXMgd291bGRcbiAqIGNhbmNlbCBpdCBtaWQtZmxpZ2h0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVSb3V0aW5nQ29uZmlnKGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGRhdGE6IEJ1ZmZlciwgY29uZmlnPzogeyBsYXN0TW9kaWZpZWQ/OiBudW1iZXIgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGFzc2VydFdyaXRlc0FsbG93ZWQoKTtcbiAgICBsZXQgc3RvcmUgPSBnZXRTdG9yZShhY2NvdW50LCBidWNrZXROYW1lLCBuYW1lKTtcbiAgICBsZXQgaW5jb21pbmcgPSBwYXJzZVJvdXRpbmdEYXRhKGRhdGEpO1xuICAgIGxldCBjdXJyZW50ID0gYXdhaXQgcmVhZFJvdXRpbmdGcm9tRGlzayhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBsZXQgc3RvcmVkID0gcmVpbmplY3RJbnRlcm1lZGlhdGVzKGN1cnJlbnQsIGluY29taW5nKTtcbiAgICBhd2FpdCBzdG9yZS5zZXQoeyBwYXRoOiBST1VUSU5HX0ZJTEUsIGRhdGE6IEJ1ZmZlci5mcm9tKHNlcmlhbGl6ZVJlbW90ZUNvbmZpZyhzdG9yZWQpKSwgbGFzdE1vZGlmaWVkOiBjb25maWc/Lmxhc3RNb2RpZmllZCB9KTtcbiAgICBicm9hZGNhc3RSb3V0aW5nQ2hhbmdlZCgpO1xufVxuXG4vKiogV2hpY2ggYnVja2V0cyB0aGlzIHByb2Nlc3MgY3VycmVudGx5IGhhcyBhY3RpdmUgKHNvbWUgc3RvcmUgb2YgdGhlaXJzIHdhcyBvcGVuZWQpIC0gd2hhdCBhIGRlcGxveSBzdWNjZXNzb3IgYXNrcyBpdHMgcHJlZGVjZXNzb3IgZm9yLCBzbyBpdCBhY3RpdmF0ZXMgZXhhY3RseSB0aGUgYnVja2V0cyB0aGF0IGFyZSBhY3R1YWxseSBpbiB1c2UuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aXZlQnVja2V0S2V5cygpOiB7IGFjY291bnQ6IHN0cmluZzsgYnVja2V0TmFtZTogc3RyaW5nIH1bXSB7XG4gICAgcmV0dXJuIFsuLi5hY3RpdmVTdG9yZXMua2V5cygpXS5tYXAoa2V5ID0+IHtcbiAgICAgICAgbGV0IHNsYXNoID0ga2V5LmluZGV4T2YoXCIvXCIpO1xuICAgICAgICByZXR1cm4geyBhY2NvdW50OiBrZXkuc2xpY2UoMCwgc2xhc2gpLCBidWNrZXROYW1lOiBrZXkuc2xpY2Uoc2xhc2ggKyAxKSB9O1xuICAgIH0pO1xufVxuXG5leHBvcnQgdHlwZSBTZXJ2ZXJCdWNrZXRJbmZvID0ge1xuICAgIGJ1Y2tldE5hbWU6IHN0cmluZztcbiAgICBhY3RpdmU6IGJvb2xlYW47XG4gICAgLyoqIFdoZXJlIHRoZSBidWNrZXQncyBkYXRhIGxpdmVzIG9uIHRoaXMgc2VydmVyICovXG4gICAgZm9sZGVyOiBzdHJpbmc7XG4gICAgLyoqIFRoZSBkcml2ZSB0aGF0IGZvbGRlciBpcyBvbi4gQnVja2V0cyBzaGFyaW5nIGEgZHJpdmUgcmVwb3J0IHRoZSBzYW1lIG51bWJlcnMuICovXG4gICAgZGlzaz86IEJ1Y2tldERpc2tJbmZvO1xuICAgIGRpc2tFcnJvcj86IHN0cmluZztcbiAgICB3cml0ZVN0YXRzPzogQnVja2V0V3JpdGVTdGF0cztcbiAgICBjb25maWc/OiBBcmNoaXZlc0NvbmZpZztcbiAgICBlcnJvcj86IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIEFjdGl2ZUJ1Y2tldEluZm8gPSB7XG4gICAgZm9sZGVyOiBzdHJpbmc7XG4gICAgLyoqIFRoZSBidWNrZXQncyByb3V0aW5nIGNvbmZpZywgdGhlIG5ld2VzdCBjb3B5IGFtb25nIGl0cyBzdG9yZXMuIEFic2VudCB3aGVuIG5vbmUgb2YgdGhlbSBoYXMgb25lIHlldC4gKi9cbiAgICByb3V0aW5nPzogUmVtb3RlQ29uZmlnO1xuICAgIGNvbmZpZzogQXJjaGl2ZXNDb25maWc7XG59O1xuXG4vKiogVGhlIHN0YXRlIG9mIE9ORSBhY3RpdmUgYnVja2V0LiBSZXR1cm5zIGFuIGVycm9yIHN0cmluZyB3aGVuIHRoZSBidWNrZXQgaXMgbm90IGFjdGl2ZSBoZXJlLCB3aGljaCBpcyB0aGUgbm9ybWFsIHN0YXRlIGZvciBhIGJ1Y2tldCBub3RoaW5nIGhhcyBhY2Nlc3NlZCBzaW5jZSBzdGFydHVwLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlYnVnR2V0QWN0aXZlQnVja2V0KGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nKTogUHJvbWlzZTxBY3RpdmVCdWNrZXRJbmZvIHwgc3RyaW5nPiB7XG4gICAgbGV0IGtleSA9IGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gO1xuICAgIGxldCBvcGVuZWQgPSBhY3RpdmVTdG9yZXMuZ2V0KGtleSk7XG4gICAgaWYgKCFvcGVuZWQgfHwgIW9wZW5lZC5zaXplKSB7XG4gICAgICAgIHJldHVybiBgQnVja2V0ICR7a2V5fSBpcyBub3QgYWN0aXZlIG9uIHRoaXMgc2VydmVyIChhIGJ1Y2tldCBhY3RpdmF0ZXMgb24gZmlyc3QgYWNjZXNzKWA7XG4gICAgfVxuICAgIGxldCBidWNrZXRTdG9yZXMgPSBbLi4ub3BlbmVkLnZhbHVlcygpXTtcbiAgICBsZXQgcm91dGluZyA9IGF3YWl0IHJlYWRSb3V0aW5nRnJvbURpc2soYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgcmV0dXJuIHsgZm9sZGVyOiBidWNrZXRTdG9yZXNbMF0uZm9sZGVyLCByb3V0aW5nLCBjb25maWc6IGFnZ3JlZ2F0ZUFyY2hpdmVzQ29uZmlnKGJ1Y2tldFN0b3Jlcywgcm91dGluZykgfTtcbn1cblxuLyoqIExvYWRzIGV2ZXJ5IHN0b3JlIG9mIGEgYnVja2V0IHRoYXQgZXhpc3RzIG9uIHRoaXMgc2VydmVyJ3MgZGlzayBpbnRvIG1lbW9yeSwgd2hpY2ggc3RhcnRzIHRoZWlyIHN5bmNocm9uaXphdGlvbiBhbmQgd2luZG93IHRpbWVycywgYW5kIHJldHVybnMgdGhlIGJ1Y2tldCdzIHN0YXRlLiBOb3RoaW5nIGlzIHdyaXR0ZW4gYW5kIG5vIG90aGVyIHNlcnZlciBpcyBjb250YWN0ZWQgLSB1bmxpa2UgYnVpbGRpbmcgYW4gQXJjaGl2ZXNDaGFpbiBmb3IgaXQsIHdoaWNoIHdvdWxkIHByb2JlIGV2ZXJ5IHNvdXJjZSBhbmQgY291bGQgd3JpdGUgdGhlIHJvdXRpbmcgY29uZmlnLiBBbHJlYWR5LWFjdGl2ZSBidWNrZXRzIGp1c3QgcmV0dXJuIHRoZWlyIHN0YXRlLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFjdGl2YXRlQnVja2V0KGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nKTogUHJvbWlzZTxBY3RpdmVCdWNrZXRJbmZvIHwgc3RyaW5nPiB7XG4gICAgbGV0IGtleSA9IGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gO1xuICAgIGxldCB3YXNBY3RpdmUgPSBhY3RpdmVTdG9yZXMuaGFzKGtleSk7XG4gICAgbGV0IGJ1Y2tldFN0b3JlcyA9IGF3YWl0IGdldEJ1Y2tldFN0b3JlcyhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBpZiAoIWJ1Y2tldFN0b3Jlcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGBCdWNrZXQgJHtrZXl9IGRvZXMgbm90IGV4aXN0IG9uIHRoaXMgc2VydmVyIChpdCBoYXMgbm8gc3RvcmUgZm9sZGVycyB1bmRlciAke2dldEJ1Y2tldEZvbGRlcihcIjxuYW1lPlwiLCBhY2NvdW50LCBidWNrZXROYW1lKX0pYDtcbiAgICB9XG4gICAgLy8gV2FpdCBmb3IgdGhlIGluZGV4ZXMgdG8gbG9hZCwgc28gdGhlIHRvdGFscyB3ZSByZXR1cm4gYXJlIHRoZSByZWFsIG9uZXMgcmF0aGVyIHRoYW4gemVyb2VzIGZyb20gc3RvcmVzIHRoYXQgaGF2ZSBub3QgcmVhZCB0aGVpciBpbmRleCB5ZXQuIFRoZSBzb3VyY2Ugc2NhbnMga2VlcCBydW5uaW5nIGluIHRoZSBiYWNrZ3JvdW5kLlxuICAgIGZvciAobGV0IHMgb2YgYnVja2V0U3RvcmVzKSB7XG4gICAgICAgIGF3YWl0IHMuc3RvcmUuaW5pdCgpO1xuICAgIH1cbiAgICBpZiAoIXdhc0FjdGl2ZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhgQWN0aXZhdGVkIGJ1Y2tldCAke2tleX0gb24gcmVxdWVzdDogaXRzICR7YnVja2V0U3RvcmVzLmxlbmd0aH0gc3RvcmUocykgYXJlIG5vdyBsb2FkZWQgYW5kIHN5bmNocm9uaXppbmdgKTtcbiAgICB9XG4gICAgbGV0IHJvdXRpbmcgPSBhd2FpdCByZWFkUm91dGluZ0Zyb21EaXNrKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIHJldHVybiB7IGZvbGRlcjogYnVja2V0U3RvcmVzWzBdLnN0b3JlLmZvbGRlciwgcm91dGluZywgY29uZmlnOiBhZ2dyZWdhdGVBcmNoaXZlc0NvbmZpZyhidWNrZXRTdG9yZXMubWFwKHggPT4geC5zdG9yZSksIHJvdXRpbmcpIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWJ1Z0xpc3RBY2NvdW50QnVja2V0cyhhY2NvdW50OiBzdHJpbmcpOiBQcm9taXNlPFNlcnZlckJ1Y2tldEluZm9bXT4ge1xuICAgIGxldCBzdGFydCA9IERhdGUubm93KCk7XG4gICAgLy8gVGhlIGRpc2sgaXMgdGhlIHJlY29yZDogYSBidWNrZXQgZXhpc3RzIGhlcmUgd2hlbiBpdCBoYXMgYXQgbGVhc3Qgb25lIHN0b3JlIGZvbGRlciwgYW5kIHNldmVyYWwgbmFtZXMgZm9yIG9uZSBidWNrZXQgYXJlIHN0aWxsIG9uZSBidWNrZXRcbiAgICBsZXQgZm9sZGVycyA9IGF3YWl0IGxpc3RBY2NvdW50U3RvcmVGb2xkZXJzKGFjY291bnQpO1xuICAgIGxldCBieUJ1Y2tldCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgZm9yIChsZXQgc3RvcmUgb2YgZm9sZGVycykge1xuICAgICAgICBpZiAoYnlCdWNrZXQuaGFzKHN0b3JlLmJ1Y2tldE5hbWUpKSBjb250aW51ZTtcbiAgICAgICAgYnlCdWNrZXQuc2V0KHN0b3JlLmJ1Y2tldE5hbWUsIHN0b3JlLmZvbGRlcik7XG4gICAgfVxuICAgIGxldCBuYW1lcyA9IFsuLi5ieUJ1Y2tldC5rZXlzKCldO1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBQcm9taXNlLmFsbChuYW1lcy5tYXAoYXN5bmMgYnVja2V0TmFtZSA9PiB7XG4gICAgICAgICAgICBsZXQga2V5ID0gYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWA7XG4gICAgICAgICAgICBsZXQgZm9sZGVyID0gYnlCdWNrZXQuZ2V0KGJ1Y2tldE5hbWUpIHx8IFwiXCI7XG4gICAgICAgICAgICBsZXQgYmFzZTogU2VydmVyQnVja2V0SW5mbyA9IHsgYnVja2V0TmFtZSwgYWN0aXZlOiBhY3RpdmVTdG9yZXMuaGFzKGtleSksIGZvbGRlciB9O1xuICAgICAgICAgICAgYmFzZS5kaXNrID0gYXdhaXQgZ2V0RGlza0luZm8oZm9sZGVyKS5jYXRjaCgoZTogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBiYXNlLmRpc2tFcnJvciA9IFN0cmluZyhlLnN0YWNrID8/IGUpLnNsaWNlKDAsIDUwMCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYmFzZS53cml0ZVN0YXRzID0gZ2V0QnVja2V0V3JpdGVTdGF0cyhrZXkpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXQgcm91dGluZyA9IGF3YWl0IHJlYWRSb3V0aW5nRnJvbURpc2soYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgICAgICAgICAgICAgaWYgKGJhc2UuYWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBvcGVuZWQgPSBbLi4uKGFjdGl2ZVN0b3Jlcy5nZXQoa2V5KT8udmFsdWVzKCkgfHwgW10pXTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgY29uZmlnOiBhZ2dyZWdhdGVBcmNoaXZlc0NvbmZpZyhvcGVuZWQsIHJvdXRpbmcpIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghcm91dGluZykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyAuLi5iYXNlLCBlcnJvcjogYE5vIHJvdXRpbmcgZmlsZSAoJHtST1VUSU5HX0ZJTEV9KSBpbiBhbnkgb2YgaXRzIHN0b3Jlc2AgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgY29uZmlnOiB7IHJlbW90ZUNvbmZpZzogcm91dGluZyB9IH07XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgZXJyb3I6IFN0cmluZygoZSBhcyBFcnJvcikuc3RhY2sgPz8gZSkuc2xpY2UoMCwgNTAwKSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgY29uc29sZS5sb2coYGRlYnVnTGlzdEFjY291bnRCdWNrZXRzKCR7YWNjb3VudH0pIHRvb2sgJHtEYXRlLm5vdygpIC0gc3RhcnR9bXMgZm9yICR7bmFtZXMubGVuZ3RofSBidWNrZXRzYCk7XG4gICAgfVxufVxuIl19
|
|
261
|
+
/* _JS_SOURCE_HASH = "936e396123327b0032ec8d8f63634734905ba795799fcfc00e19984fb096d01c"; */
|