@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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -0
  3. package/bin/verdaccio +3 -0
  4. package/bin/verdaccio-canary +3 -0
  5. package/build/api/debug/index.js +28 -0
  6. package/build/api/endpoint/api/dist-tags.js +77 -0
  7. package/build/api/endpoint/api/package.js +103 -0
  8. package/build/api/endpoint/api/ping.js +13 -0
  9. package/build/api/endpoint/api/publish.js +359 -0
  10. package/build/api/endpoint/api/search.js +107 -0
  11. package/build/api/endpoint/api/star.js +73 -0
  12. package/build/api/endpoint/api/stars.js +42 -0
  13. package/build/api/endpoint/api/user.js +84 -0
  14. package/build/api/endpoint/api/v1/profile.js +69 -0
  15. package/build/api/endpoint/api/v1/search.js +181 -0
  16. package/build/api/endpoint/api/v1/token.js +140 -0
  17. package/build/api/endpoint/api/whoami.js +15 -0
  18. package/build/api/endpoint/index.js +58 -0
  19. package/build/api/index.js +105 -0
  20. package/build/api/middleware.js +56 -0
  21. package/build/api/web/api/index.js +31 -0
  22. package/build/api/web/api/package.js +165 -0
  23. package/build/api/web/api/search.js +53 -0
  24. package/build/api/web/api/user.js +70 -0
  25. package/build/api/web/api/utils.js +14 -0
  26. package/build/api/web/html/favicon.ico +0 -0
  27. package/build/api/web/index.js +96 -0
  28. package/build/index.js +76 -0
  29. package/build/lib/auth-utils.js +16 -0
  30. package/build/lib/bootstrap.js +167 -0
  31. package/build/lib/cli/cli.js +26 -0
  32. package/build/lib/cli/commands/info.js +26 -0
  33. package/build/lib/cli/commands/init.js +78 -0
  34. package/build/lib/cli/commands/version.js +17 -0
  35. package/build/lib/cli/utils.js +14 -0
  36. package/build/lib/cli.js +16 -0
  37. package/build/lib/config.js +22 -0
  38. package/build/lib/constants.js +121 -0
  39. package/build/lib/experiments.js +29 -0
  40. package/build/lib/local-storage.js +760 -0
  41. package/build/lib/logger/index.js +21 -0
  42. package/build/lib/metadata-utils.js +39 -0
  43. package/build/lib/run-server.js +122 -0
  44. package/build/lib/storage-utils.js +282 -0
  45. package/build/lib/storage.js +676 -0
  46. package/build/lib/up-storage.js +605 -0
  47. package/build/lib/uplink-util.js +36 -0
  48. package/build/lib/utils.js +265 -0
  49. package/conf/.gitkeep +0 -0
  50. package/index.js +1 -0
  51. package/package.json +156 -0
  52. package/security.txt +5 -0
  53. 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