@verdaccio/canary 6.3.2-canary.404363f
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/LICENSE +21 -0
- package/README.md +38 -0
- package/bin/verdaccio +3 -0
- package/bin/verdaccio-canary +3 -0
- package/build/api/debug/index.js +28 -0
- package/build/api/endpoint/api/dist-tags.js +77 -0
- package/build/api/endpoint/api/package.js +103 -0
- package/build/api/endpoint/api/ping.js +13 -0
- package/build/api/endpoint/api/publish.js +359 -0
- package/build/api/endpoint/api/search.js +107 -0
- package/build/api/endpoint/api/star.js +73 -0
- package/build/api/endpoint/api/stars.js +42 -0
- package/build/api/endpoint/api/user.js +84 -0
- package/build/api/endpoint/api/v1/profile.js +69 -0
- package/build/api/endpoint/api/v1/search.js +181 -0
- package/build/api/endpoint/api/v1/token.js +140 -0
- package/build/api/endpoint/api/whoami.js +15 -0
- package/build/api/endpoint/index.js +58 -0
- package/build/api/index.js +105 -0
- package/build/api/middleware.js +56 -0
- package/build/api/web/api/index.js +31 -0
- package/build/api/web/api/package.js +165 -0
- package/build/api/web/api/search.js +53 -0
- package/build/api/web/api/user.js +70 -0
- package/build/api/web/api/utils.js +14 -0
- package/build/api/web/html/favicon.ico +0 -0
- package/build/api/web/index.js +96 -0
- package/build/index.js +76 -0
- package/build/lib/auth-utils.js +16 -0
- package/build/lib/bootstrap.js +167 -0
- package/build/lib/cli/cli.js +26 -0
- package/build/lib/cli/commands/info.js +26 -0
- package/build/lib/cli/commands/init.js +78 -0
- package/build/lib/cli/commands/version.js +17 -0
- package/build/lib/cli/utils.js +14 -0
- package/build/lib/cli.js +16 -0
- package/build/lib/config.js +22 -0
- package/build/lib/constants.js +121 -0
- package/build/lib/experiments.js +29 -0
- package/build/lib/local-storage.js +760 -0
- package/build/lib/logger/index.js +21 -0
- package/build/lib/metadata-utils.js +39 -0
- package/build/lib/run-server.js +122 -0
- package/build/lib/storage-utils.js +282 -0
- package/build/lib/storage.js +676 -0
- package/build/lib/up-storage.js +605 -0
- package/build/lib/uplink-util.js +36 -0
- package/build/lib/utils.js +265 -0
- package/conf/.gitkeep +0 -0
- package/index.js +1 -0
- package/package.json +156 -0
- package/security.txt +5 -0
- package/systemd/verdaccio.service +11 -0
|
@@ -0,0 +1,760 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _assert = _interopRequireDefault(require("assert"));
|
|
8
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
9
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
10
|
+
var _url = _interopRequireDefault(require("url"));
|
|
11
|
+
var _streams = require("@verdaccio/streams");
|
|
12
|
+
var _utils = require("@verdaccio/utils");
|
|
13
|
+
var _constants = require("./constants");
|
|
14
|
+
var _storageUtils = require("./storage-utils");
|
|
15
|
+
var _utils2 = require("./utils");
|
|
16
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
|
+
const debug = (0, _debug.default)('verdaccio:local-storage');
|
|
18
|
+
/**
|
|
19
|
+
* Implements Storage interface (same for storage.js, local-storage.js, up-storage.js).
|
|
20
|
+
*/
|
|
21
|
+
class LocalStorage {
|
|
22
|
+
constructor(config, logger, localStorage) {
|
|
23
|
+
this.logger = logger;
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.storagePlugin = localStorage;
|
|
26
|
+
}
|
|
27
|
+
addPackage(name, pkg, callback) {
|
|
28
|
+
const storage = this._getLocalStorage(name);
|
|
29
|
+
if (_lodash.default.isNil(storage)) {
|
|
30
|
+
return callback(_utils2.ErrorCode.getNotFound('this package cannot be added'));
|
|
31
|
+
}
|
|
32
|
+
storage.createPackage(name, (0, _storageUtils.generatePackageTemplate)(name), err => {
|
|
33
|
+
// FIXME: it will be fixed here https://github.com/verdaccio/verdaccio/pull/1360
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
if (_lodash.default.isNull(err) === false && (err.code === _constants.STORAGE.FILE_EXIST_ERROR || err.code === _constants.HTTP_STATUS.CONFLICT)) {
|
|
36
|
+
return callback(_utils2.ErrorCode.getConflict());
|
|
37
|
+
}
|
|
38
|
+
const latest = (0, _utils.getLatestVersion)(pkg);
|
|
39
|
+
if (_lodash.default.isNil(latest) === false && pkg.versions[latest]) {
|
|
40
|
+
return callback(null, pkg.versions[latest]);
|
|
41
|
+
}
|
|
42
|
+
return callback();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Remove package.
|
|
48
|
+
* @param {*} name
|
|
49
|
+
* @param {*} callback
|
|
50
|
+
* @return {Function}
|
|
51
|
+
*/
|
|
52
|
+
removePackage(name, callback) {
|
|
53
|
+
const storage = this._getLocalStorage(name);
|
|
54
|
+
debug('[storage] removing package %o', name);
|
|
55
|
+
if (_lodash.default.isNil(storage)) {
|
|
56
|
+
return callback(_utils2.ErrorCode.getNotFound());
|
|
57
|
+
}
|
|
58
|
+
storage.readPackage(name, (err, data) => {
|
|
59
|
+
if (_lodash.default.isNil(err) === false) {
|
|
60
|
+
if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
|
|
61
|
+
return callback(_utils2.ErrorCode.getNotFound());
|
|
62
|
+
}
|
|
63
|
+
return callback(err);
|
|
64
|
+
}
|
|
65
|
+
data = (0, _storageUtils.normalizePackage)(data);
|
|
66
|
+
this.storagePlugin.remove(name, removeFailed => {
|
|
67
|
+
if (removeFailed) {
|
|
68
|
+
// This will happen when database is locked
|
|
69
|
+
this.logger.error({
|
|
70
|
+
name
|
|
71
|
+
}, `[storage/removePackage] the database is locked, removed has failed for @{name}`);
|
|
72
|
+
return callback(_utils2.ErrorCode.getBadData(removeFailed.message));
|
|
73
|
+
}
|
|
74
|
+
storage.deletePackage(_constants.STORAGE.PACKAGE_FILE_NAME, err => {
|
|
75
|
+
if (err) {
|
|
76
|
+
return callback(err);
|
|
77
|
+
}
|
|
78
|
+
const attachments = Object.keys(data._attachments);
|
|
79
|
+
this._deleteAttachments(storage, attachments, callback);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Synchronize remote package info with the local one
|
|
87
|
+
* @param {*} name
|
|
88
|
+
* @param {*} packageInfo
|
|
89
|
+
* @param {*} callback
|
|
90
|
+
*/
|
|
91
|
+
updateVersions(name, packageInfo, callback) {
|
|
92
|
+
this._readCreatePackage(name, (err, packageLocalJson) => {
|
|
93
|
+
if (err) {
|
|
94
|
+
return callback(err);
|
|
95
|
+
}
|
|
96
|
+
let change = false;
|
|
97
|
+
// updating readme
|
|
98
|
+
packageLocalJson.readme = (0, _storageUtils.getLatestReadme)(packageInfo);
|
|
99
|
+
if (packageInfo.readme !== packageLocalJson.readme) {
|
|
100
|
+
change = true;
|
|
101
|
+
}
|
|
102
|
+
for (const versionId in packageInfo.versions) {
|
|
103
|
+
if (_lodash.default.isNil(packageLocalJson.versions[versionId])) {
|
|
104
|
+
let version = packageInfo.versions[versionId];
|
|
105
|
+
|
|
106
|
+
// we don't keep readme for package versions,
|
|
107
|
+
// only one readme per package
|
|
108
|
+
version = (0, _storageUtils.cleanUpReadme)(version);
|
|
109
|
+
version.contributors = (0, _utils.normalizeContributors)(version.contributors);
|
|
110
|
+
change = true;
|
|
111
|
+
packageLocalJson.versions[versionId] = version;
|
|
112
|
+
if (version.dist && version.dist.tarball) {
|
|
113
|
+
const urlObject = _url.default.parse(version.dist.tarball);
|
|
114
|
+
const filename = urlObject.pathname.replace(/^.*\//, '');
|
|
115
|
+
|
|
116
|
+
// we do NOT overwrite any existing records
|
|
117
|
+
if (_lodash.default.isNil(packageLocalJson._distfiles[filename])) {
|
|
118
|
+
const hash = packageLocalJson._distfiles[filename] = {
|
|
119
|
+
url: version.dist.tarball,
|
|
120
|
+
sha: version.dist.shasum
|
|
121
|
+
};
|
|
122
|
+
/* eslint spaced-comment: 0 */
|
|
123
|
+
const upLink = version[Symbol.for('__verdaccio_uplink')];
|
|
124
|
+
if (_lodash.default.isNil(upLink) === false) {
|
|
125
|
+
this._updateUplinkToRemoteProtocol(hash, upLink);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
for (const tag in packageInfo[_constants.DIST_TAGS]) {
|
|
132
|
+
if (!packageLocalJson[_constants.DIST_TAGS][tag] || packageLocalJson[_constants.DIST_TAGS][tag] !== packageInfo[_constants.DIST_TAGS][tag]) {
|
|
133
|
+
change = true;
|
|
134
|
+
packageLocalJson[_constants.DIST_TAGS][tag] = packageInfo[_constants.DIST_TAGS][tag];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
for (const up in packageInfo._uplinks) {
|
|
138
|
+
if (Object.prototype.hasOwnProperty.call(packageInfo._uplinks, up)) {
|
|
139
|
+
const need_change = !(0, _utils2.isObject)(packageLocalJson._uplinks[up]) || packageInfo._uplinks[up].etag !== packageLocalJson._uplinks[up].etag || packageInfo._uplinks[up].fetched !== packageLocalJson._uplinks[up].fetched;
|
|
140
|
+
if (need_change) {
|
|
141
|
+
change = true;
|
|
142
|
+
packageLocalJson._uplinks[up] = packageInfo._uplinks[up];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if ('time' in packageInfo && !_lodash.default.isEqual(packageLocalJson.time, packageInfo.time)) {
|
|
147
|
+
packageLocalJson.time = packageInfo.time;
|
|
148
|
+
change = true;
|
|
149
|
+
}
|
|
150
|
+
if (change) {
|
|
151
|
+
debug('updating package %o info', name);
|
|
152
|
+
this._writePackage(name, packageLocalJson, function (err) {
|
|
153
|
+
callback(err, packageLocalJson);
|
|
154
|
+
});
|
|
155
|
+
} else {
|
|
156
|
+
callback(null, packageLocalJson);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Add a new version to a previous local package.
|
|
163
|
+
* @param {*} name
|
|
164
|
+
* @param {*} version
|
|
165
|
+
* @param {*} metadata
|
|
166
|
+
* @param {*} tag
|
|
167
|
+
* @param {*} callback
|
|
168
|
+
*/
|
|
169
|
+
addVersion(name, version, metadata, tag, callback) {
|
|
170
|
+
this._updatePackage(name, (data, cb) => {
|
|
171
|
+
// keep only one readme per package
|
|
172
|
+
data.readme = metadata.readme;
|
|
173
|
+
|
|
174
|
+
// TODO: lodash remove
|
|
175
|
+
metadata = (0, _storageUtils.cleanUpReadme)(metadata);
|
|
176
|
+
metadata.contributors = (0, _utils.normalizeContributors)(metadata.contributors);
|
|
177
|
+
const hasVersion = data.versions[version] != null;
|
|
178
|
+
if (hasVersion) {
|
|
179
|
+
return cb(_utils2.ErrorCode.getConflict());
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// if uploaded tarball has a different shasum, it's very likely that we have some kind of error
|
|
183
|
+
if ((0, _utils2.isObject)(metadata.dist) && _lodash.default.isString(metadata.dist.tarball)) {
|
|
184
|
+
const tarball = metadata.dist.tarball.replace(/.*\//, '');
|
|
185
|
+
if ((0, _utils2.isObject)(data._attachments[tarball])) {
|
|
186
|
+
if (_lodash.default.isNil(data._attachments[tarball].shasum) === false && _lodash.default.isNil(metadata.dist.shasum) === false) {
|
|
187
|
+
if (data._attachments[tarball].shasum != metadata.dist.shasum) {
|
|
188
|
+
const errorMessage = `shasum error, ${data._attachments[tarball].shasum} != ${metadata.dist.shasum}`;
|
|
189
|
+
return cb(_utils2.ErrorCode.getBadRequest(errorMessage));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const currentDate = new Date().toISOString();
|
|
193
|
+
|
|
194
|
+
// some old storage do not have this field #740
|
|
195
|
+
if (_lodash.default.isNil(data.time)) {
|
|
196
|
+
data.time = {};
|
|
197
|
+
}
|
|
198
|
+
data.time['modified'] = currentDate;
|
|
199
|
+
if ('created' in data.time === false) {
|
|
200
|
+
data.time.created = currentDate;
|
|
201
|
+
}
|
|
202
|
+
data.time[version] = currentDate;
|
|
203
|
+
data._attachments[tarball].version = version;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
data.versions[version] = metadata;
|
|
207
|
+
(0, _utils2.tagVersion)(data, version, tag);
|
|
208
|
+
this.storagePlugin.add(name, addFailed => {
|
|
209
|
+
if (addFailed) {
|
|
210
|
+
return cb(_utils2.ErrorCode.getBadData(addFailed.message));
|
|
211
|
+
}
|
|
212
|
+
cb();
|
|
213
|
+
});
|
|
214
|
+
}, callback);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Merge a new list of tags for a local packages with the existing one.
|
|
219
|
+
* @param {*} pkgName
|
|
220
|
+
* @param {*} tags
|
|
221
|
+
* @param {*} callback
|
|
222
|
+
*/
|
|
223
|
+
mergeTags(pkgName, tags, callback) {
|
|
224
|
+
this._updatePackage(pkgName, (data, cb) => {
|
|
225
|
+
/* eslint guard-for-in: 0 */
|
|
226
|
+
for (const tag in tags) {
|
|
227
|
+
// this handle dist-tag rm command
|
|
228
|
+
if (_lodash.default.isNull(tags[tag])) {
|
|
229
|
+
delete data[_constants.DIST_TAGS][tag];
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (_lodash.default.isNil(data.versions[tags[tag]])) {
|
|
233
|
+
return cb(this._getVersionNotFound());
|
|
234
|
+
}
|
|
235
|
+
const version = tags[tag];
|
|
236
|
+
(0, _utils2.tagVersion)(data, version, tag);
|
|
237
|
+
}
|
|
238
|
+
cb(null);
|
|
239
|
+
}, callback);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Return version not found
|
|
244
|
+
* @return {String}
|
|
245
|
+
* @private
|
|
246
|
+
*/
|
|
247
|
+
_getVersionNotFound() {
|
|
248
|
+
return _utils2.ErrorCode.getNotFound(_constants.API_ERROR.VERSION_NOT_EXIST);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Return file no available
|
|
253
|
+
* @return {String}
|
|
254
|
+
* @private
|
|
255
|
+
*/
|
|
256
|
+
_getFileNotAvailable() {
|
|
257
|
+
return _utils2.ErrorCode.getNotFound('no such file available');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Update the package metadata, tags and attachments (tarballs).
|
|
262
|
+
* Note: Currently supports unpublishing and deprecation.
|
|
263
|
+
* @param {*} name
|
|
264
|
+
* @param {*} incomingPkg
|
|
265
|
+
* @param {*} revision
|
|
266
|
+
* @param {*} callback
|
|
267
|
+
* @return {Function}
|
|
268
|
+
*/
|
|
269
|
+
changePackage(name, incomingPkg, revision, callback) {
|
|
270
|
+
if (!(0, _utils2.isObject)(incomingPkg.versions) || !(0, _utils2.isObject)(incomingPkg[_constants.DIST_TAGS])) {
|
|
271
|
+
this.logger.error({
|
|
272
|
+
name
|
|
273
|
+
}, `changePackage bad data for @{name}`);
|
|
274
|
+
return callback(_utils2.ErrorCode.getBadData());
|
|
275
|
+
}
|
|
276
|
+
debug('changePackage udapting package for %o', name);
|
|
277
|
+
this._updatePackage(name, (localData, cb) => {
|
|
278
|
+
for (const version in localData.versions) {
|
|
279
|
+
const incomingVersion = incomingPkg.versions[version];
|
|
280
|
+
if (_lodash.default.isNil(incomingVersion)) {
|
|
281
|
+
this.logger.info({
|
|
282
|
+
name: name,
|
|
283
|
+
version: version
|
|
284
|
+
}, 'unpublishing @{name}@@{version}');
|
|
285
|
+
|
|
286
|
+
// FIXME: I prefer return a new object rather mutate the metadata
|
|
287
|
+
delete localData.versions[version];
|
|
288
|
+
delete localData.time[version];
|
|
289
|
+
for (const file in localData._attachments) {
|
|
290
|
+
if (localData._attachments[file].version === version) {
|
|
291
|
+
delete localData._attachments[file].version;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
} else if (Object.prototype.hasOwnProperty.call(incomingVersion, 'deprecated')) {
|
|
295
|
+
const incomingDeprecated = incomingVersion.deprecated;
|
|
296
|
+
if (incomingDeprecated != localData.versions[version].deprecated) {
|
|
297
|
+
if (!incomingDeprecated) {
|
|
298
|
+
this.logger.info({
|
|
299
|
+
name: name,
|
|
300
|
+
version: version
|
|
301
|
+
}, 'undeprecating @{name}@@{version}');
|
|
302
|
+
delete localData.versions[version].deprecated;
|
|
303
|
+
} else {
|
|
304
|
+
this.logger.info({
|
|
305
|
+
name: name,
|
|
306
|
+
version: version
|
|
307
|
+
}, 'deprecating @{name}@@{version}');
|
|
308
|
+
localData.versions[version].deprecated = incomingDeprecated;
|
|
309
|
+
}
|
|
310
|
+
localData.time.modified = new Date().toISOString();
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
localData[_constants.USERS] = incomingPkg[_constants.USERS];
|
|
315
|
+
localData[_constants.DIST_TAGS] = incomingPkg[_constants.DIST_TAGS];
|
|
316
|
+
cb(null);
|
|
317
|
+
}, function (err) {
|
|
318
|
+
if (err) {
|
|
319
|
+
return callback(err);
|
|
320
|
+
}
|
|
321
|
+
callback();
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Remove a tarball.
|
|
326
|
+
* @param {*} name
|
|
327
|
+
* @param {*} filename
|
|
328
|
+
* @param {*} revision
|
|
329
|
+
* @param {*} callback
|
|
330
|
+
*/
|
|
331
|
+
removeTarball(name, filename, revision, callback) {
|
|
332
|
+
(0, _assert.default)((0, _utils.validateName)(filename));
|
|
333
|
+
this._updatePackage(name, (data, cb) => {
|
|
334
|
+
if (data._attachments[filename]) {
|
|
335
|
+
delete data._attachments[filename];
|
|
336
|
+
cb(null);
|
|
337
|
+
} else {
|
|
338
|
+
cb(this._getFileNotAvailable());
|
|
339
|
+
}
|
|
340
|
+
}, err => {
|
|
341
|
+
if (err) {
|
|
342
|
+
return callback(err);
|
|
343
|
+
}
|
|
344
|
+
const storage = this._getLocalStorage(name);
|
|
345
|
+
if (storage) {
|
|
346
|
+
storage.deletePackage(filename, callback);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Add a tarball.
|
|
353
|
+
* @param {String} name
|
|
354
|
+
* @param {String} filename
|
|
355
|
+
* @return {Stream}
|
|
356
|
+
*/
|
|
357
|
+
addTarball(name, filename) {
|
|
358
|
+
(0, _assert.default)((0, _utils.validateName)(filename));
|
|
359
|
+
let length = 0;
|
|
360
|
+
const shaOneHash = (0, _utils.createTarballHash)();
|
|
361
|
+
const uploadStream = new _streams.UploadTarball({});
|
|
362
|
+
const _transform = uploadStream._transform;
|
|
363
|
+
const storage = this._getLocalStorage(name);
|
|
364
|
+
uploadStream.abort = function () {};
|
|
365
|
+
uploadStream.done = function () {};
|
|
366
|
+
uploadStream._transform = function (data, ...args) {
|
|
367
|
+
shaOneHash.update(data);
|
|
368
|
+
// measure the length for validation reasons
|
|
369
|
+
length += data.length;
|
|
370
|
+
const appliedData = [data, ...args];
|
|
371
|
+
// FIXME: not sure about this approach, tsc complains
|
|
372
|
+
// @ts-ignore
|
|
373
|
+
_transform.apply(uploadStream, appliedData);
|
|
374
|
+
};
|
|
375
|
+
if (name === '__proto__') {
|
|
376
|
+
process.nextTick(() => {
|
|
377
|
+
uploadStream.emit('error', _utils2.ErrorCode.getForbidden());
|
|
378
|
+
});
|
|
379
|
+
return uploadStream;
|
|
380
|
+
}
|
|
381
|
+
if (!storage) {
|
|
382
|
+
process.nextTick(() => {
|
|
383
|
+
uploadStream.emit('error', "can't upload this package");
|
|
384
|
+
});
|
|
385
|
+
return uploadStream;
|
|
386
|
+
}
|
|
387
|
+
const writeStream = storage.writeTarball(filename);
|
|
388
|
+
writeStream.on('error', err => {
|
|
389
|
+
if (err.code === _constants.STORAGE.FILE_EXIST_ERROR || err.code === _constants.HTTP_STATUS.CONFLICT) {
|
|
390
|
+
uploadStream.emit('error', _utils2.ErrorCode.getConflict());
|
|
391
|
+
uploadStream.abort();
|
|
392
|
+
} else if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
|
|
393
|
+
// check if package exists to throw an appropriate message
|
|
394
|
+
this.getPackageMetadata(name, function (_err) {
|
|
395
|
+
if (_err) {
|
|
396
|
+
uploadStream.emit('error', _err);
|
|
397
|
+
} else {
|
|
398
|
+
uploadStream.emit('error', err);
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
} else {
|
|
402
|
+
uploadStream.emit('error', err);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
writeStream.on('open', function () {
|
|
406
|
+
// re-emitting open because it's handled in storage.js
|
|
407
|
+
uploadStream.emit('open');
|
|
408
|
+
});
|
|
409
|
+
writeStream.on('success', () => {
|
|
410
|
+
this._updatePackage(name, function updater(data, cb) {
|
|
411
|
+
data._attachments[filename] = {
|
|
412
|
+
shasum: shaOneHash.digest('hex')
|
|
413
|
+
};
|
|
414
|
+
cb(null);
|
|
415
|
+
}, function (err) {
|
|
416
|
+
if (err) {
|
|
417
|
+
uploadStream.emit('error', err);
|
|
418
|
+
} else {
|
|
419
|
+
uploadStream.emit('success');
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
uploadStream.abort = function () {
|
|
424
|
+
writeStream.abort();
|
|
425
|
+
};
|
|
426
|
+
uploadStream.done = function () {
|
|
427
|
+
if (!length) {
|
|
428
|
+
uploadStream.emit('error', _utils2.ErrorCode.getBadData('refusing to accept zero-length file'));
|
|
429
|
+
writeStream.abort();
|
|
430
|
+
} else {
|
|
431
|
+
writeStream.done();
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
uploadStream.pipe(writeStream);
|
|
435
|
+
return uploadStream;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Get a tarball.
|
|
440
|
+
* @param {*} name
|
|
441
|
+
* @param {*} filename
|
|
442
|
+
* @return {ReadTarball}
|
|
443
|
+
*/
|
|
444
|
+
getTarball(name, filename) {
|
|
445
|
+
(0, _assert.default)((0, _utils.validateName)(filename));
|
|
446
|
+
const storage = this._getLocalStorage(name);
|
|
447
|
+
if (_lodash.default.isNil(storage)) {
|
|
448
|
+
return this._createFailureStreamResponse();
|
|
449
|
+
}
|
|
450
|
+
return this._streamSuccessReadTarBall(storage, filename);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Return a stream that emits a read failure.
|
|
455
|
+
* @private
|
|
456
|
+
* @return {ReadTarball}
|
|
457
|
+
*/
|
|
458
|
+
_createFailureStreamResponse() {
|
|
459
|
+
const stream = new _streams.ReadTarball({});
|
|
460
|
+
process.nextTick(() => {
|
|
461
|
+
stream.emit('error', this._getFileNotAvailable());
|
|
462
|
+
});
|
|
463
|
+
return stream;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Return a stream that emits the tarball data
|
|
468
|
+
* @param {Object} storage
|
|
469
|
+
* @param {String} filename
|
|
470
|
+
* @private
|
|
471
|
+
* @return {ReadTarball}
|
|
472
|
+
*/
|
|
473
|
+
_streamSuccessReadTarBall(storage, filename) {
|
|
474
|
+
const stream = new _streams.ReadTarball({});
|
|
475
|
+
const readTarballStream = storage.readTarball(filename);
|
|
476
|
+
const e404 = _utils2.ErrorCode.getNotFound;
|
|
477
|
+
stream.abort = function () {
|
|
478
|
+
if (_lodash.default.isNil(readTarballStream) === false) {
|
|
479
|
+
readTarballStream.abort();
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
readTarballStream.on('error', function (err) {
|
|
483
|
+
if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
|
|
484
|
+
stream.emit('error', e404('no such file available'));
|
|
485
|
+
} else {
|
|
486
|
+
stream.emit('error', err);
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
readTarballStream.on('content-length', function (content) {
|
|
490
|
+
stream.emit('content-length', content);
|
|
491
|
+
});
|
|
492
|
+
readTarballStream.on('open', function () {
|
|
493
|
+
// re-emitting open because it's handled in storage.js
|
|
494
|
+
stream.emit('open');
|
|
495
|
+
readTarballStream.pipe(stream);
|
|
496
|
+
});
|
|
497
|
+
return stream;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Retrieve a package by name.
|
|
502
|
+
* @param {*} name
|
|
503
|
+
* @param {*} callback
|
|
504
|
+
* @return {Function}
|
|
505
|
+
*/
|
|
506
|
+
getPackageMetadata(name, callback = () => {}) {
|
|
507
|
+
const storage = this._getLocalStorage(name);
|
|
508
|
+
if (_lodash.default.isNil(storage)) {
|
|
509
|
+
return callback(_utils2.ErrorCode.getNotFound());
|
|
510
|
+
}
|
|
511
|
+
this._readPackage(name, storage, callback);
|
|
512
|
+
}
|
|
513
|
+
getPackageMetadataAsync(name) {
|
|
514
|
+
return new Promise((resolve, reject) => {
|
|
515
|
+
this.getPackageMetadata(name, (err, metadata) => {
|
|
516
|
+
if (err) {
|
|
517
|
+
return reject(err);
|
|
518
|
+
}
|
|
519
|
+
resolve(metadata);
|
|
520
|
+
});
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
updateVersionsAsync(name, packageInfo) {
|
|
524
|
+
return new Promise((resolve, reject) => {
|
|
525
|
+
this.updateVersions(name, packageInfo, (err, result) => {
|
|
526
|
+
if (err) {
|
|
527
|
+
return reject(err);
|
|
528
|
+
}
|
|
529
|
+
resolve(result);
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Search a local package.
|
|
536
|
+
* @param {*} startKey
|
|
537
|
+
* @param {*} options
|
|
538
|
+
* @return {Function}
|
|
539
|
+
*/
|
|
540
|
+
search(startKey, options) {
|
|
541
|
+
debug('options for search %o', options);
|
|
542
|
+
const stream = new _streams.ReadTarball({
|
|
543
|
+
objectMode: true
|
|
544
|
+
});
|
|
545
|
+
this._searchEachPackage((item, cb) => {
|
|
546
|
+
// @ts-ignore
|
|
547
|
+
if (item.time > parseInt(startKey, 10)) {
|
|
548
|
+
this.getPackageMetadata(item.name, (err, data) => {
|
|
549
|
+
if (err) {
|
|
550
|
+
return cb(err);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// @ts-ignore
|
|
554
|
+
const time = new Date(item.time).toISOString();
|
|
555
|
+
const result = (0, _storageUtils.prepareSearchPackage)(data, time);
|
|
556
|
+
if (_lodash.default.isNil(result) === false) {
|
|
557
|
+
stream.push(result);
|
|
558
|
+
}
|
|
559
|
+
cb(null);
|
|
560
|
+
});
|
|
561
|
+
} else {
|
|
562
|
+
cb(null);
|
|
563
|
+
}
|
|
564
|
+
}, function onEnd(err) {
|
|
565
|
+
if (err) {
|
|
566
|
+
stream.emit('error', err);
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
stream.end();
|
|
570
|
+
});
|
|
571
|
+
return stream;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Retrieve a wrapper that provide access to the package location.
|
|
576
|
+
* @param {Object} pkgName package name.
|
|
577
|
+
* @return {Object}
|
|
578
|
+
*/
|
|
579
|
+
_getLocalStorage(pkgName) {
|
|
580
|
+
return this.storagePlugin.getPackageStorage(pkgName);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Read a json file from storage.
|
|
585
|
+
* @param {Object} storage
|
|
586
|
+
* @param {Function} callback
|
|
587
|
+
*/
|
|
588
|
+
_readPackage(name, storage, callback) {
|
|
589
|
+
storage.readPackage(name, (err, result) => {
|
|
590
|
+
if (err) {
|
|
591
|
+
if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
|
|
592
|
+
return callback(_utils2.ErrorCode.getNotFound());
|
|
593
|
+
}
|
|
594
|
+
return callback(this._internalError(err, _constants.STORAGE.PACKAGE_FILE_NAME, 'error reading'));
|
|
595
|
+
}
|
|
596
|
+
callback(err, (0, _storageUtils.normalizePackage)(result));
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Walks through each package and calls `on_package` on them.
|
|
602
|
+
* @param {*} onPackage
|
|
603
|
+
* @param {*} onEnd
|
|
604
|
+
*/
|
|
605
|
+
_searchEachPackage(onPackage, onEnd) {
|
|
606
|
+
// save wait whether plugin still do not support search functionality
|
|
607
|
+
if (_lodash.default.isNil(this.storagePlugin.search)) {
|
|
608
|
+
this.logger.warn('plugin search not implemented yet');
|
|
609
|
+
onEnd();
|
|
610
|
+
} else {
|
|
611
|
+
this.storagePlugin.search(onPackage, onEnd, _utils.validateName);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Retrieve either a previous created local package or a boilerplate.
|
|
617
|
+
* @param {*} pkgName
|
|
618
|
+
* @param {*} callback
|
|
619
|
+
* @return {Function}
|
|
620
|
+
*/
|
|
621
|
+
_readCreatePackage(pkgName, callback) {
|
|
622
|
+
const storage = this._getLocalStorage(pkgName);
|
|
623
|
+
if (_lodash.default.isNil(storage)) {
|
|
624
|
+
this._createNewPackage(pkgName, callback);
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
storage.readPackage(pkgName, (err, data) => {
|
|
628
|
+
// TODO: race condition
|
|
629
|
+
if (_lodash.default.isNil(err) === false) {
|
|
630
|
+
if (err.code === _constants.STORAGE.NO_SUCH_FILE_ERROR || err.code === _constants.HTTP_STATUS.NOT_FOUND) {
|
|
631
|
+
data = (0, _storageUtils.generatePackageTemplate)(pkgName);
|
|
632
|
+
} else {
|
|
633
|
+
return callback(this._internalError(err, _constants.STORAGE.PACKAGE_FILE_NAME, 'error reading'));
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
callback(null, (0, _storageUtils.normalizePackage)(data));
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
_createNewPackage(name, callback) {
|
|
640
|
+
return callback(null, (0, _storageUtils.normalizePackage)((0, _storageUtils.generatePackageTemplate)(name)));
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Handle internal error
|
|
645
|
+
* @param {*} err
|
|
646
|
+
* @param {*} file
|
|
647
|
+
* @param {*} message
|
|
648
|
+
* @return {Object} Error instance
|
|
649
|
+
*/
|
|
650
|
+
_internalError(err, file, message) {
|
|
651
|
+
this.logger.error({
|
|
652
|
+
err: err,
|
|
653
|
+
file: file
|
|
654
|
+
}, `${message} @{file}: @{!err.message}`);
|
|
655
|
+
return _utils2.ErrorCode.getInternalError();
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* @param {*} name package name
|
|
660
|
+
* @param {*} updateHandler function(package, cb) - update function
|
|
661
|
+
* @param {*} callback callback that gets invoked after it's all updated
|
|
662
|
+
* @return {Function}
|
|
663
|
+
*/
|
|
664
|
+
_updatePackage(name, updateHandler, callback) {
|
|
665
|
+
const storage = this._getLocalStorage(name);
|
|
666
|
+
if (!storage) {
|
|
667
|
+
return callback(_utils2.ErrorCode.getNotFound());
|
|
668
|
+
}
|
|
669
|
+
storage.updatePackage(name, updateHandler, this._writePackage.bind(this), _storageUtils.normalizePackage, callback);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Update the revision (_rev) string for a package.
|
|
674
|
+
* @param {*} name
|
|
675
|
+
* @param {*} json
|
|
676
|
+
* @param {*} callback
|
|
677
|
+
* @return {Function}
|
|
678
|
+
*/
|
|
679
|
+
_writePackage(name, json, callback) {
|
|
680
|
+
const storage = this._getLocalStorage(name);
|
|
681
|
+
if (_lodash.default.isNil(storage)) {
|
|
682
|
+
return callback();
|
|
683
|
+
}
|
|
684
|
+
storage.savePackage(name, this._setDefaultRevision(json), callback);
|
|
685
|
+
}
|
|
686
|
+
_setDefaultRevision(json) {
|
|
687
|
+
// calculate revision from couch db
|
|
688
|
+
if (_lodash.default.isString(json._rev) === false) {
|
|
689
|
+
json._rev = _constants.STORAGE.DEFAULT_REVISION;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// this is intended in debug mode we do not want modify the store revision
|
|
693
|
+
if (_lodash.default.isNil(this.config._debug)) {
|
|
694
|
+
json._rev = (0, _storageUtils.generateRevision)(json._rev);
|
|
695
|
+
}
|
|
696
|
+
return json;
|
|
697
|
+
}
|
|
698
|
+
_deleteAttachments(storage, attachments, callback) {
|
|
699
|
+
debug('[storage/_deleteAttachments] delete attachments total: %o', attachments?.length);
|
|
700
|
+
const unlinkNext = function (cb) {
|
|
701
|
+
if (_lodash.default.isEmpty(attachments)) {
|
|
702
|
+
return cb();
|
|
703
|
+
}
|
|
704
|
+
const attachment = attachments.shift();
|
|
705
|
+
storage.deletePackage(attachment, function () {
|
|
706
|
+
unlinkNext(cb);
|
|
707
|
+
});
|
|
708
|
+
};
|
|
709
|
+
unlinkNext(function () {
|
|
710
|
+
// try to unlink the directory, but ignore errors because it can fail
|
|
711
|
+
storage.removePackage(function (err) {
|
|
712
|
+
callback(err);
|
|
713
|
+
});
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Ensure the dist file remains as the same protocol
|
|
719
|
+
* @param {Object} hash metadata
|
|
720
|
+
* @param {String} upLinkKey registry key
|
|
721
|
+
* @private
|
|
722
|
+
*/
|
|
723
|
+
_updateUplinkToRemoteProtocol(hash, upLinkKey) {
|
|
724
|
+
// if we got this information from a known registry,
|
|
725
|
+
// use the same protocol for the tarball
|
|
726
|
+
//
|
|
727
|
+
// see https://github.com/rlidwka/sinopia/issues/166
|
|
728
|
+
const tarballUrl = _url.default.parse(hash.url);
|
|
729
|
+
const uplinkUrl = _url.default.parse(this.config.uplinks[upLinkKey].url);
|
|
730
|
+
if (uplinkUrl.host === tarballUrl.host) {
|
|
731
|
+
tarballUrl.protocol = uplinkUrl.protocol;
|
|
732
|
+
hash.registry = upLinkKey;
|
|
733
|
+
hash.url = _url.default.format(tarballUrl);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
async getSecret(config) {
|
|
737
|
+
const secretKey = await this.storagePlugin.getSecret();
|
|
738
|
+
return this.storagePlugin.setSecret(config.checkSecretKey(secretKey));
|
|
739
|
+
}
|
|
740
|
+
saveToken(token) {
|
|
741
|
+
if (_lodash.default.isFunction(this.storagePlugin.saveToken) === false) {
|
|
742
|
+
return Promise.reject(_utils2.ErrorCode.getCode(_constants.HTTP_STATUS.SERVICE_UNAVAILABLE, _constants.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
|
|
743
|
+
}
|
|
744
|
+
return this.storagePlugin.saveToken(token);
|
|
745
|
+
}
|
|
746
|
+
deleteToken(user, tokenKey) {
|
|
747
|
+
if (_lodash.default.isFunction(this.storagePlugin.deleteToken) === false) {
|
|
748
|
+
return Promise.reject(_utils2.ErrorCode.getCode(_constants.HTTP_STATUS.SERVICE_UNAVAILABLE, _constants.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
|
|
749
|
+
}
|
|
750
|
+
return this.storagePlugin.deleteToken(user, tokenKey);
|
|
751
|
+
}
|
|
752
|
+
readTokens(filter) {
|
|
753
|
+
if (_lodash.default.isFunction(this.storagePlugin.readTokens) === false) {
|
|
754
|
+
return Promise.reject(_utils2.ErrorCode.getCode(_constants.HTTP_STATUS.SERVICE_UNAVAILABLE, _constants.SUPPORT_ERRORS.PLUGIN_MISSING_INTERFACE));
|
|
755
|
+
}
|
|
756
|
+
return this.storagePlugin.readTokens(filter);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
var _default = exports.default = LocalStorage;
|
|
760
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfYXNzZXJ0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfZGVidWciLCJfbG9kYXNoIiwiX3VybCIsIl9zdHJlYW1zIiwiX3V0aWxzIiwiX2NvbnN0YW50cyIsIl9zdG9yYWdlVXRpbHMiLCJfdXRpbHMyIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiZGVidWciLCJidWlsRGVidWciLCJMb2NhbFN0b3JhZ2UiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImxvZ2dlciIsImxvY2FsU3RvcmFnZSIsInN0b3JhZ2VQbHVnaW4iLCJhZGRQYWNrYWdlIiwibmFtZSIsInBrZyIsImNhbGxiYWNrIiwic3RvcmFnZSIsIl9nZXRMb2NhbFN0b3JhZ2UiLCJfIiwiaXNOaWwiLCJFcnJvckNvZGUiLCJnZXROb3RGb3VuZCIsImNyZWF0ZVBhY2thZ2UiLCJnZW5lcmF0ZVBhY2thZ2VUZW1wbGF0ZSIsImVyciIsImlzTnVsbCIsImNvZGUiLCJTVE9SQUdFIiwiRklMRV9FWElTVF9FUlJPUiIsIkhUVFBfU1RBVFVTIiwiQ09ORkxJQ1QiLCJnZXRDb25mbGljdCIsImxhdGVzdCIsImdldExhdGVzdFZlcnNpb24iLCJ2ZXJzaW9ucyIsInJlbW92ZVBhY2thZ2UiLCJyZWFkUGFja2FnZSIsImRhdGEiLCJOT19TVUNIX0ZJTEVfRVJST1IiLCJOT1RfRk9VTkQiLCJub3JtYWxpemVQYWNrYWdlIiwicmVtb3ZlIiwicmVtb3ZlRmFpbGVkIiwiZXJyb3IiLCJnZXRCYWREYXRhIiwibWVzc2FnZSIsImRlbGV0ZVBhY2thZ2UiLCJQQUNLQUdFX0ZJTEVfTkFNRSIsImF0dGFjaG1lbnRzIiwiT2JqZWN0Iiwia2V5cyIsIl9hdHRhY2htZW50cyIsIl9kZWxldGVBdHRhY2htZW50cyIsInVwZGF0ZVZlcnNpb25zIiwicGFja2FnZUluZm8iLCJfcmVhZENyZWF0ZVBhY2thZ2UiLCJwYWNrYWdlTG9jYWxKc29uIiwiY2hhbmdlIiwicmVhZG1lIiwiZ2V0TGF0ZXN0UmVhZG1lIiwidmVyc2lvbklkIiwidmVyc2lvbiIsImNsZWFuVXBSZWFkbWUiLCJjb250cmlidXRvcnMiLCJub3JtYWxpemVDb250cmlidXRvcnMiLCJkaXN0IiwidGFyYmFsbCIsInVybE9iamVjdCIsIlVybE5vZGUiLCJwYXJzZSIsImZpbGVuYW1lIiwicGF0aG5hbWUiLCJyZXBsYWNlIiwiX2Rpc3RmaWxlcyIsImhhc2giLCJ1cmwiLCJzaGEiLCJzaGFzdW0iLCJ1cExpbmsiLCJTeW1ib2wiLCJmb3IiLCJfdXBkYXRlVXBsaW5rVG9SZW1vdGVQcm90b2NvbCIsInRhZyIsIkRJU1RfVEFHUyIsInVwIiwiX3VwbGlua3MiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJuZWVkX2NoYW5nZSIsImlzT2JqZWN0IiwiZXRhZyIsImZldGNoZWQiLCJpc0VxdWFsIiwidGltZSIsIl93cml0ZVBhY2thZ2UiLCJhZGRWZXJzaW9uIiwibWV0YWRhdGEiLCJfdXBkYXRlUGFja2FnZSIsImNiIiwiaGFzVmVyc2lvbiIsImlzU3RyaW5nIiwiZXJyb3JNZXNzYWdlIiwiZ2V0QmFkUmVxdWVzdCIsImN1cnJlbnREYXRlIiwiRGF0ZSIsInRvSVNPU3RyaW5nIiwiY3JlYXRlZCIsInRhZ1ZlcnNpb24iLCJhZGQiLCJhZGRGYWlsZWQiLCJtZXJnZVRhZ3MiLCJwa2dOYW1lIiwidGFncyIsIl9nZXRWZXJzaW9uTm90Rm91bmQiLCJBUElfRVJST1IiLCJWRVJTSU9OX05PVF9FWElTVCIsIl9nZXRGaWxlTm90QXZhaWxhYmxlIiwiY2hhbmdlUGFja2FnZSIsImluY29taW5nUGtnIiwicmV2aXNpb24iLCJsb2NhbERhdGEiLCJpbmNvbWluZ1ZlcnNpb24iLCJpbmZvIiwiZmlsZSIsImluY29taW5nRGVwcmVjYXRlZCIsImRlcHJlY2F0ZWQiLCJtb2RpZmllZCIsIlVTRVJTIiwicmVtb3ZlVGFyYmFsbCIsImFzc2VydCIsInZhbGlkYXRlTmFtZSIsImFkZFRhcmJhbGwiLCJsZW5ndGgiLCJzaGFPbmVIYXNoIiwiY3JlYXRlVGFyYmFsbEhhc2giLCJ1cGxvYWRTdHJlYW0iLCJVcGxvYWRUYXJiYWxsIiwiX3RyYW5zZm9ybSIsImFib3J0IiwiZG9uZSIsImFyZ3MiLCJ1cGRhdGUiLCJhcHBsaWVkRGF0YSIsImFwcGx5IiwicHJvY2VzcyIsIm5leHRUaWNrIiwiZW1pdCIsImdldEZvcmJpZGRlbiIsIndyaXRlU3RyZWFtIiwid3JpdGVUYXJiYWxsIiwib24iLCJnZXRQYWNrYWdlTWV0YWRhdGEiLCJfZXJyIiwidXBkYXRlciIsImRpZ2VzdCIsInBpcGUiLCJnZXRUYXJiYWxsIiwiX2NyZWF0ZUZhaWx1cmVTdHJlYW1SZXNwb25zZSIsIl9zdHJlYW1TdWNjZXNzUmVhZFRhckJhbGwiLCJzdHJlYW0iLCJSZWFkVGFyYmFsbCIsInJlYWRUYXJiYWxsU3RyZWFtIiwicmVhZFRhcmJhbGwiLCJlNDA0IiwiY29udGVudCIsIl9yZWFkUGFja2FnZSIsImdldFBhY2thZ2VNZXRhZGF0YUFzeW5jIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJ1cGRhdGVWZXJzaW9uc0FzeW5jIiwicmVzdWx0Iiwic2VhcmNoIiwic3RhcnRLZXkiLCJvcHRpb25zIiwib2JqZWN0TW9kZSIsIl9zZWFyY2hFYWNoUGFja2FnZSIsIml0ZW0iLCJwYXJzZUludCIsInByZXBhcmVTZWFyY2hQYWNrYWdlIiwicHVzaCIsIm9uRW5kIiwiZW5kIiwiZ2V0UGFja2FnZVN0b3JhZ2UiLCJfaW50ZXJuYWxFcnJvciIsIm9uUGFja2FnZSIsIndhcm4iLCJfY3JlYXRlTmV3UGFja2FnZSIsImdldEludGVybmFsRXJyb3IiLCJ1cGRhdGVIYW5kbGVyIiwidXBkYXRlUGFja2FnZSIsImJpbmQiLCJqc29uIiwic2F2ZVBhY2thZ2UiLCJfc2V0RGVmYXVsdFJldmlzaW9uIiwiX3JldiIsIkRFRkFVTFRfUkVWSVNJT04iLCJnZW5lcmF0ZVJldmlzaW9uIiwidW5saW5rTmV4dCIsImlzRW1wdHkiLCJhdHRhY2htZW50Iiwic2hpZnQiLCJ1cExpbmtLZXkiLCJ0YXJiYWxsVXJsIiwidXBsaW5rVXJsIiwidXBsaW5rcyIsImhvc3QiLCJwcm90b2NvbCIsInJlZ2lzdHJ5IiwiZm9ybWF0IiwiZ2V0U2VjcmV0Iiwic2VjcmV0S2V5Iiwic2V0U2VjcmV0IiwiY2hlY2tTZWNyZXRLZXkiLCJzYXZlVG9rZW4iLCJ0b2tlbiIsImlzRnVuY3Rpb24iLCJnZXRDb2RlIiwiU0VSVklDRV9VTkFWQUlMQUJMRSIsIlNVUFBPUlRfRVJST1JTIiwiUExVR0lOX01JU1NJTkdfSU5URVJGQUNFIiwiZGVsZXRlVG9rZW4iLCJ1c2VyIiwidG9rZW5LZXkiLCJyZWFkVG9rZW5zIiwiZmlsdGVyIiwiX2RlZmF1bHQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9sb2NhbC1zdG9yYWdlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCBidWlsRGVidWcgZnJvbSAnZGVidWcnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBVcmxOb2RlIGZyb20gJ3VybCc7XG5cbmltcG9ydCB7IFJlYWRUYXJiYWxsLCBVcGxvYWRUYXJiYWxsIH0gZnJvbSAnQHZlcmRhY2Npby9zdHJlYW1zJztcbmltcG9ydCB7XG4gIEF1dGhvcixcbiAgQ2FsbGJhY2ssXG4gIENvbmZpZyxcbiAgRGlzdEZpbGUsXG4gIExvZ2dlcixcbiAgTWFuaWZlc3QsXG4gIE1lcmdlVGFncyxcbiAgU3RvcmFnZVVwZGF0ZUNhbGxiYWNrLFxuICBUb2tlbixcbiAgVG9rZW5GaWx0ZXIsXG4gIFZlcnNpb24sXG4gIG9uRW5kU2VhcmNoUGFja2FnZSxcbiAgb25TZWFyY2hQYWNrYWdlLFxufSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7XG4gIGNyZWF0ZVRhcmJhbGxIYXNoLFxuICBnZXRMYXRlc3RWZXJzaW9uLFxuICBub3JtYWxpemVDb250cmlidXRvcnMsXG4gIHZhbGlkYXRlTmFtZSxcbn0gZnJvbSAnQHZlcmRhY2Npby91dGlscyc7XG5cbmltcG9ydCB7IFN0b3JhZ2VQbHVnaW5MZWdhY3kgfSBmcm9tICcuLi8uLi90eXBlcy9jdXN0b20nO1xuaW1wb3J0IHsgU3RyaW5nVmFsdWUgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBBUElfRVJST1IsIERJU1RfVEFHUywgSFRUUF9TVEFUVVMsIFNUT1JBR0UsIFNVUFBPUlRfRVJST1JTLCBVU0VSUyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7XG4gIGNsZWFuVXBSZWFkbWUsXG4gIGdlbmVyYXRlUGFja2FnZVRlbXBsYXRlLFxuICBnZW5lcmF0ZVJldmlzaW9uLFxuICBnZXRMYXRlc3RSZWFkbWUsXG4gIG5vcm1hbGl6ZVBhY2thZ2UsXG59IGZyb20gJy4vc3RvcmFnZS11dGlscyc7XG5pbXBvcnQgeyBwcmVwYXJlU2VhcmNoUGFja2FnZSB9IGZyb20gJy4vc3RvcmFnZS11dGlscyc7XG5pbXBvcnQgeyBFcnJvckNvZGUsIGlzT2JqZWN0LCB0YWdWZXJzaW9uIH0gZnJvbSAnLi91dGlscyc7XG5cbmNvbnN0IGRlYnVnID0gYnVpbERlYnVnKCd2ZXJkYWNjaW86bG9jYWwtc3RvcmFnZScpO1xuZXhwb3J0IHR5cGUgU3RvcmFnZVBsdWdpbiA9IFN0b3JhZ2VQbHVnaW5MZWdhY3k8Q29uZmlnPiB8IGFueTtcbi8qKlxuICogSW1wbGVtZW50cyBTdG9yYWdlIGludGVyZmFjZSAoc2FtZSBmb3Igc3RvcmFnZS5qcywgbG9jYWwtc3RvcmFnZS5qcywgdXAtc3RvcmFnZS5qcykuXG4gKi9cbmNsYXNzIExvY2FsU3RvcmFnZSB7XG4gIHB1YmxpYyBjb25maWc6IENvbmZpZztcbiAgcHVibGljIHN0b3JhZ2VQbHVnaW46IFN0b3JhZ2VQbHVnaW47XG4gIHB1YmxpYyBsb2dnZXI6IExvZ2dlcjtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcsIGxvZ2dlcjogTG9nZ2VyLCBsb2NhbFN0b3JhZ2U6IFN0b3JhZ2VQbHVnaW4pIHtcbiAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlcjtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLnN0b3JhZ2VQbHVnaW4gPSBsb2NhbFN0b3JhZ2U7XG4gIH1cblxuICBwdWJsaWMgYWRkUGFja2FnZShuYW1lOiBzdHJpbmcsIHBrZzogTWFuaWZlc3QsIGNhbGxiYWNrOiBDYWxsYmFjayk6IHZvaWQge1xuICAgIGNvbnN0IHN0b3JhZ2U6IGFueSA9IHRoaXMuX2dldExvY2FsU3RvcmFnZShuYW1lKTtcblxuICAgIGlmIChfLmlzTmlsKHN0b3JhZ2UpKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soRXJyb3JDb2RlLmdldE5vdEZvdW5kKCd0aGlzIHBhY2thZ2UgY2Fubm90IGJlIGFkZGVkJykpO1xuICAgIH1cblxuICAgIHN0b3JhZ2UuY3JlYXRlUGFja2FnZShuYW1lLCBnZW5lcmF0ZVBhY2thZ2VUZW1wbGF0ZShuYW1lKSwgKGVycikgPT4ge1xuICAgICAgLy8gRklYTUU6IGl0IHdpbGwgYmUgZml4ZWQgaGVyZSBodHRwczovL2dpdGh1Yi5jb20vdmVyZGFjY2lvL3ZlcmRhY2Npby9wdWxsLzEzNjBcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIGlmIChcbiAgICAgICAgXy5pc051bGwoZXJyKSA9PT0gZmFsc2UgJiZcbiAgICAgICAgKGVyci5jb2RlID09PSBTVE9SQUdFLkZJTEVfRVhJU1RfRVJST1IgfHwgZXJyLmNvZGUgPT09IEhUVFBfU1RBVFVTLkNPTkZMSUNUKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhFcnJvckNvZGUuZ2V0Q29uZmxpY3QoKSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxhdGVzdCA9IGdldExhdGVzdFZlcnNpb24ocGtnKTtcbiAgICAgIGlmIChfLmlzTmlsKGxhdGVzdCkgPT09IGZhbHNlICYmIHBrZy52ZXJzaW9uc1tsYXRlc3RdKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBwa2cudmVyc2lvbnNbbGF0ZXN0XSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBwYWNrYWdlLlxuICAgKiBAcGFyYW0geyp9IG5hbWVcbiAgICogQHBhcmFtIHsqfSBjYWxsYmFja1xuICAgKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAgICovXG4gIHB1YmxpYyByZW1vdmVQYWNrYWdlKG5hbWU6IHN0cmluZywgY2FsbGJhY2s6IENhbGxiYWNrKTogdm9pZCB7XG4gICAgY29uc3Qgc3RvcmFnZTogYW55ID0gdGhpcy5fZ2V0TG9jYWxTdG9yYWdlKG5hbWUpO1xuICAgIGRlYnVnKCdbc3RvcmFnZV0gcmVtb3ZpbmcgcGFja2FnZSAlbycsIG5hbWUpO1xuICAgIGlmIChfLmlzTmlsKHN0b3JhZ2UpKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soRXJyb3JDb2RlLmdldE5vdEZvdW5kKCkpO1xuICAgIH1cblxuICAgIHN0b3JhZ2UucmVhZFBhY2thZ2UobmFtZSwgKGVyciwgZGF0YTogTWFuaWZlc3QpOiB2b2lkID0+IHtcbiAgICAgIGlmIChfLmlzTmlsKGVycikgPT09IGZhbHNlKSB7XG4gICAgICAgIGlmIChlcnIuY29kZSA9PT0gU1RPUkFHRS5OT19TVUNIX0ZJTEVfRVJST1IgfHwgZXJyLmNvZGUgPT09IEhUVFBfU1RBVFVTLk5PVF9GT1VORCkge1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhFcnJvckNvZGUuZ2V0Tm90Rm91bmQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICB9XG5cbiAgICAgIGRhdGEgPSBub3JtYWxpemVQYWNrYWdlKGRhdGEpO1xuICAgICAgdGhpcy5zdG9yYWdlUGx1Z2luLnJlbW92ZShuYW1lLCAocmVtb3ZlRmFpbGVkOiBFcnJvcik6IHZvaWQgPT4ge1xuICAgICAgICBpZiAocmVtb3ZlRmFpbGVkKSB7XG4gICAgICAgICAgLy8gVGhpcyB3aWxsIGhhcHBlbiB3aGVuIGRhdGFiYXNlIGlzIGxvY2tlZFxuICAgICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgeyBuYW1lIH0sXG4gICAgICAgICAgICBgW3N0b3JhZ2UvcmVtb3ZlUGFja2FnZV0gdGhlIGRhdGFiYXNlIGlzIGxvY2tlZCwgcmVtb3ZlZCBoYXMgZmFpbGVkIGZvciBAe25hbWV9YFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKEVycm9yQ29kZS5nZXRCYWREYXRhKHJlbW92ZUZhaWxlZC5tZXNzYWdlKSk7XG4gICAgICAgIH1cblxuICAgICAgICBzdG9yYWdlLmRlbGV0ZVBhY2thZ2UoU1RPUkFHRS5QQUNLQUdFX0ZJTEVfTkFNRSwgKGVycik6IHZvaWQgPT4ge1xuICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhdHRhY2htZW50cyA9IE9iamVjdC5rZXlzKGRhdGEuX2F0dGFjaG1lbnRzKTtcblxuICAgICAgICAgIHRoaXMuX2RlbGV0ZUF0dGFjaG1lbnRzKHN0b3JhZ2UsIGF0dGFjaG1lbnRzLCBjYWxsYmFjayk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3luY2hyb25pemUgcmVtb3RlIHBhY2thZ2UgaW5mbyB3aXRoIHRoZSBsb2NhbCBvbmVcbiAgICogQHBhcmFtIHsqfSBuYW1lXG4gICAqIEBwYXJhbSB7Kn0gcGFja2FnZUluZm9cbiAgICogQHBhcmFtIHsqfSBjYWxsYmFja1xuICAgKi9cbiAgcHVibGljIHVwZGF0ZVZlcnNpb25zKG5hbWU6IHN0cmluZywgcGFja2FnZUluZm86IE1hbmlmZXN0LCBjYWxsYmFjazogQ2FsbGJhY2spOiB2b2lkIHtcbiAgICB0aGlzLl9yZWFkQ3JlYXRlUGFja2FnZShuYW1lLCAoZXJyLCBwYWNrYWdlTG9jYWxKc29uKTogdm9pZCA9PiB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgfVxuXG4gICAgICBsZXQgY2hhbmdlID0gZmFsc2U7XG4gICAgICAvLyB1cGRhdGluZyByZWFkbWVcbiAgICAgIHBhY2thZ2VMb2NhbEpzb24ucmVhZG1lID0gZ2V0TGF0ZXN0UmVhZG1lKHBhY2thZ2VJbmZvKTtcbiAgICAgIGlmIChwYWNrYWdlSW5mby5yZWFkbWUgIT09IHBhY2thZ2VMb2NhbEpzb24ucmVhZG1lKSB7XG4gICAgICAgIGNoYW5nZSA9IHRydWU7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IHZlcnNpb25JZCBpbiBwYWNrYWdlSW5mby52ZXJzaW9ucykge1xuICAgICAgICBpZiAoXy5pc05pbChwYWNrYWdlTG9jYWxKc29uLnZlcnNpb25zW3ZlcnNpb25JZF0pKSB7XG4gICAgICAgICAgbGV0IHZlcnNpb24gPSBwYWNrYWdlSW5mby52ZXJzaW9uc1t2ZXJzaW9uSWRdO1xuXG4gICAgICAgICAgLy8gd2UgZG9uJ3Qga2VlcCByZWFkbWUgZm9yIHBhY2thZ2UgdmVyc2lvbnMsXG4gICAgICAgICAgLy8gb25seSBvbmUgcmVhZG1lIHBlciBwYWNrYWdlXG4gICAgICAgICAgdmVyc2lvbiA9IGNsZWFuVXBSZWFkbWUodmVyc2lvbik7XG4gICAgICAgICAgdmVyc2lvbi5jb250cmlidXRvcnMgPSBub3JtYWxpemVDb250cmlidXRvcnModmVyc2lvbi5jb250cmlidXRvcnMgYXMgQXV0aG9yW10pO1xuXG4gICAgICAgICAgY2hhbmdlID0gdHJ1ZTtcbiAgICAgICAgICBwYWNrYWdlTG9jYWxKc29uLnZlcnNpb25zW3ZlcnNpb25JZF0gPSB2ZXJzaW9uO1xuXG4gICAgICAgICAgaWYgKHZlcnNpb24uZGlzdCAmJiB2ZXJzaW9uLmRpc3QudGFyYmFsbCkge1xuICAgICAgICAgICAgY29uc3QgdXJsT2JqZWN0OiBhbnkgPSBVcmxOb2RlLnBhcnNlKHZlcnNpb24uZGlzdC50YXJiYWxsKTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVuYW1lID0gdXJsT2JqZWN0LnBhdGhuYW1lLnJlcGxhY2UoL14uKlxcLy8sICcnKTtcblxuICAgICAgICAgICAgLy8gd2UgZG8gTk9UIG92ZXJ3cml0ZSBhbnkgZXhpc3RpbmcgcmVjb3Jkc1xuICAgICAgICAgICAgaWYgKF8uaXNOaWwocGFja2FnZUxvY2FsSnNvbi5fZGlzdGZpbGVzW2ZpbGVuYW1lXSkpIHtcbiAgICAgICAgICAgICAgY29uc3QgaGFzaDogRGlzdEZpbGUgPSAocGFja2FnZUxvY2FsSnNvbi5fZGlzdGZpbGVzW2ZpbGVuYW1lXSA9IHtcbiAgICAgICAgICAgICAgICB1cmw6IHZlcnNpb24uZGlzdC50YXJiYWxsLFxuICAgICAgICAgICAgICAgIHNoYTogdmVyc2lvbi5kaXN0LnNoYXN1bSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIC8qIGVzbGludCBzcGFjZWQtY29tbWVudDogMCAqL1xuICAgICAgICAgICAgICBjb25zdCB1cExpbms6IHN0cmluZyA9IHZlcnNpb25bU3ltYm9sLmZvcignX192ZXJkYWNjaW9fdXBsaW5rJyldO1xuXG4gICAgICAgICAgICAgIGlmIChfLmlzTmlsKHVwTGluaykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlVXBsaW5rVG9SZW1vdGVQcm90b2NvbChoYXNoLCB1cExpbmspO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgdGFnIGluIHBhY2thZ2VJbmZvW0RJU1RfVEFHU10pIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFwYWNrYWdlTG9jYWxKc29uW0RJU1RfVEFHU11bdGFnXSB8fFxuICAgICAgICAgIHBhY2thZ2VMb2NhbEpzb25bRElTVF9UQUdTXVt0YWddICE9PSBwYWNrYWdlSW5mb1tESVNUX1RBR1NdW3RhZ11cbiAgICAgICAgKSB7XG4gICAgICAgICAgY2hhbmdlID0gdHJ1ZTtcbiAgICAgICAgICBwYWNrYWdlTG9jYWxKc29uW0RJU1RfVEFHU11bdGFnXSA9IHBhY2thZ2VJbmZvW0RJU1RfVEFHU11bdGFnXTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IHVwIGluIHBhY2thZ2VJbmZvLl91cGxpbmtzKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocGFja2FnZUluZm8uX3VwbGlua3MsIHVwKSkge1xuICAgICAgICAgIGNvbnN0IG5lZWRfY2hhbmdlID1cbiAgICAgICAgICAgICFpc09iamVjdChwYWNrYWdlTG9jYWxKc29uLl91cGxpbmtzW3VwXSkgfHxcbiAgICAgICAgICAgIHBhY2thZ2VJbmZvLl91cGxpbmtzW3VwXS5ldGFnICE9PSBwYWNrYWdlTG9jYWxKc29uLl91cGxpbmtzW3VwXS5ldGFnIHx8XG4gICAgICAgICAgICBwYWNrYWdlSW5mby5fdXBsaW5rc1t1cF0uZmV0Y2hlZCAhPT0gcGFja2FnZUxvY2FsSnNvbi5fdXBsaW5rc1t1cF0uZmV0Y2hlZDtcblxuICAgICAgICAgIGlmIChuZWVkX2NoYW5nZSkge1xuICAgICAgICAgICAgY2hhbmdlID0gdHJ1ZTtcbiAgICAgICAgICAgIHBhY2thZ2VMb2NhbEpzb24uX3VwbGlua3NbdXBdID0gcGFja2FnZUluZm8uX3VwbGlua3NbdXBdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoJ3RpbWUnIGluIHBhY2thZ2VJbmZvICYmICFfLmlzRXF1YWwocGFja2FnZUxvY2FsSnNvbi50aW1lLCBwYWNrYWdlSW5mby50aW1lKSkge1xuICAgICAgICBwYWNrYWdlTG9jYWxKc29uLnRpbWUgPSBwYWNrYWdlSW5mby50aW1lO1xuICAgICAgICBjaGFuZ2UgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhbmdlKSB7XG4gICAgICAgIGRlYnVnKCd1cGRhdGluZyBwYWNrYWdlICVvIGluZm8nLCBuYW1lKTtcbiAgICAgICAgdGhpcy5fd3JpdGVQYWNrYWdlKG5hbWUsIHBhY2thZ2VMb2NhbEpzb24sIGZ1bmN0aW9uIChlcnIpOiB2b2lkIHtcbiAgICAgICAgICBjYWxsYmFjayhlcnIsIHBhY2thZ2VMb2NhbEpzb24pO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsIHBhY2thZ2VMb2NhbEpzb24pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIG5ldyB2ZXJzaW9uIHRvIGEgcHJldmlvdXMgbG9jYWwgcGFja2FnZS5cbiAgICogQHBhcmFtIHsqfSBuYW1lXG4gICAqIEBwYXJhbSB7Kn0gdmVyc2lvblxuICAgKiBAcGFyYW0geyp9IG1ldGFkYXRhXG4gICAqIEBwYXJhbSB7Kn0gdGFnXG4gICAqIEBwYXJhbSB7Kn0gY2FsbGJhY2tcbiAgICovXG4gIHB1YmxpYyBhZGRWZXJzaW9uKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB2ZXJzaW9uOiBzdHJpbmcsXG4gICAgbWV0YWRhdGE6IFZlcnNpb24sXG4gICAgdGFnOiBTdHJpbmdWYWx1ZSxcbiAgICBjYWxsYmFjazogQ2FsbGJhY2tcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5fdXBkYXRlUGFja2FnZShcbiAgICAgIG5hbWUsXG4gICAgICAoZGF0YSwgY2I6IENhbGxiYWNrKTogdm9pZCA9PiB7XG4gICAgICAgIC8vIGtlZXAgb25seSBvbmUgcmVhZG1lIHBlciBwYWNrYWdlXG4gICAgICAgIGRhdGEucmVhZG1lID0gbWV0YWRhdGEucmVhZG1lO1xuXG4gICAgICAgIC8vIFRPRE86IGxvZGFzaCByZW1vdmVcbiAgICAgICAgbWV0YWRhdGEgPSBjbGVhblVwUmVhZG1lKG1ldGFkYXRhKTtcbiAgICAgICAgbWV0YWRhdGEuY29udHJpYnV0b3JzID0gbm9ybWFsaXplQ29udHJpYnV0b3JzKG1ldGFkYXRhLmNvbnRyaWJ1dG9ycyBhcyBBdXRob3JbXSk7XG5cbiAgICAgICAgY29uc3QgaGFzVmVyc2lvbiA9IGRhdGEudmVyc2lvbnNbdmVyc2lvbl0gIT0gbnVsbDtcbiAgICAgICAgaWYgKGhhc1ZlcnNpb24pIHtcbiAgICAgICAgICByZXR1cm4gY2IoRXJyb3JDb2RlLmdldENvbmZsaWN0KCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgdXBsb2FkZWQgdGFyYmFsbCBoYXMgYSBkaWZmZXJlbnQgc2hhc3VtLCBpdCdzIHZlcnkgbGlrZWx5IHRoYXQgd2UgaGF2ZSBzb21lIGtpbmQgb2YgZXJyb3JcbiAgICAgICAgaWYgKGlzT2JqZWN0KG1ldGFkYXRhLmRpc3QpICYmIF8uaXNTdHJpbmcobWV0YWRhdGEuZGlzdC50YXJiYWxsKSkge1xuICAgICAgICAgIGNvbnN0IHRhcmJhbGwgPSBtZXRhZGF0YS5kaXN0LnRhcmJhbGwucmVwbGFjZSgvLipcXC8vLCAnJyk7XG5cbiAgICAgICAgICBpZiAoaXNPYmplY3QoZGF0YS5fYXR0YWNobWVudHNbdGFyYmFsbF0pKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIF8uaXNOaWwoZGF0YS5fYXR0YWNobWVudHNbdGFyYmFsbF0uc2hhc3VtKSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgXy5pc05pbChtZXRhZGF0YS5kaXN0LnNoYXN1bSkgPT09IGZhbHNlXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgaWYgKGRhdGEuX2F0dGFjaG1lbnRzW3RhcmJhbGxdLnNoYXN1bSAhPSBtZXRhZGF0YS5kaXN0LnNoYXN1bSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGBzaGFzdW0gZXJyb3IsICR7ZGF0YS5fYXR0YWNobWVudHNbdGFyYmFsbF0uc2hhc3VtfSAhPSAke21ldGFkYXRhLmRpc3Quc2hhc3VtfWA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNiKEVycm9yQ29kZS5nZXRCYWRSZXF1ZXN0KGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnREYXRlID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuXG4gICAgICAgICAgICAvLyBzb21lIG9sZCBzdG9yYWdlIGRvIG5vdCBoYXZlIHRoaXMgZmllbGQgIzc0MFxuICAgICAgICAgICAgaWYgKF8uaXNOaWwoZGF0YS50aW1lKSkge1xuICAgICAgICAgICAgICBkYXRhLnRpbWUgPSB7fTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGF0YS50aW1lWydtb2RpZmllZCddID0gY3VycmVudERhdGU7XG5cbiAgICAgICAgICAgIGlmICgnY3JlYXRlZCcgaW4gZGF0YS50aW1lID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICBkYXRhLnRpbWUuY3JlYXRlZCA9IGN1cnJlbnREYXRlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkYXRhLnRpbWVbdmVyc2lvbl0gPSBjdXJyZW50RGF0ZTtcbiAgICAgICAgICAgIGRhdGEuX2F0dGFjaG1lbnRzW3RhcmJhbGxdLnZlcnNpb24gPSB2ZXJzaW9uO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGRhdGEudmVyc2lvbnNbdmVyc2lvbl0gPSBtZXRhZGF0YTtcbiAgICAgICAgdGFnVmVyc2lvbihkYXRhLCB2ZXJzaW9uLCB0YWcpO1xuXG4gICAgICAgIHRoaXMuc3RvcmFnZVBsdWdpbi5hZGQobmFtZSwgKGFkZEZhaWxlZCk6IHZvaWQgPT4ge1xuICAgICAgICAgIGlmIChhZGRGYWlsZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjYihFcnJvckNvZGUuZ2V0QmFkRGF0YShhZGRGYWlsZWQubWVzc2FnZSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNiKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIGNhbGxiYWNrXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZSBhIG5ldyBsaXN0IG9mIHRhZ3MgZm9yIGEgbG9jYWwgcGFja2FnZXMgd2l0aCB0aGUgZXhpc3Rpbmcgb25lLlxuICAgKiBAcGFyYW0geyp9IHBrZ05hbWVcbiAgICogQHBhcmFtIHsqfSB0YWdzXG4gICAqIEBwYXJhbSB7Kn0gY2FsbGJhY2tcbiAgICovXG4gIHB1YmxpYyBtZXJnZVRhZ3MocGtnTmFtZTogc3RyaW5nLCB0YWdzOiBNZXJnZVRhZ3MsIGNhbGxiYWNrOiBDYWxsYmFjayk6IHZvaWQge1xuICAgIHRoaXMuX3VwZGF0ZVBhY2thZ2UoXG4gICAgICBwa2dOYW1lLFxuICAgICAgKGRhdGEsIGNiKTogdm9pZCA9PiB7XG4gICAgICAgIC8qIGVzbGludCBndWFyZC1mb3ItaW46IDAgKi9cbiAgICAgICAgZm9yIChjb25zdCB0YWcgaW4gdGFncykge1xuICAgICAgICAgIC8vIHRoaXMgaGFuZGxlIGRpc3QtdGFnIHJtIGNvbW1hbmRcbiAgICAgICAgICBpZiAoXy5pc051bGwodGFnc1t0YWddKSkge1xuICAgICAgICAgICAgZGVsZXRlIGRhdGFbRElTVF9UQUdTXVt0YWddO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKF8uaXNOaWwoZGF0YS52ZXJzaW9uc1t0YWdzW3RhZ11dKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNiKHRoaXMuX2dldFZlcnNpb25Ob3RGb3VuZCgpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgdmVyc2lvbjogc3RyaW5nID0gdGFnc1t0YWddO1xuICAgICAgICAgIHRhZ1ZlcnNpb24oZGF0YSwgdmVyc2lvbiwgdGFnKTtcbiAgICAgICAgfVxuICAgICAgICBjYihudWxsKTtcbiAgICAgIH0sXG4gICAgICBjYWxsYmFja1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHZlcnNpb24gbm90IGZvdW5kXG4gICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgX2dldFZlcnNpb25Ob3RGb3VuZCgpOiBhbnkge1xuICAgIHJldHVybiBFcnJvckNvZGUuZ2V0Tm90Rm91bmQoQVBJX0VSUk9SLlZFUlNJT05fTk9UX0VYSVNUKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gZmlsZSBubyBhdmFpbGFibGVcbiAgICogQHJldHVybiB7U3RyaW5nfVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0RmlsZU5vdEF2YWlsYWJsZSgpOiBhbnkge1xuICAgIHJldHVybiBFcnJvckNvZGUuZ2V0Tm90Rm91bmQoJ25vIHN1Y2ggZmlsZSBhdmFpbGFibGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIHBhY2thZ2UgbWV0YWRhdGEsIHRhZ3MgYW5kIGF0dGFjaG1lbnRzICh0YXJiYWxscykuXG4gICAqIE5vdGU6IEN1cnJlbnRseSBzdXBwb3J0cyB1bnB1Ymxpc2hpbmcgYW5kIGRlcHJlY2F0aW9uLlxuICAgKiBAcGFyYW0geyp9IG5hbWVcbiAgICogQHBhcmFtIHsqfSBpbmNvbWluZ1BrZ1xuICAgKiBAcGFyYW0geyp9IHJldmlzaW9uXG4gICAqIEBwYXJhbSB7Kn0gY2FsbGJhY2tcbiAgICogQHJldHVybiB7RnVuY3Rpb259XG4gICAqL1xuICBwdWJsaWMgY2hhbmdlUGFja2FnZShcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgaW5jb21pbmdQa2c6IE1hbmlmZXN0LFxuICAgIHJldmlzaW9uOiBzdHJpbmcgfCB2b2lkLFxuICAgIGNhbGxiYWNrOiBDYWxsYmFja1xuICApOiB2b2lkIHtcbiAgICBpZiAoIWlzT2JqZWN0KGluY29taW5nUGtnLnZlcnNpb25zKSB8fCAhaXNPYmplY3QoaW5jb21pbmdQa2dbRElTVF9UQUdTXSkpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKHsgbmFtZSB9LCBgY2hhbmdlUGFja2FnZSBiYWQgZGF0YSBmb3IgQHtuYW1lfWApO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKEVycm9yQ29kZS5nZXRCYWREYXRhKCkpO1xuICAgIH1cbiAgICBkZWJ1ZygnY2hhbmdlUGFja2FnZSB1ZGFwdGluZyBwYWNrYWdlIGZvciAlbycsIG5hbWUpO1xuICAgIHRoaXMuX3VwZGF0ZVBhY2thZ2UoXG4gICAgICBuYW1lLFxuICAgICAgKGxvY2FsRGF0YTogTWFuaWZlc3QsIGNiOiBDYWxsYmFjayk6IHZvaWQgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHZlcnNpb24gaW4gbG9jYWxEYXRhLnZlcnNpb25zKSB7XG4gICAgICAgICAgY29uc3QgaW5jb21pbmdWZXJzaW9uID0gaW5jb21pbmdQa2cudmVyc2lvbnNbdmVyc2lvbl07XG4gICAgICAgICAgaWYgKF8uaXNOaWwoaW5jb21pbmdWZXJzaW9uKSkge1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuaW5mbyh7IG5hbWU6IG5hbWUsIHZlcnNpb246IHZlcnNpb24gfSwgJ3VucHVibGlzaGluZyBAe25hbWV9QEB7dmVyc2lvbn0nKTtcblxuICAgICAgICAgICAgLy8gRklYTUU6IEkgcHJlZmVyIHJldHVybiBhIG5ldyBvYmplY3QgcmF0aGVyIG11dGF0ZSB0aGUgbWV0YWRhdGFcbiAgICAgICAgICAgIGRlbGV0ZSBsb2NhbERhdGEudmVyc2lvbnNbdmVyc2lvbl07XG4gICAgICAgICAgICBkZWxldGUgbG9jYWxEYXRhLnRpbWUhW3ZlcnNpb25dO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZpbGUgaW4gbG9jYWxEYXRhLl9hdHRhY2htZW50cykge1xuICAgICAgICAgICAgICBpZiAobG9jYWxEYXRhLl9hdHRhY2htZW50c1tmaWxlXS52ZXJzaW9uID09PSB2ZXJzaW9uKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGxvY2FsRGF0YS5fYXR0YWNobWVudHNbZmlsZV0udmVyc2lvbjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGluY29taW5nVmVyc2lvbiwgJ2RlcHJlY2F0ZWQnKSkge1xuICAgICAgICAgICAgY29uc3QgaW5jb21pbmdEZXByZWNhdGVkID0gaW5jb21pbmdWZXJzaW9uLmRlcHJlY2F0ZWQ7XG4gICAgICAgICAgICBpZiAoaW5jb21pbmdEZXByZWNhdGVkICE9IGxvY2FsRGF0YS52ZXJzaW9uc1t2ZXJzaW9uXS5kZXByZWNhdGVkKSB7XG4gICAgICAgICAgICAgIGlmICghaW5jb21pbmdEZXByZWNhdGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgICAgIHsgbmFtZTogbmFtZSwgdmVyc2lvbjogdmVyc2lvbiB9LFxuICAgICAgICAgICAgICAgICAgJ3VuZGVwcmVjYXRpbmcgQHtuYW1lfUBAe3ZlcnNpb259J1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGxvY2FsRGF0YS52ZXJzaW9uc1t2ZXJzaW9uXS5kZXByZWNhdGVkO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICAgICB7IG5hbWU6IG5hbWUsIHZlcnNpb246IHZlcnNpb24gfSxcbiAgICAgICAgICAgICAgICAgICdkZXByZWNhdGluZyBAe25hbWV9QEB7dmVyc2lvbn0nXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBsb2NhbERhdGEudmVyc2lvbnNbdmVyc2lvbl0uZGVwcmVjYXRlZCA9IGluY29taW5nRGVwcmVjYXRlZDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsb2NhbERhdGEudGltZSEubW9kaWZpZWQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbG9jYWxEYXRhW1VTRVJTXSA9IGluY29taW5nUGtnW1VTRVJTXTtcbiAgICAgICAgbG9jYWxEYXRhW0RJU1RfVEFHU10gPSBpbmNvbWluZ1BrZ1tESVNUX1RBR1NdO1xuICAgICAgICBjYihudWxsKTtcbiAgICAgIH0sXG4gICAgICBmdW5jdGlvbiAoZXJyKTogdm9pZCB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgfVxuICAgICk7XG4gIH1cbiAgLyoqXG4gICAqIFJlbW92ZSBhIHRhcmJhbGwuXG4gICAqIEBwYXJhbSB7Kn0gbmFtZVxuICAgKiBAcGFyYW0geyp9IGZpbGVuYW1lXG4gICAqIEBwYXJhbSB7Kn0gcmV2aXNpb25cbiAgICogQHBhcmFtIHsqfSBjYWxsYmFja1xuICAgKi9cbiAgcHVibGljIHJlbW92ZVRhcmJhbGwobmFtZTogc3RyaW5nLCBmaWxlbmFtZTogc3RyaW5nLCByZXZpc2lvbjogc3RyaW5nLCBjYWxsYmFjazogQ2FsbGJhY2spOiB2b2lkIHtcbiAgICBhc3NlcnQodmFsaWRhdGVOYW1lKGZpbGVuYW1lKSk7XG5cbiAgICB0aGlzLl91cGRhdGVQYWNrYWdlKFxuICAgICAgbmFtZSxcbiAgICAgIChkYXRhLCBjYik6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoZGF0YS5fYXR0YWNobWVudHNbZmlsZW5hbWVdKSB7XG4gICAgICAgICAgZGVsZXRlIGRhdGEuX2F0dGFjaG1lbnRzW2ZpbGVuYW1lXTtcbiAgICAgICAgICBjYihudWxsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYih0aGlzLl9nZXRGaWxlTm90QXZhaWxhYmxlKCkpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKGVycjogYW55KTogdm9pZCA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdG9yYWdlID0gdGhpcy5fZ2V0TG9jYWxTdG9yYWdlKG5hbWUpO1xuXG4gICAgICAgIGlmIChzdG9yYWdlKSB7XG4gICAgICAgICAgc3RvcmFnZS5kZWxldGVQYWNrYWdlKGZpbGVuYW1lLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIHRhcmJhbGwuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBmaWxlbmFtZVxuICAgKiBAcmV0dXJuIHtTdHJlYW19XG4gICAqL1xuICBwdWJsaWMgYWRkVGFyYmFsbChuYW1lOiBzdHJpbmcsIGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICBhc3NlcnQodmFsaWRhdGVOYW1lKGZpbGVuYW1lKSk7XG5cbiAgICBsZXQgbGVuZ3RoID0gMDtcbiAgICBjb25zdCBzaGFPbmVIYXNoID0gY3JlYXRlVGFyYmFsbEhhc2goKTtcbiAgICBjb25zdCB1cGxvYWRTdHJlYW0gPSBuZXcgVXBsb2FkVGFyYmFsbCh7fSk7XG4gICAgY29uc3QgX3RyYW5zZm9ybSA9IHVwbG9hZFN0cmVhbS5fdHJhbnNmb3JtO1xuICAgIGNvbnN0IHN0b3JhZ2UgPSB0aGlzLl9nZXRMb2NhbFN0b3JhZ2UobmFtZSk7XG5cbiAgICB1cGxvYWRTdHJlYW0uYWJvcnQgPSBmdW5jdGlvbiAoKTogdm9pZCB7fTtcbiAgICB1cGxvYWRTdHJlYW0uZG9uZSA9IGZ1bmN0aW9uICgpOiB2b2lkIHt9O1xuXG4gICAgdXBsb2FkU3RyZWFtLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgLi4uYXJncyk6IHZvaWQge1xuICAgICAgc2hhT25lSGFzaC51cGRhdGUoZGF0YSk7XG4gICAgICAvLyBtZWFzdXJlIHRoZSBsZW5ndGggZm9yIHZhbGlkYXRpb24gcmVhc29uc1xuICAgICAgbGVuZ3RoICs9IGRhdGEubGVuZ3RoO1xuICAgICAgY29uc3QgYXBwbGllZERhdGEgPSBbZGF0YSwgLi4uYXJnc107XG4gICAgICAvLyBGSVhNRTogbm90IHN1cmUgYWJvdXQgdGhpcyBhcHByb2FjaCwgdHNjIGNvbXBsYWluc1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgX3RyYW5zZm9ybS5hcHBseSh1cGxvYWRTdHJlYW0sIGFwcGxpZWREYXRhKTtcbiAgICB9O1xuXG4gICAgaWYgKG5hbWUgPT09ICdfX3Byb3RvX18nKSB7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKCgpOiB2b2lkID0+IHtcbiAgICAgICAgdXBsb2FkU3RyZWFtLmVtaXQoJ2Vycm9yJywgRXJyb3JDb2RlLmdldEZvcmJpZGRlbigpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHVwbG9hZFN0cmVhbTtcbiAgICB9XG5cbiAgICBpZiAoIXN0b3JhZ2UpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soKCk6IHZvaWQgPT4ge1xuICAgICAgICB1cGxvYWRTdHJlYW0uZW1pdCgnZXJyb3InLCBcImNhbid0IHVwbG9hZCB0aGlzIHBhY2thZ2VcIik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB1cGxvYWRTdHJlYW07XG4gICAgfVxuXG4gICAgY29uc3Qgd3JpdGVTdHJlYW0gPSBzdG9yYWdlLndyaXRlVGFyYmFsbChmaWxlbmFtZSk7XG5cbiAgICB3cml0ZVN0cmVhbS5vbignZXJyb3InLCAoZXJyKSA9PiB7XG4gICAgICBpZiAoZXJyLmNvZGUgPT09IFNUT1JBR0UuRklMRV9FWElTVF9FUlJPUiB8fCBlcnIuY29kZSA9PT0gSFRUUF9TVEFUVVMuQ09ORkxJQ1QpIHtcbiAgICAgICAgdXBsb2FkU3RyZWFtLmVtaXQoJ2Vycm9yJywgRXJyb3JDb2RlLmdldENvbmZsaWN0KCkpO1xuICAgICAgICB1cGxvYWRTdHJlYW0uYWJvcnQoKTtcbiAgICAgIH0gZWxzZSBpZiAoZXJyLmNvZGUgPT09IFNUT1JBR0UuTk9fU1VDSF9GSUxFX0VSUk9SIHx8IGVyci5jb2RlID09PSBIVFRQX1NUQVRVUy5OT1RfRk9VTkQpIHtcbiAgICAgICAgLy8gY2hlY2sgaWYgcGFja2FnZSBleGlzdHMgdG8gdGhyb3cgYW4gYXBwcm9wcmlhdGUgbWVzc2FnZVxuICAgICAgICB0aGlzLmdldFBhY2thZ2VNZXRhZGF0YShuYW1lLCBmdW5jdGlvbiAoX2VycjogYW55KTogdm9pZCB7XG4gICAgICAgICAgaWYgKF9lcnIpIHtcbiAgICAgICAgICAgIHVwbG9hZFN0cmVhbS5lbWl0KCdlcnJvcicsIF9lcnIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1cGxvYWRTdHJlYW0uZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cGxvYWRTdHJlYW0uZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgd3JpdGVTdHJlYW0ub24oJ29wZW4nLCBmdW5jdGlvbiAoKTogdm9pZCB7XG4gICAgICAvLyByZS1lbWl0dGluZyBvcGVuIGJlY2F1c2UgaXQncyBoYW5kbGVkIGluIHN0b3JhZ2UuanNcbiAgICAgIHVwbG9hZFN0cmVhbS5lbWl0KCdvcGVuJyk7XG4gICAgfSk7XG5cbiAgICB3cml0ZVN0cmVhbS5vbignc3VjY2VzcycsICgpOiB2b2lkID0+IHtcbiAgICAgIHRoaXMuX3VwZGF0ZVBhY2thZ2UoXG4gICAgICAgIG5hbWUsXG4gICAgICAgIGZ1bmN0aW9uIHVwZGF0ZXIoZGF0YSwgY2IpOiB2b2lkIHtcbiAgICAgICAgICBkYXRhLl9hdHRhY2htZW50c1tmaWxlbmFtZV0gPSB7XG4gICAgICAgICAgICBzaGFzdW06IHNoYU9uZUhhc2guZGlnZXN0KCdoZXgnKSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNiKG51bGwpO1xuICAgICAgICB9LFxuICAgICAgICBmdW5jdGlvbiAoZXJyKTogdm9pZCB7XG4gICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdXBsb2FkU3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdXBsb2FkU3RyZWFtLmVtaXQoJ3N1Y2Nlc3MnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB1cGxvYWRTdHJlYW0uYWJvcnQgPSBmdW5jdGlvbiAoKTogdm9pZCB7XG4gICAgICB3cml0ZVN0cmVhbS5hYm9ydCgpO1xuICAgIH07XG5cbiAgICB1cGxvYWRTdHJlYW0uZG9uZSA9IGZ1bmN0aW9uICgpOiB2b2lkIHtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHVwbG9hZFN0cmVhbS5lbWl0KCdlcnJvcicsIEVycm9yQ29kZS5nZXRCYWREYXRhKCdyZWZ1c2luZyB0byBhY2NlcHQgemVyby1sZW5ndGggZmlsZScpKTtcbiAgICAgICAgd3JpdGVTdHJlYW0uYWJvcnQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdyaXRlU3RyZWFtLmRvbmUoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdXBsb2FkU3RyZWFtLnBpcGUod3JpdGVTdHJlYW0pO1xuXG4gICAgcmV0dXJuIHVwbG9hZFN0cmVhbTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSB0YXJiYWxsLlxuICAgKiBAcGFyYW0geyp9IG5hbWVcbiAgICogQHBhcmFtIHsqfSBmaWxlbmFtZVxuICAgKiBAcmV0dXJuIHtSZWFkVGFyYmFsbH1cbiAgICovXG4gIHB1YmxpYyBnZXRUYXJiYWxsKG5hbWU6IHN0cmluZywgZmlsZW5hbWU6IHN0cmluZykge1xuICAgIGFzc2VydCh2YWxpZGF0ZU5hbWUoZmlsZW5hbWUpKTtcblxuICAgIGNvbnN0IHN0b3JhZ2UgPSB0aGlzLl9nZXRMb2NhbFN0b3JhZ2UobmFtZSk7XG5cbiAgICBpZiAoXy5pc05pbChzdG9yYWdlKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUZhaWx1cmVTdHJlYW1SZXNwb25zZSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9zdHJlYW1TdWNjZXNzUmVhZFRhckJhbGwoc3RvcmFnZSwgZmlsZW5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHN0cmVhbSB0aGF0IGVtaXRzIGEgcmVhZCBmYWlsdXJlLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcmV0dXJuIHtSZWFkVGFyYmFsbH1cbiAgICovXG4gIHByaXZhdGUgX2NyZWF0ZUZhaWx1cmVTdHJlYW1SZXNwb25zZSgpIHtcbiAgICBjb25zdCBzdHJlYW0gPSBuZXcgUmVhZFRhcmJhbGwoe30pO1xuXG4gICAgcHJvY2Vzcy5uZXh0VGljaygoKTogdm9pZCA9PiB7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCB0aGlzLl9nZXRGaWxlTm90QXZhaWxhYmxlKCkpO1xuICAgIH0pO1xuICAgIHJldHVybiBzdHJlYW07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgc3RyZWFtIHRoYXQgZW1pdHMgdGhlIHRhcmJhbGwgZGF0YVxuICAgKiBAcGFyYW0ge09iamVjdH0gc3RvcmFnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gZmlsZW5hbWVcbiAgICogQHByaXZhdGVcbiAgICogQHJldHVybiB7UmVhZFRhcmJhbGx9XG4gICAqL1xuICBwcml2YXRlIF9zdHJlYW1TdWNjZXNzUmVhZFRhckJhbGwoc3RvcmFnZTogYW55LCBmaWxlbmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gbmV3IFJlYWRUYXJiYWxsKHt9KTtcbiAgICBjb25zdCByZWFkVGFyYmFsbFN0cmVhbSA9IHN0b3JhZ2UucmVhZFRhcmJhbGwoZmlsZW5hbWUpO1xuICAgIGNvbnN0IGU0MDQgPSBFcnJvckNvZGUuZ2V0Tm90Rm91bmQ7XG5cbiAgICBzdHJlYW0uYWJvcnQgPSBmdW5jdGlvbiAoKTogdm9pZCB7XG4gICAgICBpZiAoXy5pc05pbChyZWFkVGFyYmFsbFN0cmVhbSkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJlYWRUYXJiYWxsU3RyZWFtLmFib3J0KCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJlYWRUYXJiYWxsU3RyZWFtLm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGlmIChlcnIuY29kZSA9PT0gU1RPUkFHRS5OT19TVUNIX0ZJTEVfRVJST1IgfHwgZXJyLmNvZGUgPT09IEhUVFBfU1RBVFVTLk5PVF9GT1VORCkge1xuICAgICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlNDA0KCdubyBzdWNoIGZpbGUgYXZhaWxhYmxlJykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJlYWRUYXJiYWxsU3RyZWFtLm9uKCdjb250ZW50LWxlbmd0aCcsIGZ1bmN0aW9uIChjb250ZW50KTogdm9pZCB7XG4gICAgICBzdHJlYW0uZW1pdCgnY29udGVudC1sZW5ndGgnLCBjb250ZW50KTtcbiAgICB9KTtcblxuICAgIHJlYWRUYXJiYWxsU3RyZWFtLm9uKCdvcGVuJywgZnVuY3Rpb24gKCk6IHZvaWQge1xuICAgICAgLy8gcmUtZW1pdHRpbmcgb3BlbiBiZWNhdXNlIGl0J3MgaGFuZGxlZCBpbiBzdG9yYWdlLmpzXG4gICAgICBzdHJlYW0uZW1pdCgnb3BlbicpO1xuICAgICAgcmVhZFRhcmJhbGxTdHJlYW0ucGlwZShzdHJlYW0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHN0cmVhbTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhIHBhY2thZ2UgYnkgbmFtZS5cbiAgICogQHBhcmFtIHsqfSBuYW1lXG4gICAqIEBwYXJhbSB7Kn0gY2FsbGJhY2tcbiAgICogQHJldHVybiB7RnVuY3Rpb259XG4gICAqL1xuICBwdWJsaWMgZ2V0UGFja2FnZU1ldGFkYXRhKG5hbWU6IHN0cmluZywgY2FsbGJhY2s6IENhbGxiYWNrID0gKCk6IHZvaWQgPT4ge30pOiB2b2lkIHtcbiAgICBjb25zdCBzdG9yYWdlID0gdGhpcy5fZ2V0TG9jYWxTdG9yYWdlKG5hbWUpO1xuICAgIGlmIChfLmlzTmlsKHN0b3JhZ2UpKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soRXJyb3JDb2RlLmdldE5vdEZvdW5kKCkpO1xuICAgIH1cblxuICAgIHRoaXMuX3JlYWRQYWNrYWdlKG5hbWUsIHN0b3JhZ2UsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRQYWNrYWdlTWV0YWRhdGFBc3luYyhuYW1lOiBzdHJpbmcpOiBQcm9taXNlPE1hbmlmZXN0PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE1hbmlmZXN0PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmdldFBhY2thZ2VNZXRhZGF0YShuYW1lLCAoZXJyOiBhbnksIG1ldGFkYXRhOiBNYW5pZmVzdCkgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUobWV0YWRhdGEpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlVmVyc2lvbnNBc3luYyhuYW1lOiBzdHJpbmcsIHBhY2thZ2VJbmZvOiBNYW5pZmVzdCk6IFByb21pc2U8TWFuaWZlc3Q+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TWFuaWZlc3Q+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMudXBkYXRlVmVyc2lvbnMobmFtZSwgcGFja2FnZUluZm8sIChlcnI6IGFueSwgcmVzdWx0OiBNYW5pZmVzdCkgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlYXJjaCBhIGxvY2FsIHBhY2thZ2UuXG4gICAqIEBwYXJhbSB7Kn0gc3RhcnRLZXlcbiAgICogQHBhcmFtIHsqfSBvcHRpb25zXG4gICAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICAgKi9cbiAgcHVibGljIHNlYXJjaChzdGFydEtleTogc3RyaW5nLCBvcHRpb25zOiBhbnkpIHtcbiAgICBkZWJ1Zygnb3B0aW9ucyBmb3Igc2VhcmNoICVvJywgb3B0aW9ucyk7XG4gICAgY29uc3Qgc3RyZWFtID0gbmV3IFJlYWRUYXJiYWxsKHsgb2JqZWN0TW9kZTogdHJ1ZSB9KTtcblxuICAgIHRoaXMuX3NlYXJjaEVhY2hQYWNrYWdlKFxuICAgICAgKGl0ZW06IE1hbmlmZXN0LCBjYjogQ2FsbGJhY2spOiB2b2lkID0+IHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBpZiAoaXRlbS50aW1lID4gcGFyc2VJbnQoc3RhcnRLZXksIDEwKSkge1xuICAgICAgICAgIHRoaXMuZ2V0UGFja2FnZU1ldGFkYXRhKGl0ZW0ubmFtZSwgKGVycjogYW55LCBkYXRhOiBNYW5pZmVzdCk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICByZXR1cm4gY2IoZXJyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc3QgdGltZSA9IG5ldyBEYXRlKGl0ZW0udGltZSkudG9JU09TdHJpbmcoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHByZXBhcmVTZWFyY2hQYWNrYWdlKGRhdGEsIHRpbWUpO1xuICAgICAgICAgICAgaWYgKF8uaXNOaWwocmVzdWx0KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgc3RyZWFtLnB1c2gocmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNiKG51bGwpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNiKG51bGwpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZnVuY3Rpb24gb25FbmQoZXJyKTogdm9pZCB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdHJlYW0uZW5kKCk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHJldHVybiBzdHJlYW07XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgYSB3cmFwcGVyIHRoYXQgcHJvdmlkZSBhY2Nlc3MgdG8gdGhlIHBhY2thZ2UgbG9jYXRpb24uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwa2dOYW1lIHBhY2thZ2UgbmFtZS5cbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0TG9jYWxTdG9yYWdlKHBrZ05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLnN0b3JhZ2VQbHVnaW4uZ2V0UGFja2FnZVN0b3JhZ2UocGtnTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVhZCBhIGpzb24gZmlsZSBmcm9tIHN0b3JhZ2UuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBzdG9yYWdlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBwcml2YXRlIF9yZWFkUGFja2FnZShuYW1lOiBzdHJpbmcsIHN0b3JhZ2U6IGFueSwgY2FsbGJhY2s6IENhbGxiYWNrKTogdm9pZCB7XG4gICAgc3RvcmFnZS5yZWFkUGFja2FnZShuYW1lLCAoZXJyLCByZXN1bHQpOiB2b2lkID0+IHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgaWYgKGVyci5jb2RlID09PSBTVE9SQUdFLk5PX1NVQ0hfRklMRV9FUlJPUiB8fCBlcnIuY29kZSA9PT0gSFRUUF9TVEFUVVMuTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKEVycm9yQ29kZS5nZXROb3RGb3VuZCgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sodGhpcy5faW50ZXJuYWxFcnJvcihlcnIsIFNUT1JBR0UuUEFDS0FHRV9GSUxFX05BTUUsICdlcnJvciByZWFkaW5nJykpO1xuICAgICAgfVxuXG4gICAgICBjYWxsYmFjayhlcnIsIG5vcm1hbGl6ZVBhY2thZ2UocmVzdWx0KSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogV2Fsa3MgdGhyb3VnaCBlYWNoIHBhY2thZ2UgYW5kIGNhbGxzIGBvbl9wYWNrYWdlYCBvbiB0aGVtLlxuICAgKiBAcGFyYW0geyp9IG9uUGFja2FnZVxuICAgKiBAcGFyYW0geyp9IG9uRW5kXG4gICAqL1xuICBwcml2YXRlIF9zZWFyY2hFYWNoUGFja2FnZShvblBhY2thZ2U6IG9uU2VhcmNoUGFja2FnZSwgb25FbmQ6IG9uRW5kU2VhcmNoUGFja2FnZSk6IHZvaWQge1xuICAgIC8vIHNhdmUgd2FpdCB3aGV0aGVyIHBsdWdpbiBzdGlsbCBkbyBub3Qgc3VwcG9ydCBzZWFyY2ggZnVuY3Rpb25hbGl0eVxuICAgIGlmIChfLmlzTmlsKHRoaXMuc3RvcmFnZVBsdWdpbi5zZWFyY2gpKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKCdwbHVnaW4gc2VhcmNoIG5vdCBpbXBsZW1lbnRlZCB5ZXQnKTtcbiAgICAgIG9uRW5kKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RvcmFnZVBsdWdpbi5zZWFyY2gob25QYWNrYWdlLCBvbkVuZCwgdmFsaWRhdGVOYW1lKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgZWl0aGVyIGEgcHJldmlvdXMgY3JlYXRlZCBsb2NhbCBwYWNrYWdlIG9yIGEgYm9pbGVycGxhdGUuXG4gICAqIEBwYXJhbSB7Kn0gcGtnTmFtZVxuICAgKiBAcGFyYW0geyp9IGNhbGxiYWNrXG4gICAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICAgKi9cbiAgcHJpdmF0ZSBfcmVhZENyZWF0ZVBhY2thZ2UocGtnTmFtZTogc3RyaW5nLCBjYWxsYmFjazogQ2FsbGJhY2spOiB2b2lkIHtcbiAgICBjb25zdCBzdG9yYWdlOiBhbnkgPSB0aGlzLl9nZXRMb2NhbFN0b3JhZ2UocGtnTmFtZSk7XG4gICAgaWYgKF8uaXNOaWwoc3RvcmFnZSkpIHtcbiAgICAgIHRoaXMuX2NyZWF0ZU5ld1BhY2thZ2UocGtnTmFtZSwgY2FsbGJhY2spO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN0b3JhZ2UucmVhZFBhY2thZ2UocGtnTmFtZSwgKGVyciwgZGF0YSk6IHZvaWQgPT4ge1xuICAgICAgLy8gVE9ETzogcmFjZSBjb25kaXRpb25cbiAgICAgIGlmIChfLmlzTmlsKGVycikgPT09IGZhbHNlKSB7XG4gICAgICAgIGlmIChlcnIuY29kZSA9PT0gU1RPUkFHRS5OT19TVUNIX0ZJTEVfRVJST1IgfHwgZXJyLmNvZGUgPT09IEhUVFBfU1RBVFVTLk5PVF9GT1VORCkge1xuICAgICAgICAgIGRhdGEgPSBnZW5lcmF0ZVBhY2thZ2VUZW1wbGF0ZShwa2dOYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sodGhpcy5faW50ZXJuYWxFcnJvcihlcnIsIFNUT1JBR0UuUEFDS0FHRV9GSUxFX05BTUUsICdlcnJvciByZWFkaW5nJykpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNhbGxiYWNrKG51bGwsIG5vcm1hbGl6ZVBhY2thZ2UoZGF0YSkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfY3JlYXRlTmV3UGFja2FnZShuYW1lOiBzdHJpbmcsIGNhbGxiYWNrOiBDYWxsYmFjayk6IENhbGxiYWNrIHtcbiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgbm9ybWFsaXplUGFja2FnZShnZW5lcmF0ZVBhY2thZ2VUZW1wbGF0ZShuYW1lKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSBpbnRlcm5hbCBlcnJvclxuICAgKiBAcGFyYW0geyp9IGVyclxuICAgKiBAcGFyYW0geyp9IGZpbGVcbiAgICogQHBhcmFtIHsqfSBtZXNzYWdlXG4gICAqIEByZXR1cm4ge09iamVjdH0gRXJyb3IgaW5zdGFuY2VcbiAgICovXG4gIHByaXZhdGUgX2ludGVybmFsRXJyb3IoZXJyOiBzdHJpbmcsIGZpbGU6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKTogYW55IHtcbiAgICB0aGlzLmxvZ2dlci5lcnJvcih7IGVycjogZXJyLCBmaWxlOiBmaWxlIH0sIGAke21lc3NhZ2V9ICBAe2ZpbGV9OiBAeyFlcnIubWVzc2FnZX1gKTtcblxuICAgIHJldHVybiBFcnJvckNvZGUuZ2V0SW50ZXJuYWxFcnJvcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Kn0gbmFtZSBwYWNrYWdlIG5hbWVcbiAgICogQHBhcmFtIHsqfSB1cGRhdGVIYW5kbGVyIGZ1bmN0aW9uKHBhY2thZ2UsIGNiKSAtIHVwZGF0ZSBmdW5jdGlvblxuICAgKiBAcGFyYW0geyp9IGNhbGxiYWNrIGNhbGxiYWNrIHRoYXQgZ2V0cyBpbnZva2VkIGFmdGVyIGl0J3MgYWxsIHVwZGF0ZWRcbiAgICogQHJldHVybiB7RnVuY3Rpb259XG4gICAqL1xuICBwcml2YXRlIF91cGRhdGVQYWNrYWdlKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB1cGRhdGVIYW5kbGVyOiBTdG9yYWdlVXBkYXRlQ2FsbGJhY2ssXG4gICAgY2FsbGJhY2s6IENhbGxiYWNrXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHN0b3JhZ2UgPSB0aGlzLl9nZXRMb2NhbFN0b3JhZ2UobmFtZSk7XG5cbiAgICBpZiAoIXN0b3JhZ2UpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayhFcnJvckNvZGUuZ2V0Tm90Rm91bmQoKSk7XG4gICAgfVxuXG4gICAgc3RvcmFnZS51cGRhdGVQYWNrYWdlKFxuICAgICAgbmFtZSxcbiAgICAgIHVwZGF0ZUhhbmRsZXIsXG4gICAgICB0aGlzLl93cml0ZVBhY2thZ2UuYmluZCh0aGlzKSxcbiAgICAgIG5vcm1hbGl6ZVBhY2thZ2UsXG4gICAgICBjYWxsYmFja1xuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRoZSByZXZpc2lvbiAoX3Jldikgc3RyaW5nIGZvciBhIHBhY2thZ2UuXG4gICAqIEBwYXJhbSB7Kn0gbmFtZVxuICAgKiBAcGFyYW0geyp9IGpzb25cbiAgICogQHBhcmFtIHsqfSBjYWxsYmFja1xuICAgKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAgICovXG4gIHByaXZhdGUgX3dyaXRlUGFja2FnZShuYW1lOiBzdHJpbmcsIGpzb246IE1hbmlmZXN0LCBjYWxsYmFjazogQ2FsbGJhY2spOiB2b2lkIHtcbiAgICBjb25zdCBzdG9yYWdlOiBhbnkgPSB0aGlzLl9nZXRMb2NhbFN0b3JhZ2UobmFtZSk7XG4gICAgaWYgKF8uaXNOaWwoc3RvcmFnZSkpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgIH1cbiAgICBzdG9yYWdlLnNhdmVQYWNrYWdlKG5hbWUsIHRoaXMuX3NldERlZmF1bHRSZXZpc2lvbihqc29uKSwgY2FsbGJhY2spO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2V0RGVmYXVsdFJldmlzaW9uKGpzb246IE1hbmlmZXN0KTogTWFuaWZlc3Qge1xuICAgIC8vIGNhbGN1bGF0ZSByZXZpc2lvbiBmcm9tIGNvdWNoIGRiXG4gICAgaWYgKF8uaXNTdHJpbmcoanNvbi5fcmV2KSA9PT0gZmFsc2UpIHtcbiAgICAgIGpzb24uX3JldiA9IFNUT1JBR0UuREVGQVVMVF9SRVZJU0lPTjtcbiAgICB9XG5cbiAgICAvLyB0aGlzIGlzIGludGVuZGVkIGluIGRlYnVnIG1vZGUgd2UgZG8gbm90IHdhbnQgbW9kaWZ5IHRoZSBzdG9yZSByZXZpc2lvblxuICAgIGlmIChfLmlzTmlsKHRoaXMuY29uZmlnLl9kZWJ1ZykpIHtcbiAgICAgIGpzb24uX3JldiA9IGdlbmVyYXRlUmV2aXNpb24oanNvbi5fcmV2KTtcbiAgICB9XG5cbiAgICByZXR1cm4ganNvbjtcbiAgfVxuXG4gIHByaXZhdGUgX2RlbGV0ZUF0dGFjaG1lbnRzKHN0b3JhZ2U6IGFueSwgYXR0YWNobWVudHM6IHN0cmluZ1tdLCBjYWxsYmFjazogQ2FsbGJhY2spOiB2b2lkIHtcbiAgICBkZWJ1ZygnW3N0b3JhZ2UvX2RlbGV0ZUF0dGFjaG1lbnRzXSBkZWxldGUgYXR0YWNobWVudHMgdG90YWw6ICVvJywgYXR0YWNobWVudHM/Lmxlbmd0aCk7XG4gICAgY29uc3QgdW5saW5rTmV4dCA9IGZ1bmN0aW9uIChjYik6IHZvaWQge1xuICAgICAgaWYgKF8uaXNFbXB0eShhdHRhY2htZW50cykpIHtcbiAgICAgICAgcmV0dXJuIGNiKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGF0dGFjaG1lbnQgPSBhdHRhY2htZW50cy5zaGlmdCgpO1xuICAgICAgc3RvcmFnZS5kZWxldGVQYWNrYWdlKGF0dGFjaG1lbnQsIGZ1bmN0aW9uICgpOiB2b2lkIHtcbiAgICAgICAgdW5saW5rTmV4dChjYik7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgdW5saW5rTmV4dChmdW5jdGlvbiAoKTogdm9pZCB7XG4gICAgICAvLyB0cnkgdG8gdW5saW5rIHRoZSBkaXJlY3RvcnksIGJ1dCBpZ25vcmUgZXJyb3JzIGJlY2F1c2UgaXQgY2FuIGZhaWxcbiAgICAgIHN0b3JhZ2UucmVtb3ZlUGFja2FnZShmdW5jdGlvbiAoZXJyKTogdm9pZCB7XG4gICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmUgdGhlIGRpc3QgZmlsZSByZW1haW5zIGFzIHRoZSBzYW1lIHByb3RvY29sXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBoYXNoIG1ldGFkYXRhXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB1cExpbmtLZXkgcmVnaXN0cnkga2V5XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIF91cGRhdGVVcGxpbmtUb1JlbW90ZVByb3RvY29sKGhhc2g6IERpc3RGaWxlLCB1cExpbmtLZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIC8vIGlmIHdlIGdvdCB0aGlzIGluZm9ybWF0aW9uIGZyb20gYSBrbm93biByZWdpc3RyeSxcbiAgICAvLyB1c2UgdGhlIHNhbWUgcHJvdG9jb2wgZm9yIHRoZSB0YXJiYWxsXG4gICAgLy9cbiAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3JsaWR3a2Evc2lub3BpYS9pc3N1ZXMvMTY2XG4gICAgY29uc3QgdGFyYmFsbFVybDogYW55ID0gVXJsTm9kZS5wYXJzZShoYXNoLnVybCk7XG4gICAgY29uc3QgdXBsaW5rVXJsOiBhbnkgPSBVcmxOb2RlLnBhcnNlKHRoaXMuY29uZmlnLnVwbGlua3NbdXBMaW5rS2V5XS51cmwpO1xuXG4gICAgaWYgKHVwbGlua1VybC5ob3N0ID09PSB0YXJiYWxsVXJsLmhvc3QpIHtcbiAgICAgIHRhcmJhbGxVcmwucHJvdG9jb2wgPSB1cGxpbmtVcmwucHJvdG9jb2w7XG4gICAgICBoYXNoLnJlZ2lzdHJ5ID0gdXBMaW5rS2V5O1xuICAgICAgaGFzaC51cmwgPSBVcmxOb2RlLmZvcm1hdCh0YXJiYWxsVXJsKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0U2VjcmV0KGNvbmZpZzogQ29uZmlnKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBzZWNyZXRLZXkgPSBhd2FpdCB0aGlzLnN0b3JhZ2VQbHVnaW4uZ2V0U2VjcmV0KCk7XG5cbiAgICByZXR1cm4gdGhpcy5zdG9yYWdlUGx1Z2luLnNldFNlY3JldChjb25maWcuY2hlY2tTZWNyZXRLZXkoc2VjcmV0S2V5KSk7XG4gIH1cblxuICBwdWJsaWMgc2F2ZVRva2VuKHRva2VuOiBUb2tlbik6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKF8uaXNGdW5jdGlvbih0aGlzLnN0b3JhZ2VQbHVnaW4uc2F2ZVRva2VuKSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgRXJyb3JDb2RlLmdldENvZGUoSFRUUF9TVEFUVVMuU0VSVklDRV9VTkFWQUlMQUJMRSwgU1VQUE9SVF9FUlJPUlMuUExVR0lOX01JU1NJTkdfSU5URVJGQUNFKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdG9yYWdlUGx1Z2luLnNhdmVUb2tlbih0b2tlbik7XG4gIH1cblxuICBwdWJsaWMgZGVsZXRlVG9rZW4odXNlcjogc3RyaW5nLCB0b2tlbktleTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICBpZiAoXy5pc0Z1bmN0aW9uKHRoaXMuc3RvcmFnZVBsdWdpbi5kZWxldGVUb2tlbikgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgIEVycm9yQ29kZS5nZXRDb2RlKEhUVFBfU1RBVFVTLlNFUlZJQ0VfVU5BVkFJTEFCTEUsIFNVUFBPUlRfRVJST1JTLlBMVUdJTl9NSVNTSU5HX0lOVEVSRkFDRSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RvcmFnZVBsdWdpbi5kZWxldGVUb2tlbih1c2VyLCB0b2tlbktleSk7XG4gIH1cblxuICBwdWJsaWMgcmVhZFRva2VucyhmaWx0ZXI6IFRva2VuRmlsdGVyKTogUHJvbWlzZTxUb2tlbltdPiB7XG4gICAgaWYgKF8uaXNGdW5jdGlvbih0aGlzLnN0b3JhZ2VQbHVnaW4ucmVhZFRva2VucykgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgIEVycm9yQ29kZS5nZXRDb2RlKEhUVFBfU1RBVFVTLlNFUlZJQ0VfVU5BVkFJTEFCTEUsIFNVUFBPUlRfRVJST1JTLlBMVUdJTl9NSVNTSU5HX0lOVEVSRkFDRSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RvcmFnZVBsdWdpbi5yZWFkVG9rZW5zKGZpbHRlcik7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTG9jYWxTdG9yYWdlO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSxPQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxNQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRSxPQUFBLEdBQUFILHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRyxJQUFBLEdBQUFKLHNCQUFBLENBQUFDLE9BQUE7QUFFQSxJQUFBSSxRQUFBLEdBQUFKLE9BQUE7QUFnQkEsSUFBQUssTUFBQSxHQUFBTCxPQUFBO0FBU0EsSUFBQU0sVUFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8sYUFBQSxHQUFBUCxPQUFBO0FBUUEsSUFBQVEsT0FBQSxHQUFBUixPQUFBO0FBQTBELFNBQUFELHVCQUFBVSxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRTFELE1BQU1HLEtBQUssR0FBRyxJQUFBQyxjQUFTLEVBQUMseUJBQXlCLENBQUM7QUFFbEQ7QUFDQTtBQUNBO0FBQ0EsTUFBTUMsWUFBWSxDQUFDO0VBS1ZDLFdBQVdBLENBQUNDLE1BQWMsRUFBRUMsTUFBYyxFQUFFQyxZQUEyQixFQUFFO0lBQzlFLElBQUksQ0FBQ0QsTUFBTSxHQUFHQSxNQUFNO0lBQ3BCLElBQUksQ0FBQ0QsTUFBTSxHQUFHQSxNQUFNO0lBQ3BCLElBQUksQ0FBQ0csYUFBYSxHQUFHRCxZQUFZO0VBQ25DO0VBRU9FLFVBQVVBLENBQUNDLElBQVksRUFBRUMsR0FBYSxFQUFFQyxRQUFrQixFQUFRO0lBQ3ZFLE1BQU1DLE9BQVksR0FBRyxJQUFJLENBQUNDLGdCQUFnQixDQUFDSixJQUFJLENBQUM7SUFFaEQsSUFBSUssZUFBQyxDQUFDQyxLQUFLLENBQUNILE9BQU8sQ0FBQyxFQUFFO01BQ3BCLE9BQU9ELFFBQVEsQ0FBQ0ssaUJBQVMsQ0FBQ0MsV0FBVyxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFDeEU7SUFFQUwsT0FBTyxDQUFDTSxhQUFhLENBQUNULElBQUksRUFBRSxJQUFBVSxxQ0FBdUIsRUFBQ1YsSUFBSSxDQUFDLEVBQUdXLEdBQUcsSUFBSztNQUNsRTtNQUNBO01BQ0EsSUFDRU4sZUFBQyxDQUFDTyxNQUFNLENBQUNELEdBQUcsQ0FBQyxLQUFLLEtBQUssS0FDdEJBLEdBQUcsQ0FBQ0UsSUFBSSxLQUFLQyxrQkFBTyxDQUFDQyxnQkFBZ0IsSUFBSUosR0FBRyxDQUFDRSxJQUFJLEtBQUtHLHNCQUFXLENBQUNDLFFBQVEsQ0FBQyxFQUM1RTtRQUNBLE9BQU9mLFFBQVEsQ0FBQ0ssaUJBQVMsQ0FBQ1csV0FBVyxDQUFDLENBQUMsQ0FBQztNQUMxQztNQUVBLE1BQU1DLE1BQU0sR0FBRyxJQUFBQyx1QkFBZ0IsRUFBQ25CLEdBQUcsQ0FBQztNQUNwQyxJQUFJSSxlQUFDLENBQUNDLEtBQUssQ0FBQ2EsTUFBTSxDQUFDLEtBQUssS0FBSyxJQUFJbEIsR0FBRyxDQUFDb0IsUUFBUSxDQUFDRixNQUFNLENBQUMsRUFBRTtRQUNyRCxPQUFPakIsUUFBUSxDQUFDLElBQUksRUFBRUQsR0FBRyxDQUFDb0IsUUFBUSxDQUFDRixNQUFNLENBQUMsQ0FBQztNQUM3QztNQUVBLE9BQU9qQixRQUFRLENBQUMsQ0FBQztJQUNuQixDQUFDLENBQUM7RUFDSjs7RUFFQTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDU29CLGFBQWFBLENBQUN0QixJQUFZLEVBQUVFLFFBQWtCLEVBQVE7SUFDM0QsTUFBTUMsT0FBWSxHQUFHLElBQUksQ0FBQ0MsZ0JBQWdCLENBQUNKLElBQUksQ0FBQztJQUNoRFQsS0FBSyxDQUFDLCtCQUErQixFQUFFUyxJQUFJLENBQUM7SUFDNUMsSUFBSUssZUFBQyxDQUFDQyxLQUFLLENBQUNILE9BQU8sQ0FBQyxFQUFFO01BQ3BCLE9BQU9ELFFBQVEsQ0FBQ0ssaUJBQVMsQ0FBQ0MsV0FBVyxDQUFDLENBQUMsQ0FBQztJQUMxQztJQUVBTCxPQUFPLENBQUNvQixXQUFXLENBQUN2QixJQUFJLEVBQUUsQ0FBQ1csR0FBRyxFQUFFYSxJQUFjLEtBQVc7TUFDdkQsSUFBSW5CLGVBQUMsQ0FBQ0MsS0FBSyxDQUFDSyxHQUFHLENBQUMsS0FBSyxLQUFLLEVBQUU7UUFDMUIsSUFBSUEsR0FBRyxDQUFDRSxJQUFJLEtBQUtDLGtCQUFPLENBQUNXLGtCQUFrQixJQUFJZCxHQUFHLENBQUNFLElBQUksS0FBS0csc0JBQVcsQ0FBQ1UsU0FBUyxFQUFFO1VBQ2pGLE9BQU94QixRQUFRLENBQUNLLGlCQUFTLENBQUNDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDMUM7UUFDQSxPQUFPTixRQUFRLENBQUNTLEdBQUcsQ0FBQztNQUN0QjtNQUVBYSxJQUFJLEdBQUcsSUFBQUcsOEJBQWdCLEVBQUNILElBQUksQ0FBQztNQUM3QixJQUFJLENBQUMxQixhQUFhLENBQUM4QixNQUFNLENBQUM1QixJQUFJLEVBQUc2QixZQUFtQixJQUFXO1FBQzdELElBQUlBLFlBQVksRUFBRTtVQUNoQjtVQUNBLElBQUksQ0FBQ2pDLE1BQU0sQ0FBQ2tDLEtBQUssQ0FDZjtZQUFFOUI7VUFBSyxDQUFDLEVBQ1IsZ0ZBQ0YsQ0FBQztVQUNELE9BQU9FLFFBQVEsQ0FBQ0ssaUJBQVMsQ0FBQ3dCLFVBQVUsQ0FBQ0YsWUFBWSxDQUFDRyxPQUFPLENBQUMsQ0FBQztRQUM3RDtRQUVBN0IsT0FBTyxDQUFDOEIsYUFBYSxDQUFDbkIsa0JBQU8sQ0FBQ29CLGlCQUFpQixFQUFHdkIsR0FBRyxJQUFXO1VBQzlELElBQUlBLEdBQUcsRUFBRTtZQUNQLE9BQU9ULFFBQVEsQ0FBQ1MsR0FBRyxDQUFDO1VBQ3RCO1VBQ0EsTUFBTXdCLFdBQVcsR0FBR0MsTUFBTSxDQUFDQyxJQUFJLENBQUNiLElBQUksQ0FBQ2MsWUFBWSxDQUFDO1VBRWxELElBQUksQ0FBQ0Msa0JBQWtCLENBQUNwQyxPQUFPLEVBQUVnQyxXQUFXLEVBQUVqQyxRQUFRLENBQUM7UUFDekQsQ0FBQyxDQUFDO01BQ0osQ0FBQyxDQUFDO0lBQ0osQ0FBQyxDQUFDO0VBQ0o7O0VBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ1NzQyxjQUFjQSxDQUFDeEMsSUFBWSxFQUFFeUMsV0FBcUIsRUFBRXZDLFFBQWtCLEVBQVE7SUFDbkYsSUFBSSxDQUFDd0Msa0JBQWtCLENBQUMxQyxJQUFJLEVBQUUsQ0FBQ1csR0FBRyxFQUFFZ0MsZ0JBQWdCLEtBQVc7TUFDN0QsSUFBSWhDLEdBQUcsRUFBRTtRQUNQLE9BQU9ULFFBQVEsQ0FBQ1MsR0FBRyxDQUFDO01BQ3RCO01BRUEsSUFBSWlDLE1BQU0sR0FBRyxLQUFLO01BQ2xCO01BQ0FELGdCQUFnQixDQUFDRSxNQUFNLEdBQUcsSUFBQUMsNkJBQWUsRUFBQ0wsV0FBVyxDQUFDO01BQ3RELElBQUlBLFdBQVcsQ0FBQ0ksTUFBTSxLQUFLRixnQkFBZ0IsQ0FBQ0UsTUFBTSxFQUFFO1FBQ2xERCxNQUFNLEdBQUcsSUFBSTtNQUNmO01BQ0EsS0FBSyxNQUFNRyxTQUFTLElBQUlOLFdBQVcsQ0FBQ3BCLFFBQVEsRUFBRTtRQUM1QyxJQUFJaEIsZUFBQyxDQUFDQyxLQUFLLENBQUNxQyxnQkFBZ0IsQ0FBQ3RCLFFBQVEsQ0FBQzBCLFNBQVMsQ0FBQyxDQUFDLEVBQUU7VUFDakQsSUFBSUMsT0FBTyxHQUFHUCxXQUFXLENBQUNwQixRQUFRLENBQUMwQixTQUFTLENBQUM7O1VBRTdDO1VBQ0E7VUFDQUMsT0FBTyxHQUFHLElBQUFDLDJCQUFhLEVBQUNELE9BQU8sQ0FBQztVQUNoQ0EsT0FBTyxDQUFDRSxZQUFZLEdBQUcsSUFBQUMsNEJBQXFCLEVBQUNILE9BQU8sQ0FBQ0UsWUFBd0IsQ0FBQztVQUU5RU4sTUFBTSxHQUFHLElBQUk7VUFDYkQsZ0JBQWdCLENBQUN0QixRQUFRLENBQUMwQixTQUFTLENBQUMsR0FBR0MsT0FBTztVQUU5QyxJQUFJQSxPQUFPLENBQUNJLElBQUksSUFBSUosT0FBTyxDQUFDSSxJQUFJLENBQUNDLE9BQU8sRUFBRTtZQUN4QyxNQUFNQyxTQUFjLEdBQUdDLFlBQU8sQ0FBQ0MsS0FBSyxDQUFDUixPQUFPLENBQUNJLElBQUksQ0FBQ0MsT0FBTyxDQUFDO1lBQzFELE1BQU1JLFFBQVEsR0FBR0gsU0FBUyxDQUFDSSxRQUFRLENBQUNDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDOztZQUV4RDtZQUNBLElBQUl0RCxlQUFDLENBQUNDLEtBQUssQ0FBQ3FDLGdCQUFnQixDQUFDaUIsVUFBVSxDQUFDSCxRQUFRLENBQUMsQ0FBQyxFQUFFO2NBQ2xELE1BQU1JLElBQWMsR0FBSWxCLGdCQUFnQixDQUFDaUIsVUFBVSxDQUFDSCxRQUFRLENBQUMsR0FBRztnQkFDOURLLEdBQUcsRUFBRWQsT0FBTyxDQUFDSSxJQUFJLENBQUNDLE9BQU87Z0JBQ3pCVSxHQUFHLEVBQUVmLE9BQU8sQ0FBQ0ksSUFBSSxDQUFDWTtjQUNwQixDQUFFO2NBQ0Y7Y0FDQSxNQUFNQyxNQUFjLEdBQUdqQixPQUFPLENBQUNrQixNQUFNLENBQUNDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO2NBRWhFLElBQUk5RCxlQUFDLENBQUNDLEtBQUssQ0FBQzJELE1BQU0sQ0FBQyxLQUFLLEtBQUssRUFBRTtnQkFDN0IsSUFBSSxDQUFDRyw2QkFBNkIsQ0FBQ1AsSUFBSSxFQUFFSSxNQUFNLENBQUM7Y0FDbEQ7WUFDRjtVQUNGO1FBQ0Y7TUFDRjtNQUVBLEtBQUssTUFBTUksR0FBRyxJQUFJNUIsV0FBVyxDQUFDNkIsb0JBQVMsQ0FBQyxFQUFFO1FBQ3hDLElBQ0UsQ0FBQzNCLGdCQUFnQixDQUFDMkIsb0JBQVMsQ0FBQyxDQUFDRCxHQUFHLENBQUMsSUFDakMxQixnQkFBZ0IsQ0FBQzJCLG9CQUFTLENBQUMsQ0FBQ0QsR0FBRyxDQUFDLEtBQUs1QixXQUFXLENBQUM2QixvQkFBUyxDQUFDLENBQUNELEdBQUcsQ0FBQyxFQUNoRTtVQUNBekIsTUFBTSxHQUFHLElBQUk7VUFDYkQsZ0JBQWdCLENBQUMyQixvQkFBUyxDQUFDLENBQUNELEdBQUcsQ0FBQyxHQUFHNUIsV0FBVyxDQUFDNkIsb0JBQVMsQ0FBQyxDQUFDRCxHQUFHLENBQUM7UUFDaEU7TUFDRjtNQUVBLEtBQUssTUFBTUUsRUFBRSxJQUFJOUIsV0FBVyxDQUFDK0IsUUFBUSxFQUFFO1FBQ3JDLElBQUlwQyxNQUFNLENBQUNxQyxTQUFTLENBQUNDLGNBQWMsQ0FBQ0MsSUFBSSxDQUFDbEMsV0FBVyxDQUFDK0IsUUFBUSxFQUFFRCxFQUFFLENBQUMsRUFBRTtVQUNsRSxNQUFNSyxXQUFXLEdBQ2YsQ0FBQyxJQUFBQyxnQkFBUSxFQUFDbEMsZ0JBQWdCLENBQUM2QixRQUFRLENBQUNELEVBQUUsQ0FBQyxDQUFDLElBQ3hDOUIsV0FBVyxDQUFDK0IsUUFBUSxDQUFDRCxFQUFFLENBQUMsQ0FBQ08sSUFBSSxLQUFLbkMsZ0JBQWdCLENBQUM2QixRQUFRLENBQUNELEVBQUUsQ0FBQyxDQUFDTyxJQUFJLElBQ3BFckMsV0FBVyxDQUFDK0IsUUFBUSxDQUFDRCxFQUFFLENBQUMsQ0FBQ1EsT0FBTyxLQUFLcEMsZ0JBQWdCLENBQUM2QixRQUFRLENBQUNELEVBQUUsQ0FBQyxDQUFDUSxPQUFPO1VBRTVFLElBQUlILFdBQVcsRUFBRTtZQUNmaEMsTUFBTSxHQUFHLElBQUk7WUFDYkQsZ0JBQWdCLENBQUM2QixRQUFRLENBQUNELEVBQUUsQ0FBQyxHQUFHOUIsV0FBVyxDQUFDK0IsUUFBUSxDQUFDRCxFQUFFLENBQUM7VUFDMUQ7UUFDRjtNQUNGO01BRUEsSUFBSSxNQUFNLElBQUk5QixXQUFXLElBQUksQ0FBQ3BDLGVBQUMsQ0FBQzJFLE9BQU8sQ0FBQ3JDLGdCQUFnQixDQUFDc0MsSUFBSSxFQUFFeEMsV0FBVyxDQUFDd0MsSUFBSSxDQUFDLEVBQUU7UUFDaEZ0QyxnQkFBZ0IsQ0FBQ3NDLElBQUksR0FBR3hDLFdBQVcsQ0FBQ3dDLElBQUk7UUFDeENyQyxNQUFNLEdBQUcsSUFBSTtNQUNmO01BRUEsSUFBSUEsTUFBTSxFQUFFO1FBQ1ZyRCxLQUFLLENBQUMsMEJBQTBCLEVBQUVTLElBQUksQ0FBQztRQUN2QyxJQUFJLENBQUNrRixhQUFhLENBQUNsRixJQUFJLEVBQUUyQyxnQkFBZ0IsRUFBRSxVQUFVaEMsR0FBRyxFQUFRO1VBQzlEVCxRQUFRLENBQUNTLEdBQUcsRUFBRWdDLGdCQUFnQixDQUFDO1FBQ2pDLENBQUMsQ0FBQztNQUNKLENBQUMsTUFBTTtRQUNMekMsUUFBUSxDQUFDLElBQUksRUFBRXlDLGdCQUFnQixDQUFDO01BQ2xDO0lBQ0YsQ0FBQyxDQUFDO0VBQ0o7O0VBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNTd0MsVUFBVUEsQ0FDZm5GLElBQVksRUFDWmdELE9BQWUsRUFDZm9DLFFBQWlCLEVBQ2pCZixHQUFnQixFQUNoQm5FLFFBQWtCLEVBQ1o7SUFDTixJQUFJLENBQUNtRixjQUFjLENBQ2pCckYsSUFBSSxFQUNKLENBQUN3QixJQUFJLEVBQUU4RCxFQUFZLEtBQVc7TUFDNUI7TUFDQTlELElBQUksQ0FBQ3FCLE1BQU0sR0FBR3VDLFFBQVEsQ0FBQ3ZDLE1BQU07O01BRTdCO01BQ0F1QyxRQUFRLEdBQUcsSUFBQW5DLDJCQUFhLEVBQUNtQyxRQUFRLENBQUM7TUFDbENBLFFBQVEsQ0FBQ2xDLFlBQVksR0FBRyxJQUFBQyw0QkFBcUIsRUFBQ2lDLFFBQVEsQ0FBQ2xDLFlBQXdCLENBQUM7TUFFaEYsTUFBTXFDLFVBQVUsR0FBRy9ELElBQUksQ0FBQ0gsUUFBUSxDQUFDMkIsT0FBTyxDQUFDLElBQUksSUFBSTtNQUNqRCxJQUFJdUMsVUFBVSxFQUFFO1FBQ2QsT0FBT0QsRUFBRSxDQUFDL0UsaUJBQVMsQ0FBQ1csV0FBVyxDQUFDLENBQUMsQ0FBQztNQUNwQzs7TUFFQTtNQUNBLElBQUksSUFBQTJELGdCQUFRLEVBQUNPLFFBQVEsQ0FBQ2hDLElBQUksQ0FBQyxJQUFJL0MsZUFBQyxDQUFDbUYsUUFBUSxDQUFDSixRQUFRLENBQUNoQyxJQUFJLENBQUNDLE9BQU8sQ0FBQyxFQUFFO1FBQ2hFLE1BQU1BLE9BQU8sR0FBRytCLFFBQVEsQ0FBQ2hDLElBQUksQ0FBQ0MsT0FBTyxDQUFDTSxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztRQUV6RCxJQUFJLElBQUFrQixnQkFBUSxFQUFDckQsSUFBSSxDQUFDYyxZQUFZLENBQUNlLE9BQU8sQ0FBQyxDQUFDLEVBQUU7VUFDeEMsSUFDRWhELGVBQUMsQ0FBQ0MsS0FBSyxDQUFDa0IsSUFBSSxDQUFDYyxZQUFZLENBQUNlLE9BQU8sQ0FBQyxDQUFDVyxNQUFNLENBQUMsS0FBSyxLQUFLLElBQ3BEM0QsZUFBQyxDQUFDQyxLQUFLLENBQUM4RSxRQUFRLENBQUNoQyxJQUFJLENBQUNZLE1BQU0sQ0FBQyxLQUFLLEtBQUssRUFDdkM7WUFDQSxJQUFJeEMsSUFBSSxDQUFDYyxZQUFZLENBQUNlLE9BQU8sQ0FBQyxDQUFDVyxNQUFNLElBQUlvQixRQUFRLENBQUNoQyxJQUFJLENBQUNZLE1BQU0sRUFBRTtjQUM3RCxNQUFNeUIsWUFBWSxHQUFHLGlCQUFpQmpFLElBQUksQ0FBQ2MsWUFBWSxDQUFDZSxPQUFPLENBQUMsQ0FBQ1csTUFBTSxPQUFPb0IsUUFBUSxDQUFDaEMsSUFBSSxDQUFDWSxNQUFNLEVBQUU7Y0FDcEcsT0FBT3NCLEVBQUUsQ0FBQy9FLGlCQUFTLENBQUNtRixhQUFhLENBQUNELFlBQVksQ0FBQyxDQUFDO1lBQ2xEO1VBQ0Y7VUFFQSxNQUFNRSxXQUFXLEdBQUcsSUFBSUMsSUFBSSxDQUFDLENBQUMsQ0FBQ0MsV0FBVyxDQUFDLENBQUM7O1VBRTVDO1VBQ0EsSUFBSXhGLGVBQUMsQ0FBQ0MsS0FBSyxDQUFDa0IsSUFBSSxDQUFDeUQsSUFBSSxDQUFDLEVBQUU7WUFDdEJ6RCxJQUFJLENBQUN5RCxJQUFJLEdBQUcsQ0FBQyxDQUFDO1VBQ2hCO1VBRUF6RCxJQUFJLENBQUN5RCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUdVLFdBQVc7VUFFbkMsSUFBSSxTQUFTLElBQUluRSxJQUFJLENBQUN5RCxJQUFJLEtBQUssS0FBSyxFQUFFO1lBQ3BDekQsSUFBSSxDQUFDeUQsSUFBSSxDQUFDYSxPQUFPLEdBQUdILFdBQVc7VUFDakM7VUFFQW5FLElBQUksQ0FBQ3lELElBQUksQ0FBQ2pDLE9BQU8sQ0FBQyxHQUFHMkMsV0FBVztVQUNoQ25FLElBQUksQ0FBQ2MsWUFBWSxDQUFDZSxPQUFPLENBQUMsQ0FBQ0wsT0FBTyxHQUFHQSxPQUFPO1FBQzlDO01BQ0Y7TUFFQXhCLElBQUksQ0FBQ0gsUUFBUSxDQUFDMkIsT0FBTyxDQUFDLEdBQUdvQyxRQUFRO01BQ2pDLElBQUFXLGtCQUFVLEVBQUN2RSxJQUFJLEVBQUV3QixPQUFPLEVBQUVxQixHQUFHLENBQUM7TUFFOUIsSUFBSSxDQUFDdkUsYUFBYSxDQUFDa0csR0FBRyxDQUFDaEcsSUFBSSxFQUFHaUcsU0FBUyxJQUFXO1FBQ2hELElBQUlBLFNBQVMsRUFBRTtVQUNiLE9BQU9YLEVBQUUsQ0FBQy9FLGlCQUFTLENBQUN3QixVQUFVLENBQUNrRSxTQUFTLENBQUNqRSxPQUFPLENBQUMsQ0FBQztRQUNwRDtRQUVBc0QsRUFBRSxDQUFDLENBQUM7TUFDTixDQUFDLENBQUM7SUFDSixDQUFDLEVBQ0RwRixRQUNGLENBQUM7RUFDSDs7RUFFQTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDU2dHLFNBQVNBLENBQUNDLE9BQWUsRUFBRUMsSUFBZSxFQUFFbEcsUUFBa0IsRUFBUTtJQUMzRSxJQUFJLENBQUNtRixjQUFjLENBQ2pCYyxPQUFPLEVBQ1AsQ0FBQzNFLElBQUksRUFBRThELEVBQUUsS0FBVztNQUNsQjtNQUNBLEtBQUssTUFBTWpCLEdBQUcsSUFBSStCLElBQUksRUFBRTtRQUN0QjtRQUNBLElBQUkvRixlQUFDLENBQUNPLE1BQU0sQ0FBQ3dGLElBQUksQ0FBQy9CLEdBQUcsQ0FBQyxDQUFDLEVBQUU7VUFDdkIsT0FBTzdDLElBQUksQ0FBQzhDLG9CQUFTLENBQUMsQ0FBQ0QsR0FBRyxDQUFDO1VBQzNCO1FBQ0Y7UUFFQSxJQUFJaEUsZUFBQyxDQUFDQyxLQUFLLENBQUNrQixJQUFJLENBQUNILFFBQVEsQ0FBQytFLElBQUksQ0FBQy9CLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtVQUNyQyxPQUFPaUIsRUFBRSxDQUFDLElBQUksQ0FBQ2UsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDO1FBQ0EsTUFBTXJELE9BQWUsR0FBR29ELElBQUksQ0FBQy9CLEdBQUcsQ0FBQztRQUNqQyxJQUFBMEIsa0JBQVUsRUFBQ3ZFLElBQUksRUFBRXdCLE9BQU8sRUFBRXFCLEdBQUcsQ0FBQztNQUNoQztNQUNBaUIsRUFBRSxDQUFDLElBQUksQ0FBQztJQUNWLENBQUMsRUFDRHBGLFFBQ0YsQ0FBQztFQUNIOztFQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7RUFDVW1HLG1CQUFtQkEsQ0FBQSxFQUFRO0lBQ2pDLE9BQU85RixpQkFBUyxDQUFDQyxXQUFXLENBQUM4RixvQkFBUyxDQUFDQyxpQkFBaUIsQ0FBQztFQUMzRDs7RUFFQTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0VBQ1VDLG9CQUFvQkEsQ0FBQSxFQUFRO0lBQ2xDLE9BQU9qRyxpQkFBUyxDQUFDQyxXQUFXLENBQUMsd0JBQXdCLENBQUM7RUFDeEQ7O0VBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ1NpRyxhQUFhQSxDQUNsQnpHLElBQVksRUFDWjBHLFdBQXFCLEVBQ3JCQyxRQUF1QixFQUN2QnpHLFFBQWtCLEVBQ1o7SUFDTixJQUFJLENBQUMsSUFBQTJFLGdCQUFRLEVBQUM2QixXQUFXLENBQUNyRixRQUFRLENBQUMsSUFBSSxDQUFDLElBQUF3RCxnQkFBUSxFQUFDNkIsV0FBVyxDQUFDcEMsb0JBQVMsQ0FBQyxDQUFDLEVBQUU7TUFDeEUsSUFBSSxDQUFDMUUsTUFBTSxDQUFDa0MsS0FBSyxDQUFDO1FBQUU5QjtNQUFLLENBQUMsRUFBRSxvQ0FBb0MsQ0FBQztNQUNqRSxPQUFPRSxRQUFRLENBQUNLLGlCQUFTLENBQUN3QixVQUFVLENBQUMsQ0FBQyxDQUFDO0lBQ3pDO0lBQ0F4QyxLQUFLLENBQUMsdUNBQXVDLEVBQUVTLElBQUksQ0FBQztJQUNwRCxJQUFJLENBQUNxRixjQUFjLENBQ2pCckYsSUFBSSxFQUNKLENBQUM0RyxTQUFtQixFQUFFdEIsRUFBWSxLQUFXO01BQzNDLEtBQUssTUFBTXRDLE9BQU8sSUFBSTRELFNBQVMsQ0FBQ3ZGLFFBQVEsRUFBRTtRQUN4QyxNQUFNd0YsZUFBZSxHQUFHSCxXQUFXLENBQUNyRixRQUFRLENBQUMyQixPQUFPLENBQUM7UUFDckQsSUFBSTNDLGVBQUMsQ0FBQ0MsS0FBSyxDQUFDdUcsZUFBZSxDQUFDLEVBQUU7VUFDNUIsSUFBSSxDQUFDakgsTUFBTSxDQUFDa0gsSUFBSSxDQUFDO1lBQUU5RyxJQUFJLEVBQUVBLElBQUk7WUFBRWdELE9BQU8sRUFBRUE7VUFBUSxDQUFDLEVBQUUsaUNBQWlDLENBQUM7O1VBRXJGO1VBQ0EsT0FBTzRELFNBQVMsQ0FBQ3ZGLFFBQVEsQ0FBQzJCLE9BQU8sQ0FBQztVQUNsQyxPQUFPNEQsU0FBUyxDQUFDM0IsSUFBSSxDQUFFakMsT0FBTyxDQUFDO1VBRS9CLEtBQUssTUFBTStELElBQUksSUFBSUgsU0FBUyxDQUFDdEUsWUFBWSxFQUFFO1lBQ3pDLElBQUlzRSxTQUFTLENBQUN0RSxZQUFZLENBQUN5RSxJQUFJLENBQUMsQ0FBQy9ELE9BQU8sS0FBS0EsT0FBTyxFQUFFO2NBQ3BELE9BQU80RCxTQUFTLENBQUN0RSxZQUFZLENBQUN5RSxJQUFJLENBQUMsQ0FBQy9ELE9BQU87WUFDN0M7VUFDRjtRQUNGLENBQUMsTUFBTSxJQUFJWixNQUFNLENBQUNxQyxTQUFTLENBQUNDLGNBQWMsQ0FBQ0MsSUFBSSxDQUFDa0MsZUFBZSxFQUFFLFlBQVksQ0FBQyxFQUFFO1VBQzlFLE1BQU1HLGtCQUFrQixHQUFHSCxlQUFlLENBQUNJLFVBQVU7VUFDckQsSUFBSUQsa0JBQWtCLElBQUlKLFNBQVMsQ0FBQ3ZGLFFBQVEsQ0FBQzJCLE9BQU8sQ0FBQyxDQUFDaUUsVUFBVSxFQUFFO1lBQ2hFLElBQUksQ0FBQ0Qsa0JBQWtCLEVBQUU7Y0FDdkIsSUFBSSxDQUFDcEgsTUFBTSxDQUFDa0gsSUFBSSxDQUNkO2dCQUFFOUcsSUFBSSxFQUFFQSxJQUFJO2dCQUFFZ0QsT0FBTyxFQUFFQTtjQUFRLENBQUMsRUFDaEMsa0NBQ0YsQ0FBQztjQUNELE9BQU80RCxTQUFTLENBQUN2RixRQUFRLENBQUMyQixPQUFPLENBQUMsQ0FBQ2lFLFVBQVU7WUFDL0MsQ0FBQyxNQUFNO2NBQ0wsSUFBSSxDQUFDckgsTUFBTSxDQUFDa0gsSUFBSSxDQUNkO2dCQUFFOUcsSUFBSSxFQUFFQSxJQUFJO2dCQUFFZ0QsT0FBTyxFQUFFQTtjQUFRLENBQUMsRUFDaEMsZ0NBQ0YsQ0FBQztjQUNENEQsU0FBUyxDQUFDdkYsUUFBUSxDQUFDMkIsT0FBTyxDQUFDLENBQUNpRSxVQUFVLEdBQUdELGtCQUFrQjtZQUM3RDtZQUNBSixTQUFTLENBQUMzQixJQUFJLENBQUVpQyxRQUFRLEdBQUcsSUFBSXRCLElBQUksQ0FBQyxDQUFDLENBQUNDLFdBQVcsQ0FBQyxDQUFDO1VBQ3JEO1FBQ0Y7TUFDRjtNQUVBZSxTQUFTLENBQUNPLGdCQUFLLENBQUMsR0FBR1QsV0FBVyxDQUFDUyxnQkFBSyxDQUFDO01BQ3JDUCxTQUFTLENBQUN0QyxvQkFBUyxDQUFDLEdBQUdvQyxXQUFXLENBQUNwQyxvQkFBUyxDQUFDO01BQzdDZ0IsRUFBRSxDQUFDLElBQUksQ0FBQztJQUNWLENBQUMsRUFDRCxVQUFVM0UsR0FBRyxFQUFRO01BQ25CLElBQUlBLEdBQUcsRUFBRTtRQUNQLE9BQU9ULFFBQVEsQ0FBQ1MsR0FBRyxDQUFDO01BQ3RCO01BQ0FULFFBQVEsQ0FBQyxDQUFDO0lBQ1osQ0FDRixDQUFDO0VBQ0g7RUFDQTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNTa0gsYUFBYUEsQ0FBQ3BILElBQVksRUFBRXlELFFBQWdCLEVBQUVrRCxRQUFnQixFQUFFekcsUUFBa0IsRUFBUTtJQUMvRixJQUFBbUgsZUFBTSxFQUFDLElBQUFDLG1CQUFZLEVBQUM3RCxRQUFRLENBQUMsQ0FBQztJQUU5QixJQUFJLENBQUM0QixjQUFjLENBQ2pCckYsSUFBSSxFQUNKLENBQUN3QixJQUFJLEVBQUU4RCxFQUFFLEtBQVc7TUFDbEIsSUFBSTlELElBQUksQ0FBQ2MsWUFBWSxDQUFDbUIsUUFBUSxDQUFDLEVBQUU7UUFDL0IsT0FBT2pDLElBQUksQ0FBQ2MsWUFBWSxDQUFDbUIsUUFBUSxDQUFDO1FBQ2xDNkIsRUFBRSxDQUFDLElBQUksQ0FBQztNQUNWLENBQUMsTUFBTTtRQUNMQSxFQUFFLENBQUMsSUFBSSxDQUFDa0Isb0JBQW9CLENBQUMsQ0FBQyxDQUFDO01BQ2pDO0lBQ0YsQ0FBQyxFQUNBN0YsR0FBUSxJQUFXO01BQ2xCLElBQUlBLEdBQUcsRUFBRTtRQUNQLE9BQU9ULFFBQVEsQ0FBQ1MsR0FBRyxDQUFDO01BQ3RCO01BQ0EsTUFBTVIsT0FBTyxHQUFHLElBQUksQ0FBQ0MsZ0JBQWdCLENBQUNKLElBQUksQ0FBQztNQUUzQyxJQUFJRyxPQUFPLEVBQUU7UUFDWEEsT0FBTyxDQUFDOEIsYUFBYSxDQUFDd0IsUUFBUSxFQUFFdkQsUUFBUSxDQUFDO01BQzNDO0lBQ0YsQ0FDRixDQUFDO0VBQ0g7O0VBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ1NxSCxVQUFVQSxDQUFDdkgsSUFBWSxFQUFFeUQsUUFBZ0IsRUFBRTtJQUNoRCxJQUFBNEQsZUFBTSxFQUFDLElBQUFDLG1CQUFZLEVBQUM3RCxRQUFRLENBQUMsQ0FBQztJQUU5QixJQUFJK0QsTUFBTSxHQUFHLENBQUM7SUFDZCxNQUFNQyxVQUFVLEdBQUcsSUFBQUMsd0JBQWlCLEVBQUMsQ0FBQztJQUN0QyxNQUFNQyxZQUFZLEdBQUcsSUFBSUMsc0JBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxQyxNQUFNQyxVQUFVLEdBQUdGLFlBQVksQ0FBQ0UsVUFBVTtJQUMxQyxNQUFNMUgsT0FBTyxHQUFHLElBQUksQ0FBQ0MsZ0JBQWdCLENBQUNKLElBQUksQ0FBQztJQUUzQzJILFlBQVksQ0FBQ0csS0FBSyxHQUFHLFlBQWtCLENBQUMsQ0FBQztJQUN6Q0gsWUFBWSxDQUFDSSxJQUFJLEdBQUcsWUFBa0IsQ0FBQyxDQUFDO0lBRXhDSixZQUFZLENBQUNFLFVBQVUsR0FBRyxVQUFVckcsSUFBSSxFQUFFLEdBQUd3RyxJQUFJLEVBQVE7TUFDdkRQLFVBQVUsQ0FBQ1EsTUFBTSxDQUFDekcsSUFBSSxDQUFDO01BQ3ZCO01BQ0FnRyxNQUFNLElBQUloRyxJQUFJLENBQUNnRyxNQUFNO01BQ3JCLE1BQU1VLFdBQVcsR0FBRyxDQUFDMUcsSUFBSSxFQUFFLEdBQUd3RyxJQUFJLENBQUM7TUFDbkM7TUFDQTtNQUNBSCxVQUFVLENBQUNNLEtBQUssQ0FBQ1IsWUFBWSxFQUFFTyxXQUFXLENBQUM7SUFDN0MsQ0FBQztJQUVELElBQUlsSSxJQUFJLEtBQUssV0FBVyxFQUFFO01BQ3hCb0ksT0FBTyxDQUFDQyxRQUFRLENBQUMsTUFBWTtRQUMzQlYsWUFBWSxDQUFDVyxJQUFJLENBQUMsT0FBTyxFQUFFL0gsaUJBQVMsQ0FBQ2dJLFlBQVksQ0FBQyxDQUFDLENBQUM7TUFDdEQsQ0FBQyxDQUFDO01BQ0YsT0FBT1osWUFBWTtJQUNyQjtJQUVBLElBQUksQ0FBQ3hILE9BQU8sRUFBRTtNQUNaaUksT0FBTyxDQUFDQyxRQUFRLENBQUMsTUFBWTtRQUMzQlYsWUFBWSxDQUFDVyxJQUFJLENBQUMsT0FBTyxFQUFFLDJCQUEyQixDQUFDO01BQ3pELENBQUMsQ0FBQztNQUNGLE9BQU9YLFlBQVk7SUFDckI7SUFFQSxNQUFNYSxXQUFXLEdBQUdySSxPQUFPLENBQUNzSSxZQUFZLENBQUNoRixRQUFRLENBQUM7SUFFbEQrRSxXQUFXLENBQUNFLEVBQUUsQ0FBQyxPQUFPLEVBQUcvSCxHQUFHLElBQUs7TUFDL0IsSUFBSUEsR0FBRyxDQUFDRSxJQUFJLEtBQUtDLGtCQUFPLENBQUNDLGdCQUFnQixJQUFJSixHQUFHLENBQUNFLElBQUksS0FBS0csc0JBQVcsQ0FBQ0MsUUFBUSxFQUFFO1FBQzlFMEcsWUFBWSxDQUFDVyxJQUFJLENBQUMsT0FBTyxFQUFFL0gsaUJBQVMsQ0FBQ1csV0FBVyxDQUFDLENBQUMsQ0FBQztRQUNuRHlHLFlBQVksQ0FBQ0csS0FBSyxDQUFDLENBQUM7TUFDdEIsQ0FBQyxNQUFNLElBQUluSCxHQUFHLENBQUNFLElBQUksS0FBS0Msa0JBQU8sQ0FBQ1csa0JBQWtCLElBQUlkLEdBQUcsQ0FBQ0UsSUFBSSxLQUFLRyxzQkFBVyxDQUFDVSxTQUFTLEVBQUU7UUFDeEY7UUFDQSxJQUFJLENBQUNpSCxrQkFBa0IsQ0FBQzNJLElBQUksRUFBRSxVQUFVNEksSUFBUyxFQUFRO1VBQ3ZELElBQUlBLElBQUksRUFBRTtZQUNSakIsWUFBWSxDQUFDVyxJQUFJLENBQUMsT0FBTyxFQUFFTSxJQUFJLENBQUM7VUFDbEMsQ0FBQyxNQUFNO1lBQ0xqQixZQUFZLENBQUNXLElBQUksQ0FBQyxPQUFPLEVBQUUzSCxHQUFHLENBQUM7VUFDakM7UUFDRixDQUFDLENBQUM7TUFDSixDQUFDLE1BQU07UUFDTGdILFlBQVksQ0FBQ1csSUFBSSxDQUFDLE9BQU8sRUFBRTNILEdBQUcsQ0FBQztNQUNqQztJQUNGLENBQUMsQ0FBQztJQUVGNkgsV0FBVyxDQUFDRSxFQUFFLENBQUMsTUFBTSxFQUFFLFlBQWtCO01BQ3ZDO01BQ0FmLFlBQVksQ0FBQ1csSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUMzQixDQUFDLENBQUM7SUFFRkUsV0FBVyxDQUFDRSxFQUFFLENBQUMsU0FBUyxFQUFFLE1BQVk7TUFDcEMsSUFBSSxDQUFDckQsY0FBYyxDQUNqQnJGLElBQUksRUFDSixTQUFTNkksT0FBT0EsQ0FBQ3JILElBQUksRUFBRThELEVBQUUsRUFBUTtRQUMvQjlELElBQUksQ0FBQ2MsWUFBWSxDQUFDbUIsUUFBUSxDQUFDLEdBQUc7VUFDNUJPLE1BQU0sRUFBRXlELFVBQVUsQ0FBQ3FCLE1BQU0sQ0FBQyxLQUFLO1FBQ2pDLENBQUM7UUFDRHhELEVBQUUsQ0FBQyxJQUFJLENBQUM7TUFDVixDQUFDLEVBQ0QsVUFBVTNFLEdBQUcsRUFBUTtRQUNuQixJQUFJQSxHQUFHLEVBQUU7VUFDUGdILFlBQVksQ0FBQ1csSUFBSSxDQUFDLE9BQU8sRUFBRTNILEdBQUcsQ0FBQztRQUNqQyxDQUFDLE1BQU07VUFDTGdILFlBQVksQ0FBQ1csSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM5QjtNQUNGLENBQ0YsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGWCxZQUFZLENBQUNHLEtBQUssR0FBRyxZQUFrQjtNQUNyQ1UsV0FBVyxDQUFDVixLQUFLLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRURILFlBQVksQ0FBQ0ksSUFBSSxHQUFHLFlBQWtCO01BQ3BDLElBQUksQ0FBQ1AsTUFBTSxFQUFFO1FBQ1hHLFlBQVksQ0FBQ1csSUFBSSxDQUFDLE9BQU8sRUFBRS9ILGlCQUFTLENBQUN3QixVQUFVLENBQUMscUNBQXFDLENBQUMsQ0FBQztRQUN2RnlHLFdBQVcsQ0FBQ1YsS0FBSyxDQUFDLENBQUM7TUFDckIsQ0FBQyxNQUFNO1FBQ0xVLFdBQVcsQ0FBQ1QsSUFBSSxDQUFDLENBQUM7TUFDcEI7SUFDRixDQUFDO0lBRURKLFlBQVksQ0FBQ29CLElBQUksQ0FBQ1AsV0FBVyxDQUFDO0lBRTlCLE9BQU9iLFlBQVk7RUFDckI7O0VBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ1NxQixVQUFVQSxDQUFDaEosSUFBWSxFQUFFeUQsUUFBZ0IsRUFBRTtJQUNoRCxJQUFBNEQsZUFBTSxFQUFDLElBQUFDLG1CQUFZLEVBQUM3RCxRQUFRLENBQUMsQ0FBQztJQUU5QixNQUFNdEQsT0FBTyxHQUFHLElBQUksQ0FBQ0MsZ0JBQWdCLENBQUNKLElBQUksQ0FBQztJQUUzQyxJQUFJSyxlQUFDLENBQUNDLEtBQUssQ0FBQ0gsT0FBTyxDQUFDLEVBQUU7TUFDcEIsT0FBTyxJQUFJLENBQUM4SSw0QkFBNEIsQ0FBQyxDQUFDO0lBQzVDO0lBRUEsT0FBTyxJQUFJLENBQUNDLHlCQUF5QixDQUFDL0ksT0FBTyxFQUFFc0QsUUFBUSxDQUFDO0VBQzFEOztFQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7RUFDVXdGLDRCQUE0QkEsQ0FBQSxFQUFHO0lBQ3JDLE1BQU1FLE1BQU0sR0FBRyxJQUFJQyxvQkFBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRWxDaEIsT0FBTyxDQUFDQyxRQUFRLENBQUMsTUFBWTtNQUMzQmMsTUFBTSxDQUFDYixJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQzlCLG9CQUFvQixDQUFDLENBQUMsQ0FBQztJQUNuRCxDQUFDLENBQUM7SUFDRixPQUFPMkMsTUFBTTtFQUNmOztFQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ1VELHlCQUF5QkEsQ0FBQy9JLE9BQVksRUFBRXNELFFBQWdCLEVBQUU7SUFDaEUsTUFBTTBGLE1BQU0sR0FBRyxJQUFJQyxvQkFBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xDLE1BQU1DLGlCQUFpQixHQUFHbEosT0FBTyxDQUFDbUosV0FBVyxDQUFDN0YsUUFBUSxDQUFDO0lBQ3ZELE1BQU04RixJQUFJLEdBQUdoSixpQkFBUyxDQUFDQyxXQUFXO0lBRWxDMkksTUFBTSxDQUFDckIsS0FBSyxHQUFHLFlBQWtCO01BQy9CLElBQUl6SCxlQUFDLENBQUNDLEtBQUssQ0FBQytJLGlCQUFpQixDQUFDLEtBQUssS0FBSyxFQUFFO1FBQ3hDQSxpQkFBaUIsQ0FBQ3ZCLEtBQUssQ0FBQyxDQUFDO01BQzNCO0lBQ0YsQ0FBQztJQUVEdUIsaUJBQWlCLENBQUNYLEVBQUUsQ0FBQyxPQUFPLEVBQUUsVUFBVS9ILEdBQUcsRUFBRTtNQUMzQyxJQUFJQSxHQUFHLENBQUNFLElBQUksS0FBS0Msa0JBQU8sQ0FBQ1csa0JBQWtCLElBQUlkLEdBQUcsQ0FBQ0UsSUFBSSxLQUFLRyxzQkFBVyxDQUFDVSxTQUFTLEVBQUU7UUFDakZ5SCxNQUFNLENBQUNiLElBQUksQ0FBQyxPQUFPLEVBQUVpQixJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQztNQUN0RCxDQUFDLE1BQU07UUFDTEosTUFBTSxDQUFDYixJQUFJLENBQUMsT0FBTyxFQUFFM0gsR0FBRyxDQUFDO01BQzNCO0lBQ0YsQ0FBQyxDQUFDO0lBRUYwSSxpQkFBaUIsQ0FBQ1gsRUFBRSxDQUFDLGdCQUFnQixFQUFFLFVBQVVjLE9BQU8sRUFBUTtNQUM5REwsTUFBTSxDQUFDYixJQUFJLENBQUMsZ0JBQWdCLEVBQUVrQixPQUFPLENBQUM7SUFDeEMsQ0FBQyxDQUFDO0lBRUZILGlCQUFpQixDQUFDWCxFQUFFLENBQUMsTUFBTSxFQUFFLFlBQWtCO01BQzdDO01BQ0FTLE1BQU0sQ0FBQ2IsSUFBSSxDQUFDLE1BQU0sQ0FBQztNQUNuQmUsaUJBQWlCLENBQUNOLElBQUksQ0FBQ0ksTUFBTSxDQUFDO0lBQ2hDLENBQUMsQ0FBQztJQUVGLE9BQU9BLE1BQU07RUFDZjs7RUFFQTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDU1Isa0JBQWtCQSxDQUFDM0ksSUFBWSxFQUFFRSxRQUFrQixHQUFHQSxDQUFBLEtBQVksQ0FBQyxDQUFDLEVBQVE7SUFDakYsTUFBTUMsT0FBTyxHQUFHLElBQUksQ0FBQ0MsZ0JBQWdCLENBQUNKLElBQUksQ0FBQztJQUMzQyxJQUFJSyxlQUFDLENBQUNDLEtBQUssQ0FBQ0gsT0FBTyxDQUFDLEVBQUU7TUFDcEIsT0FBT0QsUUFBUSxDQUFDSyxpQkFBUyxDQUFDQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQzFDO0lBRUEsSUFBSSxDQUFDaUosWUFBWSxDQUFDekosSUFBSSxFQUFFRyxPQUFPLEVBQUVELFFBQVEsQ0FBQztFQUM1QztFQUVPd0osdUJBQXVCQSxDQUFDMUosSUFBWSxFQUFxQjtJQUM5RCxPQUFPLElBQUkySixPQUFPLENBQVcsQ0FBQ0MsT0FBTyxFQUFFQyxNQUFNLEtBQUs7TUFDaEQsSUFBSSxDQUFDbEIsa0JBQWtCLENBQUMzSSxJQUFJLEVBQUUsQ0FBQ1csR0FBUSxFQUFFeUUsUUFBa0IsS0FBSztRQUM5RCxJQUFJekUsR0FBRyxFQUFFO1VBQ1AsT0FBT2tKLE1BQU0sQ0FBQ2xKLEdBQUcsQ0FBQztRQUNwQjtRQUNBaUosT0FBTyxDQUFDeEUsUUFBUSxDQUFDO01BQ25CLENBQUMsQ0FBQztJQUNKLENBQUMsQ0FBQztFQUNKO0VBRU8wRSxtQkFBbUJBLENBQUM5SixJQUFZLEVBQUV5QyxXQUFxQixFQUFxQjtJQUNqRixPQUFPLElBQUlrSCxPQUFPLENBQVcsQ0FBQ0MsT0FBTyxFQUFFQyxNQUFNLEtBQUs7TUFDaEQsSUFBSSxDQUFDckgsY0FBYyxDQUFDeEMsSUFBSSxFQUFFeUMsV0FBVyxFQUFFLENBQUM5QixHQUFRLEVBQUVvSixNQUFnQixLQUFLO1FBQ3JFLElBQUlwSixHQUFHLEVBQUU7VUFDUCxPQUFPa0osTUFBTSxDQUFDbEosR0FBRyxDQUFDO1FBQ3BCO1FBQ0FpSixPQUFPLENBQUNHLE1BQU0sQ0FBQztNQUNqQixDQUFDLENBQUM7SUFDSixDQUFDLENBQUM7RUFDSjs7RUFFQTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDU0MsTUFBTUEsQ0FBQ0MsUUFBZ0IsRUFBRUMsT0FBWSxFQUFFO0lBQzVDM0ssS0FBSyxDQUFDLHVCQUF1QixFQUFFMkssT0FBTyxDQUFDO0lBQ3ZDLE1BQU1mLE1BQU0sR0FBRyxJQUFJQyxvQkFBVyxDQUFDO01BQUVlLFVBQVUsRUFBRTtJQUFLLENBQUMsQ0FBQztJQUVwRCxJQUFJLENBQUNDLGtCQUFrQixDQUNyQixDQUFDQyxJQUFjLEVBQUUvRSxFQUFZLEtBQVc7TUFDdEM7TUFDQSxJQUFJK0UsSUFBSSxDQUFDcEYsSUFBSSxHQUFHcUYsUUFBUSxDQUFDTCxRQUFRLEVBQUUsRUFBRSxDQUFDLEVBQUU7UUFDdEMsSUFBSSxDQUFDdEIsa0JBQWtCLENBQUMwQixJQUFJLENBQUNySyxJQUFJLEVBQUUsQ0FBQ1csR0FBUSxFQUFFYSxJQUFjLEtBQVc7VUFDckUsSUFBSWIsR0FBRyxFQUFFO1lBQ1AsT0FBTzJFLEVBQUUsQ0FBQzNFLEdBQUcsQ0FBQztVQUNoQjs7VUFFQTtVQUNBLE1BQU1zRSxJQUFJLEdBQUcsSUFBSVcsSUFBSSxDQUFDeUUsSUFBSSxDQUFDcEYsSUFBSSxDQUFDLENBQUNZLFdBQVcsQ0FBQyxDQUFDO1VBQzlDLE1BQU1rRSxNQUFNLEdBQUcsSUFBQVEsa0NBQW9CLEVBQUMvSSxJQUFJLEVBQUV5RCxJQUFJLENBQUM7VUFDL0MsSUFBSTVFLGVBQUMsQ0FBQ0MsS0FBSyxDQUFDeUosTUFBTSxDQUFDLEtBQUssS0FBSyxFQUFFO1lBQzdCWixNQUFNLENBQUNxQixJQUFJLENBQUNULE1BQU0sQ0FBQztVQUNyQjtVQUNBekUsRUFBRSxDQUFDLElBQUksQ0FBQztRQUNWLENBQUMsQ0FBQztNQUNKLENBQUMsTUFBTTtRQUNMQSxFQUFFLENBQUMsSUFBSSxDQUFDO01BQ1Y7SUFDRixDQUFDLEVBQ0QsU0FBU21GLEtBQUtBLENBQUM5SixHQUFHLEVBQVE7TUFDeEIsSUFBSUEsR0FBRyxFQUFFO1FBQ1B3SSxNQUFNLENBQUNiLElBQUksQ0FBQyxPQUFPLEVBQUUzSCxHQUFHLENBQUM7UUFDekI7TUFDRjtNQUNBd0ksTUFBTSxDQUFDdUIsR0FBRyxDQUFDLENBQUM7SUFDZCxDQUNGLENBQUM7SUFFRCxPQUFPdkIsTUFBTTtFQUNmOztFQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7RUFDVS9JLGdCQUFnQkEsQ0FBQytGLE9BQWUsRUFBRTtJQUN4QyxPQUFPLElBQUksQ0FBQ3JHLGFBQWEsQ0FBQzZLLGlCQUFpQixDQUFDeEUsT0FBTyxDQUFDO0VBQ3REOztFQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7RUFDVXNELFlBQVlBLENBQUN6SixJQUFZLEVBQUVHLE9BQVksRUFBRUQsUUFBa0IsRUFBUTtJQUN6RUMsT0FBTyxDQUFDb0IsV0FBVyxDQUFDdkIsSUFBSSxFQUFFLENBQUNXLEdBQUcsRUFBRW9KLE1BQU0sS0FBVztNQUMvQyxJQUFJcEosR0FBRyxFQUFFO1FBQ1AsSUFBSUEsR0FBRyxDQUFDRSxJQUFJLEtBQUtDLGtCQUFPLENBQUNXLGtCQUFrQixJQUFJZCxHQUFHLENBQUNFLElBQUksS0FBS0csc0JBQVcsQ0FBQ1UsU0FBUyxFQUFFO1VBQ2pGLE9BQU94QixRQUFRLENBQUNLLGlCQUFTLENBQUNDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDMUM7UUFDQSxPQUFPTixRQUFRLENBQUMsSUFBSSxDQUFDMEssY0FBYyxDQUFDakssR0FBRyxFQUFFRyxrQkFBTyxDQUFDb0IsaUJBQWlCLEVBQUUsZUFBZSxDQUFDLENBQUM7TUFDdkY7TUFFQWhDLFFBQVEsQ0FBQ1MsR0FBRyxFQUFFLElBQUFnQiw4QkFBZ0IsRUFBQ29JLE1BQU0sQ0FBQyxDQUFDO0lBQ3pDLENBQUMsQ0FBQztFQUNKOztFQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7RUFDVUssa0JBQWtCQSxDQUFDUyxTQUEwQixFQUFFSixLQUF5QixFQUFRO0lBQ3RGO0lBQ0EsSUFBSXBLLGVBQUMsQ0FBQ0MsS0FBSyxDQUFDLElBQUksQ0FBQ1IsYUFBYSxDQUFDa0ssTUFBTSxDQUFDLEVBQUU7TUFDdEMsSUFBSSxDQUFDcEssTUFBTSxDQUFDa0wsSUFBSSxDQUFDLG1DQUFtQyxDQUFDO01BQ3JETCxLQUFLLENBQUMsQ0FBQztJQUNULENBQUMsTUFBTTtNQUNMLElBQUksQ0FBQzNLLGFBQWEsQ0FBQ2tLLE1BQU0sQ0FBQ2EsU0FBUyxFQUFFSixLQUFLLEVBQUVuRCxtQkFBWSxDQUFDO0lBQzNEO0VBQ0Y7O0VBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ1U1RSxrQkFBa0JBLENBQUN5RCxPQUFlLEVBQUVqRyxRQUFrQixFQUFRO0lBQ3BFLE1BQU1DLE9BQVksR0FBRyxJQUFJLENBQUNDLGdCQUFnQixDQUFDK0YsT0FBTyxDQUFDO0lBQ25ELElBQUk5RixlQUFDLENBQUNDLEtBQUssQ0FBQ0gsT0FBTyxDQUFDLEVBQUU7TUFDcEIsSUFBSSxDQUFDNEssaUJBQWlCLENBQUM1RSxPQUFPLEVBQUVqRyxRQUFRLENBQUM7TUFDekM7SUFDRjtJQUVBQyxPQUFPLENBQUNvQixXQUFXLENBQUM0RSxPQUFPLEVBQUUsQ0FBQ3hGLEdBQUcsRUFBRWEsSUFBSSxLQUFXO01BQ2hEO01BQ0EsSUFBSW5CLGVBQUMsQ0FBQ0MsS0FBSyxDQUFDSyxHQUFHLENBQUMsS0FBSyxLQUFLLEVBQUU7UUFDMUIsSUFBSUEsR0FBRyxDQUFDRSxJQUFJLEtBQUtDLGtCQUFPLENBQUNXLGtCQUFrQixJQUFJZCxHQUFHLENBQUNFLElBQUksS0FBS0csc0JBQVcsQ0FBQ1UsU0FBUyxFQUFFO1VBQ2pGRixJQUFJLEdBQUcsSUFBQWQscUNBQXVCLEVBQUN5RixPQUFPLENBQUM7UUFDekMsQ0FBQyxNQUFNO1VBQ0wsT0FBT2pHLFFBQVEsQ0FBQyxJQUFJLENBQUMwSyxjQUFjLENBQUNqSyxHQUFHLEVBQUVHLGtCQUFPLENBQUNvQixpQkFBaUIsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUN2RjtNQUNGO01BRUFoQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUF5Qiw4QkFBZ0IsRUFBQ0gsSUFBSSxDQUFDLENBQUM7SUFDeEMsQ0FBQyxDQUFDO0VBQ0o7RUFFUXVKLGlCQUFpQkEsQ0FBQy9LLElBQVksRUFBRUUsUUFBa0IsRUFBWTtJQUNwRSxPQUFPQSxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUF5Qiw4QkFBZ0IsRUFBQyxJQUFBakIscUNBQXVCLEVBQUNWLElBQUksQ0FBQyxDQUFDLENBQUM7RUFDeEU7O0VBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDVTRLLGNBQWNBLENBQUNqSyxHQUFXLEVBQUVvRyxJQUFZLEVBQUUvRSxPQUFlLEVBQU87SUFDdEUsSUFBSSxDQUFDcEMsTUFBTSxDQUFDa0MsS0FBSyxDQUFDO01BQUVuQixHQUFHLEVBQUVBLEdBQUc7TUFBRW9HLElBQUksRUFBRUE7SUFBSyxDQUFDLEVBQUUsR0FBRy9FLE9BQU8sNEJBQTRCLENBQUM7SUFFbkYsT0FBT3pCLGlCQUFTLENBQUN5SyxnQkFBZ0IsQ0FBQyxDQUFDO0VBQ3JDOztFQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNVM0YsY0FBY0EsQ0FDcEJyRixJQUFZLEVBQ1ppTCxhQUFvQyxFQUNwQy9LLFFBQWtCLEVBQ1o7SUFDTixNQUFNQyxPQUFPLEdBQUcsSUFBSSxDQUFDQyxnQkFBZ0IsQ0FBQ0osSUFBSSxDQUFDO0lBRTNDLElBQUksQ0FBQ0csT0FBTyxFQUFFO01BQ1osT0FBT0QsUUFBUSxDQUFDSyxpQkFBUyxDQUFDQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQzFDO0lBRUFMLE9BQU8sQ0FBQytLLGFBQWEsQ0FDbkJsTCxJQUFJLEVBQ0ppTCxhQUFhLEVBQ2IsSUFBSSxDQUFDL0YsYUFBYSxDQUFDaUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUM3QnhKLDhCQUFnQixFQUNoQnpCLFFBQ0YsQ0FBQztFQUNIOztFQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ1VnRixhQUFhQSxDQUFDbEYsSUFBWSxFQUFFb0wsSUFBYyxFQUFFbEwsUUFBa0IsRUFBUTtJQUM1RSxNQUFNQyxPQUFZLEdBQUcsSUFBSSxDQUFDQyxnQkFBZ0IsQ0FBQ0osSUFBSSxDQUFDO0lBQ2hELElBQUlLLGVBQUMsQ0FBQ0MsS0FBSyxDQUFDSCxPQUFPLENBQUMsRUFBRTtNQUNwQixPQUFPRCxRQUFRLENBQUMsQ0FBQztJQUNuQjtJQUNBQyxPQUFPLENBQUNrTCxXQUFXLENBQUNyTCxJQUFJLEVBQUUsSUFBSSxDQUFDc0wsbUJBQW1CLENBQUNGLElBQUksQ0FBQyxFQUFFbEwsUUFBUSxDQUFDO0VBQ3JFO0VBRVFvTCxtQkFBbUJBLENBQUNGLElBQWMsRUFBWTtJQUNwRDtJQUNBLElBQUkvSyxlQUFDLENBQUNtRixRQUFRLENBQUM0RixJQUFJLENBQUNHLElBQUksQ0FBQyxLQUFLLEtBQUssRUFBRTtNQUNuQ0gsSUFBSSxDQUFDRyxJQUFJLEdBQUd6SyxrQkFBTyxDQUFDMEssZ0JBQWdCO0lBQ3RDOztJQUVBO0lBQ0EsSUFBSW5MLGVBQUMsQ0FBQ0MsS0FBSyxDQUFDLElBQUksQ0FBQ1gsTUFBTSxDQUFDZixNQUFNLENBQUMsRUFBRTtNQUMvQndNLElBQUksQ0FBQ0csSUFBSSxHQUFHLElBQUFFLDhCQUFnQixFQUFDTCxJQUFJLENBQUNHLElBQUksQ0FBQztJQUN6QztJQUVBLE9BQU9ILElBQUk7RUFDYjtFQUVRN0ksa0JBQWtCQSxDQUFDcEMsT0FBWSxFQUFFZ0MsV0FBcUIsRUFBRWpDLFFBQWtCLEVBQVE7SUFDeEZYLEtBQUssQ0FBQywyREFBMkQsRUFBRTRDLFdBQVcsRUFBRXFGLE1BQU0sQ0FBQztJQUN2RixNQUFNa0UsVUFBVSxHQUFHLFNBQUFBLENBQVVwRyxFQUFFLEVBQVE7TUFDckMsSUFBSWpGLGVBQUMsQ0FBQ3NMLE9BQU8sQ0FBQ3hKLFdBQVcsQ0FBQyxFQUFFO1FBQzFCLE9BQU9tRCxFQUFFLENBQUMsQ0FBQztNQUNiO01BRUEsTUFBTXNHLFVBQVUsR0FBR3pKLFdBQVcsQ0FBQzBKLEtBQUssQ0FBQyxDQUFDO01BQ3RDMUwsT0FBTyxDQUFDOEIsYUFBYSxDQUFDMkosVUFBVSxFQUFFLFlBQWtCO1FBQ2xERixVQUFVLENBQUNwRyxFQUFFLENBQUM7TUFDaEIsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVEb0csVUFBVSxDQUFDLFlBQWtCO01BQzNCO01BQ0F2TCxPQUFPLENBQUNtQixhQUFhLENBQUMsVUFBVVgsR0FBRyxFQUFRO1FBQ3pDVCxRQUFRLENBQUNTLEdBQUcsQ0FBQztNQUNmLENBQUMsQ0FBQztJQUNKLENBQUMsQ0FBQztFQUNKOztFQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUNVeUQsNkJBQTZCQSxDQUFDUCxJQUFjLEVBQUVpSSxTQUFpQixFQUFRO0lBQzdFO0lBQ0E7SUFDQTtJQUNBO0lBQ0EsTUFBTUMsVUFBZSxHQUFHeEksWUFBTyxDQUFDQyxLQUFLLENBQUNLLElBQUksQ0FBQ0MsR0FBRyxDQUFDO0lBQy9DLE1BQU1rSSxTQUFjLEdBQUd6SSxZQUFPLENBQUNDLEtBQUssQ0FBQyxJQUFJLENBQUM3RCxNQUFNLENBQUNzTSxPQUFPLENBQUNILFNBQVMsQ0FBQyxDQUFDaEksR0FBRyxDQUFDO0lBRXhFLElBQUlrSSxTQUFTLENBQUNFLElBQUksS0FBS0gsVUFBVSxDQUFDRyxJQUFJLEVBQUU7TUFDdENILFVBQVUsQ0FBQ0ksUUFBUSxHQUFHSCxTQUFTLENBQUNHLFFBQVE7TUFDeEN0SSxJQUFJLENBQUN1SSxRQUFRLEdBQUdOLFNBQVM7TUFDekJqSSxJQUFJLENBQUNDLEdBQUcsR0FBR1AsWUFBTyxDQUFDOEksTUFBTSxDQUFDTixVQUFVLENBQUM7SUFDdkM7RUFDRjtFQUVBLE1BQWFPLFNBQVNBLENBQUMzTSxNQUFjLEVBQW1CO0lBQ3RELE1BQU00TSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUN6TSxhQUFhLENBQUN3TSxTQUFTLENBQUMsQ0FBQztJQUV0RCxPQUFPLElBQUksQ0FBQ3hNLGFBQWEsQ0FBQzBNLFNBQVMsQ0FBQzdNLE1BQU0sQ0FBQzhNLGNBQWMsQ0FBQ0YsU0FBUyxDQUFDLENBQUM7RUFDdkU7RUFFT0csU0FBU0EsQ0FBQ0MsS0FBWSxFQUFnQjtJQUMzQyxJQUFJdE0sZUFBQyxDQUFDdU0sVUFBVSxDQUFDLElBQUksQ0FBQzlNLGFBQWEsQ0FBQzRNLFNBQVMsQ0FBQyxLQUFLLEtBQUssRUFBRTtNQUN4RCxPQUFPL0MsT0FBTyxDQUFDRSxNQUFNLENBQ25CdEosaUJBQVMsQ0FBQ3NNLE9BQU8sQ0FBQzdMLHNCQUFXLENBQUM4TCxtQkFBbUIsRUFBRUMseUJBQWMsQ0FBQ0Msd0JBQXdCLENBQzVGLENBQUM7SUFDSDtJQUVBLE9BQU8sSUFBSSxDQUFDbE4sYUFBYSxDQUFDNE0sU0FBUyxDQUFDQyxLQUFLLENBQUM7RUFDNUM7RUFFT00sV0FBV0EsQ0FBQ0MsSUFBWSxFQUFFQyxRQUFnQixFQUFnQjtJQUMvRCxJQUFJOU0sZUFBQyxDQUFDdU0sVUFBVSxDQUFDLElBQUksQ0FBQzlNLGFBQWEsQ0FBQ21OLFdBQVcsQ0FBQyxLQUFLLEtBQUssRUFBRTtNQUMxRCxPQUFPdEQsT0FBTyxDQUFDRSxNQUFNLENBQ25CdEosaUJBQVMsQ0FBQ3NNLE9BQU8sQ0FBQzdMLHNCQUFXLENBQUM4TCxtQkFBbUIsRUFBRUMseUJBQWMsQ0FBQ0Msd0JBQXdCLENBQzVGLENBQUM7SUFDSDtJQUVBLE9BQU8sSUFBSSxDQUFDbE4sYUFBYSxDQUFDbU4sV0FBVyxDQUFDQyxJQUFJLEVBQUVDLFFBQVEsQ0FBQztFQUN2RDtFQUVPQyxVQUFVQSxDQUFDQyxNQUFtQixFQUFvQjtJQUN2RCxJQUFJaE4sZUFBQyxDQUFDdU0sVUFBVSxDQUFDLElBQUksQ0FBQzlNLGFBQWEsQ0FBQ3NOLFVBQVUsQ0FBQyxLQUFLLEtBQUssRUFBRTtNQUN6RCxPQUFPekQsT0FBTyxDQUFDRSxNQUFNLENBQ25CdEosaUJBQVMsQ0FBQ3NNLE9BQU8sQ0FBQzdMLHNCQUFXLENBQUM4TCxtQkFBbUIsRUFBRUMseUJBQWMsQ0FBQ0Msd0JBQXdCLENBQzVGLENBQUM7SUFDSDtJQUVBLE9BQU8sSUFBSSxDQUFDbE4sYUFBYSxDQUFDc04sVUFBVSxDQUFDQyxNQUFNLENBQUM7RUFDOUM7QUFDRjtBQUFDLElBQUFDLFFBQUEsR0FBQUMsT0FBQSxDQUFBak8sT0FBQSxHQUVjRyxZQUFZIiwiaWdub3JlTGlzdCI6W119
|