ng-virtual-list 17.4.0 → 17.4.2

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 (64) hide show
  1. package/README.md +34 -1
  2. package/esm2020/lib/components/ng-virtual-list-item.component.mjs +131 -0
  3. package/esm2020/lib/const/index.mjs +44 -0
  4. package/esm2020/lib/enums/direction.mjs +2 -0
  5. package/esm2020/lib/enums/directions.mjs +18 -0
  6. package/esm2020/lib/enums/index.mjs +4 -0
  7. package/esm2020/lib/enums/snapping-method.mjs +2 -0
  8. package/esm2020/lib/enums/snapping-methods.mjs +18 -0
  9. package/esm2020/lib/models/base-virtual-list-item-component.mjs +9 -0
  10. package/esm2020/lib/models/collection.model.mjs +3 -0
  11. package/esm2020/lib/models/component.model.mjs +2 -0
  12. package/esm2020/lib/models/index.mjs +2 -0
  13. package/esm2020/lib/models/item.model.mjs +2 -0
  14. package/esm2020/lib/models/render-collection.model.mjs +3 -0
  15. package/esm2020/lib/models/render-item-config.model.mjs +2 -0
  16. package/esm2020/lib/models/render-item.model.mjs +3 -0
  17. package/esm2020/lib/models/scroll-direction.model.mjs +2 -0
  18. package/esm2020/lib/models/scroll-event.model.mjs +2 -0
  19. package/esm2020/lib/models/sticky-map.model.mjs +2 -0
  20. package/esm2020/lib/ng-virtual-list.component.mjs +675 -0
  21. package/esm2020/lib/ng-virtual-list.module.mjs +20 -0
  22. package/esm2020/lib/types/id.mjs +2 -0
  23. package/esm2020/lib/types/index.mjs +2 -0
  24. package/esm2020/lib/types/rect.mjs +2 -0
  25. package/esm2020/lib/types/size.mjs +2 -0
  26. package/esm2020/lib/utils/browser.mjs +3 -0
  27. package/esm2020/lib/utils/buffer-interpolation.mjs +27 -0
  28. package/esm2020/lib/utils/cacheMap.mjs +167 -0
  29. package/esm2020/lib/utils/debounce.mjs +31 -0
  30. package/esm2020/lib/utils/disposableComponent.mjs +29 -0
  31. package/esm2020/lib/utils/eventEmitter.mjs +106 -0
  32. package/esm2020/lib/utils/index.mjs +5 -0
  33. package/esm2020/lib/utils/isDirection.mjs +15 -0
  34. package/esm2020/lib/utils/scrollEvent.mjs +42 -0
  35. package/esm2020/lib/utils/snapping-method.mjs +9 -0
  36. package/esm2020/lib/utils/toggleClassName.mjs +15 -0
  37. package/esm2020/lib/utils/trackBox.mjs +756 -0
  38. package/esm2020/lib/utils/tracker.mjs +134 -0
  39. package/esm2020/ng-virtual-list.mjs +5 -0
  40. package/esm2020/public-api.mjs +10 -0
  41. package/esm2022/lib/components/ng-virtual-list-item.component.mjs +2 -2
  42. package/esm2022/lib/models/base-virtual-list-item-component.mjs +1 -1
  43. package/esm2022/lib/models/index.mjs +2 -3
  44. package/esm2022/lib/ng-virtual-list.component.mjs +4 -6
  45. package/esm2022/lib/utils/index.mjs +2 -6
  46. package/esm2022/lib/utils/trackBox.mjs +12 -4
  47. package/esm2022/lib/utils/tracker.mjs +1 -1
  48. package/esm2022/public-api.mjs +2 -1
  49. package/fesm2015/ng-virtual-list.mjs +2224 -0
  50. package/fesm2015/ng-virtual-list.mjs.map +1 -0
  51. package/fesm2020/ng-virtual-list.mjs +2229 -0
  52. package/fesm2020/ng-virtual-list.mjs.map +1 -0
  53. package/fesm2022/ng-virtual-list.mjs +195 -190
  54. package/fesm2022/ng-virtual-list.mjs.map +1 -1
  55. package/lib/components/ng-virtual-list-item.component.d.ts +9 -9
  56. package/lib/models/base-virtual-list-item-component.d.ts +0 -1
  57. package/lib/models/index.d.ts +1 -4
  58. package/lib/ng-virtual-list.component.d.ts +47 -50
  59. package/lib/utils/disposableComponent.d.ts +15 -0
  60. package/lib/utils/index.d.ts +3 -6
  61. package/lib/utils/trackBox.d.ts +4 -1
  62. package/lib/utils/tracker.d.ts +11 -4
  63. package/package.json +1 -1
  64. package/public-api.d.ts +1 -0
@@ -0,0 +1,756 @@
1
+ import { CacheMap } from "./cacheMap";
2
+ import { Tracker } from "./tracker";
3
+ import { HEIGHT_PROP_NAME, TRACK_BY_PROPERTY_NAME, WIDTH_PROP_NAME, X_PROP_NAME, Y_PROP_NAME } from "../const";
4
+ import { bufferInterpolation } from "./buffer-interpolation";
5
+ export const TRACK_BOX_CHANGE_EVENT_NAME = 'change';
6
+ export var ItemDisplayMethods;
7
+ (function (ItemDisplayMethods) {
8
+ ItemDisplayMethods[ItemDisplayMethods["CREATE"] = 0] = "CREATE";
9
+ ItemDisplayMethods[ItemDisplayMethods["UPDATE"] = 1] = "UPDATE";
10
+ ItemDisplayMethods[ItemDisplayMethods["DELETE"] = 2] = "DELETE";
11
+ ItemDisplayMethods[ItemDisplayMethods["NOT_CHANGED"] = 3] = "NOT_CHANGED";
12
+ })(ItemDisplayMethods || (ItemDisplayMethods = {}));
13
+ const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000;
14
+ /**
15
+ * An object that performs tracking, calculations and caching.
16
+ * @link https://github.com/DjonnyX/ng-virtual-list/blob/15.x/projects/ng-virtual-list/src/lib/utils/trackBox.ts
17
+ * @author Evgenii Grebennikov
18
+ * @email djonnyx@gmail.com
19
+ */
20
+ export class TrackBox extends CacheMap {
21
+ set items(v) {
22
+ if (this._items === v) {
23
+ return;
24
+ }
25
+ this._items = v;
26
+ }
27
+ set displayComponents(v) {
28
+ if (this._displayComponents === v) {
29
+ return;
30
+ }
31
+ this._displayComponents = v;
32
+ }
33
+ set snapedDisplayComponent(v) {
34
+ if (this._snapedDisplayComponent === v) {
35
+ return;
36
+ }
37
+ this._snapedDisplayComponent = v;
38
+ }
39
+ set isSnappingMethodAdvanced(v) {
40
+ if (this._isSnappingMethodAdvanced === v) {
41
+ return;
42
+ }
43
+ this._isSnappingMethodAdvanced = v;
44
+ }
45
+ /**
46
+ * Set the trackBy property
47
+ */
48
+ set trackingPropertyName(v) {
49
+ this._trackingPropertyName = this._tracker.trackingPropertyName = v;
50
+ }
51
+ constructor(trackingPropertyName) {
52
+ super();
53
+ this._isSnappingMethodAdvanced = false;
54
+ this._trackingPropertyName = TRACK_BY_PROPERTY_NAME;
55
+ this._deletedItemsMap = {};
56
+ this._crudDetected = false;
57
+ this._previousTotalSize = 0;
58
+ this._scrollDelta = 0;
59
+ this.isAdaptiveBuffer = true;
60
+ this._bufferSequenceExtraThreshold = DEFAULT_BUFFER_EXTREMUM_THRESHOLD;
61
+ this._maxBufferSequenceLength = DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH;
62
+ this._bufferSizeSequence = [];
63
+ this._bufferSize = 0;
64
+ this._defaultBufferSize = 0;
65
+ this._maxBufferSize = this._defaultBufferSize;
66
+ this._resetBufferSizeTimeout = DEFAULT_RESET_BUFFER_SIZE_TIMEOUT;
67
+ this._previousScrollSize = 0;
68
+ this._trackingPropertyName = trackingPropertyName;
69
+ this.initialize();
70
+ }
71
+ initialize() {
72
+ this._tracker = new Tracker(this._trackingPropertyName);
73
+ }
74
+ set(id, bounds) {
75
+ if (this._map.has(id)) {
76
+ const b = this._map.get(id);
77
+ if (b?.width === bounds.width && b.height === bounds.height) {
78
+ return this._map;
79
+ }
80
+ }
81
+ const v = this._map.set(id, bounds);
82
+ this.bumpVersion();
83
+ return v;
84
+ }
85
+ get crudDetected() { return this._crudDetected; }
86
+ fireChangeIfNeed() {
87
+ if (this.changesDetected()) {
88
+ this.dispatch(TRACK_BOX_CHANGE_EVENT_NAME, this._version);
89
+ }
90
+ }
91
+ get scrollDelta() { return this._scrollDelta; }
92
+ get bufferSize() { return this._bufferSize; }
93
+ lifeCircle() {
94
+ this.fireChangeIfNeed();
95
+ this.lifeCircleDo();
96
+ }
97
+ /**
98
+ * Scans the collection for deleted items and flushes the deleted item cache.
99
+ */
100
+ resetCollection(currentCollection, itemSize) {
101
+ if (currentCollection !== undefined && currentCollection !== null && currentCollection === this._previousCollection) {
102
+ console.warn('Attention! The collection must be immutable.');
103
+ return;
104
+ }
105
+ this.updateCache(this._previousCollection, currentCollection, itemSize);
106
+ this._previousCollection = currentCollection;
107
+ }
108
+ /**
109
+ * Update the cache of items from the list
110
+ */
111
+ updateCache(previousCollection, currentCollection, itemSize) {
112
+ let crudDetected = false;
113
+ if (!currentCollection || currentCollection.length === 0) {
114
+ if (previousCollection) {
115
+ // deleted
116
+ for (let i = 0, l = previousCollection.length; i < l; i++) {
117
+ const item = previousCollection[i], id = item.id;
118
+ crudDetected = true;
119
+ if (this._map.has(id)) {
120
+ this._map.delete(id);
121
+ }
122
+ }
123
+ }
124
+ return;
125
+ }
126
+ if (!previousCollection || previousCollection.length === 0) {
127
+ if (currentCollection) {
128
+ // added
129
+ for (let i = 0, l = currentCollection.length; i < l; i++) {
130
+ crudDetected = true;
131
+ const item = currentCollection[i], id = item.id;
132
+ this._map.set(id, { width: itemSize, height: itemSize, method: ItemDisplayMethods.CREATE });
133
+ }
134
+ }
135
+ return;
136
+ }
137
+ const collectionDict = {};
138
+ for (let i = 0, l = currentCollection.length; i < l; i++) {
139
+ const item = currentCollection[i];
140
+ if (item) {
141
+ collectionDict[item.id] = item;
142
+ }
143
+ }
144
+ const notChangedMap = {}, deletedMap = {}, deletedItemsMap = {}, updatedMap = {};
145
+ for (let i = 0, l = previousCollection.length; i < l; i++) {
146
+ const item = previousCollection[i], id = item.id;
147
+ if (item) {
148
+ if (collectionDict.hasOwnProperty(id)) {
149
+ if (item === collectionDict[id]) {
150
+ // not changed
151
+ notChangedMap[item.id] = item;
152
+ this._map.set(id, { ...(this._map.get(id) || { width: itemSize, height: itemSize }), method: ItemDisplayMethods.NOT_CHANGED });
153
+ continue;
154
+ }
155
+ else {
156
+ // updated
157
+ crudDetected = true;
158
+ updatedMap[item.id] = item;
159
+ this._map.set(id, { ...(this._map.get(id) || { width: itemSize, height: itemSize }), method: ItemDisplayMethods.UPDATE });
160
+ continue;
161
+ }
162
+ }
163
+ // deleted
164
+ crudDetected = true;
165
+ deletedMap[item.id] = item;
166
+ deletedItemsMap[i] = this._map.get(item.id);
167
+ this._map.delete(id);
168
+ }
169
+ }
170
+ for (let i = 0, l = currentCollection.length; i < l; i++) {
171
+ const item = currentCollection[i], id = item.id;
172
+ if (item && !deletedMap.hasOwnProperty(id) && !updatedMap.hasOwnProperty(id) && !notChangedMap.hasOwnProperty(id)) {
173
+ // added
174
+ crudDetected = true;
175
+ this._map.set(id, { width: itemSize, height: itemSize, method: ItemDisplayMethods.CREATE });
176
+ }
177
+ }
178
+ this._crudDetected = crudDetected;
179
+ this._deletedItemsMap = deletedItemsMap;
180
+ }
181
+ /**
182
+ * Finds the position of a collection element by the given Id
183
+ */
184
+ getItemPosition(id, stickyMap, options) {
185
+ const opt = { fromItemId: id, stickyMap, ...options };
186
+ this._defaultBufferSize = opt.bufferSize;
187
+ this._maxBufferSize = opt.maxBufferSize;
188
+ const { scrollSize, isFromItemIdFound } = this.recalculateMetrics({
189
+ ...opt,
190
+ dynamicSize: this._crudDetected || opt.dynamicSize,
191
+ previousTotalSize: this._previousTotalSize,
192
+ crudDetected: this._crudDetected,
193
+ deletedItemsMap: this._deletedItemsMap,
194
+ });
195
+ return isFromItemIdFound ? scrollSize : -1;
196
+ }
197
+ /**
198
+ * Updates the collection of display objects
199
+ */
200
+ updateCollection(items, stickyMap, options) {
201
+ const opt = { stickyMap, ...options }, crudDetected = this._crudDetected, deletedItemsMap = this._deletedItemsMap;
202
+ if (opt.dynamicSize) {
203
+ this.cacheElements();
204
+ }
205
+ this._defaultBufferSize = opt.bufferSize;
206
+ this._maxBufferSize = opt.maxBufferSize;
207
+ const metrics = this.recalculateMetrics({
208
+ ...opt,
209
+ collection: items,
210
+ previousTotalSize: this._previousTotalSize,
211
+ crudDetected: this._crudDetected,
212
+ deletedItemsMap,
213
+ });
214
+ this._delta += metrics.delta;
215
+ this.updateAdaptiveBufferParams(metrics, items.length);
216
+ this._previousTotalSize = metrics.totalSize;
217
+ this._deletedItemsMap = {};
218
+ this._crudDetected = false;
219
+ if (opt.dynamicSize) {
220
+ this.snapshot();
221
+ }
222
+ const displayItems = this.generateDisplayCollection(items, stickyMap, { ...metrics, });
223
+ return { displayItems, totalSize: metrics.totalSize, delta: metrics.delta, crudDetected };
224
+ }
225
+ /**
226
+ * Finds the closest element in the collection by scrollSize
227
+ */
228
+ getNearestItem(scrollSize, items, itemSize, isVertical) {
229
+ return this.getElementFromStart(scrollSize, items, this._map, itemSize, isVertical);
230
+ }
231
+ updateAdaptiveBufferParams(metrics, totalItemsLength) {
232
+ this.disposeClearBufferSizeTimer();
233
+ const scrollSize = metrics.scrollSize + this._delta, delta = Math.abs(this._previousScrollSize - scrollSize);
234
+ this._previousScrollSize = scrollSize;
235
+ const bufferRawSize = Math.min(Math.floor(delta / metrics.typicalItemSize) * 5, totalItemsLength), minBufferSize = bufferRawSize < this._defaultBufferSize ? this._defaultBufferSize : bufferRawSize, bufferValue = minBufferSize > this._maxBufferSize ? this._maxBufferSize : minBufferSize;
236
+ this._bufferSize = bufferInterpolation(this._bufferSize, this._bufferSizeSequence, bufferValue, {
237
+ extremumThreshold: this._bufferSequenceExtraThreshold,
238
+ bufferSize: this._maxBufferSequenceLength,
239
+ });
240
+ this.startResetBufferSizeTimer();
241
+ }
242
+ startResetBufferSizeTimer() {
243
+ this._resetBufferSizeTimer = setTimeout(() => {
244
+ this._bufferSize = this._defaultBufferSize;
245
+ this._bufferSizeSequence = [];
246
+ }, this._resetBufferSizeTimeout);
247
+ }
248
+ disposeClearBufferSizeTimer() {
249
+ clearTimeout(this._resetBufferSizeTimer);
250
+ }
251
+ /**
252
+ * Calculates the position of an element based on the given scrollSize
253
+ */
254
+ getElementFromStart(scrollSize, collection, map, typicalItemSize, isVertical) {
255
+ const sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME;
256
+ let offset = 0;
257
+ for (let i = 0, l = collection.length; i < l; i++) {
258
+ const item = collection[i];
259
+ let itemSize = 0;
260
+ if (map.has(item.id)) {
261
+ const bounds = map.get(item.id);
262
+ itemSize = bounds ? bounds[sizeProperty] : typicalItemSize;
263
+ }
264
+ else {
265
+ itemSize = typicalItemSize;
266
+ }
267
+ if (offset > scrollSize) {
268
+ return item;
269
+ }
270
+ offset += itemSize;
271
+ }
272
+ return undefined;
273
+ }
274
+ /**
275
+ * Calculates the entry into the overscroll area and returns the number of overscroll elements
276
+ */
277
+ getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical, indexOffset = 0) {
278
+ const sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME;
279
+ let offset = 0, num = 0;
280
+ for (let j = collection.length - indexOffset - 1; j >= i; j--) {
281
+ const item = collection[j];
282
+ let itemSize = 0;
283
+ if (map.has(item.id)) {
284
+ const bounds = map.get(item.id);
285
+ itemSize = bounds ? bounds[sizeProperty] : typicalItemSize;
286
+ }
287
+ else {
288
+ itemSize = typicalItemSize;
289
+ }
290
+ offset += itemSize;
291
+ num++;
292
+ if (offset > size) {
293
+ return { num: 0, offset };
294
+ }
295
+ }
296
+ return { num, offset };
297
+ }
298
+ /**
299
+ * Calculates list metrics
300
+ */
301
+ recalculateMetrics(options) {
302
+ const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, bufferSize: minBufferSize, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
303
+ const bufferSize = Math.max(minBufferSize, this._bufferSize), { width, height } = bounds, sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = isVertical ? height : width, totalLength = collection.length, typicalItemSize = itemSize, w = isVertical ? width : typicalItemSize, h = isVertical ? typicalItemSize : height, map = this._map, snapshot = this._snapshot, checkOverscrollItemsLimit = Math.ceil(size / typicalItemSize), snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
304
+ || (typeof fromItemId === 'string' && fromItemId > '-1');
305
+ let leftItemsOffset = 0, rightItemsOffset = 0;
306
+ if (enabledBufferOptimization) {
307
+ switch (this.scrollDirection) {
308
+ case 1: {
309
+ leftItemsOffset = 0;
310
+ rightItemsOffset = bufferSize;
311
+ break;
312
+ }
313
+ case -1: {
314
+ leftItemsOffset = bufferSize;
315
+ rightItemsOffset = 0;
316
+ break;
317
+ }
318
+ case 0:
319
+ default: {
320
+ leftItemsOffset = rightItemsOffset = bufferSize;
321
+ }
322
+ }
323
+ }
324
+ else {
325
+ leftItemsOffset = rightItemsOffset = bufferSize;
326
+ }
327
+ let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, leftSizeOfAddedItems = 0, leftSizeOfUpdatedItems = 0, leftSizeOfDeletedItems = 0, itemById = undefined, itemByIdPos = 0, targetDisplayItemIndex = -1, isTargetInOverscroll = false, actualScrollSize = itemByIdPos, totalSize = 0, startIndex, isFromItemIdFound = false;
328
+ // If the list is dynamic or there are new elements in the collection, then it switches to the long algorithm.
329
+ if (dynamicSize) {
330
+ let y = 0, stickyCollectionItem = undefined, stickyComponentSize = 0;
331
+ for (let i = 0, l = collection.length; i < l; i++) {
332
+ const ii = i + 1, collectionItem = collection[i], id = collectionItem.id;
333
+ let componentSize = 0, componentSizeDelta = 0, itemDisplayMethod = ItemDisplayMethods.NOT_CHANGED;
334
+ if (map.has(id)) {
335
+ const bounds = map.get(id) || { width: typicalItemSize, height: typicalItemSize };
336
+ componentSize = bounds[sizeProperty];
337
+ itemDisplayMethod = bounds?.method ?? ItemDisplayMethods.UPDATE;
338
+ switch (itemDisplayMethod) {
339
+ case ItemDisplayMethods.UPDATE: {
340
+ const snapshotBounds = snapshot.get(id);
341
+ const componentSnapshotSize = componentSize - (snapshotBounds ? snapshotBounds[sizeProperty] : typicalItemSize);
342
+ componentSizeDelta = componentSnapshotSize;
343
+ map.set(id, { ...bounds, method: ItemDisplayMethods.NOT_CHANGED });
344
+ break;
345
+ }
346
+ case ItemDisplayMethods.CREATE: {
347
+ componentSizeDelta = typicalItemSize;
348
+ map.set(id, { ...bounds, method: ItemDisplayMethods.NOT_CHANGED });
349
+ break;
350
+ }
351
+ }
352
+ }
353
+ if (deletedItemsMap.hasOwnProperty(i)) {
354
+ const bounds = deletedItemsMap[i], size = bounds?.[sizeProperty] ?? typicalItemSize;
355
+ if (y < scrollSize - size) {
356
+ leftSizeOfDeletedItems += size;
357
+ }
358
+ }
359
+ totalSize += componentSize;
360
+ if (isFromId) {
361
+ if (itemById === undefined) {
362
+ if (id !== fromItemId && stickyMap && stickyMap[id] === 1) {
363
+ stickyComponentSize = componentSize;
364
+ stickyCollectionItem = collectionItem;
365
+ }
366
+ if (id === fromItemId) {
367
+ isFromItemIdFound = true;
368
+ targetDisplayItemIndex = i;
369
+ if (stickyCollectionItem && stickyMap) {
370
+ const { num } = this.getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical);
371
+ if (num > 0) {
372
+ isTargetInOverscroll = true;
373
+ y -= size - componentSize;
374
+ }
375
+ else {
376
+ if (stickyMap && !stickyMap[collectionItem.id] && y >= scrollSize && y < scrollSize + stickyComponentSize) {
377
+ const snappedY = scrollSize - stickyComponentSize;
378
+ leftHiddenItemsWeight -= (snappedY - y);
379
+ y = snappedY;
380
+ }
381
+ else {
382
+ y -= stickyComponentSize;
383
+ leftHiddenItemsWeight -= stickyComponentSize;
384
+ }
385
+ }
386
+ }
387
+ itemById = collectionItem;
388
+ itemByIdPos = y;
389
+ }
390
+ else {
391
+ leftItemsWeights.push(componentSize);
392
+ leftHiddenItemsWeight += componentSize;
393
+ itemsFromStartToScrollEnd = ii;
394
+ }
395
+ }
396
+ }
397
+ else if (y <= scrollSize - componentSize) {
398
+ leftItemsWeights.push(componentSize);
399
+ leftHiddenItemsWeight += componentSize;
400
+ itemsFromStartToScrollEnd = ii;
401
+ }
402
+ if (isFromId) {
403
+ if (itemById === undefined || y < itemByIdPos + size + componentSize) {
404
+ itemsFromStartToDisplayEnd = ii;
405
+ totalItemsToDisplayEndWeight += componentSize;
406
+ itemsFromDisplayEndToOffsetEnd = itemsFromStartToDisplayEnd + rightItemsOffset;
407
+ }
408
+ }
409
+ else if (y <= scrollSize + size + componentSize) {
410
+ itemsFromStartToDisplayEnd = ii;
411
+ totalItemsToDisplayEndWeight += componentSize;
412
+ itemsFromDisplayEndToOffsetEnd = itemsFromStartToDisplayEnd + rightItemsOffset;
413
+ if (y <= scrollSize - componentSize) {
414
+ switch (itemDisplayMethod) {
415
+ case ItemDisplayMethods.CREATE: {
416
+ leftSizeOfAddedItems += componentSizeDelta;
417
+ break;
418
+ }
419
+ case ItemDisplayMethods.UPDATE: {
420
+ leftSizeOfUpdatedItems += componentSizeDelta;
421
+ break;
422
+ }
423
+ case ItemDisplayMethods.DELETE: {
424
+ leftSizeOfDeletedItems += componentSizeDelta;
425
+ break;
426
+ }
427
+ }
428
+ }
429
+ }
430
+ else {
431
+ if (i < itemsFromDisplayEndToOffsetEnd) {
432
+ rightItemsWeight += componentSize;
433
+ }
434
+ }
435
+ y += componentSize;
436
+ }
437
+ if (isTargetInOverscroll) {
438
+ const { num } = this.getElementNumToEnd(collection.length - (checkOverscrollItemsLimit < 0 ? 0 : collection.length - checkOverscrollItemsLimit), collection, map, typicalItemSize, size, isVertical, collection.length - (collection.length - (targetDisplayItemIndex + 1)));
439
+ if (num > 0) {
440
+ itemsFromStartToScrollEnd -= num;
441
+ }
442
+ }
443
+ if (itemsFromStartToScrollEnd <= -1) {
444
+ itemsFromStartToScrollEnd = 0;
445
+ }
446
+ if (itemsFromStartToDisplayEnd <= -1) {
447
+ itemsFromStartToDisplayEnd = 0;
448
+ }
449
+ actualScrollSize = isFromId ? itemByIdPos : scrollSize;
450
+ leftItemsWeights.splice(0, leftItemsWeights.length - leftItemsOffset);
451
+ leftItemsWeights.forEach(v => {
452
+ leftItemsWeight += v;
453
+ });
454
+ leftItemLength = Math.min(itemsFromStartToScrollEnd, leftItemsOffset);
455
+ rightItemLength = itemsFromStartToDisplayEnd + rightItemsOffset > totalLength
456
+ ? totalLength - itemsFromStartToDisplayEnd : rightItemsOffset;
457
+ }
458
+ else
459
+ // Buffer optimization does not work on fast linear algorithm
460
+ {
461
+ if (crudDetected) {
462
+ let y = 0;
463
+ for (let i = 0, l = collection.length; i < l; i++) {
464
+ const collectionItem = collection[i], id = collectionItem.id;
465
+ let componentSize = typicalItemSize, itemDisplayMethod = ItemDisplayMethods.NOT_CHANGED;
466
+ if (map.has(id)) {
467
+ const bounds = map.get(id);
468
+ itemDisplayMethod = bounds?.method ?? ItemDisplayMethods.UPDATE;
469
+ if (itemDisplayMethod === ItemDisplayMethods.CREATE) {
470
+ map.set(id, { ...bounds, method: ItemDisplayMethods.NOT_CHANGED });
471
+ }
472
+ }
473
+ if (deletedItemsMap.hasOwnProperty(i)) {
474
+ const bounds = deletedItemsMap[i], size = bounds?.[sizeProperty] ?? typicalItemSize;
475
+ if (y < scrollSize - size) {
476
+ leftSizeOfDeletedItems += size;
477
+ }
478
+ }
479
+ if (y < scrollSize - componentSize) {
480
+ switch (itemDisplayMethod) {
481
+ case ItemDisplayMethods.CREATE: {
482
+ leftSizeOfUpdatedItems += componentSize;
483
+ break;
484
+ }
485
+ case ItemDisplayMethods.UPDATE: {
486
+ leftSizeOfUpdatedItems += componentSize;
487
+ break;
488
+ }
489
+ case ItemDisplayMethods.DELETE: {
490
+ leftSizeOfDeletedItems += componentSize;
491
+ break;
492
+ }
493
+ }
494
+ }
495
+ y += componentSize;
496
+ }
497
+ }
498
+ itemsFromStartToScrollEnd = Math.floor(scrollSize / typicalItemSize);
499
+ itemsFromStartToDisplayEnd = Math.ceil((scrollSize + size) / typicalItemSize);
500
+ leftItemLength = Math.min(itemsFromStartToScrollEnd, bufferSize);
501
+ rightItemLength = itemsFromStartToDisplayEnd + bufferSize > totalLength
502
+ ? totalLength - itemsFromStartToDisplayEnd : bufferSize;
503
+ leftItemsWeight = leftItemLength * typicalItemSize;
504
+ rightItemsWeight = rightItemLength * typicalItemSize;
505
+ leftHiddenItemsWeight = itemsFromStartToScrollEnd * typicalItemSize;
506
+ totalItemsToDisplayEndWeight = itemsFromStartToDisplayEnd * typicalItemSize;
507
+ totalSize = totalLength * typicalItemSize;
508
+ const k = totalSize !== 0 ? previousTotalSize / totalSize : 0;
509
+ actualScrollSize = scrollSize * k;
510
+ }
511
+ startIndex = Math.min(itemsFromStartToScrollEnd - leftItemLength, totalLength > 0 ? totalLength - 1 : 0);
512
+ const itemsOnDisplayWeight = totalItemsToDisplayEndWeight - leftItemsWeight, itemsOnDisplayLength = itemsFromStartToDisplayEnd - itemsFromStartToScrollEnd, startPosition = leftHiddenItemsWeight - leftItemsWeight, renderItems = itemsOnDisplayLength + leftItemLength + rightItemLength, delta = leftSizeOfUpdatedItems + leftSizeOfAddedItems - leftSizeOfDeletedItems;
513
+ const metrics = {
514
+ delta,
515
+ normalizedItemWidth: w,
516
+ normalizedItemHeight: h,
517
+ width,
518
+ height,
519
+ dynamicSize,
520
+ itemSize,
521
+ itemsFromStartToScrollEnd,
522
+ itemsFromStartToDisplayEnd,
523
+ itemsOnDisplayWeight,
524
+ itemsOnDisplayLength,
525
+ isVertical,
526
+ leftHiddenItemsWeight,
527
+ leftItemLength,
528
+ leftItemsWeight,
529
+ renderItems,
530
+ rightItemLength,
531
+ rightItemsWeight,
532
+ scrollSize: actualScrollSize,
533
+ leftSizeOfAddedItems,
534
+ sizeProperty,
535
+ snap,
536
+ snippedPos,
537
+ startIndex,
538
+ startPosition,
539
+ totalItemsToDisplayEndWeight,
540
+ totalLength,
541
+ totalSize,
542
+ typicalItemSize,
543
+ isFromItemIdFound,
544
+ };
545
+ return metrics;
546
+ }
547
+ clearDeltaDirection() {
548
+ this.clearScrollDirectionCache();
549
+ }
550
+ clearDelta(clearDirectionDetector = false) {
551
+ this._delta = 0;
552
+ if (clearDirectionDetector) {
553
+ this.clearScrollDirectionCache();
554
+ }
555
+ }
556
+ changes() {
557
+ this.bumpVersion();
558
+ }
559
+ generateDisplayCollection(items, stickyMap, metrics) {
560
+ const { width, height, normalizedItemWidth, normalizedItemHeight, dynamicSize, itemsOnDisplayLength, itemsFromStartToScrollEnd, isVertical, renderItems: renderItemsLength, scrollSize, sizeProperty, snap, snippedPos, startPosition, totalLength, startIndex, typicalItemSize, } = metrics, displayItems = [];
561
+ if (items.length) {
562
+ const actualSnippedPosition = snippedPos, isSnappingMethodAdvanced = this.isSnappingMethodAdvanced, boundsSize = isVertical ? height : width, actualEndSnippedPosition = boundsSize;
563
+ let pos = startPosition, renderItems = renderItemsLength, stickyItem, nextSticky, stickyItemIndex = -1, stickyItemSize = 0, endStickyItem, nextEndSticky, endStickyItemIndex = -1, endStickyItemSize = 0;
564
+ if (snap) {
565
+ for (let i = Math.min(itemsFromStartToScrollEnd > 0 ? itemsFromStartToScrollEnd : 0, totalLength - 1); i >= 0; i--) {
566
+ if (!items[i]) {
567
+ continue;
568
+ }
569
+ const id = items[i].id, sticky = stickyMap[id], size = dynamicSize ? this.get(id)?.[sizeProperty] || typicalItemSize : typicalItemSize;
570
+ if (sticky === 1) {
571
+ const measures = {
572
+ x: isVertical ? 0 : actualSnippedPosition,
573
+ y: isVertical ? actualSnippedPosition : 0,
574
+ width: isVertical ? normalizedItemWidth : size,
575
+ height: isVertical ? size : normalizedItemHeight,
576
+ delta: 0,
577
+ }, config = {
578
+ isVertical,
579
+ sticky,
580
+ snap,
581
+ snapped: true,
582
+ snappedOut: false,
583
+ dynamic: dynamicSize,
584
+ isSnappingMethodAdvanced,
585
+ zIndex: '1',
586
+ };
587
+ const itemData = items[i];
588
+ stickyItem = { id, measures, data: itemData, config };
589
+ stickyItemIndex = i;
590
+ stickyItemSize = size;
591
+ displayItems.push(stickyItem);
592
+ break;
593
+ }
594
+ }
595
+ }
596
+ if (snap) {
597
+ const startIndex = itemsFromStartToScrollEnd + itemsOnDisplayLength - 1;
598
+ for (let i = Math.min(startIndex, totalLength > 0 ? totalLength - 1 : 0), l = totalLength; i < l; i++) {
599
+ if (!items[i]) {
600
+ continue;
601
+ }
602
+ const id = items[i].id, sticky = stickyMap[id], size = dynamicSize
603
+ ? this.get(id)?.[sizeProperty] || typicalItemSize
604
+ : typicalItemSize;
605
+ if (sticky === 2) {
606
+ const w = isVertical ? normalizedItemWidth : size, h = isVertical ? size : normalizedItemHeight, measures = {
607
+ x: isVertical ? 0 : actualEndSnippedPosition - w,
608
+ y: isVertical ? actualEndSnippedPosition - h : 0,
609
+ width: w,
610
+ height: h,
611
+ delta: 0,
612
+ }, config = {
613
+ isVertical,
614
+ sticky,
615
+ snap,
616
+ snapped: true,
617
+ snappedOut: false,
618
+ dynamic: dynamicSize,
619
+ isSnappingMethodAdvanced,
620
+ zIndex: '1',
621
+ };
622
+ const itemData = items[i];
623
+ endStickyItem = { id, measures, data: itemData, config };
624
+ endStickyItemIndex = i;
625
+ endStickyItemSize = size;
626
+ displayItems.push(endStickyItem);
627
+ break;
628
+ }
629
+ }
630
+ }
631
+ let i = startIndex;
632
+ while (renderItems > 0) {
633
+ if (i >= totalLength) {
634
+ break;
635
+ }
636
+ if (!items[i]) {
637
+ continue;
638
+ }
639
+ const id = items[i].id, size = dynamicSize ? this.get(id)?.[sizeProperty] || typicalItemSize : typicalItemSize;
640
+ if (id !== stickyItem?.id && id !== endStickyItem?.id) {
641
+ const snapped = snap && (stickyMap[id] === 1 && pos <= scrollSize || stickyMap[id] === 2 && pos >= scrollSize + boundsSize - size), measures = {
642
+ x: isVertical ? stickyMap[id] === 1 ? 0 : boundsSize - size : pos,
643
+ y: isVertical ? pos : stickyMap[id] === 2 ? boundsSize - size : 0,
644
+ width: isVertical ? normalizedItemWidth : size,
645
+ height: isVertical ? size : normalizedItemHeight,
646
+ delta: 0,
647
+ }, config = {
648
+ isVertical,
649
+ sticky: stickyMap[id],
650
+ snap,
651
+ snapped: false,
652
+ snappedOut: false,
653
+ dynamic: dynamicSize,
654
+ isSnappingMethodAdvanced,
655
+ zIndex: '0',
656
+ };
657
+ if (snapped) {
658
+ config.zIndex = '2';
659
+ }
660
+ const itemData = items[i];
661
+ const item = { id, measures, data: itemData, config };
662
+ if (!nextSticky && stickyItemIndex < i && stickyMap[id] === 1 && (pos <= scrollSize + size + stickyItemSize)) {
663
+ item.measures.x = isVertical ? 0 : snapped ? actualSnippedPosition : pos;
664
+ item.measures.y = isVertical ? snapped ? actualSnippedPosition : pos : 0;
665
+ nextSticky = item;
666
+ nextSticky.config.snapped = snapped;
667
+ nextSticky.measures.delta = isVertical ? (item.measures.y - scrollSize) : (item.measures.x - scrollSize);
668
+ nextSticky.config.zIndex = '3';
669
+ }
670
+ else if (!nextEndSticky && endStickyItemIndex > i && stickyMap[id] === 2 && (pos >= scrollSize + boundsSize - size - endStickyItemSize)) {
671
+ item.measures.x = isVertical ? 0 : snapped ? actualEndSnippedPosition - size : pos;
672
+ item.measures.y = isVertical ? snapped ? actualEndSnippedPosition - size : pos : 0;
673
+ nextEndSticky = item;
674
+ nextEndSticky.config.zIndex = '3';
675
+ nextEndSticky.config.snapped = snapped;
676
+ nextEndSticky.measures.delta = isVertical ? (item.measures.y - scrollSize) : (item.measures.x - scrollSize);
677
+ }
678
+ displayItems.push(item);
679
+ }
680
+ renderItems -= 1;
681
+ pos += size;
682
+ i++;
683
+ }
684
+ const axis = isVertical ? Y_PROP_NAME : X_PROP_NAME;
685
+ if (nextSticky && stickyItem && nextSticky.measures[axis] <= scrollSize + stickyItemSize) {
686
+ if (nextSticky.measures[axis] > scrollSize) {
687
+ stickyItem.measures[axis] = nextSticky.measures[axis] - stickyItemSize;
688
+ stickyItem.config.snapped = nextSticky.config.snapped = false;
689
+ stickyItem.config.snappedOut = true;
690
+ stickyItem.config.sticky = 1;
691
+ stickyItem.measures.delta = isVertical ? stickyItem.measures.y - scrollSize : stickyItem.measures.x - scrollSize;
692
+ }
693
+ else {
694
+ nextSticky.config.snapped = true;
695
+ nextSticky.measures.delta = isVertical ? nextSticky.measures.y - scrollSize : nextSticky.measures.x - scrollSize;
696
+ }
697
+ }
698
+ if (nextEndSticky && endStickyItem && nextEndSticky.measures[axis] >= scrollSize + boundsSize - endStickyItemSize - nextEndSticky.measures[sizeProperty]) {
699
+ if (nextEndSticky.measures[axis] < scrollSize + boundsSize - endStickyItemSize) {
700
+ endStickyItem.measures[axis] = nextEndSticky.measures[axis] + nextEndSticky.measures[sizeProperty];
701
+ endStickyItem.config.snapped = nextEndSticky.config.snapped = false;
702
+ endStickyItem.config.snappedOut = true;
703
+ endStickyItem.config.sticky = 2;
704
+ endStickyItem.measures.delta = isVertical ? endStickyItem.measures.y - scrollSize : endStickyItem.measures.x - scrollSize;
705
+ }
706
+ else {
707
+ nextEndSticky.config.snapped = true;
708
+ nextEndSticky.measures.delta = isVertical ? nextEndSticky.measures.y - scrollSize : nextEndSticky.measures.x - scrollSize;
709
+ }
710
+ }
711
+ }
712
+ return displayItems;
713
+ }
714
+ /**
715
+ * tracking by propName
716
+ */
717
+ track() {
718
+ if (!this._items || !this._displayComponents) {
719
+ return;
720
+ }
721
+ this._tracker.track(this._items, this._displayComponents, this._snapedDisplayComponent, this.scrollDirection);
722
+ }
723
+ setDisplayObjectIndexMapById(v) {
724
+ this._tracker.displayObjectIndexMapById = v;
725
+ }
726
+ untrackComponentByIdProperty(component) {
727
+ this._tracker.untrackComponentByIdProperty(component);
728
+ }
729
+ getItemBounds(id) {
730
+ if (this.has(id)) {
731
+ return this.get(id);
732
+ }
733
+ return undefined;
734
+ }
735
+ cacheElements() {
736
+ if (!this._displayComponents) {
737
+ return;
738
+ }
739
+ for (let i = 0, l = this._displayComponents.length; i < l; i++) {
740
+ const component = this._displayComponents[i], itemId = component.instance.itemId;
741
+ if (itemId === undefined) {
742
+ continue;
743
+ }
744
+ const bounds = component.instance.getBounds();
745
+ this.set(itemId, bounds);
746
+ }
747
+ }
748
+ dispose() {
749
+ super.dispose();
750
+ this.disposeClearBufferSizeTimer();
751
+ if (this._tracker) {
752
+ this._tracker.dispose();
753
+ }
754
+ }
755
+ }
756
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2tCb3guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy12aXJ0dWFsLWxpc3Qvc3JjL2xpYi91dGlscy90cmFja0JveC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQUUsUUFBUSxFQUFRLE1BQU0sWUFBWSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFcEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLHNCQUFzQixFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRS9HLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzdELE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLFFBQVEsQ0FBQztBQWdFcEQsTUFBTSxDQUFOLElBQVksa0JBS1g7QUFMRCxXQUFZLGtCQUFrQjtJQUMxQiwrREFBTSxDQUFBO0lBQ04sK0RBQU0sQ0FBQTtJQUNOLCtEQUFNLENBQUE7SUFDTix5RUFBVyxDQUFBO0FBQ2YsQ0FBQyxFQUxXLGtCQUFrQixLQUFsQixrQkFBa0IsUUFLN0I7QUFTRCxNQUFNLGlDQUFpQyxHQUFHLEVBQUUsRUFDeEMsa0NBQWtDLEdBQUcsRUFBRSxFQUN2QyxpQ0FBaUMsR0FBRyxLQUFLLENBQUM7QUFFOUM7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sUUFDVCxTQUFRLFFBQXdGO0lBTWhHLElBQUksS0FBSyxDQUFDLENBQWtEO1FBQ3hELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDbkIsT0FBTztTQUNWO1FBRUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDcEIsQ0FBQztJQUlELElBQUksaUJBQWlCLENBQUMsQ0FBNEM7UUFDOUQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEtBQUssQ0FBQyxFQUFFO1lBQy9CLE9BQU87U0FDVjtR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WyJpbXBvcnQgeyBDb21wb25lbnRSZWYgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBJUmVuZGVyVmlydHVhbExpc3RDb2xsZWN0aW9uLCB9IGZyb20gXCIuLi9tb2RlbHMvcmVuZGVyLWNvbGxlY3Rpb24ubW9kZWxcIjtcclxuaW1wb3J0IHsgSVJlbmRlclZpcnR1YWxMaXN0SXRlbSB9IGZyb20gXCIuLi9tb2RlbHMvcmVuZGVyLWl0ZW0ubW9kZWxcIjtcclxuaW1wb3J0IHsgSWQgfSBmcm9tIFwiLi4vdHlwZXMvaWRcIjtcclxuaW1wb3J0IHsgQ2FjaGVNYXAsIENNYXAgfSBmcm9tIFwiLi9jYWNoZU1hcFwiO1xyXG5pbXBvcnQgeyBUcmFja2VyIH0gZnJvbSBcIi4vdHJhY2tlclwiO1xyXG5pbXBvcnQgeyBJU2l6ZSB9IGZyb20gXCIuLi90eXBlc1wiO1xyXG5pbXBvcnQgeyBIRUlHSFRfUFJPUF9OQU1FLCBUUkFDS19CWV9QUk9QRVJUWV9OQU1FLCBXSURUSF9QUk9QX05BTUUsIFhfUFJPUF9OQU1FLCBZX1BST1BfTkFNRSB9IGZyb20gXCIuLi9jb25zdFwiO1xyXG5pbXBvcnQgeyBJVmlydHVhbExpc3RTdGlja3lNYXAgfSBmcm9tIFwiLi4vbW9kZWxzXCI7XHJcbmltcG9ydCB7IGJ1ZmZlckludGVycG9sYXRpb24gfSBmcm9tIFwiLi9idWZmZXItaW50ZXJwb2xhdGlvblwiO1xyXG5pbXBvcnQgeyBCYXNlVmlydHVhbExpc3RJdGVtQ29tcG9uZW50IH0gZnJvbSBcIi4uL21vZGVscy9iYXNlLXZpcnR1YWwtbGlzdC1pdGVtLWNvbXBvbmVudFwiO1xyXG5cclxuZXhwb3J0IGNvbnN0IFRSQUNLX0JPWF9DSEFOR0VfRVZFTlRfTkFNRSA9ICdjaGFuZ2UnO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBJTWV0cmljcyB7XHJcbiAgICBkZWx0YTogbnVtYmVyO1xyXG4gICAgbm9ybWFsaXplZEl0ZW1XaWR0aDogbnVtYmVyO1xyXG4gICAgbm9ybWFsaXplZEl0ZW1IZWlnaHQ6IG51bWJlcjtcclxuICAgIHdpZHRoOiBudW1iZXI7XHJcbiAgICBoZWlnaHQ6IG51bWJlcjtcclxuICAgIGR5bmFtaWNTaXplOiBib29sZWFuO1xyXG4gICAgaXRlbVNpemU6IG51bWJlcjtcclxuICAgIGl0ZW1zRnJvbVN0YXJ0VG9TY3JvbGxFbmQ6IG51bWJlcjtcclxuICAgIGl0ZW1zRnJvbVN0YXJ0VG9EaXNwbGF5RW5kOiBudW1iZXI7XHJcbiAgICBpdGVtc09uRGlzcGxheVdlaWdodDogbnVtYmVyO1xyXG4gICAgaXRlbXNPbkRpc3BsYXlMZW5ndGg6IG51bWJlcjtcclxuICAgIGlzVmVydGljYWw6IGJvb2xlYW47XHJcbiAgICBsZWZ0SGlkZGVuSXRlbXNXZWlnaHQ6IG51bWJlcjtcclxuICAgIGxlZnRJdGVtTGVuZ3RoOiBudW1iZXI7XHJcbiAgICBsZWZ0SXRlbXNXZWlnaHQ6IG51bWJlcjtcclxuICAgIHJlbmRlckl0ZW1zOiBudW1iZXI7XHJcbiAgICByaWdodEl0ZW1MZW5ndGg6IG51bWJlcjtcclxuICAgIHJpZ2h0SXRlbXNXZWlnaHQ6IG51bWJlcjtcclxuICAgIHNjcm9sbFNpemU6IG51bWJlcjtcclxuICAgIGxlZnRTaXplT2ZBZGRlZEl0ZW1zOiBudW1iZXI7XHJcbiAgICBzaXplUHJvcGVydHk6IHR5cGVvZiBIRUlHSFRfUFJPUF9OQU1FIHwgdHlwZW9mIFdJRFRIX1BST1BfTkFNRTtcclxuICAgIHNuYXA6IGJvb2xlYW47XHJcbiAgICBzbmlwcGVkUG9zOiBudW1iZXI7XHJcbiAgICBzdGFydEluZGV4OiBudW1iZXI7XHJcbiAgICBzdGFydFBvc2l0aW9uOiBudW1iZXI7XHJcbiAgICB0b3RhbEl0ZW1zVG9EaXNwbGF5RW5kV2VpZ2h0OiBudW1iZXI7XHJcbiAgICB0b3RhbExlbmd0aDogbnVtYmVyO1xyXG4gICAgdG90YWxTaXplOiBudW1iZXI7XHJcbiAgICB0eXBpY2FsSXRlbVNpemU6IG51bWJlcjtcclxuICAgIGlzRnJvbUl0ZW1JZEZvdW5kOiBib29sZWFuO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElSZWNhbGN1bGF0ZU1ldHJpY3NPcHRpb25zPEkgZXh0ZW5kcyB7IGlkOiBJZCB9LCBDIGV4dGVuZHMgQXJyYXk8ST4+IHtcclxuICAgIGJvdW5kczogSVNpemU7XHJcbiAgICBjb2xsZWN0aW9uOiBDO1xyXG4gICAgaXNWZXJ0aWNhbDogYm9vbGVhbjtcclxuICAgIGl0ZW1TaXplOiBudW1iZXI7XHJcbiAgICBidWZmZXJTaXplOiBudW1iZXI7XHJcbiAgICBtYXhCdWZmZXJTaXplOiBudW1iZXI7XHJcbiAgICBkeW5hbWljU2l6ZTogYm9vbGVhbjtcclxuICAgIHNjcm9sbFNpemU6IG51bWJlcjtcclxuICAgIHNuYXA6IGJvb2xlYW47XHJcbiAgICBlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uOiBib29sZWFuO1xyXG4gICAgZnJvbUl0ZW1JZD86IElkO1xyXG4gICAgcHJldmlvdXNUb3RhbFNpemU6IG51bWJlcjtcclxuICAgIGNydWREZXRlY3RlZDogYm9vbGVhbjtcclxuICAgIGRlbGV0ZWRJdGVtc01hcDogeyBbaW5kZXg6IG51bWJlcl06IElTaXplOyB9O1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIElHZXRJdGVtUG9zaXRpb25PcHRpb25zPEkgZXh0ZW5kcyB7IGlkOiBJZCB9LCBDIGV4dGVuZHMgQXJyYXk8ST4+XHJcbiAgICBleHRlbmRzIE9taXQ8SVJlY2FsY3VsYXRlTWV0cmljc09wdGlvbnM8SSwgQz4sICdwcmV2aW91c1RvdGFsU2l6ZScgfCAnY3J1ZERldGVjdGVkJyB8ICdkZWxldGVkSXRlbXNNYXAnPiB7IH1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgSVVwZGF0ZUNvbGxlY3Rpb25PcHRpb25zPEkgZXh0ZW5kcyB7IGlkOiBJZCB9LCBDIGV4dGVuZHMgQXJyYXk8ST4+XHJcbiAgICBleHRlbmRzIE9taXQ8SVJlY2FsY3VsYXRlTWV0cmljc09wdGlvbnM8SSwgQz4sICdjb2xsZWN0aW9uJyB8ICdwcmV2aW91c1RvdGFsU2l6ZScgfCAnY3J1ZERldGVjdGVkJyB8ICdkZWxldGVkSXRlbXNNYXAnPiB7IH1cclxuXHJcbmV4cG9ydCB0eXBlIENhY2hlTWFwRXZlbnRzID0gdHlwZW9mIFRSQUNLX0JPWF9DSEFOR0VfRVZFTlRfTkFNRTtcclxuXHJcbmV4cG9ydCB0eXBlIE9uQ2hhbmdlRXZlbnRMaXN0ZW5lciA9ICh2ZXJzaW9uOiBudW1iZXIpID0+IHZvaWQ7XHJcblxyXG5leHBvcnQgdHlwZSBDYWNoZU1hcExpc3RlbmVycyA9IE9uQ2hhbmdlRXZlbnRMaXN0ZW5lcjtcclxuXHJcbmV4cG9ydCBlbnVtIEl0ZW1EaXNwbGF5TWV0aG9kcyB7XHJcbiAgICBDUkVBVEUsXHJcbiAgICBVUERBVEUsXHJcbiAgICBERUxFVEUsXHJcbiAgICBOT1RfQ0hBTkdFRCxcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBJVXBkYXRlQ29sbGVjdGlvblJldHVybnMge1xyXG4gICAgZGlzcGxheUl0ZW1zOiBJUmVuZGVyVmlydHVhbExpc3RDb2xsZWN0aW9uO1xyXG4gICAgdG90YWxTaXplOiBudW1iZXI7XHJcbiAgICBkZWx0YTogbnVtYmVyO1xyXG4gICAgY3J1ZERldGVjdGVkOiBib29sZWFuO1xyXG59XHJcblxyXG5jb25zdCBERUZBVUxUX0JVRkZFUl9FWFRSRU1VTV9USFJFU0hPTEQgPSAxNSxcclxuICAgIERFRkFVTFRfTUFYX0JVRkZFUl9TRVFVRU5DRV9MRU5HVEggPSAzMCxcclxuICAgIERFRkFVTFRfUkVTRVRfQlVGRkVSX1NJWkVfVElNRU9VVCA9IDEwMDAwO1xyXG5cclxuLyoqXHJcbiAqIEFuIG9iamVjdCB0aGF0IHBlcmZvcm1zIHRyYWNraW5nLCBjYWxjdWxhdGlvbnMgYW5kIGNhY2hpbmcuXHJcbiAqIEBsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9Eam9ubnlYL25nLXZpcnR1YWwtbGlzdC9ibG9iLzE1LngvcHJvamVjdHMvbmctdmlydHVhbC1saXN0L3NyYy9saWIvdXRpbHMvdHJhY2tCb3gudHNcclxuICogQGF1dGhvciBFdmdlbmlpIEdyZWJlbm5pa292XHJcbiAqIEBlbWFpbCBkam9ubnl4QGdtYWlsLmNvbVxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFRyYWNrQm94PEMgZXh0ZW5kcyBCYXNlVmlydHVhbExpc3RJdGVtQ29tcG9uZW50ID0gYW55PlxyXG4gICAgZXh0ZW5kcyBDYWNoZU1hcDxJZCwgSVNpemUgJiB7IG1ldGhvZD86IEl0ZW1EaXNwbGF5TWV0aG9kcyB9LCBDYWNoZU1hcEV2ZW50cywgQ2FjaGVNYXBMaXN0ZW5lcnM+IHtcclxuXHJcbiAgICBwcm90ZWN0ZWQgX3RyYWNrZXIhOiBUcmFja2VyPEM+O1xyXG5cclxuICAgIHByb3RlY3RlZCBfaXRlbXM6IElSZW5kZXJWaXJ0dWFsTGlzdENvbGxlY3Rpb24gfCBudWxsIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgIHNldCBpdGVtcyh2OiBJUmVuZGVyVmlydHVhbExpc3RDb2xsZWN0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9pdGVtcyA9PT0gdikge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9pdGVtcyA9IHY7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIF9kaXNwbGF5Q29tcG9uZW50czogQXJyYXk8Q29tcG9uZW50UmVmPEM+PiB8IG51bGwgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgc2V0IGRpc3BsYXlDb21wb25lbnRzKHY6IEFycmF5PENvbXBvbmVudFJlZjxDPj4gfCBudWxsIHwgdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2Rpc3BsYXlDb21wb25lbnRzID09PSB2KSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX2Rpc3BsYXlDb21wb25lbnRzID0gdjtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgX3NuYXBlZERpc3BsYXlDb21wb25lbnQ6IENvbXBvbmVudFJlZjxDPiB8IG51bGwgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgc2V0IHNuYXBlZERpc3BsYXlDb21wb25lbnQodjogQ29tcG9uZW50UmVmPEM+IHwgbnVsbCB8IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9zbmFwZWREaXNwbGF5Q29tcG9uZW50ID09PSB2KSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NuYXBlZERpc3BsYXlDb21wb25lbnQgPSB2O1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBfaXNTbmFwcGluZ01ldGhvZEFkdmFuY2VkOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgc2V0IGlzU25hcHBpbmdNZXRob2RBZHZhbmNlZCh2OiBib29sZWFuKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2lzU25hcHBpbmdNZXRob2RBZHZhbmNlZCA9PT0gdikge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9pc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQgPSB2O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0IHRoZSB0cmFja0J5IHByb3BlcnR5XHJcbiAgICAgKi9cclxuICAgIHNldCB0cmFja2luZ1Byb3BlcnR5TmFtZSh2OiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLl90cmFja2luZ1Byb3BlcnR5TmFtZSA9IHRoaXMuX3RyYWNrZXIudHJhY2tpbmdQcm9wZXJ0eU5hbWUgPSB2O1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBfdHJhY2tpbmdQcm9wZXJ0eU5hbWU6IHN0cmluZyA9IFRSQUNLX0JZX1BST1BFUlRZX05BTUU7XHJcblxyXG4gICAgY29uc3RydWN0b3IodHJhY2tpbmdQcm9wZXJ0eU5hbWU6IHN0cmluZykge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcblxyXG4gICAgICAgIHRoaXMuX3RyYWNraW5nUHJvcGVydHlOYW1lID0gdHJhY2tpbmdQcm9wZXJ0eU5hbWU7XHJcblxyXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBpbml0aWFsaXplKCkge1xyXG4gICAgICAgIHRoaXMuX3RyYWNrZXIgPSBuZXcgVHJhY2tlcih0aGlzLl90cmFja2luZ1Byb3BlcnR5TmFtZSk7XHJcbiAgICB9XHJcblxyXG4gICAgb3ZlcnJpZGUgc2V0KGlkOiBJZCwgYm91bmRzOiBJU2l6ZSk6IENNYXA8SWQsIElTaXplPiB7XHJcbiAgICAgICAgaWYgKHRoaXMuX21hcC5oYXMoaWQpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGIgPSB0aGlzLl9tYXAuZ2V0KGlkKTtcclxuICAgICAgICAgICAgaWYgKGI/LndpZHRoID09PSBib3VuZHMud2lkdGggJiYgYi5oZWlnaHQgPT09IGJvdW5kcy5oZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tYXA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHYgPSB0aGlzLl9tYXAuc2V0KGlkLCBib3VuZHMpO1xyXG5cclxuICAgICAgICB0aGlzLmJ1bXBWZXJzaW9uKCk7XHJcbiAgICAgICAgcmV0dXJuIHY7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIF9wcmV2aW91c0NvbGxlY3Rpb246IEFycmF5PHsgaWQ6IElkOyB9PiB8IG51bGwgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgcHJvdGVjdGVkIF9kZWxldGVkSXRlbXNNYXA6IHsgW2luZGV4OiBudW1iZXJdOiBJU2l6ZSB9ID0ge307XHJcblxyXG4gICAgcHJvdGVjdGVkIF9jcnVkRGV0ZWN0ZWQgPSBmYWxzZTtcclxuICAgIGdldCBjcnVkRGV0ZWN0ZWQoKSB7IHJldHVybiB0aGlzLl9jcnVkRGV0ZWN0ZWQ7IH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgZmlyZUNoYW5nZUlmTmVlZCgpIHtcclxuICAgICAgICBpZiAodGhpcy5jaGFuZ2VzRGV0ZWN0ZWQoKSkge1xyXG4gICAgICAgICAgICB0aGlzLmRpc3BhdGNoKFRSQUNLX0JPWF9DSEFOR0VfRVZFTlRfTkFNRSwgdGhpcy5fdmVyc2lvbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBfcHJldmlvdXNUb3RhbFNpemUgPSAwO1xyXG5cclxuICAgIHByb3RlY3RlZCBfc2Nyb2xsRGVsdGE6IG51bWJlciA9IDA7XHJcbiAgICBnZXQgc2Nyb2xsRGVsdGEoKSB7IHJldHVybiB0aGlzLl9zY3JvbGxEZWx0YTsgfVxyXG5cclxuICAgIGlzQWRhcHRpdmVCdWZmZXIgPSB0cnVlO1xyXG5cclxuICAgIHByb3RlY3RlZCBfYnVmZmVyU2VxdWVuY2VFeHRyYVRocmVzaG9sZCA9IERFRkFVTFRfQlVGRkVSX0VYVFJFTVVNX1RIUkVTSE9MRDtcclxuXHJcbiAgICBwcm90ZWN0ZWQgX21heEJ1ZmZlclNlcXVlbmNlTGVuZ3RoID0gREVGQVVMVF9NQVhfQlVGRkVSX1NFUVVFTkNFX0xFTkdUSDtcclxuXHJcbiAgICBwcm90ZWN0ZWQgX2J1ZmZlclNpemVTZXF1ZW5jZTogQXJyYXk8bnVtYmVyPiA9IFtdO1xyXG5cclxuICAgIHByb3RlY3RlZCBfYnVmZmVyU2l6ZTogbnVtYmVyID0gMDtcclxuICAgIGdldCBidWZmZXJTaXplKCkgeyByZXR1cm4gdGhpcy5fYnVmZmVyU2l6ZTsgfVxyXG5cclxuICAgIHByb3RlY3RlZCBfZGVmYXVsdEJ1ZmZlclNpemU6IG51bWJlciA9IDA7XHJcblxyXG4gICAgcHJvdGVjdGVkIF9tYXhCdWZmZXJTaXplOiBudW1iZXIgPSB0aGlzLl9kZWZhdWx0QnVmZmVyU2l6ZTtcclxuXHJcbiAgICBwcm90ZWN0ZWQgX3Jlc2V0QnVmZmVyU2l6ZVRpbWVvdXQ6IG51bWJlciA9IERFRkFVTFRfUkVTRVRfQlVGRkVSX1NJWkVfVElNRU9VVDtcclxuXHJcbiAgICBwcm90ZWN0ZWQgX3Jlc2V0QnVmZmVyU2l6ZVRpbWVyOiBudW1iZXIgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgcHJvdGVjdGVkIG92ZXJyaWRlIGxpZmVDaXJjbGUoKSB7XHJcbiAgICAgICAgdGhpcy5maXJlQ2hhbmdlSWZOZWVkKCk7XHJcblxyXG4gICAgICAgIHRoaXMubGlmZUNpcmNsZURvKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTY2FucyB0aGUgY29sbGVjdGlvbiBmb3IgZGVsZXRlZCBpdGVtcyBhbmQgZmx1c2hlcyB0aGUgZGVsZXRlZCBpdGVtIGNhY2hlLlxyXG4gICAgICovXHJcbiAgICByZXNldENvbGxlY3Rpb248SSBleHRlbmRzIHsgaWQ6IElkOyB9LCBDIGV4dGVuZHMgQXJyYXk8ST4+KGN1cnJlbnRDb2xsZWN0aW9uOiBDIHwgbnVsbCB8IHVuZGVmaW5lZCwgaXRlbVNpemU6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGlmIChjdXJyZW50Q29sbGVjdGlvbiAhPT0gdW5kZWZpbmVkICYmIGN1cnJlbnRDb2xsZWN0aW9uICE9PSBudWxsICYmIGN1cnJlbnRDb2xsZWN0aW9uID09PSB0aGlzLl9wcmV2aW91c0NvbGxlY3Rpb24pIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKCdBdHRlbnRpb24hIFRoZSBjb2xsZWN0aW9uIG11c3QgYmUgaW1tdXRhYmxlLicpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZUNhY2hlKHRoaXMuX3ByZXZpb3VzQ29sbGVjdGlvbiwgY3VycmVudENvbGxlY3Rpb24sIGl0ZW1TaXplKTtcclxuXHJcbiAgICAgICAgdGhpcy5fcHJldmlvdXNDb2xsZWN0aW9uID0gY3VycmVudENvbGxlY3Rpb247XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBVcGRhdGUgdGhlIGNhY2hlIG9mIGl0ZW1zIGZyb20gdGhlIGxpc3RcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIHVwZGF0ZUNhY2hlPEkgZXh0ZW5kcyB7IGlkOiBJZDsgfSwgQyBleHRlbmRzIEFycmF5PEk+PihwcmV2aW91c0NvbGxlY3Rpb246IEMgfCBudWxsIHwgdW5kZWZpbmVkLCBjdXJyZW50Q29sbGVjdGlvbjogQyB8IG51bGwgfCB1bmRlZmluZWQsXHJcbiAgICAgICAgaXRlbVNpemU6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGxldCBjcnVkRGV0ZWN0ZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgaWYgKCFjdXJyZW50Q29sbGVjdGlvbiB8fCBjdXJyZW50Q29sbGVjdGlvbi5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgaWYgKHByZXZpb3VzQ29sbGVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgLy8gZGVsZXRlZFxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBwcmV2aW91c0NvbGxlY3Rpb24ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbSA9IHByZXZpb3VzQ29sbGVjdGlvbltpXSwgaWQgPSBpdGVtLmlkO1xyXG4gICAgICAgICAgICAgICAgICAgIGNydWREZXRlY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX21hcC5oYXMoaWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21hcC5kZWxldGUoaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghcHJldmlvdXNDb2xsZWN0aW9uIHx8IHByZXZpb3VzQ29sbGVjdGlvbi5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgaWYgKGN1cnJlbnRDb2xsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBhZGRlZFxyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBjdXJyZW50Q29sbGVjdGlvbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjcnVkRGV0ZWN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSBjdXJyZW50Q29sbGVjdGlvbltpXSwgaWQgPSBpdGVtLmlkO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX21hcC5zZXQoaWQsIHsgd2lkdGg6IGl0ZW1TaXplLCBoZWlnaHQ6IGl0ZW1TaXplLCBtZXRob2Q6IEl0ZW1EaXNwbGF5TWV0aG9kcy5DUkVBVEUgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBjb2xsZWN0aW9uRGljdDogeyBbaWQ6IElkXTogSSB9ID0ge307XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBjdXJyZW50Q29sbGVjdGlvbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgaXRlbSA9IGN1cnJlbnRDb2xsZWN0aW9uW2ldO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgY29sbGVjdGlvbkRpY3RbaXRlbS5pZF0gPSBpdGVtO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG5vdENoYW5nZWRNYXA6IHsgW2lkOiBJZF06IEkgfSA9IHt9LCBkZWxldGVkTWFwOiB7IFtpZDogSWRdOiBJIH0gPSB7fSwgZGVsZXRlZEl0ZW1zTWFwOiB7IFtpbmRleDogbnVtYmVyXTogSVNpemUgfSA9IHt9LCB1cGRhdGVkTWFwOiB7IFtpZDogSWRdOiBJIH0gPSB7fTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbCA9IHByZXZpb3VzQ29sbGVjdGlvbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgaXRlbSA9IHByZXZpb3VzQ29sbGVjdGlvbltpXSwgaWQgPSBpdGVtLmlkO1xyXG4gICAgICAgICAgICBpZiAoaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNvbGxlY3Rpb25EaWN0Lmhhc093blByb3BlcnR5KGlkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtID09PSBjb2xsZWN0aW9uRGljdFtpZF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm90IGNoYW5nZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm90Q2hhbmdlZE1hcFtpdGVtLmlkXSA9IGl0ZW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21hcC5zZXQoaWQsIHsgLi4uKHRoaXMuX21hcC5nZXQoaWQpIHx8IHsgd2lkdGg6IGl0ZW1TaXplLCBoZWlnaHQ6IGl0ZW1TaXplIH0pLCBtZXRob2Q6IEl0ZW1EaXNwbGF5TWV0aG9kcy5OT1RfQ0hBTkdFRCB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXBkYXRlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjcnVkRGV0ZWN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkTWFwW2l0ZW0uaWRdID0gaXRlbTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWFwLnNldChpZCwgeyAuLi4odGhpcy5fbWFwLmdldChpZCkgfHwgeyB3aWR0aDogaXRlbVNpemUsIGhlaWdodDogaXRlbVNpemUgfSksIG1ldGhvZDogSXRlbURpc3BsYXlNZXRob2RzLlVQREFURSB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIGRlbGV0ZWRcclxuICAgICAgICAgICAgICAgIGNydWREZXRlY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBkZWxldGVkTWFwW2l0ZW0uaWRdID0gaXRlbTtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZWRJdGVtc01hcFtpXSA9IHRoaXMuX21hcC5nZXQoaXRlbS5pZCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9tYXAuZGVsZXRlKGlkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBjdXJyZW50Q29sbGVjdGlvbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgaXRlbSA9IGN1cnJlbnRDb2xsZWN0aW9uW2ldLCBpZCA9IGl0ZW0uaWQ7XHJcbiAgICAgICAgICAgIGlmIChpdGVtICYmICFkZWxldGVkTWFwLmhhc093blByb3BlcnR5KGlkKSAmJiAhdXBkYXRlZE1hcC5oYXNPd25Qcm9wZXJ0eShpZCkgJiYgIW5vdENoYW5nZWRNYXAuaGFzT3duUHJvcGVydHkoaWQpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBhZGRlZFxyXG4gICAgICAgICAgICAgICAgY3J1ZERldGVjdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX21hcC5zZXQoaWQsIHsgd2lkdGg6IGl0ZW1TaXplLCBoZWlnaHQ6IGl0ZW1TaXplLCBtZXRob2Q6IEl0ZW1EaXNwbGF5TWV0aG9kcy5DUkVBVEUgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fY3J1ZERldGVjdGVkID0gY3J1ZERldGVjdGVkO1xyXG4gICAgICAgIHRoaXMuX2RlbGV0ZWRJdGVtc01hcCA9IGRlbGV0ZWRJdGVtc01hcDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpbmRzIHRoZSBwb3NpdGlvbiBvZiBhIGNvbGxlY3Rpb24gZWxlbWVudCBieSB0aGUgZ2l2ZW4gSWRcclxuICAgICAqL1xyXG4gICAgZ2V0SXRlbVBvc2l0aW9uPEkgZXh0ZW5kcyB7IGlkOiBJZCB9LCBDIGV4dGVuZHMgQXJyYXk8ST4+KGlkOiBJZCwgc3RpY2t5TWFwOiBJVmlydHVhbExpc3RTdGlja3lNYXAsXHJcbiAgICAgICAgb3B0aW9uczogSUdldEl0ZW1Qb3NpdGlvbk9wdGlvbnM8SSwgQz4pOiBudW1iZXIge1xyXG4gICAgICAgIGNvbnN0IG9wdCA9IHsgZnJvbUl0ZW1JZDogaWQsIHN0aWNreU1hcCwgLi4ub3B0aW9ucyB9O1xyXG4gICAgICAgIHRoaXMuX2RlZmF1bHRCdWZmZXJTaXplID0gb3B0LmJ1ZmZlclNpemU7XHJcbiAgICAgICAgdGhpcy5fbWF4QnVmZmVyU2l6ZSA9IG9wdC5tYXhCdWZmZXJTaXplO1xyXG5cclxuICAgICAgICBjb25zdCB7IHNjcm9sbFNpemUsIGlzRnJvbUl0ZW1JZEZvdW5kIH0gPSB0aGlzLnJlY2FsY3VsYXRlTWV0cmljcyh7XHJcbiAgICAgICAgICAgIC4uLm9wdCxcclxuICAgICAgICAgICAgZHluYW1pY1NpemU6IHRoaXMuX2NydWREZXRlY3RlZCB8fCBvcHQuZHluYW1pY1NpemUsXHJcbiAgICAgICAgICAgIHByZXZpb3VzVG90YWxTaXplOiB0aGlzLl9wcmV2aW91c1RvdGFsU2l6ZSxcclxuICAgICAgICAgICAgY3J1ZERldGVjdGVkOiB0aGlzLl9jcnVkRGV0ZWN0ZWQsXHJcbiAgICAgICAgICAgIGRlbGV0ZWRJdGVtc01hcDogdGhpcy5fZGVsZXRlZEl0ZW1zTWFwLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBpc0Zyb21JdGVtSWRGb3VuZCA/IHNjcm9sbFNpemUgOiAtMTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFVwZGF0ZXMgdGhlIGNvbGxlY3Rpb24gb2YgZGlzcGxheSBvYmplY3RzXHJcbiAgICAgKi9cclxuICAgIHVwZGF0ZUNvbGxlY3Rpb248SSBleHRlbmRzIHsgaWQ6IElkIH0sIEMgZXh0ZW5kcyBBcnJheTxJPj4oaXRlbXM6IEMsIHN0aWNreU1hcDogSVZpcnR1YWxMaXN0U3RpY2t5TWFwLFxyXG4gICAgICAgIG9wdGlvbnM6IElVcGRhdGVDb2xsZWN0aW9uT3B0aW9uczxJLCBDPik6IElVcGRhdGVDb2xsZWN0aW9uUmV0dXJucyB7XHJcbiAgICAgICAgY29uc3Qgb3B0ID0geyBzdGlja3lNYXAsIC4uLm9wdGlvbnMgfSwgY3J1ZERldGVjdGVkID0gdGhpcy5fY3J1ZERldGVjdGVkLCBkZWxldGVkSXRlbXNNYXAgPSB0aGlzLl9kZWxldGVkSXRlbXNNYXA7XHJcbiAgICAgICAgaWYgKG9wdC5keW5hbWljU2l6ZSkge1xyXG4gICAgICAgICAgICB0aGlzLmNhY2hlRWxlbWVudHMoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fZGVmYXVsdEJ1ZmZlclNpemUgPSBvcHQuYnVmZmVyU2l6ZTtcclxuICAgICAgICB0aGlzLl9tYXhCdWZmZXJTaXplID0gb3B0Lm1heEJ1ZmZlclNpemU7XHJcblxyXG4gICAgICAgIGNvbnN0IG1ldHJpY3MgPSB0aGlzLnJlY2FsY3VsYXRlTWV0cmljcyh7XHJcbiAgICAgICAgICAgIC4uLm9wdCxcclxuICAgICAgICAgICAgY29sbGVjdGlvbjogaXRlbXMsXHJcbiAgICAgICAgICAgIHByZXZpb3VzVG90YWxTaXplOiB0aGlzLl9wcmV2aW91c1RvdGFsU2l6ZSxcclxuICAgICAgICAgICAgY3J1ZERldGVjdGVkOiB0aGlzLl9jcnVkRGV0ZWN0ZWQsXHJcbiAgICAgICAgICAgIGRlbGV0ZWRJdGVtc01hcCxcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5fZGVsdGEgKz0gbWV0cmljcy5kZWx0YTtcclxuXHJcbiAgICAgICAgdGhpcy51cGRhdGVBZGFwdGl2ZUJ1ZmZlclBhcmFtcyhtZXRyaWNzLCBpdGVtcy5sZW5ndGgpO1xyXG5cclxuICAgICAgICB0aGlzLl9wcmV2aW91c1RvdGFsU2l6ZSA9IG1ldHJpY3MudG90YWxTaXplO1xyXG5cclxuICAgICAgICB0aGlzLl9kZWxldGVkSXRlbXNNYXAgPSB7fTtcclxuXHJcbiAgICAgICAgdGhpcy5fY3J1ZERldGVjdGVkID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmIChvcHQuZHluYW1pY1NpemUpIHtcclxuICAgICAgICAgICAgdGhpcy5zbmFwc2hvdCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZGlzcGxheUl0ZW1zID0gdGhpcy5nZW5lcmF0ZURpc3BsYXlDb2xsZWN0aW9uKGl0ZW1zLCBzdGlja3lNYXAsIHsgLi4ubWV0cmljcywgfSk7XHJcbiAgICAgICAgcmV0dXJuIHsgZGlzcGxheUl0ZW1zLCB0b3RhbFNpemU6IG1ldHJpY3MudG90YWxTaXplLCBkZWx0YTogbWV0cmljcy5kZWx0YSwgY3J1ZERldGVjdGVkIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaW5kcyB0aGUgY2xvc2VzdCBlbGVtZW50IGluIHRoZSBjb2xsZWN0aW9uIGJ5IHNjcm9sbFNpemVcclxuICAgICAqL1xyXG4gICAgZ2V0TmVhcmVzdEl0ZW08SSBleHRlbmRzIHsgaWQ6IElkIH0sIEMgZXh0ZW5kcyBBcnJheTxJPj4oc2Nyb2xsU2l6ZTogbnVtYmVyLCBpdGVtczogQywgaXRlbVNpemU6IG51bWJlciwgaXNWZXJ0aWNhbDogYm9vbGVhbik6IEkgfCB1bmRlZmluZWQge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnRGcm9tU3RhcnQoc2Nyb2xsU2l6ZSwgaXRlbXMsIHRoaXMuX21hcCwgaXRlbVNpemUsIGlzVmVydGljYWwpO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBfcHJldmlvdXNTY3JvbGxTaXplID0gMDtcclxuXHJcbiAgICBwcm90ZWN0ZWQgdXBkYXRlQWRhcHRpdmVCdWZmZXJQYXJhbXMobWV0cmljczogSU1ldHJpY3MsIHRvdGFsSXRlbXNMZW5ndGg6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuZGlzcG9zZUNsZWFyQnVmZmVyU2l6ZVRpbWVyKCk7XHJcblxyXG4gICAgICAgIGNvbnN0IHNjcm9sbFNpemUgPSBtZXRyaWNzLnNjcm9sbFNpemUgKyB0aGlzLl9kZWx0YSwgZGVsdGEgPSBNYXRoLmFicyh0aGlzLl9wcmV2aW91c1Njcm9sbFNpemUgLSBzY3JvbGxTaXplKTtcclxuICAgICAgICB0aGlzLl9wcmV2aW91c1Njcm9sbFNpemUgPSBzY3JvbGxTaXplO1xyXG4gICAgICAgIGNvbnN0IGJ1ZmZlclJhd1NpemUgPSBNYXRoLm1pbihNYXRoLmZsb29yKGRlbHRhIC8gbWV0cmljcy50eXBpY2FsSXRlbVNpemUpICogNSwgdG90YWxJdGVtc0xlbmd0aCksXHJcbiAgICAgICAgICAgIG1pbkJ1ZmZlclNpemUgPSBidWZmZXJSYXdTaXplIDwgdGhpcy5fZGVmYXVsdEJ1ZmZlclNpemUgPyB0aGlzLl9kZWZhdWx0QnVmZmVyU2l6ZSA6IGJ1ZmZlclJhd1NpemUsXHJcbiAgICAgICAgICAgIGJ1ZmZlclZhbHVlID0gbWluQnVmZmVyU2l6ZSA+IHRoaXMuX21heEJ1ZmZlclNpemUgPyB0aGlzLl9tYXhCdWZmZXJTaXplIDogbWluQnVmZmVyU2l6ZTtcclxuXHJcbiAgICAgICAgdGhpcy5fYnVmZmVyU2l6ZSA9IGJ1ZmZlckludGVycG9sYXRpb24odGhpcy5fYnVmZmVyU2l6ZSwgdGhpcy5fYnVmZmVyU2l6ZVNlcXVlbmNlLCBidWZmZXJWYWx1ZSwge1xyXG4gICAgICAgICAgICBleHRyZW11bVRocmVzaG9sZDogdGhpcy5fYnVmZmVyU2VxdWVuY2VFeHRyYVRocmVzaG9sZCxcclxuICAgICAgICAgICAgYnVmZmVyU2l6ZTogdGhpcy5fbWF4QnVmZmVyU2VxdWVuY2VMZW5ndGgsXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuc3RhcnRSZXNldEJ1ZmZlclNpemVUaW1lcigpO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBzdGFydFJlc2V0QnVmZmVyU2l6ZVRpbWVyKCkge1xyXG4gICAgICAgIHRoaXMuX3Jlc2V0QnVmZmVyU2l6ZVRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlclNpemUgPSB0aGlzLl9kZWZhdWx0QnVmZmVyU2l6ZTtcclxuICAgICAgICAgICAgdGhpcy5fYnVmZmVyU2l6ZVNlcXVlbmNlID0gW107XHJcbiAgICAgICAgfSwgdGhpcy5fcmVzZXRCdWZmZXJTaXplVGltZW91dCkgYXMgdW5rbm93biBhcyBudW1iZXI7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGRpc3Bvc2VDbGVhckJ1ZmZlclNpemVUaW1lcigpIHtcclxuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fcmVzZXRCdWZmZXJTaXplVGltZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgcG9zaXRpb24gb2YgYW4gZWxlbWVudCBiYXNlZCBvbiB0aGUgZ2l2ZW4gc2Nyb2xsU2l6ZVxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgZ2V0RWxlbWVudEZyb21TdGFydDxJIGV4dGVuZHMgeyBpZDogSWQgfSwgQyBleHRlbmRzIEFycmF5PEk+PihzY3JvbGxTaXplOiBudW1iZXIsIGNvbGxlY3Rpb246IEMsIG1hcDogQ01hcDxJZCwgSVNpemU+LCB0eXBpY2FsSXRlbVNpemU6IG51bWJlcixcclxuICAgICAgICBpc1ZlcnRpY2FsOiBib29sZWFuKTogSSB8IHVuZGVmaW5lZCB7XHJcbiAgICAgICAgY29uc3Qgc2l6ZVByb3BlcnR5ID0gaXNWZXJ0aWNhbCA/IEhFSUdIVF9QUk9QX05BTUUgOiBXSURUSF9QUk9QX05BTUU7XHJcbiAgICAgICAgbGV0IG9mZnNldCA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBjb2xsZWN0aW9uLmxlbmd0aDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBpdGVtID0gY29sbGVjdGlvbltpXTtcclxuICAgICAgICAgICAgbGV0IGl0ZW1TaXplID0gMDtcclxuICAgICAgICAgICAgaWYgKG1hcC5oYXMoaXRlbS5pZCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJvdW5kcyA9IG1hcC5nZXQoaXRlbS5pZCk7XHJcbiAgICAgICAgICAgICAgICBpdGVtU2l6ZSA9IGJvdW5kcyA/IGJvdW5kc1tzaXplUHJvcGVydHldIDogdHlwaWNhbEl0ZW1TaXplO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaXRlbVNpemUgPSB0eXBpY2FsSXRlbVNpemU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG9mZnNldCA+IHNjcm9sbFNpemUpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpdGVtO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9mZnNldCArPSBpdGVtU2l6ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgdGhlIGVudHJ5IGludG8gdGhlIG92ZXJzY3JvbGwgYXJlYSBhbmQgcmV0dXJucyB0aGUgbnVtYmVyIG9mIG92ZXJzY3JvbGwgZWxlbWVudHNcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGdldEVsZW1lbnROdW1Ub0VuZDxJIGV4dGVuZHMgeyBpZDogSWQgfSwgQyBleHRlbmRzIEFycmF5PEk+PihpOiBudW1iZXIsIGNvbGxlY3Rpb246IEMsIG1hcDogQ01hcDxJZCwgSVNpemU+LCB0eXBpY2FsSXRlbVNpemU6IG51bWJlcixcclxuICAgICAgICBzaXplOiBudW1iZXIsIGlzVmVydGljYWw6IGJvb2xlYW4sIGluZGV4T2Zmc2V0OiBudW1iZXIgPSAwKTogeyBudW06IG51bWJlciwgb2Zmc2V0OiBudW1iZXIgfSB7XHJcbiAgICAgICAgY29uc3Qgc2l6ZVByb3BlcnR5ID0gaXNWZXJ0aWNhbCA/IEhFSUdIVF9QUk9QX05BTUUgOiBXSURUSF9QUk9QX05BTUU7XHJcbiAgICAgICAgbGV0IG9mZnNldCA9IDAsIG51bSA9IDA7XHJcbiAgICAgICAgZm9yIChsZXQgaiA9IGNvbGxlY3Rpb24ubGVuZ3RoIC0gaW5kZXhPZmZzZXQgLSAxOyBqID49IGk7IGotLSkge1xyXG4gICAgICAgICAgICBjb25zdCBpdGVtID0gY29sbGVjdGlvbltqXTtcclxuICAgICAgICAgICAgbGV0IGl0ZW1TaXplID0gMDtcclxuICAgICAgICAgICAgaWYgKG1hcC5oYXMoaXRlbS5pZCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJvdW5kcyA9IG1hcC5nZXQoaXRlbS5pZCk7XHJcbiAgICAgICAgICAgICAgICBpdGVtU2l6ZSA9IGJvdW5kcyA/IGJvdW5kc1tzaXplUHJvcGVydHldIDogdHlwaWNhbEl0ZW1TaXplO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaXRlbVNpemUgPSB0eXBpY2FsSXRlbVNpemU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb2Zmc2V0ICs9IGl0ZW1TaXplO1xyXG4gICAgICAgICAgICBudW0rKztcclxuICAgICAgICAgICAgaWYgKG9mZnNldCA+IHNpemUpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7IG51bTogMCwgb2Zmc2V0IH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHsgbnVtLCBvZmZzZXQgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgbGlzdCBtZXRyaWNzXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCByZWNhbGN1bGF0ZU1ldHJpY3M8SSBleHRlbmRzIHsgaWQ6IElkIH0sIEMgZXh0ZW5kcyBBcnJheTxJPj4ob3B0aW9uczogSVJlY2FsY3VsYXRlTWV0cmljc09wdGlvbnM8SSwgQz4pOiBJTWV0cmljcyB7XHJcbiAgICAgICAgY29uc3QgeyBmcm9tSXRlbUlkLCBib3VuZHMsIGNvbGxlY3Rpb24sIGR5bmFtaWNTaXplLCBpc1ZlcnRpY2FsLCBpdGVtU2l6ZSxcclxuICAgICAgICAgICAgYnVmZmVyU2l6ZTogbWluQnVmZmVyU2l6ZSwgc2Nyb2xsU2l6ZSwgc25hcCwgc3RpY2t5TWFwLCBlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uLFxyXG4gICAgICAgICAgICBwcmV2aW91c1RvdGFsU2l6ZSwgY3J1ZERldGVjdGVkLCBkZWxldGVkSXRlbXNNYXAgfSA9IG9wdGlvbnMgYXMgSVJlY2FsY3VsYXRlTWV0cmljc09wdGlvbnM8SSwgQz4gJiB7XHJcbiAgICAgICAgICAgICAgICBzdGlja3lNYXA6IElWaXJ0dWFsTGlzdFN0aWNreU1hcCxcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY29uc3QgYnVmZmVyU2l6ZSA9IE1hdGgubWF4KG1pbkJ1ZmZlclNpemUsIHRoaXMuX2J1ZmZlclNpemUpLFxyXG4gICAgICAgICAgICB7IHdpZHRoLCBoZWlnaHQgfSA9IGJvdW5kcywgc2l6ZVByb3BlcnR5ID0gaXNWZXJ0aWNhbCA/IEhFSUdIVF9QUk9QX05BTUUgOiBXSURUSF9QUk9QX05BTUUsXHJcbiAgICAgICAgICAgIHNpemUgPSBpc1ZlcnRpY2FsID8gaGVpZ2h0IDogd2lkdGgsIHRvdGFsTGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGgsIHR5cGljYWxJdGVtU2l6ZSA9IGl0ZW1TaXplLFxyXG4gICAgICAgICAgICB3ID0gaXNWZXJ0aWNhbCA/IHdpZHRoIDogdHlwaWNhbEl0ZW1TaXplLCBoID0gaXNWZXJ0aWNhbCA/IHR5cGljYWxJdGVtU2l6ZSA6IGhlaWdodCxcclxuICAgICAgICAgICAgbWFwID0gdGhpcy5fbWFwLCBzbmFwc2hvdCA9IHRoaXMuX3NuYXBzaG90LCBjaGVja092ZXJzY3JvbGxJdGVtc0xpbWl0ID0gTWF0aC5jZWlsKHNpemUgLyB0eXBpY2FsSXRlbVNpemUpLFxyXG4gICAgICAgICAgICBzbmlwcGVkUG9zID0gTWF0aC5mbG9vcihzY3JvbGxTaXplKSwgbGVmdEl0ZW1zV2VpZ2h0czogQXJyYXk8bnVtYmVyPiA9IFtdLFxyXG4gICAgICAgICAgICBpc0Zyb21JZCA9IGZyb21JdGVtSWQgIT09IHVuZGVmaW5lZCAmJiAodHlwZW9mIGZyb21JdGVtSWQgPT09ICdudW1iZXInICYmIGZyb21JdGVtSWQgPiAtMSlcclxuICAgICAgICAgICAgICAgIHx8ICh0eXBlb2YgZnJvbUl0ZW1JZCA9PT0gJ3N0cmluZycgJiYgZnJvbUl0ZW1JZCA+ICctMScpO1xyXG5cclxuICAgICAgICBsZXQgbGVmdEl0ZW1zT2Zmc2V0ID0gMCwgcmlnaHRJdGVtc09mZnNldCA9IDA7XHJcbiAgICAgICAgaWYgKGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24pIHtcclxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLnNjcm9sbERpcmVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGVmdEl0ZW1zT2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICByaWdodEl0ZW1zT2Zmc2V0ID0gYnVmZmVyU2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNhc2UgLTE6IHtcclxuICAgICAgICAgICAgICAgICAgICBsZWZ0SXRlbXNPZmZzZXQgPSBidWZmZXJTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0SXRlbXNPZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY2FzZSAwOlxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDoge1xyXG4gICAgICAgICAgICAgICAgICAgIGxlZnRJdGVtc09mZnNldCA9IHJpZ2h0SXRlbXNPZmZzZXQgPSBidWZmZXJTaXplO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGVmdEl0ZW1zT2Zmc2V0ID0gcmlnaHRJdGVtc09mZnNldCA9IGJ1ZmZlclNpemU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgaXRlbXNGcm9tU3RhcnRUb1Njcm9sbEVuZDogbnVtYmVyID0gLTEsIGl0ZW1zRnJvbURpc3BsYXlFbmRUb09mZnNldEVuZCA9IDAsIGl0ZW1zRnJvbVN0YXJ0VG9EaXNwbGF5RW5kID0gLTEsXHJcbiAgICAgICAgICAgIGxlZnRJdGVtTGVuZ3RoID0gMCwgcmlnaHRJdGVtTGVuZ3RoID0gMCxcclxuICAgICAgICAgICAgbGVmdEl0ZW1zV2VpZ2h0ID0gMCwgcmlnaHRJdGVtc1dlaWdodCA9IDAsXHJcbiAgICAgICAgICAgIGxlZnRIaWRkZW5JdGVtc1dlaWdodCA9IDAsXHJcbiAgICAgICAgICAgIHRvdGFsSXRlbXNUb0Rpc3BsYXlFbmRXZWlnaHQgPSAwLFxyXG4gICAgICAgICAgICBsZWZ0U2l6ZU9mQWRkZWRJdGVtcyA9IDAsXHJcbiAgICAgICAgICAgIGxlZnRTaXplT2ZVcGRhdGVkSXRlbXMgPSAwLFxyXG4gICAgICAgICAgICBsZWZ0U2l6ZU9mRGVsZXRlZEl0ZW1zID0gMCxcclxuICAgICAgICAgICAgaXRlbUJ5SWQ6IEkgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIGl0ZW1CeUlkUG9zOiBudW1iZXIgPSAwLFxyXG4gICAgICAgICAgICB0YXJnZXREaXNwbGF5SXRlbUluZGV4OiBudW1iZXIgPSAtMSxcclxuICAgICAgICAgICAgaXNUYXJnZXRJbk92ZXJzY3JvbGw6IGJvb2xlYW4gPSBmYWxzZSxcclxuICAgICAgICAgICAgYWN0dWFsU2Nyb2xsU2l6ZSA9IGl0ZW1CeUlkUG9zLFxyXG4gICAgICAgICAgICB0b3RhbFNpemUgPSAwLFxyXG4gICAgICAgICAgICBzdGFydEluZGV4OiBudW1iZXIsXHJcbiAgICAgICAgICAgIGlzRnJvbUl0ZW1JZEZvdW5kID0gZmFsc2U7XHJcblxyXG4gICAgICAgIC8vIElmIHRoZSBsaXN0IGlzIGR5bmFtaWMgb3IgdGhlcmUgYXJlIG5ldyBlbGVtZW50cyBpbiB0aGUgY29sbGVjdGlvbiwgdGhlbiBpdCBzd2l0Y2hlcyB0byB0aGUgbG9uZyBhbGdvcml0aG0uXHJcbiAgICAgICAgaWYgKGR5bmFtaWNTaXplKSB7XHJcbiAgICAgICAgICAgIGxldCB5ID0gMCwgc3RpY2t5Q29sbGVjdGlvbkl0ZW06IEkgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsIHN0aWNreUNvbXBvbmVudFNpemUgPSAwO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbCA9IGNvbGxlY3Rpb24ubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpaSA9IGkgKyAxLCBjb2xsZWN0aW9uSXRlbSA9IGNvbGxlY3Rpb25baV0sIGlkID0gY29sbGVjdGlvbkl0ZW0uaWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGNvbXBvbmVudFNpemUgPSAwLCBjb21wb25lbnRTaXplRGVsdGEgPSAwLCBpdGVtRGlzcGxheU1ldGhvZDogSXRlbURpc3BsYXlNZXRob2RzID0gSXRlbURpc3BsYXlNZXRob2RzLk5PVF9DSEFOR0VEO1xyXG4gICAgICAgICAgICAgICAgaWYgKG1hcC5oYXMoaWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYm91bmRzID0gbWFwLmdldChpZCkgfHwgeyB3aWR0aDogdHlwaWNhbEl0ZW1TaXplLCBoZWlnaHQ6IHR5cGljYWxJdGVtU2l6ZSB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFNpemUgPSBib3VuZHNbc2l6ZVByb3BlcnR5XTtcclxuICAgICAgICAgICAgICAgICAgICBpdGVtRGlzcGxheU1ldGhvZCA9IGJvdW5kcz8ubWV0aG9kID8/IEl0ZW1EaXNwbGF5TWV0aG9kcy5VUERBVEU7XHJcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChpdGVtRGlzcGxheU1ldGhvZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEl0ZW1EaXNwbGF5TWV0aG9kcy5VUERBVEU6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNuYXBzaG90Qm91bmRzID0gc25hcHNob3QuZ2V0KGlkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudFNuYXBzaG90U2l6ZSA9IGNvbXBvbmVudFNpemUgLSAoc25hcHNob3RCb3VuZHMgPyBzbmFwc2hvdEJvdW5kc1tzaXplUHJvcGVydHldIDogdHlwaWNhbEl0ZW1TaXplKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFNpemVEZWx0YSA9IGNvbXBvbmVudFNuYXBzaG90U2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcC5zZXQoaWQsIHsgLi4uYm91bmRzLCBtZXRob2Q6IEl0ZW1EaXNwbGF5TWV0aG9kcy5OT1RfQ0hBTkdFRCB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgSXRlbURpc3BsYXlNZXRob2RzLkNSRUFURToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50U2l6ZURlbHRhID0gdHlwaWNhbEl0ZW1TaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwLnNldChpZCwgeyAuLi5ib3VuZHMsIG1ldGhvZDogSXRlbURpc3BsYXlNZXRob2RzLk5PVF9DSEFOR0VEIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGRlbGV0ZWRJdGVtc01hcC5oYXNPd25Qcm9wZXJ0eShpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJvdW5kcyA9IGRlbGV0ZWRJdGVtc01hcFtpXSwgc2l6ZSA9IGJvdW5kcz8uW3NpemVQcm9wZXJ0eV0gPz8gdHlwaWNhbEl0ZW1TaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh5IDwgc2Nyb2xsU2l6ZSAtIHNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFNpemVPZkRlbGV0ZWRJdGVtcyArPSBzaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0b3RhbFNpemUgKz0gY29tcG9uZW50U2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaXNGcm9tSWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbUJ5SWQgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWQgIT09IGZyb21JdGVtSWQgJiYgc3RpY2t5TWFwICYmIHN0aWNreU1hcFtpZF0gPT09IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0aWNreUNvbXBvbmVudFNpemUgPSBjb21wb25lbnRTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RpY2t5Q29sbGVjdGlvbkl0ZW0gPSBjb2xsZWN0aW9uSXRlbTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlkID09PSBmcm9tSXRlbUlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0Zyb21JdGVtSWRGb3VuZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXREaXNwbGF5SXRlbUluZGV4ID0gaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGlja3lDb2xsZWN0aW9uSXRlbSAmJiBzdGlja3lNYXApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG51bSB9ID0gdGhpcy5nZXRFbGVtZW50TnVtVG9FbmQoaSwgY29sbGVjdGlvbiwgbWFwLCB0eXBpY2FsSXRlbVNpemUsIHNpemUsIGlzVmVydGljYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChudW0gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzVGFyZ2V0SW5PdmVyc2Nyb2xsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSAtPSBzaXplIC0gY29tcG9uZW50U2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RpY2t5TWFwICYmICFzdGlja3lNYXBbY29sbGVjdGlvbkl0ZW0uaWRdICYmIHkgPj0gc2Nyb2xsU2l6ZSAmJiB5IDwgc2Nyb2xsU2l6ZSArIHN0aWNreUNvbXBvbmVudFNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNuYXBwZWRZID0gc2Nyb2xsU2l6ZSAtIHN0aWNreUNvbXBvbmVudFNpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0SGlkZGVuSXRlbXNXZWlnaHQgLT0gKHNuYXBwZWRZIC0geSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gc25hcHBlZFk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5IC09IHN0aWNreUNvbXBvbmVudFNpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0SGlkZGVuSXRlbXNXZWlnaHQgLT0gc3RpY2t5Q29tcG9uZW50U2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1CeUlkID0gY29sbGVjdGlvbkl0ZW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtQnlJZFBvcyA9IHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0SXRlbXNXZWlnaHRzLnB1c2goY29tcG9uZW50U2l6ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0SGlkZGVuSXRlbXNXZWlnaHQgKz0gY29tcG9uZW50U2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zRnJvbVN0YXJ0VG9TY3JvbGxFbmQgPSBpaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeSA8PSBzY3JvbGxTaXplIC0gY29tcG9uZW50U2l6ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxlZnRJdGVtc1dlaWdodHMucHVzaChjb21wb25lbnRTaXplKTtcclxuICAgICAgICAgICAgICAgICAgICBsZWZ0SGlkZGVuSXRlbXNXZWlnaHQgKz0gY29tcG9uZW50U2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICBpdGVtc0Zyb21TdGFydFRvU2Nyb2xsRW5kID0gaWk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGlzRnJvbUlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1CeUlkID09PSB1bmRlZmluZWQgfHwgeSA8IGl0ZW1CeUlkUG9zICsgc2l6ZSArIGNvbXBvbmVudFNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXNGcm9tU3RhcnRUb0Rpc3BsYXlFbmQgPSBpaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxJdGVtc1RvRGlzcGxheUVuZFdlaWdodCArPSBjb21wb25lbnRTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtc0Zyb21EaXNwbGF5RW5kVG9PZmZzZXRFbmQgPSBpdGVtc0Zyb21TdGFydFRvRGlzcGxheUVuZCArIHJpZ2h0SXRlbXNPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh5IDw9IHNjcm9sbFNpemUgKyBzaXplICsgY29tcG9uZW50U2l6ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zRnJvbVN0YXJ0VG9EaXNwbGF5RW5kID0gaWk7XHJcbiAgICAgICAgICAgICAgICAgICAgdG90YWxJdGVtc1RvRGlzcGxheUVuZFdlaWdodCArPSBjb21wb25lbnRTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zRnJvbURpc3BsYXlFbmRUb09mZnNldEVuZCA9IGl0ZW1zRnJvbVN0YXJ0VG9EaXNwbGF5RW5kICsgcmlnaHRJdGVtc09mZnNldDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHkgPD0gc2Nyb2xsU2l6ZSAtIGNvbXBvbmVudFNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChpdGVtRGlzcGxheU1ldGhvZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJdGVtRGlzcGxheU1ldGhvZHMuQ1JFQVRFOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFNpemVPZkFkZGVkSXRlbXMgKz0gY29tcG9uZW50U2l6ZURlbHRhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJdGVtRGlzcGxheU1ldGhvZHMuVVBEQVRFOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFNpemVPZlVwZGF0ZWRJdGVtcyArPSBjb21wb25lbnRTaXplRGVsdGE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIEl0ZW1EaXNwbGF5TWV0aG9kcy5ERUxFVEU6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0U2l6ZU9mRGVsZXRlZEl0ZW1zICs9IGNvbXBvbmVudFNpemVEZWx0YTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBpdGVtc0Zyb21EaXNwbGF5RW5kVG9PZmZzZXRFbmQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHRJdGVtc1dlaWdodCArPSBjb21wb25lbnRTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB5ICs9IGNvbXBvbmVudFNpemU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChpc1RhcmdldEluT3ZlcnNjcm9sbCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgeyBudW0gfSA9IHRoaXMuZ2V0RWxlbWVudE51bVRvRW5kKFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb24ubGVuZ3RoIC0gKGNoZWNrT3ZlcnNjcm9sbEl0ZW1zTGltaXQgPCAwID8gMCA6IGNvbGxlY3Rpb24ubGVuZ3RoIC0gY2hlY2tPdmVyc2Nyb2xsSXRlbXNMaW1pdCksXHJcbiAgICAgICAgICAgICAgICAgICAgY29sbGVjdGlvbiwgbWFwLCB0eXBpY2FsSXRlbVNpemUsIHNpemUsIGlzVmVydGljYWwsIGNvbGxlY3Rpb24ubGVuZ3RoIC0gKGNvbGxlY3Rpb24ubGVuZ3RoIC0gKHRhcmdldERpc3BsYXlJdGVtSW5kZXggKyAxKSksXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgaWYgKG51bSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpdGVtc0Zyb21TdGFydFRvU2Nyb2xsRW5kIC09IG51bTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGl0ZW1zRnJvbVN0YXJ0VG9TY3JvbGxFbmQgPD0gLTEpIHtcclxuICAgICAgICAgICAgICAgIGl0ZW1zRnJvbVN0YXJ0VG9TY3JvbGxFbmQgPSAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChpdGVtc0Zyb21TdGFydFRvRGlzcGxheUVuZCA8PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgaXRlbXNGcm9tU3RhcnRUb0Rpc3BsYXlFbmQgPSAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGFjdHVhbFNjcm9sbFNpemUgPSBpc0Zyb21JZCA/IGl0ZW1CeUlkUG9zIDogc2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgIGxlZnRJdGVtc1dlaWdodHMuc3BsaWNlKDAsIGxlZnRJdGVtc1dlaWdodHMubGVuZ3RoIC0gbGVmdEl0ZW1zT2Zmc2V0KTtcclxuICAgICAgICAgICAgbGVmdEl0ZW1zV2VpZ2h0cy5mb3JFYWNoKHYgPT4ge1xyXG4gICAgICAgICAgICAgICAgbGVmdEl0ZW1zV2VpZ2h0ICs9IHY7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgbGVmdEl0ZW1MZW5ndGggPSBNYXRoLm1pbihpdGVtc0Zyb21TdGFydFRvU2Nyb2xsRW5kLCBsZWZ0SXRlbXNPZmZzZXQpO1xyXG4gICAgICAgICAgICByaWdodEl0ZW1MZW5ndGggPSBpdGVtc0Zyb21TdGFydFRvRGlzcGxheUVuZCArIHJpZ2h0SXRlbXNPZmZzZXQgPiB0b3RhbExlbmd0aFxyXG4gICAgICAgICAgICAgICAgPyB0b3RhbExlbmd0aCAtIGl0ZW1zRnJvbVN0YXJ0VG9EaXNwbGF5RW5kIDogcmlnaHRJdGVtc09mZnNldDtcclxuXHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgLy8gQnVmZmVyIG9wdGltaXphdGlvbiBkb2VzIG5vdCB3b3JrIG9uIGZhc3QgbGluZWFyIGFsZ29yaXRobVxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgaWYgKGNydWREZXRlY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgbGV0IHkgPSAwO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBjb2xsZWN0aW9uLmxlbmd0aDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbGxlY3Rpb25JdGVtID0gY29sbGVjdGlvbltpXSwgaWQgPSBjb2xsZWN0aW9uSXRlbS5pZDtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgY29tcG9uZW50U2l6ZSA9IHR5cGljYWxJdGVtU2l6ZSwgaXRlbURpc3BsYXlNZXRob2Q6IEl0ZW1EaXNwbGF5TWV0aG9kcyA9IEl0ZW1EaXNwbGF5TWV0aG9kcy5OT1RfQ0hBTkdFRDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobWFwLmhhcyhpZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYm91bmRzID0gbWFwLmdldChpZCkhO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtRGlzcGxheU1ldGhvZCA9IGJvdW5kcz8ubWV0aG9kID8/IEl0ZW1EaXNwbGF5TWV0aG9kcy5VUERBVEU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtRGlzcGxheU1ldGhvZCA9PT0gSXRlbURpc3BsYXlNZXRob2RzLkNSRUFURSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwLnNldChpZCwgeyAuLi5ib3VuZHMsIG1ldGhvZDogSXRlbURpc3BsYXlNZXRob2RzLk5PVF9DSEFOR0VEIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZGVsZXRlZEl0ZW1zTWFwLmhhc093blByb3BlcnR5KGkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJvdW5kcyA9IGRlbGV0ZWRJdGVtc01hcFtpXSwgc2l6ZSA9IGJvdW5kcz8uW3NpemVQcm9wZXJ0eV0gPz8gdHlwaWNhbEl0ZW1TaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoeSA8IHNjcm9sbFNpemUgLSBzaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0U2l6ZU9mRGVsZXRlZEl0ZW1zICs9IHNpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh5IDwgc2Nyb2xsU2l6ZSAtIGNvbXBvbmVudFNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChpdGVtRGlzcGxheU1ldGhvZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJdGVtRGlzcGxheU1ldGhvZHMuQ1JFQVRFOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFNpemVPZlVwZGF0ZWRJdGVtcyArPSBjb21wb25lbnRTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJdGVtRGlzcGxheU1ldGhvZHMuVVBEQVRFOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFNpemVPZlVwZGF0ZWRJdGVtcyArPSBjb21wb25lbnRTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBJdGVtRGlzcGxheU1ldGhvZHMuREVMRVRFOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFNpemVPZkRlbGV0ZWRJdGVtcyArPSBjb21wb25lbnRTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHkgKz0gY29tcG9uZW50U2l6ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpdGVtc0Zyb21TdGFydFRvU2Nyb2xsRW5kID0gTWF0aC5mbG9vcihzY3JvbGxTaXplIC8gdHlwaWNhbEl0ZW1TaXplKTtcclxuICAgICAgICAgICAgaXRlbXNGcm9tU3RhcnRUb0Rpc3BsYXlFbmQgPSBNYXRoLmNlaWwoKHNjcm9sbFNpemUgKyBzaXplKSAvIHR5cGljYWxJdGVtU2l6ZSk7XHJcbiAgICAgICAgICAgIGxlZnRJdGVtTGVuZ3RoID0gTWF0aC5taW4oaXRlbXNGcm9tU3RhcnRUb1Njcm9sbEVuZCwgYnVmZmVyU2l6ZSk7XHJcbiAgICAgICAgICAgIHJpZ2h0SXRlbUxlbmd0aCA9IGl0ZW1zRnJvbVN0YXJ0VG9EaXNwbGF5RW5kICsgYnVmZmVyU2l6ZSA+IHRvdGFsTGVuZ3RoXHJcbiAgICAgICAgICAgICAgICA/IHRvdGFsTGVuZ3RoIC0gaXRlbXNGcm9tU3RhcnRUb0Rpc3BsYXlFbmQgOiBidWZmZXJTaXplO1xyXG4gICAgICAgICAgICBsZWZ0SXRlbXNXZWlnaHQgPSBsZWZ0SXRlbUxlbmd0aCAqIHR5cGljYWxJdGVtU2l6ZTtcclxuICAgICAgICAgICAgcmlnaHRJdGVtc1dlaWdodCA9IHJpZ2h0SXRlbUxlbmd0aCAqIHR5cGljYWxJdGVtU2l6ZTtcclxuICAgICAgICAgICAgbGVmdEhpZGRlbkl0ZW1zV2VpZ2h0ID0gaXRlbXNGcm9tU3RhcnRUb1Njcm9sbEVuZCAqIHR5cGljYWxJdGVtU2l6ZTtcclxuICAgICAgICAgICAgdG90YWxJdGVtc1RvRGlzcGxheUVuZFdlaWdodCA9IGl0ZW1zRnJvbVN0YXJ0VG9EaXNwbGF5RW5kICogdHlwaWNhbEl0ZW1TaXplO1xyXG4gICAgICAgICAgICB0b3RhbFNpemUgPSB0b3RhbExlbmd0aCAqIHR5cGljYWxJdGVtU2l6ZTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGsgPSB0b3RhbFNpemUgIT09IDAgPyBwcmV2aW91c1RvdGFsU2l6ZSAvIHRvdGFsU2l6ZSA6IDA7XHJcbiAgICAgICAgICAgIGFjdHVhbFNjcm9sbFNpemUgPSBzY3JvbGxTaXplICogaztcclxuICAgICAgICB9XHJcbiAgICAgICAgc3RhcnRJbmRleCA9IE1hdGgubWluKGl0ZW1zRnJvbVN0YXJ0VG9TY3JvbGxFbmQgLSBsZWZ0SXRlbUxlbmd0aCwgdG90YWxMZW5ndGggPiAwID8gdG90YWxMZW5ndGggLSAxIDogMCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGl0ZW1zT25EaXNwbGF5V2VpZ2h0ID0gdG90YWxJdGVtc1RvRGlzcGxheUVuZFdlaWdodCAtIGxlZnRJdGVtc1dlaWdodCxcclxuICAgICAgICAgICAgaXRlbXNPbkRpc3BsYXlMZW5ndGggPSBpdGVtc0Zyb21TdGFydFRvRGlzcGxheUVuZCAtIGl0ZW1zRnJvbVN0YXJ0VG9TY3JvbGxFbmQsXHJcbiAgICAgICAgICAgIHN0YXJ0UG9zaXRpb24gPSBsZWZ0SGlkZGVuSXRlbXNXZWlnaHQgLSBsZWZ0SXRlbXNXZWlnaHQsXHJcbiAgICAgICAgICAgIHJlbmRlckl0ZW1zID0gaXRlbXNPbkRpc3BsYXlMZW5ndGggKyBsZWZ0SXRlbUxlbmd0aCArIHJpZ2h0SXRlbUxlbmd0aCxcclxuICAgICAgICAgICAgZGVsdGEgPSBsZWZ0U2l6ZU9mVXBkYXRlZEl0ZW1zICsgbGVmdFNpemVPZkFkZGVkSXRlbXMgLSBsZWZ0U2l6ZU9mRGVsZXRlZEl0ZW1zO1xyXG5cclxuICAgICAgICBjb25zdCBtZXRyaWNzOiBJTWV0cmljcyA9IHtcclxuICAgICAgICAgICAgZGVsdGEsXHJcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRJdGVtV2lkdGg6IHcsXHJcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRJdGVtSGVpZ2h0OiBoLFxyXG4gICAgICAgICAgICB3aWR0aCxcclxuICAgICAgICAgICAgaGVpZ2h0LFxyXG4gICAgICAgICAgICBkeW5hbWljU2l6ZSxcclxuICAgICAgICAgICAgaXRlbVNpemUsXHJcbiAgICAgICAgICAgIGl0ZW1zRnJvbVN0YXJ0VG9TY3JvbGxFbmQsXHJcbiAgICAgICAgICAgIGl0ZW1zRnJvbVN0YXJ0VG9EaXNwbGF5RW5kLFxyXG4gICAgICAgICAgICBpdGVtc09uRGlzcGxheVdlaWdodCxcclxuICAgICAgICAgICAgaXRlbXNPbkRpc3BsYXlMZW5ndGgsXHJcbiAgICAgICAgICAgIGlzVmVydGljYWwsXHJcbiAgICAgICAgICAgIGxlZnRIaWRkZW5JdGVtc1dlaWdodCxcclxuICAgICAgICAgICAgbGVmdEl0ZW1MZW5ndGgsXHJcbiAgICAgICAgICAgIGxlZnRJdGVtc1dlaWdodCxcclxuICAgICAgICAgICAgcmVuZGVySXRlbXMsXHJcbiAgICAgICAgICAgIHJpZ2h0SXRlbUxlbmd0aCxcclxuICAgICAgICAgICAgcmlnaHRJdGVtc1dlaWdodCxcclxuICAgICAgICAgICAgc2Nyb2xsU2l6ZTogYWN0dWFsU2Nyb2xsU2l6ZSxcclxuICAgICAgICAgICAgbGVmdFNpemVPZkFkZGVkSXRlbXMsXHJcbiAgICAgICAgICAgIHNpemVQcm9wZXJ0eSxcclxuICAgICAgICAgICAgc25hcCxcclxuICAgICAgICAgICAgc25pcHBlZFBvcyxcclxuICAgICAgICAgICAgc3RhcnRJbmRleCxcclxuICAgICAgICAgICAgc3RhcnRQb3NpdGlvbixcclxuICAgICAgICAgICAgdG90YWxJdGVtc1RvRGlzcGxheUVuZFdlaWdodCxcclxuICAgICAgICAgICAgdG90YWxMZW5ndGgsXHJcbiAgICAgICAgICAgIHRvdGFsU2l6ZSxcclxuICAgICAgICAgICAgdHlwaWNhbEl0ZW1TaXplLFxyXG4gICAgICAgICAgICBpc0Zyb21JdGVtSWRGb3VuZCxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gbWV0cmljcztcclxuICAgIH1cclxuXHJcbiAgICBjbGVhckRlbHRhRGlyZWN0aW9uKCkge1xyXG4gICAgICAgIHRoaXMuY2xlYXJTY3JvbGxEaXJlY3Rpb25DYWNoZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsZWFyRGVsdGEoY2xlYXJEaXJlY3Rpb25EZXRlY3RvciA9IGZhbHNlKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZGVsdGEgPSAwO1xyXG5cclxuICAgICAgICBpZiAoY2xlYXJEaXJlY3Rpb25EZXRlY3Rvcikge1xyXG4gICAgICAgICAgICB0aGlzLmNsZWFyU2Nyb2xsRGlyZWN0aW9uQ2FjaGUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY2hhbmdlcygpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmJ1bXBWZXJzaW9uKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGdlbmVyYXRlRGlzcGxheUNvbGxlY3Rpb248SSBleHRlbmRzIHsgaWQ6IElkIH0sIEMgZXh0ZW5kcyBBcnJheTxJPj4oaXRlbXM6IEMsIHN0aWNreU1hcDogSVZpcnR1YWxMaXN0U3RpY2t5TWFwLFxyXG4gICAgICAgIG1ldHJpY3M6IElNZXRyaWNzKTogSVJlbmRlclZpcnR1YWxMaXN0Q29sbGVjdGlvbiB7XHJcbiAgICAgICAgY29uc3Qge1xyXG4gICAgICAgICAgICB3aWR0aCxcclxuICAgICAgICAgICAgaGVpZ2h0LFxyXG4gICAgICAgICAgICBub3JtYWxpemVkSXRlbVdpZHRoLFxyXG4gICAgICAgICAgICBub3JtYWxpemVkSXRlbUhlaWdodCxcclxuICAgICAgICAgICAgZHluYW1pY1NpemUsXHJcbiAgICAgICAgICAgIGl0ZW1zT25EaXNwbGF5TGVuZ3RoLFxyXG4gICAgICAgICAgICBpdGVtc0Zyb21TdGFydFRvU2Nyb2xsRW5kLFxyXG4gICAgICAgICAgICBpc1ZlcnRpY2FsLFxyXG4gICAgICAgICAgICByZW5kZXJJdGVtczogcmVuZGVySXRlbXNMZW5ndGgsXHJcbiAgICAgICAgICAgIHNjcm9sbFNpemUsXHJcbiAgICAgICAgICAgIHNpemVQcm9wZXJ0eSxcclxuICAgICAgICAgICAgc25hcCxcclxuICAgICAgICAgICAgc25pcHBlZFBvcyxcclxuICAgICAgICAgICAgc3RhcnRQb3NpdGlvbixcclxuICAgICAgICAgICAgdG90YWxMZW5ndGgsXHJcbiAgICAgICAgICAgIHN0YXJ0SW5kZXgsXHJcbiAgICAgICAgICAgIHR5cGljYWxJdGVtU2l6ZSxcclxuICAgICAgICB9ID0gbWV0cmljcyxcclxuICAgICAgICAgICAgZGlzcGxheUl0ZW1zOiBJUmVuZGVyVmlydHVhbExpc3RDb2xsZWN0aW9uID0gW107XHJcbiAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBjb25zdCBhY3R1YWxTbmlwcGVkUG9zaXRpb24gPSBzbmlwcGVkUG9zLCBpc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQgPSB0aGlzLmlzU25hcHBpbmdNZXRob2RBZHZhbmNlZCxcclxuICAgICAgICAgICAgICAgIGJvdW5kc1NpemUgPSBpc1ZlcnRpY2FsID8gaGVpZ2h0IDogd2lkdGgsIGFjdHVhbEVuZFNuaXBwZWRQb3NpdGlvbiA9IGJvdW5kc1NpemU7XHJcbiAgICAgICAgICAgIGxldCBwb3MgPSBzdGFydFBvc2l0aW9uLFxyXG4gICAgICAgICAgICAgICAgcmVuZGVySXRlbXMgPSByZW5kZXJJdGVtc0xlbmd0aCxcclxuICAgICAgICAgICAgICAgIHN0aWNreUl0ZW06IElSZW5kZXJWaXJ0dWFsTGlzdEl0ZW0gfCB1bmRlZmluZWQsIG5leHRTdGlja3k6IElSZW5kZXJWaXJ0dWFsTGlzdEl0ZW0gfCB1bmRlZmluZWQsIHN0aWNreUl0ZW1JbmRleCA9IC0xLFxyXG4gICAgICAgICAgICAgICAgc3RpY2t5SXRlbVNpemUgPSAwLCBlbmRTdGlja3lJdGVtOiBJUmVuZGVyVmlydHVhbExpc3RJdGVtIHwgdW5kZWZpbmVkLCBuZXh0RW5kU3RpY2t5OiBJUmVuZGVyVmlydHVhbExpc3RJdGVtIHwgdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgZW5kU3RpY2t5SXRlbUluZGV4ID0gLTEsIGVuZFN0aWNreUl0ZW1TaXplID0gMDtcclxuXHJcbiAgICAgICAgICAgIGlmIChzbmFwKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gTWF0aC5taW4oaXRlbXNGcm9tU3RhcnRUb1Njcm9sbEVuZCA+IDAgPyBpdGVtc0Zyb21TdGFydFRvU2Nyb2xsRW5kIDogMCwgdG90YWxMZW5ndGggLSAxKTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWl0ZW1zW2ldKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IGl0ZW1zW2ldLmlkLCBzdGlja3kgPSBzdGlja3lNYXBbaWRdLCBzaXplID0gZHluYW1pY1NpemUgPyB0aGlzLmdldChpZCk/LltzaXplUHJvcGVydHldIHx8IHR5cGljYWxJdGVtU2l6ZSA6IHR5cGljYWxJdGVtU2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3RpY2t5ID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lYXN1cmVzID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaXNWZXJ0aWNhbCA/IDAgOiBhY3R1YWxTbmlwcGVkUG9zaXRpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpc1ZlcnRpY2FsID8gYWN0dWFsU25pcHBlZFBvc2l0aW9uIDogMCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBpc1ZlcnRpY2FsID8gbm9ybWFsaXplZEl0ZW1XaWR0aCA6IHNpemUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGlzVmVydGljYWwgPyBzaXplIDogbm9ybWFsaXplZEl0ZW1IZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWx0YTogMCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgY29uZmlnID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNWZXJ0aWNhbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0aWNreSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNuYXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbmFwcGVkOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc25hcHBlZE91dDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeW5hbWljOiBkeW5hbWljU2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU25hcHBpbmdNZXRob2RBZHZhbmNlZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHpJbmRleDogJzEnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbURhdGE6IEkgPSBpdGVtc1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0aWNreUl0ZW0gPSB7IGlkLCBtZWFzdXJlcywgZGF0YTogaXRlbURhdGEsIGNvbmZpZyB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGlja3lJdGVtSW5kZXggPSBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGlja3lJdGVtU2l6ZSA9IHNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5SXRlbXMucHVzaChzdGlja3lJdGVtKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoc25hcCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRJbmRleCA9IGl0ZW1zRnJvbVN0YXJ0VG9TY3JvbGxFbmQgKyBpdGVtc09uRGlzcGxheUxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gTWF0aC5taW4oc3RhcnRJbmRleCwgdG90YWxMZW5ndGggPiAwID8gdG90YWxMZW5ndGggLSAxIDogMCksIGwgPSB0b3RhbExlbmd0aDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghaXRlbXNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gaXRlbXNbaV0uaWQsIHN0aWNreSA9IHN0aWNreU1hcFtpZF0sIHNpemUgPSBkeW5hbWljU2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMuZ2V0KGlkKT8uW3NpemVQcm9wZXJ0eV0gfHwgdHlwaWNhbEl0ZW1TaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwaWNhbEl0ZW1TaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGlja3kgPT09IDIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdyA9IGlzVmVydGljYWwgPyBub3JtYWxpemVkSXRlbVdpZHRoIDogc2l6ZSwgaCA9IGlzVmVydGljYWwgPyBzaXplIDogbm9ybWFsaXplZEl0ZW1IZWlnaHQsIG1lYXN1cmVzID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaXNWZXJ0aWNhbCA/IDAgOiBhY3R1YWxFbmRTbmlwcGVkUG9zaXRpb24gLSB3LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaXNWZXJ0aWNhbCA/IGFjdHVhbEVuZFNuaXBwZWRQb3NpdGlvbiAtIGggOiAwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWx0YTogMCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgY29uZmlnID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNWZXJ0aWNhbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0aWNreSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNuYXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbmFwcGVkOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc25hcHBlZE91dDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeW5hbWljOiBkeW5hbWljU2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU25hcHBpbmdNZXRob2RBZHZhbmNlZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHpJbmRleDogJzEnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbURhdGE6IEkgPSBpdGVtc1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZFN0aWNreUl0ZW0gPSB7IGlkLCBtZWFzdXJlcywgZGF0YTogaXRlbURhdGEsIGNvbmZpZyB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmRTdGlja3lJdGVtSW5kZXggPSBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmRTdGlja3lJdGVtU2l6ZSA9IHNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5SXRlbXMucHVzaChlbmRTdGlja3lJdGVtKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgaSA9IHN0YXJ0SW5kZXg7XHJcblxyXG4gICAgICAgICAgICB3aGlsZSAocmVuZGVySXRlbXMgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaSA+PSB0b3RhbExlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCFpdGVtc1tpXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gaXRlbXNbaV0uaWQsIHNpemUgPSBkeW5hbWljU2l6ZSA/IHRoaXMuZ2V0KGlkKT8uW3NpemVQcm9wZXJ0eV0gfHwgdHlwaWNhbEl0ZW1TaXplIDogdHlwaWNhbEl0ZW1TaXplO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpZCAhPT0gc3RpY2t5SXRlbT8uaWQgJiYgaWQgIT09IGVuZFN0aWNreUl0ZW0/LmlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc25hcHBlZCA9IHNuYXAgJiYgKHN0aWNreU1hcFtpZF0gPT09IDEgJiYgcG9zIDw9IHNjcm9sbFNpemUgfHwgc3RpY2t5TWFwW2lkXSA9PT0gMiAmJiBwb3MgPj0gc2Nyb2xsU2l6ZSArIGJvdW5kc1NpemUgLSBzaXplKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWVhc3VyZXMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBpc1ZlcnRpY2FsID8gc3RpY2t5TWFwW2lkXSA9PT0gMSA/IDAgOiBib3VuZHNTaXplIC0gc2l6ZSA6IHBvcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGlzVmVydGljYWwgPyBwb3MgOiBzdGlja3lNYXBbaWRdID09PSAyID8gYm91bmRzU2l6ZSAtIHNpemUgOiAwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGlzVmVydGljYWwgPyBub3JtYWxpemVkSXRlbVdpZHRoIDogc2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogaXNWZXJ0aWNhbCA/IHNpemUgOiBub3JtYWxpemVkSXRlbUhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhOiAwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBjb25maWcgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1ZlcnRpY2FsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RpY2t5OiBzdGlja3lNYXBbaWRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc25hcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNuYXBwZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc25hcHBlZE91dDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeW5hbWljOiBkeW5hbWljU2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU25hcHBpbmdNZXRob2RBZHZhbmNlZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHpJbmRleDogJzAnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc25hcHBlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWcuekluZGV4ID0gJzInO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbURhdGE6IEkgPSBpdGVtc1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXRlbTogSVJlbmRlclZpcnR1YWxMaXN0SXRlbSA9IHsgaWQsIG1lYXN1cmVzLCBkYXRhOiBpdGVtRGF0YSwgY29uZmlnIH07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuZXh0U3RpY2t5ICYmIHN0aWNreUl0ZW1JbmRleCA8IGkgJiYgc3RpY2t5TWFwW2lkXSA9PT0gMSAmJiAocG9zIDw9IHNjcm9sbFNpemUgKyBzaXplICsgc3RpY2t5SXRlbVNpemUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0ubWVhc3VyZXMueCA9IGlzVmVydGljYWwgPyAwIDogc25hcHBlZCA/IGFjdHVhbFNuaXBwZWRQb3NpdGlvbiA6IHBvcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5tZWFzdXJlcy55ID0gaXNWZXJ0aWNhbCA/IHNuYXBwZWQgPyBhY3R1YWxTbmlwcGVkUG9zaXRpb24gOiBwb3MgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXh0U3RpY2t5ID0gaXRlbTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFN0aWNreS5jb25maWcuc25hcHBlZCA9IHNuYXBwZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRTdGlja3kubWVhc3VyZXMuZGVsdGEgPSBpc1ZlcnRpY2FsID8gKGl0ZW0ubWVhc3VyZXMueSAtIHNjcm9sbFNpemUpIDogKGl0ZW0ubWVhc3VyZXMueCAtIHNjcm9sbFNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXh0U3RpY2t5LmNvbmZpZy56SW5kZXggPSAnMyc7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghbmV4dEVuZFN0aWNreSAmJiBlbmRTdGlja3lJdGVtSW5kZXggPiBpICYmIHN0aWNreU1hcFtpZF0gPT09IDIgJiYgKHBvcyA+PSBzY3JvbGxTaXplICsgYm91bmRzU2l6ZSAtIHNpemUgLSBlbmRTdGlja3lJdGVtU2l6ZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5tZWFzdXJlcy54ID0gaXNWZXJ0aWNhbCA/IDAgOiBzbmFwcGVkID8gYWN0dWFsRW5kU25pcHBlZFBvc2l0aW9uIC0gc2l6ZSA6IHBvcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5tZWFzdXJlcy55ID0gaXNWZXJ0aWNhbCA/IHNuYXBwZWQgPyBhY3R1YWxFbmRTbmlwcGVkUG9zaXRpb24gLSBzaXplIDogcG9zIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dEVuZFN0aWNreSA9IGl0ZW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRFbmRTdGlja3kuY29uZmlnLnpJbmRleCA9ICczJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dEVuZFN0aWNreS5jb25maWcuc25hcHBlZCA9IHNuYXBwZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRFbmRTdGlja3kubWVhc3VyZXMuZGVsdGEgPSBpc1ZlcnRpY2FsID8gKGl0ZW0ubWVhc3VyZXMueSAtIHNjcm9sbFNpemUpIDogKGl0ZW0ubWVhc3VyZXMueCAtIHNjcm9sbFNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheUl0ZW1zLnB1c2goaXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmVuZGVySXRlbXMgLT0gMTtcclxuICAgICAgICAgICAgICAgIHBvcyArPSBzaXplO1xyXG4gICAgICAgICAgICAgICAgaSsrO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBjb25zdCBheGlzID0gaXNWZXJ0aWNhbCA/IFlfUFJPUF9OQU1FIDogWF9QUk9QX05BTUU7XHJcblxyXG4gICAgICAgICAgICBpZiAobmV4dFN0aWNreSAmJiBzdGlja3lJdGVtICYmIG5leHRTdGlja3kubWVhc3VyZXNbYXhpc10gPD0gc2Nyb2xsU2l6ZSArIHN0aWNreUl0ZW1TaXplKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAobmV4dFN0aWNreS5tZWFzdXJlc1theGlzXSA+IHNjcm9sbFNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdGlja3lJdGVtLm1lYXN1cmVzW2F4aXNdID0gbmV4dFN0aWNreS5tZWFzdXJlc1theGlzXSAtIHN0aWNreUl0ZW1TaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0aWNreUl0ZW0uY29uZmlnLnNuYXBwZWQgPSBuZXh0U3RpY2t5LmNvbmZpZy5zbmFwcGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RpY2t5SXRlbS5jb25maWcuc25hcHBlZE91dCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RpY2t5SXRlbS5jb25maWcuc3RpY2t5ID0gMTtcclxuICAgICAgICAgICAgICAgICAgICBzdGlja3lJdGVtLm1lYXN1cmVzLmRlbHRhID0gaXNWZXJ0aWNhbCA/IHN0aWNreUl0ZW0ubWVhc3VyZXMueSAtIHNjcm9sbFNpemUgOiBzdGlja3lJdGVtLm1lYXN1cmVzLnggLSBzY3JvbGxTaXplO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0U3RpY2t5LmNvbmZpZy5zbmFwcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0U3RpY2t5Lm1lYXN1cmVzLmRlbHRhID0gaXNWZXJ0aWNhbCA/IG5leHRTdGlja3kubWVhc3VyZXMueSAtIHNjcm9sbFNpemUgOiBuZXh0U3RpY2t5Lm1lYXN1cmVzLnggLSBzY3JvbGxTaXplO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAobmV4dEVuZFN0aWNreSAmJiBlbmRTdGlja3lJdGVtICYmIG5leHRFbmRTdGlja3kubWVhc3VyZXNbYXhpc10gPj0gc2Nyb2xsU2l6ZSArIGJvdW5kc1NpemUgLSBlbmRTdGlja3lJdGVtU2l6ZSAtIG5leHRFbmRTdGlja3kubWVhc3VyZXNbc2l6ZVByb3BlcnR5XSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG5leHRFbmRTdGlja3kubWVhc3VyZXNbYXhpc10gPCBzY3JvbGxTaXplICsgYm91bmRzU2l6ZSAtIGVuZFN0aWNreUl0ZW1TaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW5kU3RpY2t5SXRlbS5tZWFzdXJlc1theGlzXSA9IG5leHRFbmRTdGlja3kubWVhc3VyZXNbYXhpc10gKyBuZXh0RW5kU3RpY2t5Lm1lYXN1cmVzW3NpemVQcm9wZXJ0eV07XHJcbiAgICAgICAgICAgICAgICAgICAgZW5kU3RpY2t5SXRlbS5jb25maWcuc25hcHBlZCA9IG5leHRFbmRTdGlja3kuY29uZmlnLnNuYXBwZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBlbmRTdGlja3lJdGVtLmNvbmZpZy5zbmFwcGVkT3V0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBlbmRTdGlja3lJdGVtLmNvbmZpZy5zdGlja3kgPSAyO1xyXG4gICAgICAgICAgICAgICAgICAgIGVuZFN0aWNreUl0ZW0ubWVhc3VyZXMuZGVsdGEgPSBpc1ZlcnRpY2FsID8gZW5kU3RpY2t5SXRlbS5tZWFzdXJlcy55IC0gc2Nyb2xsU2l6ZSA6IGVuZFN0aWNreUl0ZW0ubWVhc3VyZXMueCAtIHNjcm9sbFNpemU7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG5leHRFbmRTdGlja3kuY29uZmlnLnNuYXBwZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIG5leHRFbmRTdGlja3kubWVhc3VyZXMuZGVsdGEgPSBpc1ZlcnRpY2FsID8gbmV4dEVuZFN0aWNreS5tZWFzdXJlcy55IC0gc2Nyb2xsU2l6ZSA6IG5leHRFbmRTdGlja3kubWVhc3VyZXMueCAtIHNjcm9sbFNpemU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGRpc3BsYXlJdGVtcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIHRyYWNraW5nIGJ5IHByb3BOYW1lXHJcbiAgICAgKi9cclxuICAgIHRyYWNrKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghdGhpcy5faXRlbXMgfHwgIXRoaXMuX2Rpc3BsYXlDb21wb25lbnRzKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3RyYWNrZXIudHJhY2sodGhpcy5faXRlbXMsIHRoaXMuX2Rpc3BsYXlDb21wb25lbnRzLCB0aGlzLl9zbmFwZWREaXNwbGF5Q29tcG9uZW50LCB0aGlzLnNjcm9sbERpcmVjdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0RGlzcGxheU9iamVjdEluZGV4TWFwQnlJZCh2OiB7IFtpZDogbnVtYmVyXTogbnVtYmVyIH0pOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl90cmFja2VyLmRpc3BsYXlPYmplY3RJbmRleE1hcEJ5SWQgPSB2O1xyXG4gICAgfVxyXG5cclxuICAgIHVudHJhY2tDb21wb25lbnRCeUlkUHJvcGVydHkoY29tcG9uZW50PzogQyB8IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHRoaXMuX3RyYWNrZXIudW50cmFja0NvbXBvbmVudEJ5SWRQcm9wZXJ0eShjb21wb25lbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEl0ZW1Cb3VuZHMoaWQ6IElkKTogSVNpemUgfCB1bmRlZmluZWQge1xyXG4gICAgICAgIGlmICh0aGlzLmhhcyhpZCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KGlkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgY2FjaGVFbGVtZW50cygpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2Rpc3BsYXlDb21wb25lbnRzKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gdGhpcy5fZGlzcGxheUNvbXBvbmVudHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuX2Rpc3BsYXlDb21wb25lbnRzW2ldLCBpdGVtSWQgPSBjb21wb25lbnQuaW5zdGFuY2UuaXRlbUlkO1xyXG4gICAgICAgICAgICBpZiAoaXRlbUlkID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGJvdW5kcyA9IGNvbXBvbmVudC5pbnN0YW5jZS5nZXRCb3VuZHMoKTtcclxuICAgICAgICAgICAgdGhpcy5zZXQoaXRlbUlkLCBib3VuZHMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBvdmVycmlkZSBkaXNwb3NlKCkge1xyXG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcclxuXHJcbiAgICAgICAgdGhpcy5kaXNwb3NlQ2xlYXJCdWZmZXJTaXplVGltZXIoKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3RyYWNrZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5fdHJhY2tlci5kaXNwb3NlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiJdfQ==