ng-virtual-list 18.4.2 → 18.5.0

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 (59) hide show
  1. package/README.md +23 -0
  2. package/esm2022/lib/components/ng-virtual-list-item.component.mjs +19 -4
  3. package/esm2022/lib/const/index.mjs +6 -1
  4. package/esm2022/lib/models/render-item-config.model.mjs +1 -1
  5. package/esm2022/lib/models/render-item.model.mjs +1 -1
  6. package/esm2022/lib/utils/trackBox.mjs +13 -7
  7. package/esm2022/lib/utils/tracker.mjs +18 -9
  8. package/fesm2022/ng-virtual-list.mjs +50 -16
  9. package/fesm2022/ng-virtual-list.mjs.map +1 -1
  10. package/lib/components/ng-virtual-list-item.component.d.ts +3 -0
  11. package/lib/const/index.d.ts +4 -0
  12. package/lib/models/render-item-config.model.d.ts +8 -0
  13. package/lib/models/render-item.model.d.ts +4 -0
  14. package/lib/utils/tracker.d.ts +3 -7
  15. package/package.json +1 -1
  16. package/esm2020/lib/components/ng-virtual-list-item.component.mjs +0 -131
  17. package/esm2020/lib/const/index.mjs +0 -44
  18. package/esm2020/lib/enums/direction.mjs +0 -2
  19. package/esm2020/lib/enums/directions.mjs +0 -18
  20. package/esm2020/lib/enums/index.mjs +0 -4
  21. package/esm2020/lib/enums/snapping-method.mjs +0 -2
  22. package/esm2020/lib/enums/snapping-methods.mjs +0 -18
  23. package/esm2020/lib/models/base-virtual-list-item-component.mjs +0 -9
  24. package/esm2020/lib/models/collection.model.mjs +0 -3
  25. package/esm2020/lib/models/component.model.mjs +0 -2
  26. package/esm2020/lib/models/index.mjs +0 -2
  27. package/esm2020/lib/models/item.model.mjs +0 -2
  28. package/esm2020/lib/models/render-collection.model.mjs +0 -3
  29. package/esm2020/lib/models/render-item-config.model.mjs +0 -2
  30. package/esm2020/lib/models/render-item.model.mjs +0 -3
  31. package/esm2020/lib/models/scroll-direction.model.mjs +0 -2
  32. package/esm2020/lib/models/scroll-event.model.mjs +0 -2
  33. package/esm2020/lib/models/sticky-map.model.mjs +0 -2
  34. package/esm2020/lib/ng-virtual-list.component.mjs +0 -675
  35. package/esm2020/lib/ng-virtual-list.module.mjs +0 -20
  36. package/esm2020/lib/types/id.mjs +0 -2
  37. package/esm2020/lib/types/index.mjs +0 -2
  38. package/esm2020/lib/types/rect.mjs +0 -2
  39. package/esm2020/lib/types/size.mjs +0 -2
  40. package/esm2020/lib/utils/browser.mjs +0 -3
  41. package/esm2020/lib/utils/buffer-interpolation.mjs +0 -27
  42. package/esm2020/lib/utils/cacheMap.mjs +0 -167
  43. package/esm2020/lib/utils/debounce.mjs +0 -31
  44. package/esm2020/lib/utils/disposableComponent.mjs +0 -29
  45. package/esm2020/lib/utils/eventEmitter.mjs +0 -106
  46. package/esm2020/lib/utils/index.mjs +0 -5
  47. package/esm2020/lib/utils/isDirection.mjs +0 -15
  48. package/esm2020/lib/utils/scrollEvent.mjs +0 -42
  49. package/esm2020/lib/utils/snapping-method.mjs +0 -9
  50. package/esm2020/lib/utils/toggleClassName.mjs +0 -15
  51. package/esm2020/lib/utils/trackBox.mjs +0 -756
  52. package/esm2020/lib/utils/tracker.mjs +0 -134
  53. package/esm2020/ng-virtual-list.mjs +0 -5
  54. package/esm2020/public-api.mjs +0 -10
  55. package/fesm2015/ng-virtual-list.mjs +0 -2224
  56. package/fesm2015/ng-virtual-list.mjs.map +0 -1
  57. package/fesm2020/ng-virtual-list.mjs +0 -2229
  58. package/fesm2020/ng-virtual-list.mjs.map +0 -1
  59. package/lib/utils/disposableComponent.d.ts +0 -15
@@ -1,675 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, Output, ViewChild, ViewContainerRef, ViewEncapsulation, } from '@angular/core';
2
- import { BehaviorSubject, combineLatest, distinctUntilChanged, filter, map, of, switchMap, takeUntil, tap } from 'rxjs';
3
- import { BEHAVIOR_AUTO, BEHAVIOR_INSTANT, CLASS_LIST_HORIZONTAL, CLASS_LIST_VERTICAL, DEFAULT_BUFFER_SIZE, DEFAULT_DIRECTION, DEFAULT_DYNAMIC_SIZE, DEFAULT_ENABLED_BUFFER_OPTIMIZATION, DEFAULT_ITEM_SIZE, DEFAULT_LIST_SIZE, DEFAULT_MAX_BUFFER_SIZE, DEFAULT_SNAP, DEFAULT_SNAPPING_METHOD, HEIGHT_PROP_NAME, LEFT_PROP_NAME, MAX_SCROLL_TO_ITERATIONS, PX, SCROLL, SCROLL_END, TOP_PROP_NAME, TRACK_BY_PROPERTY_NAME, WIDTH_PROP_NAME, } from './const';
4
- import { Directions } from './enums';
5
- import { ScrollEvent, toggleClassName } from './utils';
6
- import { TRACK_BOX_CHANGE_EVENT_NAME, TrackBox } from './utils/trackBox';
7
- import { DisposableComponent } from './utils/disposableComponent';
8
- import { isSnappingMethodAdvenced } from './utils/snapping-method';
9
- import { FIREFOX_SCROLLBAR_OVERLAP_SIZE, IS_FIREFOX } from './utils/browser';
10
- import { NgVirtualListItemComponent } from './components/ng-virtual-list-item.component';
11
- import { isDirection } from './utils/isDirection';
12
- import * as i0 from "@angular/core";
13
- import * as i1 from "@angular/common";
14
- /**
15
- * Virtual list component.
16
- * Maximum performance for extremely large lists.
17
- * It is based on algorithms for virtualization of screen objects.
18
- * @link https://github.com/DjonnyX/ng-virtual-list/blob/15.x/projects/ng-virtual-list/src/lib/ng-virtual-list.component.ts
19
- * @author Evgenii Grebennikov
20
- * @email djonnyx@gmail.com
21
- */
22
- export class NgVirtualListComponent extends DisposableComponent {
23
- /**
24
- * Readonly. Returns the unique identifier of the component.
25
- */
26
- get id() { return this._id; }
27
- /**
28
- * Collection of list items.
29
- */
30
- set items(v) {
31
- if (this._$items.getValue() === v) {
32
- return;
33
- }
34
- const transformedValue = this._itemsTransform(v);
35
- this._$items.next(transformedValue);
36
- this._cdr.markForCheck();
37
- }
38
- ;
39
- get items() { return this._$items.getValue(); }
40
- /**
41
- * Determines whether elements will snap. Default value is "true".
42
- */
43
- set snap(v) {
44
- if (this._$snap.getValue() === v) {
45
- return;
46
- }
47
- this._$snap.next(v);
48
- this._cdr.markForCheck();
49
- }
50
- ;
51
- get snap() { return this._$snap.getValue(); }
52
- /**
53
- * Experimental!
54
- * Enables buffer optimization.
55
- * Can only be used if items in the collection are not added or updated. Otherwise, artifacts in the form of twitching of the scroll area are possible.
56
- * Works only if the property dynamic = true
57
- */
58
- set enabledBufferOptimization(v) {
59
- if (this._$enabledBufferOptimization.getValue() === v) {
60
- return;
61
- }
62
- this._$enabledBufferOptimization.next(v);
63
- this._cdr.markForCheck();
64
- }
65
- ;
66
- get enabledBufferOptimization() { return this._$enabledBufferOptimization.getValue(); }
67
- /**
68
- * Rendering element template.
69
- */
70
- set itemRenderer(v) {
71
- if (this._$itemRenderer.getValue() === v) {
72
- return;
73
- }
74
- this._$itemRenderer.next(v);
75
- this._cdr.markForCheck();
76
- }
77
- ;
78
- get itemRenderer() { return this._$itemRenderer.getValue(); }
79
- /**
80
- * Dictionary zIndex by id of the list element. If the value is not set or equal to 0,
81
- * then a simple element is displayed, if the value is greater than 0, then the sticky position mode is enabled for the element.
82
- */
83
- set stickyMap(v) {
84
- if (this._$stickyMap.getValue() === v) {
85
- return;
86
- }
87
- this._$stickyMap.next(v);
88
- this._cdr.markForCheck();
89
- }
90
- ;
91
- get stickyMap() { return this._$stickyMap.getValue(); }
92
- /**
93
- * If direction = 'vertical', then the height of a typical element. If direction = 'horizontal', then the width of a typical element.
94
- * Ignored if the dynamicSize property is true.
95
- */
96
- set itemSize(v) {
97
- if (this._$itemSize.getValue() === v) {
98
- return;
99
- }
100
- this._$itemSize.next(this._itemSizeOptions(v));
101
- this._cdr.markForCheck();
102
- }
103
- ;
104
- get itemSize() { return this._$itemSize.getValue(); }
105
- /**
106
- * If true then the items in the list can have different sizes and the itemSize property is ignored.
107
- * If false then the items in the list have a fixed size specified by the itemSize property. The default value is false.
108
- */
109
- set dynamicSize(v) {
110
- if (this._$dynamicSize.getValue() === v) {
111
- return;
112
- }
113
- this._$dynamicSize.next(v);
114
- this._cdr.markForCheck();
115
- }
116
- ;
117
- get dynamicSize() { return this._$dynamicSize.getValue(); }
118
- /**
119
- * Determines the direction in which elements are placed. Default value is "vertical".
120
- */
121
- set direction(v) {
122
- if (this._$direction.getValue() === v) {
123
- return;
124
- }
125
- this._$direction.next(v);
126
- this._cdr.markForCheck();
127
- }
128
- ;
129
- get direction() { return this._$direction.getValue(); }
130
- /**
131
- * @deprecated "itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".
132
- */
133
- set itemsOffset(v) {
134
- throw Error('"itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".');
135
- }
136
- ;
137
- /**
138
- * Number of elements outside the scope of visibility. Default value is 2.
139
- */
140
- set bufferSize(v) {
141
- if (this._$bufferSize.getValue() === v) {
142
- return;
143
- }
144
- this._$bufferSize.next(v);
145
- }
146
- ;
147
- get bufferSize() { return this._$bufferSize.getValue(); }
148
- /**
149
- * Maximum number of elements outside the scope of visibility. Default value is 100.
150
- * If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled.
151
- * The greater the scroll size, the more elements are allocated for rendering.
152
- */
153
- set maxBufferSize(v) {
154
- const val = this._maxBufferSizeTransform(v);
155
- if (this._$maxBufferSize.getValue() === val) {
156
- return;
157
- }
158
- this._$maxBufferSize.next(val);
159
- }
160
- ;
161
- get maxBufferSize() { return this._$maxBufferSize.getValue(); }
162
- /**
163
- * The name of the property by which tracking is performed
164
- */
165
- set trackBy(v) {
166
- if (this._$trackBy.getValue() === v) {
167
- return;
168
- }
169
- this._$trackBy.next(v);
170
- }
171
- ;
172
- get trackBy() { return this._$trackBy.getValue(); }
173
- /**
174
- * Snapping method.
175
- * 'default' - Normal group rendering.
176
- * 'advanced' - The group is rendered on a transparent background. List items below the group are not rendered.
177
- */
178
- set snappingMethod(v) {
179
- if (this._$snappingMethod.getValue() === v) {
180
- return;
181
- }
182
- this._$snappingMethod.next(v);
183
- }
184
- ;
185
- get snappingMethod() { return this._$snappingMethod.getValue(); }
186
- get isSnappingMethodAdvanced() { return this._isSnappingMethodAdvanced; }
187
- get $cacheVersion() { return this._$cacheVersion.asObservable(); }
188
- constructor(_cdr, _elementRef) {
189
- super();
190
- this._cdr = _cdr;
191
- this._elementRef = _elementRef;
192
- this._id = NgVirtualListComponent.__nextId;
193
- /**
194
- * Fires when the list has been scrolled.
195
- */
196
- this.onScroll = new EventEmitter();
197
- /**
198
- * Fires when the list has completed scrolling.
199
- */
200
- this.onScrollEnd = new EventEmitter();
201
- this._$items = new BehaviorSubject(undefined);
202
- this.$items = this._$items.asObservable();
203
- this._itemsTransform = (v) => {
204
- this._trackBox.resetCollection(v, this._$itemSize.getValue());
205
- return v;
206
- };
207
- this._$snap = new BehaviorSubject(DEFAULT_SNAP);
208
- this.$snap = this._$snap.asObservable();
209
- this._$enabledBufferOptimization = new BehaviorSubject(DEFAULT_ENABLED_BUFFER_OPTIMIZATION);
210
- this.$enabledBufferOptimization = this._$enabledBufferOptimization.asObservable();
211
- this._$itemRenderer = new BehaviorSubject(undefined);
212
- this.$itemRenderer = this._$itemRenderer.asObservable();
213
- this._$renderer = new BehaviorSubject(undefined);
214
- this._$stickyMap = new BehaviorSubject({});
215
- this.$stickyMap = this._$stickyMap.asObservable();
216
- this._itemSizeOptions = (v) => {
217
- if (v === undefined) {
218
- return DEFAULT_ITEM_SIZE;
219
- }
220
- const val = Number(v);
221
- return Number.isNaN(val) || val <= 0 ? DEFAULT_ITEM_SIZE : val;
222
- };
223
- this._$itemSize = new BehaviorSubject(DEFAULT_ITEM_SIZE);
224
- this.$itemSize = this._$itemSize.asObservable();
225
- this._$dynamicSize = new BehaviorSubject(DEFAULT_DYNAMIC_SIZE);
226
- this.$dynamicSize = this._$dynamicSize.asObservable();
227
- this._$direction = new BehaviorSubject(DEFAULT_DIRECTION);
228
- this.$direction = this._$direction.asObservable();
229
- this._$bufferSize = new BehaviorSubject(DEFAULT_BUFFER_SIZE);
230
- this.$bufferSize = this._$bufferSize.asObservable();
231
- this._maxBufferSizeTransform = (v) => {
232
- const bufferSize = this._$bufferSize.getValue();
233
- if (v === undefined || v <= bufferSize) {
234
- return bufferSize;
235
- }
236
- return v;
237
- };
238
- this._$maxBufferSize = new BehaviorSubject(DEFAULT_MAX_BUFFER_SIZE);
239
- this.$maxBufferSize = this._$maxBufferSize.asObservable();
240
- this._$trackBy = new BehaviorSubject(TRACK_BY_PROPERTY_NAME);
241
- this.$trackBy = this._$trackBy.asObservable();
242
- this._isVertical = this.getIsVertical();
243
- this._$snappingMethod = new BehaviorSubject(DEFAULT_SNAPPING_METHOD);
244
- this.$snappingMethod = this._$snappingMethod.asObservable();
245
- this._isSnappingMethodAdvanced = this.getIsSnappingMethodAdvanced();
246
- this._displayComponents = [];
247
- this._$bounds = new BehaviorSubject(null);
248
- this._$scrollSize = new BehaviorSubject(0);
249
- this._resizeObserver = null;
250
- this._resizeSnappedComponentHandler = () => {
251
- const list = this._list, container = this._container, snappedComponent = this._snapedDisplayComponent?.instance;
252
- if (list && container && snappedComponent) {
253
- const isVertical = this._isVertical, listBounds = list.nativeElement.getBoundingClientRect(), listElement = list?.nativeElement, { width: lWidth, height: lHeight } = listElement?.getBoundingClientRect() ?? { width: 0, height: 0 }, { width, height } = this._$bounds.getValue() ?? { width: 0, height: 0 }, isScrollable = isVertical ? container.nativeElement.scrollHeight > 0 : container.nativeElement.scrollWidth > 0;
254
- let scrollBarSize = isVertical ? width - lWidth : height - lHeight, isScrollBarOverlap = true, overlapScrollBarSize = 0;
255
- if (scrollBarSize === 0 && isScrollable) {
256
- isScrollBarOverlap = true;
257
- }
258
- if (isScrollBarOverlap && IS_FIREFOX) {
259
- scrollBarSize = overlapScrollBarSize = FIREFOX_SCROLLBAR_OVERLAP_SIZE;
260
- }
261
- const { width: sWidth, height: sHeight } = snappedComponent.getBounds() ?? { width: 0, height: 0 };
262
- snappedComponent.element.style.clipPath = `path("M 0 0 L 0 ${sHeight} L ${sWidth - overlapScrollBarSize} ${sHeight} L ${sWidth - overlapScrollBarSize} 0 Z")`;
263
- snappedComponent.regularLength = `${isVertical ? listBounds.width : listBounds.height}${PX}`;
264
- const containerElement = container.nativeElement, delta = snappedComponent.item?.measures.delta ?? 0;
265
- let left, right, top, bottom;
266
- if (isVertical) {
267
- left = 0;
268
- right = width - scrollBarSize;
269
- top = sHeight;
270
- bottom = height;
271
- containerElement.style.clipPath = `path("M 0 ${top + delta} L 0 ${height} L ${width} ${height} L ${width} 0 L ${right} 0 L ${right} ${top + delta} Z")`;
272
- }
273
- else {
274
- left = sWidth;
275
- right = width;
276
- top = 0;
277
- bottom = height - scrollBarSize;
278
- containerElement.style.clipPath = `path("M ${left + delta} 0 L ${left + delta} ${bottom} L 0 ${bottom} L 0 ${height} L ${width} ${height} L ${width} 0 Z")`;
279
- }
280
- }
281
- };
282
- this._resizeSnappedObserver = null;
283
- this._onResizeHandler = () => {
284
- const bounds = this._container?.nativeElement?.getBoundingClientRect();
285
- if (bounds) {
286
- this._$bounds.next({ width: bounds.width, height: bounds.height });
287
- }
288
- else {
289
- this._$bounds.next({ width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE });
290
- }
291
- if (this._isSnappingMethodAdvanced) {
292
- this.updateRegularRenderer();
293
- }
294
- };
295
- this._onScrollHandler = (e) => {
296
- this.clearScrollToRepeatExecutionTimeout();
297
- const container = this._container?.nativeElement;
298
- if (container) {
299
- const scrollSize = (this._isVertical ? container.scrollTop : container.scrollLeft);
300
- this._$scrollSize.next(scrollSize);
301
- }
302
- };
303
- this._$initialized = new BehaviorSubject(false);
304
- /**
305
- * Base class of the element component
306
- */
307
- this._itemComponentClass = NgVirtualListItemComponent;
308
- /**
309
- * Base class trackBox
310
- */
311
- this._trackBoxClass = TrackBox;
312
- /**
313
- * Dictionary of element sizes by their id
314
- */
315
- this._trackBox = new this._trackBoxClass(this.trackBy);
316
- this._onTrackBoxChangeHandler = (v) => {
317
- this._$cacheVersion.next(v);
318
- };
319
- this._$cacheVersion = new BehaviorSubject(-1);
320
- this._componentsResizeObserver = new ResizeObserver(() => {
321
- this._trackBox.changes();
322
- });
323
- this._onContainerScrollHandler = (e) => {
324
- const containerEl = this._container;
325
- if (containerEl) {
326
- const scrollSize = (this._isVertical ? containerEl.nativeElement.scrollTop : containerEl.nativeElement.scrollLeft);
327
- this._trackBox.deltaDirection = this._$scrollSize.getValue() > scrollSize ? -1 : this._$scrollSize.getValue() < scrollSize ? 1 : 0;
328
- const event = new ScrollEvent({
329
- direction: this._trackBox.scrollDirection, container: containerEl.nativeElement,
330
- list: this._list.nativeElement, delta: this._trackBox.delta,
331
- scrollDelta: this._trackBox.scrollDelta, isVertical: this._isVertical,
332
- });
333
- this.onScroll.emit(event);
334
- }
335
- };
336
- this._onContainerScrollEndHandler = (e) => {
337
- const containerEl = this._container;
338
- if (containerEl) {
339
- const scrollSize = (this._isVertical ? containerEl.nativeElement.scrollTop : containerEl.nativeElement.scrollLeft);
340
- this._trackBox.deltaDirection = this._$scrollSize.getValue() > scrollSize ? -1 : 0;
341
- const event = new ScrollEvent({
342
- direction: this._trackBox.scrollDirection, container: containerEl.nativeElement,
343
- list: this._list.nativeElement, delta: this._trackBox.delta,
344
- scrollDelta: this._trackBox.scrollDelta, isVertical: this._isVertical,
345
- });
346
- this.onScrollEnd.emit(event);
347
- }
348
- };
349
- NgVirtualListComponent.__nextId = NgVirtualListComponent.__nextId + 1 === Number.MAX_SAFE_INTEGER
350
- ? 0 : NgVirtualListComponent.__nextId + 1;
351
- this._id = NgVirtualListComponent.__nextId;
352
- this._$initialized = new BehaviorSubject(false);
353
- this.$initialized = this._$initialized.asObservable();
354
- this._trackBox.displayComponents = this._displayComponents;
355
- const $trackBy = this.$trackBy;
356
- $trackBy.pipe(takeUntil(this._$unsubscribe), tap(v => {
357
- this._trackBox.trackingPropertyName = v;
358
- })).subscribe();
359
- const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $items = this.$items.pipe(map(i => !i ? [] : i)), $scrollSize = this._$scrollSize.asObservable(), $itemSize = this.$itemSize.pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = this.$bufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = this.$maxBufferSize.pipe(map(v => v < 0 ? DEFAULT_MAX_BUFFER_SIZE : v)), $stickyMap = this.$stickyMap.pipe(map(v => !v ? {} : v)), $snap = this.$snap, $isVertical = this.$direction.pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $dynamicSize = this.$dynamicSize, $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $cacheVersion = this.$cacheVersion;
360
- $isVertical.pipe(takeUntil(this._$unsubscribe), tap(v => {
361
- this._isVertical = v;
362
- const el = this._elementRef.nativeElement;
363
- toggleClassName(el, v ? CLASS_LIST_VERTICAL : CLASS_LIST_HORIZONTAL, v ? CLASS_LIST_HORIZONTAL : CLASS_LIST_VERTICAL);
364
- })).subscribe();
365
- $snappingMethod.pipe(takeUntil(this._$unsubscribe), tap(v => {
366
- this._isSnappingMethodAdvanced = this._trackBox.isSnappingMethodAdvanced = v;
367
- })).subscribe();
368
- $dynamicSize.pipe(takeUntil(this._$unsubscribe), tap(dynamicSize => {
369
- this.listenCacheChangesIfNeed(dynamicSize);
370
- })).subscribe();
371
- combineLatest([this.$initialized, $bounds, $items, $stickyMap, $scrollSize, $itemSize,
372
- $bufferSize, $maxBufferSize, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
373
- ]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, bufferSize, maxBufferSize, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
374
- let actualScrollSize = (this._isVertical ? this._container?.nativeElement.scrollTop ?? 0 : this._container?.nativeElement.scrollLeft) ?? 0;
375
- const { width, height } = bounds, opts = {
376
- bounds: { width, height }, dynamicSize, isVertical, itemSize,
377
- bufferSize, maxBufferSize, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
378
- }, { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, opts);
379
- this.resetBoundsSize(isVertical, totalSize);
380
- this.createDisplayComponentsIfNeed(displayItems);
381
- this.tracking();
382
- if (this._isSnappingMethodAdvanced) {
383
- this.updateRegularRenderer();
384
- }
385
- const container = this._container;
386
- if (container) {
387
- const delta = this._trackBox.delta;
388
- actualScrollSize = actualScrollSize + delta;
389
- this._trackBox.clearDelta();
390
- if (scrollSize !== actualScrollSize) {
391
- const params = {
392
- [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: actualScrollSize,
393
- behavior: BEHAVIOR_INSTANT
394
- };
395
- container.nativeElement.scrollTo(params);
396
- }
397
- }
398
- return of(displayItems);
399
- })).subscribe();
400
- const $itemRenderer = this.$itemRenderer;
401
- $itemRenderer.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(v => !!v), tap(v => {
402
- this._$renderer.next(v);
403
- })).subscribe();
404
- }
405
- /** @internal */
406
- ngOnInit() {
407
- this.onInit();
408
- }
409
- onInit() {
410
- this._$initialized.next(true);
411
- }
412
- listenCacheChangesIfNeed(value) {
413
- if (value) {
414
- if (!this._trackBox.hasEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler)) {
415
- this._trackBox.addEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler);
416
- }
417
- }
418
- else {
419
- if (this._trackBox.hasEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler)) {
420
- this._trackBox.removeEventListener(TRACK_BOX_CHANGE_EVENT_NAME, this._onTrackBoxChangeHandler);
421
- }
422
- }
423
- }
424
- getIsSnappingMethodAdvanced(m) {
425
- const method = m || this._$snappingMethod.getValue();
426
- return isSnappingMethodAdvenced(method);
427
- }
428
- getIsVertical(d) {
429
- const dir = d || this.direction;
430
- return isDirection(dir, Directions.VERTICAL);
431
- }
432
- createDisplayComponentsIfNeed(displayItems) {
433
- if (!displayItems || !this._listContainerRef) {
434
- this._trackBox.setDisplayObjectIndexMapById({});
435
- return;
436
- }
437
- if (this._isSnappingMethodAdvanced && this.snap) {
438
- if (!this._snapedDisplayComponent && this._snapContainerRef) {
439
- const comp = this._snapContainerRef.createComponent(this._itemComponentClass);
440
- comp.instance.regular = true;
441
- this._snapedDisplayComponent = comp;
442
- this._trackBox.snapedDisplayComponent = this._snapedDisplayComponent;
443
- this._resizeSnappedObserver = new ResizeObserver(this._resizeSnappedComponentHandler);
444
- this._resizeSnappedObserver.observe(comp.instance.element);
445
- }
446
- }
447
- this._trackBox.items = displayItems;
448
- const _listContainerRef = this._listContainerRef;
449
- const maxLength = displayItems.length, components = this._displayComponents;
450
- while (components.length < maxLength) {
451
- if (_listContainerRef) {
452
- const comp = _listContainerRef.createComponent(this._itemComponentClass);
453
- components.push(comp);
454
- this._componentsResizeObserver.observe(comp.instance.element);
455
- }
456
- }
457
- this.resetRenderers();
458
- }
459
- updateRegularRenderer() {
460
- this._resizeSnappedComponentHandler();
461
- }
462
- resetRenderers(itemRenderer) {
463
- const doMap = {};
464
- for (let i = 0, l = this._displayComponents.length; i < l; i++) {
465
- const item = this._displayComponents[i];
466
- item.instance.renderer = itemRenderer || this.itemRenderer;
467
- doMap[item.instance.id] = i;
468
- }
469
- if (this._isSnappingMethodAdvanced && this.snap && this._snapedDisplayComponent && this._snapContainerRef) {
470
- const comp = this._snapedDisplayComponent;
471
- comp.instance.renderer = itemRenderer || this.itemRenderer;
472
- }
473
- this._trackBox.setDisplayObjectIndexMapById(doMap);
474
- }
475
- /**
476
- * Tracking by id
477
- */
478
- tracking() {
479
- this._trackBox.track();
480
- }
481
- resetBoundsSize(isVertical, totalSize) {
482
- const l = this._list;
483
- if (l) {
484
- l.nativeElement.style[isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME] = `${totalSize}${PX}`;
485
- }
486
- }
487
- /**
488
- * Returns the bounds of an element with a given id
489
- */
490
- getItemBounds(id) {
491
- return this._trackBox.getItemBounds(id);
492
- }
493
- /**
494
- * The method scrolls the list to the element with the given id and returns the value of the scrolled area.
495
- * Behavior accepts the values ​​"auto", "instant" and "smooth".
496
- */
497
- scrollTo(id, behavior = BEHAVIOR_AUTO) {
498
- this.scrollToExecutor(id, behavior);
499
- }
500
- clearScrollToRepeatExecutionTimeout() {
501
- clearTimeout(this._scrollToRepeatExecutionTimeout);
502
- }
503
- scrollToExecutor(id, behavior, iteration = 0, isLastIteration = false) {
504
- const items = this.items;
505
- if (!items || !items.length) {
506
- return;
507
- }
508
- const dynamicSize = this.dynamicSize, container = this._container, itemSize = this.itemSize;
509
- if (container) {
510
- this.clearScrollToRepeatExecutionTimeout();
511
- if (dynamicSize) {
512
- if (container) {
513
- container.nativeElement.removeEventListener(SCROLL, this._onScrollHandler);
514
- }
515
- const { width, height } = this._$bounds.getValue() || { width: 0, height: 0 }, stickyMap = this.stickyMap, items = this.items, isVertical = this._isVertical, delta = this._trackBox.delta, opts = {
516
- bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
517
- bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
518
- snap: this.snap, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
519
- }, scrollSize = this._trackBox.getItemPosition(id, stickyMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
520
- if (scrollSize === -1) {
521
- container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
522
- return;
523
- }
524
- this._trackBox.clearDelta();
525
- if (container) {
526
- const { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, {
527
- ...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
528
- }), delta = this._trackBox.delta;
529
- this._trackBox.clearDelta();
530
- let actualScrollSize = scrollSize + delta;
531
- this.resetBoundsSize(isVertical, totalSize);
532
- this.createDisplayComponentsIfNeed(displayItems);
533
- this.tracking();
534
- const _scrollSize = this._trackBox.getItemPosition(id, stickyMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
535
- if (_scrollSize === -1) {
536
- container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
537
- return;
538
- }
539
- const notChanged = actualScrollSize === _scrollSize;
540
- if (!notChanged || iteration < MAX_SCROLL_TO_ITERATIONS) {
541
- this.clearScrollToRepeatExecutionTimeout();
542
- this._scrollToRepeatExecutionTimeout = setTimeout(() => {
543
- this.scrollToExecutor(id, BEHAVIOR_INSTANT, iteration + 1, notChanged);
544
- });
545
- }
546
- else {
547
- this._$scrollSize.next(actualScrollSize);
548
- container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
549
- }
550
- }
551
- container.nativeElement.scrollTo(params);
552
- this._$scrollSize.next(scrollSize);
553
- }
554
- else {
555
- const index = items.findIndex(item => item.id === id);
556
- if (index > -1) {
557
- const scrollSize = index * this.itemSize;
558
- const params = { [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
559
- container.nativeElement.scrollTo(params);
560
- }
561
- }
562
- }
563
- }
564
- /**
565
- * Scrolls the scroll area to the desired element with the specified ID.
566
- */
567
- scrollToEnd(behavior = BEHAVIOR_INSTANT) {
568
- const items = this.items, latItem = items[items.length > 0 ? items.length - 1 : 0];
569
- this.scrollTo(latItem.id, behavior);
570
- }
571
- /** @internal */
572
- ngAfterViewInit() {
573
- this.afterViewInit();
574
- }
575
- afterViewInit() {
576
- const containerEl = this._container;
577
- if (containerEl) {
578
- // for direction calculation
579
- containerEl.nativeElement.addEventListener(SCROLL, this._onContainerScrollHandler);
580
- containerEl.nativeElement.addEventListener(SCROLL_END, this._onContainerScrollEndHandler);
581
- containerEl.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
582
- this._resizeObserver = new ResizeObserver(this._onResizeHandler);
583
- this._resizeObserver.observe(containerEl.nativeElement);
584
- this._onResizeHandler();
585
- }
586
- }
587
- /** @internal */
588
- ngOnDestroy() {
589
- super.ngOnDestroy();
590
- this.dispose();
591
- }
592
- dispose() {
593
- this.clearScrollToRepeatExecutionTimeout();
594
- if (this._trackBox) {
595
- this._trackBox.dispose();
596
- }
597
- if (this._componentsResizeObserver) {
598
- this._componentsResizeObserver.disconnect();
599
- }
600
- if (this._resizeObserver) {
601
- this._resizeObserver.disconnect();
602
- }
603
- if (this._resizeSnappedObserver) {
604
- this._resizeSnappedObserver.disconnect();
605
- }
606
- const containerEl = this._container;
607
- if (containerEl) {
608
- containerEl.nativeElement.removeEventListener(SCROLL, this._onScrollHandler);
609
- containerEl.nativeElement.removeEventListener(SCROLL, this._onContainerScrollHandler);
610
- containerEl.nativeElement.removeEventListener(SCROLL_END, this._onContainerScrollEndHandler);
611
- }
612
- if (this._snapedDisplayComponent) {
613
- this._snapedDisplayComponent.destroy();
614
- }
615
- if (this._displayComponents) {
616
- while (this._displayComponents.length > 0) {
617
- const comp = this._displayComponents.pop();
618
- comp?.destroy();
619
- }
620
- }
621
- }
622
- }
623
- NgVirtualListComponent.__nextId = 0;
624
- NgVirtualListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgVirtualListComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
625
- NgVirtualListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: "items", snap: "snap", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", stickyMap: "stickyMap", itemSize: "itemSize", dynamicSize: "dynamicSize", direction: "direction", itemsOffset: "itemsOffset", bufferSize: "bufferSize", maxBufferSize: "maxBufferSize", trackBy: "trackBy", snappingMethod: "snappingMethod" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, read: (ElementRef) }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, read: (ElementRef) }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, read: ViewContainerRef }], usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
626
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NgVirtualListComponent, decorators: [{
627
- type: Component,
628
- args: [{ selector: 'ng-virtual-list', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"] }]
629
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { _listContainerRef: [{
630
- type: ViewChild,
631
- args: ['renderersContainer', { read: ViewContainerRef }]
632
- }], _container: [{
633
- type: ViewChild,
634
- args: ['container', { read: (ElementRef) }]
635
- }], _list: [{
636
- type: ViewChild,
637
- args: ['list', { read: (ElementRef) }]
638
- }], _snapContainerRef: [{
639
- type: ViewChild,
640
- args: ['snapRendererContainer', { read: ViewContainerRef }]
641
- }], _snappedContainer: [{
642
- type: ViewChild,
643
- args: ['snapped', { read: ViewContainerRef }]
644
- }], onScroll: [{
645
- type: Output
646
- }], onScrollEnd: [{
647
- type: Output
648
- }], items: [{
649
- type: Input
650
- }], snap: [{
651
- type: Input
652
- }], enabledBufferOptimization: [{
653
- type: Input
654
- }], itemRenderer: [{
655
- type: Input
656
- }], stickyMap: [{
657
- type: Input
658
- }], itemSize: [{
659
- type: Input
660
- }], dynamicSize: [{
661
- type: Input
662
- }], direction: [{
663
- type: Input
664
- }], itemsOffset: [{
665
- type: Input
666
- }], bufferSize: [{
667
- type: Input
668
- }], maxBufferSize: [{
669
- type: Input
670
- }], trackBy: [{
671
- type: Input
672
- }], snappingMethod: [{
673
- type: Input
674
- }] } });
675
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctdmlydHVhbC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXZpcnR1YWwtbGlzdC9zcmMvbGliL25nLXZpcnR1YWwtbGlzdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy12aXJ0dWFsLWxpc3Qvc3JjL2xpYi9uZy12aXJ0dWFsLWxpc3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNVLHVCQUF1QixFQUFxQixTQUFTLEVBQWdCLFVBQVUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUNoRyxNQUFNLEVBQWUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixHQUN2RixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFjLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwSSxPQUFPLEVBQ0wsYUFBYSxFQUFFLGdCQUFnQixFQUFFLHFCQUFxQixFQUFFLG1CQUFtQixFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLG9CQUFvQixFQUFFLG1DQUFtQyxFQUFFLGlCQUFpQixFQUNqTSxpQkFBaUIsRUFBRSx1QkFBdUIsRUFBRSxZQUFZLEVBQUUsdUJBQXVCLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLHdCQUF3QixFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFDcEwsc0JBQXNCLEVBQUUsZUFBZSxHQUN4QyxNQUFNLFNBQVMsQ0FBQztBQUlqQixPQUFPLEVBQWEsVUFBVSxFQUFrQixNQUFNLFNBQVMsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLGVBQWUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN2RCxPQUFPLEVBQXFE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SUFZbEMsaUJBQWlCO3NCQUR4QixTQUFTO3VCQUFDLG9CQUFvQixFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO2dCQUluRCxVQUFVO3NCQURqQixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFBLFVBQTBCLENBQUEsRUFBRTtnQkFJcEQsS0FBSztzQkFEWixTQUFTO3VCQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxDQUFBLFVBQTBCLENBQUEsRUFBRTtnQkFJL0MsaUJBQWlCO3NCQUR4QixTQUFTO3VCQUFDLHVCQUF1QixFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO2dCQUl0RCxpQkFBaUI7c0JBRHhCLFNBQVM7dUJBQUMsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO2dCQU9oRCxRQUFRO3NCQURQLE1BQU07Z0JBT1AsV0FBVztzQkFEVixNQUFNO2dCQWdCSCxLQUFLO3NCQURSLEtBQUs7Z0JBcUJGLElBQUk7c0JBRFAsS0FBSztnQkFxQkYseUJBQXlCO3NCQUQ1QixLQUFLO2dCQXFCRixZQUFZO3NCQURmLEtBQUs7Z0JBb0JGLFNBQVM7c0JBRFosS0FBSztnQkE0QkYsUUFBUTtzQkFEWCxLQUFLO2dCQW9CRixXQUFXO3NCQURkLEtBQUs7Z0JBbUJGLFNBQVM7c0JBRFosS0FBSztnQkFnQkYsV0FBVztzQkFEZCxLQUFLO2dCQVlGLFVBQVU7c0JBRGIsS0FBSztnQkEyQkYsYUFBYTtzQkFEaEIsS0FBSztnQkFrQkYsT0FBTztzQkFEVixLQUFLO2dCQXFCRixjQUFjO3NCQURqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgQ29tcG9uZW50UmVmLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LFxyXG4gIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQsIFRlbXBsYXRlUmVmLCBWaWV3Q2hpbGQsIFZpZXdDb250YWluZXJSZWYsIFZpZXdFbmNhcHN1bGF0aW9uLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBmaWx0ZXIsIG1hcCwgT2JzZXJ2YWJsZSwgb2YsIHN3aXRjaE1hcCwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtcclxuICBCRUhBVklPUl9BVVRPLCBCRUhBVklPUl9JTlNUQU5ULCBDTEFTU19MSVNUX0hPUklaT05UQUwsIENMQVNTX0xJU1RfVkVSVElDQUwsIERFRkFVTFRfQlVGRkVSX1NJWkUsIERFRkFVTFRfRElSRUNUSU9OLCBERUZBVUxUX0RZTkFNSUNfU0laRSwgREVGQVVMVF9FTkFCTEVEX0JVRkZFUl9PUFRJTUlaQVRJT04sIERFRkFVTFRfSVRFTV9TSVpFLFxyXG4gIERFRkFVTFRfTElTVF9TSVpFLCBERUZBVUxUX01BWF9CVUZGRVJfU0laRSwgREVGQVVMVF9TTkFQLCBERUZBVUxUX1NOQVBQSU5HX01FVEhPRCwgSEVJR0hUX1BST1BfTkFNRSwgTEVGVF9QUk9QX05BTUUsIE1BWF9TQ1JPTExfVE9fSVRFUkFUSU9OUywgUFgsIFNDUk9MTCwgU0NST0xMX0VORCwgVE9QX1BST1BfTkFNRSxcclxuICBUUkFDS19CWV9QUk9QRVJUWV9OQU1FLCBXSURUSF9QUk9QX05BTUUsXHJcbn0gZnJvbSAnLi9jb25zdCc7XHJcbmltcG9ydCB7IElTY3JvbGxFdmVudCwgSVZpcnR1YWxMaXN0Q29sbGVjdGlvbiwgSVZpcnR1YWxMaXN0SXRlbSwgSVZpcnR1YWxMaXN0U3RpY2t5TWFwIH0gZnJvbSAnLi9tb2RlbHMnO1xyXG5pbXBvcnQgeyBJZCwgSVNpemUgfSBmcm9tICcuL3R5cGVzJztcclxuaW1wb3J0IHsgSVJlbmRlclZpcnR1YWxMaXN0Q29sbGVjdGlvbiB9IGZyb20gJy4vbW9kZWxzL3JlbmRlci1jb2xsZWN0aW9uLm1vZGVsJztcclxuaW1wb3J0IHsgRGlyZWN0aW9uLCBEaXJlY3Rpb25zLCBTbmFwcGluZ01ldGhvZCB9IGZyb20gJy4vZW51bXMnO1xyXG5pbXBvcnQgeyBTY3JvbGxFdmVudCwgdG9nZ2xlQ2xhc3NOYW1lIH0gZnJvbSAnLi91dGlscyc7XHJcbmltcG9ydCB7IElHZXRJdGVtUG9zaXRpb25PcHRpb25zLCBJVXBkYXRlQ29sbGVjdGlvbk9wdGlvbnMsIFRSQUNLX0JPWF9DSEFOR0VfRVZFTlRfTkFNRSwgVHJhY2tCb3ggfSBmcm9tICcuL3V0aWxzL3RyYWNrQm94JztcclxuaW1wb3J0IHsgRGlzcG9zYWJsZUNvbXBvbmVudCB9IGZyb20gJy4vdXRpbHMvZGlzcG9zYWJsZUNvbXBvbmVudCc7XHJcbmltcG9ydCB7IGlzU25hcHBpbmdNZXRob2RBZHZlbmNlZCB9IGZyb20gJy4vdXRpbHMvc25hcHBpbmctbWV0aG9kJztcclxuaW1wb3J0IHsgRklSRUZPWF9TQ1JPTExCQVJfT1ZFUkxBUF9TSVpFLCBJU19GSVJFRk9YIH0gZnJvbSAnLi91dGlscy9icm93c2VyJztcclxuaW1wb3J0IHsgTmdWaXJ0dWFsTGlzdEl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvbmctdmlydHVhbC1saXN0LWl0ZW0uY29tcG9uZW50JztcclxuaW1wb3J0IHsgQmFzZVZpcnR1YWxMaXN0SXRlbUNvbXBvbmVudCB9IGZyb20gJy4vbW9kZWxzL2Jhc2UtdmlydHVhbC1saXN0LWl0ZW0tY29tcG9uZW50JztcclxuaW1wb3J0IHsgQ29tcG9uZW50JDEgfSBmcm9tICcuL21vZGVscy9jb21wb25lbnQubW9kZWwnO1xyXG5pbXBvcnQgeyBpc0RpcmVjdGlvbiB9IGZyb20gJy4vdXRpbHMvaXNEaXJlY3Rpb24nO1xyXG5cclxuLyoqXHJcbiAqIFZpcnR1YWwgbGlzdCBjb21wb25lbnQuXHJcbiAqIE1heGltdW0gcGVyZm9ybWFuY2UgZm9yIGV4dHJlbWVseSBsYXJnZSBsaXN0cy5cclxuICogSXQgaXMgYmFzZWQgb24gYWxnb3JpdGhtcyBmb3IgdmlydHVhbGl6YXRpb24gb2Ygc2NyZWVuIG9iamVjdHMuXHJcbiAqIEBsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9Eam9ubnlYL25nLXZpcnR1YWwtbGlzdC9ibG9iLzE1LngvcHJvamVjdHMvbmctdmlydHVhbC1saXN0L3NyYy9saWIvbmctdmlydHVhbC1saXN0LmNvbXBvbmVudC50c1xyXG4gKiBAYXV0aG9yIEV2Z2VuaWkgR3JlYmVubmlrb3ZcclxuICogQGVtYWlsIGRqb25ueXhAZ21haWwuY29tXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25nLXZpcnR1YWwtbGlzdCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL25nLXZpcnR1YWwtbGlzdC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vbmctdmlydHVhbC1saXN0LmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXHJcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uU2hhZG93RG9tLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmdWaXJ0dWFsTGlzdENvbXBvbmVudCBleHRlbmRzIERpc3Bvc2FibGVDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkluaXQsIE9uRGVzdHJveSB7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgX19uZXh0SWQ6IG51bWJlciA9IDA7XHJcblxyXG4gIHByaXZhdGUgX2lkOiBudW1iZXIgPSBOZ1ZpcnR1YWxMaXN0Q29tcG9uZW50Ll9fbmV4dElkO1xyXG4gIC8qKlxyXG4gICAqIFJlYWRvbmx5LiBSZXR1cm5zIHRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgY29tcG9uZW50LlxyXG4gICAqL1xyXG4gIGdldCBpZCgpIHsgcmV0dXJuIHRoaXMuX2lkOyB9XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ3JlbmRlcmVyc0NvbnRhaW5lcicsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiB9KVxyXG4gIHByaXZhdGUgX2xpc3RDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYgfCB1bmRlZmluZWQ7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ2NvbnRhaW5lcicsIHsgcmVhZDogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD4gfSlcclxuICBwcml2YXRlIF9jb250YWluZXI6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+IHwgdW5kZWZpbmVkO1xyXG5cclxuICBAVmlld0NoaWxkKCdsaXN0JywgeyByZWFkOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PiB9KVxyXG4gIHByaXZhdGUgX2xpc3Q6IEVsZW1lbnRSZWY8SFRNTFVMaXN0RWxlbWVudD4gfCB1bmRlZmluZWQ7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ3NuYXBSZW5kZXJlckNvbnRhaW5lcicsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiB9KVxyXG4gIHByaXZhdGUgX3NuYXBDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYgfCB1bmRlZmluZWQ7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ3NuYXBwZWQnLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYgfSlcclxuICBwcml2YXRlIF9zbmFwcGVkQ29udGFpbmVyOiBWaWV3Q29udGFpbmVyUmVmIHwgdW5kZWZpbmVkO1xyXG5cclxuICAvKipcclxuICAgKiBGaXJlcyB3aGVuIHRoZSBsaXN0IGhhcyBiZWVuIHNjcm9sbGVkLlxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKVxyXG4gIG9uU2Nyb2xsID0gbmV3IEV2ZW50RW1pdHRlcjxJU2Nyb2xsRXZlbnQ+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpcmVzIHdoZW4gdGhlIGxpc3QgaGFzIGNvbXBsZXRlZCBzY3JvbGxpbmcuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgb25TY3JvbGxFbmQgPSBuZXcgRXZlbnRFbWl0dGVyPElTY3JvbGxFdmVudD4oKTtcclxuXHJcblxyXG4gIHByaXZhdGUgXyRpdGVtcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SVZpcnR1YWxMaXN0Q29sbGVjdGlvbiB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcclxuICByZWFkb25seSAkaXRlbXMgPSB0aGlzLl8kaXRlbXMuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgX2l0ZW1zVHJhbnNmb3JtID0gKHY6IElWaXJ0dWFsTGlzdENvbGxlY3Rpb24gfCB1bmRlZmluZWQpID0+IHtcclxuICAgIHRoaXMuX3RyYWNrQm94LnJlc2V0Q29sbGVjdGlvbih2LCB0aGlzLl8kaXRlbVNpemUuZ2V0VmFsdWUoKSk7XHJcbiAgICByZXR1cm4gdjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBDb2xsZWN0aW9uIG9mIGxpc3QgaXRlbXMuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgaXRlbXModjogSVZpcnR1YWxMaXN0Q29sbGVjdGlvbikge1xyXG4gICAgaWYgKHRoaXMuXyRpdGVtcy5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB0cmFuc2Zvcm1lZFZhbHVlID0gdGhpcy5faXRlbXNUcmFuc2Zvcm0odik7XHJcblxyXG4gICAgdGhpcy5fJGl0ZW1zLm5leHQodHJhbnNmb3JtZWRWYWx1ZSk7XHJcblxyXG4gICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gIH07XHJcbiAgZ2V0IGl0ZW1zKCkgeyByZXR1cm4gdGhpcy5fJGl0ZW1zLmdldFZhbHVlKCkgYXMgSVZpcnR1YWxMaXN0Q29sbGVjdGlvbjsgfVxyXG5cclxuICBwcml2YXRlIF8kc25hcCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oREVGQVVMVF9TTkFQKTtcclxuICByZWFkb25seSAkc25hcCA9IHRoaXMuXyRzbmFwLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgZWxlbWVudHMgd2lsbCBzbmFwLiBEZWZhdWx0IHZhbHVlIGlzIFwidHJ1ZVwiLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNuYXAodjogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuXyRzbmFwLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuXyRzbmFwLm5leHQodik7XHJcblxyXG4gICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gIH07XHJcbiAgZ2V0IHNuYXAoKSB7IHJldHVybiB0aGlzLl8kc25hcC5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgXyRlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihERUZBVUxUX0VOQUJMRURfQlVGRkVSX09QVElNSVpBVElPTik7XHJcbiAgcmVhZG9ubHkgJGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24gPSB0aGlzLl8kZW5hYmxlZEJ1ZmZlck9wdGltaXphdGlvbi5hc09ic2VydmFibGUoKTtcclxuICAvKipcclxuICAgKiBFeHBlcmltZW50YWwhXHJcbiAgICogRW5hYmxlcyBidWZmZXIgb3B0aW1pemF0aW9uLlxyXG4gICAqIENhbiBvbmx5IGJlIHVzZWQgaWYgaXRlbXMgaW4gdGhlIGNvbGxlY3Rpb24gYXJlIG5vdCBhZGRlZCBvciB1cGRhdGVkLiBPdGhlcndpc2UsIGFydGlmYWN0cyBpbiB0aGUgZm9ybSBvZiB0d2l0Y2hpbmcgb2YgdGhlIHNjcm9sbCBhcmVhIGFyZSBwb3NzaWJsZS5cclxuICAgKiBXb3JrcyBvbmx5IGlmIHRoZSBwcm9wZXJ0eSBkeW5hbWljID0gdHJ1ZVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24odjogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuXyRlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuXyRlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uLm5leHQodik7XHJcblxyXG4gICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gIH07XHJcbiAgZ2V0IGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24oKSB7IHJldHVybiB0aGlzLl8kZW5hYmxlZEJ1ZmZlck9wdGltaXphdGlvbi5nZXRWYWx1ZSgpOyB9XHJcblxyXG5cclxuICBwcml2YXRlIF8kaXRlbVJlbmRlcmVyID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xyXG4gIHJlYWRvbmx5ICRpdGVtUmVuZGVyZXIgPSB0aGlzLl8kaXRlbVJlbmRlcmVyLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBwcml2YXRlIF8kcmVuZGVyZXIgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XHJcbiAgLyoqXHJcbiAgKiBSZW5kZXJpbmcgZWxlbWVudCB0ZW1wbGF0ZS5cclxuICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGl0ZW1SZW5kZXJlcih2OiBUZW1wbGF0ZVJlZjxhbnk+KSB7XHJcbiAgICBpZiAodGhpcy5fJGl0ZW1SZW5kZXJlci5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl8kaXRlbVJlbmRlcmVyLm5leHQodik7XHJcblxyXG4gICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gIH07XHJcbiAgZ2V0IGl0ZW1SZW5kZXJlcigpIHsgcmV0dXJuIHRoaXMuXyRpdGVtUmVuZGVyZXIuZ2V0VmFsdWUoKSBhcyBUZW1wbGF0ZVJlZjxhbnk+OyB9XHJcblxyXG4gIHByaXZhdGUgXyRzdGlja3lNYXAgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PElWaXJ0dWFsTGlzdFN0aWNreU1hcD4oe30pO1xyXG4gIHJlYWRvbmx5ICRzdGlja3lNYXAgPSB0aGlzLl8kc3RpY2t5TWFwLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICAvKipcclxuICAgKiBEaWN0aW9uYXJ5IHpJbmRleCBieSBpZCBvZiB0aGUgbGlzdCBlbGVtZW50LiBJZiB0aGUgdmFsdWUgaXMgbm90IHNldCBvciBlcXVhbCB0byAwLFxyXG4gICAqIHRoZW4gYSBzaW1wbGUgZWxlbWVudCBpcyBkaXNwbGF5ZWQsIGlmIHRoZSB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gMCwgdGhlbiB0aGUgc3RpY2t5IHBvc2l0aW9uIG1vZGUgaXMgZW5hYmxlZCBmb3IgdGhlIGVsZW1lbnQuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgc3RpY2t5TWFwKHY6IElWaXJ0dWFsTGlzdFN0aWNreU1hcCkge1xyXG4gICAgaWYgKHRoaXMuXyRzdGlja3lNYXAuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fJHN0aWNreU1hcC5uZXh0KHYpO1xyXG5cclxuICAgIHRoaXMuX2Nkci5tYXJrRm9yQ2hlY2soKTtcclxuICB9O1xyXG4gIGdldCBzdGlja3lNYXAoKSB7IHJldHVybiB0aGlzLl8kc3RpY2t5TWFwLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfaXRlbVNpemVPcHRpb25zID0gKHY6IG51bWJlciB8IHVuZGVmaW5lZCkgPT4ge1xyXG4gICAgaWYgKHYgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gREVGQVVMVF9JVEVNX1NJWkU7XHJcbiAgICB9XHJcbiAgICBjb25zdCB2YWwgPSBOdW1iZXIodik7XHJcbiAgICByZXR1cm4gTnVtYmVyLmlzTmFOKHZhbCkgfHwgdmFsIDw9IDAgPyBERUZBVUxUX0lURU1fU0laRSA6IHZhbDtcclxuICB9O1xyXG5cclxuICBwcml2YXRlIF8kaXRlbVNpemUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9JVEVNX1NJWkUpO1xyXG4gIHJlYWRvbmx5ICRpdGVtU2l6ZSA9IHRoaXMuXyRpdGVtU2l6ZS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgLyoqXHJcbiAgICogSWYgZGlyZWN0aW9uID0gJ3ZlcnRpY2FsJywgdGhlbiB0aGUgaGVpZ2h0IG9mIGEgdHlwaWNhbCBlbGVtZW50LiBJZiBkaXJlY3Rpb24gPSAnaG9yaXpvbnRhbCcsIHRoZW4gdGhlIHdpZHRoIG9mIGEgdHlwaWNhbCBlbGVtZW50LlxyXG4gICAqIElnbm9yZWQgaWYgdGhlIGR5bmFtaWNTaXplIHByb3BlcnR5IGlzIHRydWUuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgaXRlbVNpemUodjogbnVtYmVyKSB7XHJcbiAgICBpZiAodGhpcy5fJGl0ZW1TaXplLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuXyRpdGVtU2l6ZS5uZXh0KHRoaXMuX2l0ZW1TaXplT3B0aW9ucyh2KSk7XHJcblxyXG4gICAgdGhpcy5fY2RyLm1hcmtGb3JDaGVjaygpO1xyXG4gIH07XHJcbiAgZ2V0IGl0ZW1TaXplKCkgeyByZXR1cm4gdGhpcy5fJGl0ZW1TaXplLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJGR5bmFtaWNTaXplID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihERUZBVUxUX0RZTkFNSUNfU0laRSk7XHJcbiAgcmVhZG9ubHkgJGR5bmFtaWNTaXplID0gdGhpcy5fJGR5bmFtaWNTaXplLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICAvKipcclxuICAgKiBJZiB0cnVlIHRoZW4gdGhlIGl0ZW1zIGluIHRoZSBsaXN0IGNhbiBoYXZlIGRpZmZlcmVudCBzaXplcyBhbmQgdGhlIGl0ZW1TaXplIHByb3BlcnR5IGlzIGlnbm9yZWQuXHJcbiAgICogSWYgZmFsc2UgdGhlbiB0aGUgaXRlbXMgaW4gdGhlIGxpc3QgaGF2ZSBhIGZpeGVkIHNpemUgc3BlY2lmaWVkIGJ5IHRoZSBpdGVtU2l6ZSBwcm9wZXJ0eS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgZmFsc2UuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgZHluYW1pY1NpemUodjogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuXyRkeW5hbWljU2l6ZS5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl8kZHluYW1pY1NpemUubmV4dCh2KTtcclxuXHJcbiAgICB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgfTtcclxuICBnZXQgZHluYW1pY1NpemUoKSB7IHJldHVybiB0aGlzLl8kZHluYW1pY1NpemUuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF8kZGlyZWN0aW9uID0gbmV3IEJlaGF2aW9yU3ViamVjdDxEaXJlY3Rpb24+KERFRkFVTFRfRElSRUNUSU9OKTtcclxuICByZWFkb25seSAkZGlyZWN0aW9uID0gdGhpcy5fJGRpcmVjdGlvbi5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyB0aGUgZGlyZWN0aW9uIGluIHdoaWNoIGVsZW1lbnRzIGFyZSBwbGFjZWQuIERlZmF1bHQgdmFsdWUgaXMgXCJ2ZXJ0aWNhbFwiLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGRpcmVjdGlvbih2OiBEaXJlY3Rpb24pIHtcclxuICAgIGlmICh0aGlzLl8kZGlyZWN0aW9uLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuXyRkaXJlY3Rpb24ubmV4dCh2KTtcclxuXHJcbiAgICB0aGlzLl9jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgfTtcclxuICBnZXQgZGlyZWN0aW9uKCkgeyByZXR1cm4gdGhpcy5fJGRpcmVjdGlvbi5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXByZWNhdGVkIFwiaXRlbU9mZnNldFwiIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkLiBVc2UgXCJidWZmZXJTaXplXCIgYW5kIFwibWF4QnVmZmVyU2l6ZVwiLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGl0ZW1zT2Zmc2V0KHY6IG51bWJlcikge1xyXG4gICAgdGhyb3cgRXJyb3IoJ1wiaXRlbU9mZnNldFwiIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkLiBVc2UgXCJidWZmZXJTaXplXCIgYW5kIFwibWF4QnVmZmVyU2l6ZVwiLicpO1xyXG4gIH07XHJcblxyXG4gIHByaXZhdGUgXyRidWZmZXJTaXplID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KERFRkFVTFRfQlVGRkVSX1NJWkUpO1xyXG4gIHJlYWRvbmx5ICRidWZmZXJTaXplID0gdGhpcy5fJGJ1ZmZlclNpemUuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIE51bWJlciBvZiBlbGVtZW50cyBvdXRzaWRlIHRoZSBzY29wZSBvZiB2aXNpYmlsaXR5LiBEZWZhdWx0IHZhbHVlIGlzIDIuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgYnVmZmVyU2l6ZSh2OiBudW1iZXIpIHtcclxuICAgIGlmICh0aGlzLl8kYnVmZmVyU2l6ZS5nZXRWYWx1ZSgpID09PSB2KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl8kYnVmZmVyU2l6ZS5uZXh0KHYpO1xyXG4gIH07XHJcbiAgZ2V0IGJ1ZmZlclNpemUoKSB7IHJldHVybiB0aGlzLl8kYnVmZmVyU2l6ZS5nZXRWYWx1ZSgpOyB9XHJcblxyXG4gIHByaXZhdGUgX21heEJ1ZmZlclNpemVUcmFuc2Zvcm0gPSAodjogbnVtYmVyIHwgdW5kZWZpbmVkKSA9PiB7XHJcbiAgICBjb25zdCBidWZmZXJTaXplID0gdGhpcy5fJGJ1ZmZlclNpemUuZ2V0VmFsdWUoKTtcclxuICAgIGlmICh2ID09PSB1bmRlZmluZWQgfHwgdiA8PSBidWZmZXJTaXplKSB7XHJcbiAgICAgIHJldHVybiBidWZmZXJTaXplO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHY7XHJcbiAgfTtcclxuXHJcbiAgcHJpdmF0ZSBfJG1heEJ1ZmZlclNpemUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oREVGQVVMVF9NQVhfQlVGRkVSX1NJWkUpO1xyXG4gIHJlYWRvbmx5ICRtYXhCdWZmZXJTaXplID0gdGhpcy5fJG1heEJ1ZmZlclNpemUuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIE1heGltdW0gbnVtYmVyIG9mIGVsZW1lbnRzIG91dHNpZGUgdGhlIHNjb3BlIG9mIHZpc2liaWxpdHkuIERlZmF1bHQgdmFsdWUgaXMgMTAwLlxyXG4gICAqIElmIG1heEJ1ZmZlclNpemUgaXMgc2V0IHRvIGJlIGdyZWF0ZXIgdGhhbiBidWZmZXJTaXplLCB0aGVuIGFkYXB0aXZlIGJ1ZmZlciBtb2RlIGlzIGVuYWJsZWQuXHJcbiAgICogVGhlIGdyZWF0ZXIgdGhlIHNjcm9sbCBzaXplLCB0aGUgbW9yZSBlbGVtZW50cyBhcmUgYWxsb2NhdGVkIGZvciByZW5kZXJpbmcuXHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgbWF4QnVmZmVyU2l6ZSh2OiBudW1iZXIpIHtcclxuICAgIGNvbnN0IHZhbCA9IHRoaXMuX21heEJ1ZmZlclNpemVUcmFuc2Zvcm0odik7XHJcbiAgICBpZiAodGhpcy5fJG1heEJ1ZmZlclNpemUuZ2V0VmFsdWUoKSA9PT0gdmFsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl8kbWF4QnVmZmVyU2l6ZS5uZXh0KHZhbCk7XHJcbiAgfTtcclxuICBnZXQgbWF4QnVmZmVyU2l6ZSgpIHsgcmV0dXJuIHRoaXMuXyRtYXhCdWZmZXJTaXplLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfJHRyYWNrQnkgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oVFJBQ0tfQllfUFJPUEVSVFlfTkFNRSk7XHJcbiAgcmVhZG9ubHkgJHRyYWNrQnkgPSB0aGlzLl8kdHJhY2tCeS5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IGJ5IHdoaWNoIHRyYWNraW5nIGlzIHBlcmZvcm1lZFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHRyYWNrQnkodjogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5fJHRyYWNrQnkuZ2V0VmFsdWUoKSA9PT0gdikge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fJHRyYWNrQnkubmV4dCh2KTtcclxuICB9O1xyXG4gIGdldCB0cmFja0J5KCkgeyByZXR1cm4gdGhpcy5fJHRyYWNrQnkuZ2V0VmFsdWUoKTsgfVxyXG5cclxuICBwcml2YXRlIF9pc1ZlcnRpY2FsID0gdGhpcy5nZXRJc1ZlcnRpY2FsKCk7XHJcblxyXG4gIHByaXZhdGUgXyRzbmFwcGluZ01ldGhvZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8U25hcHBpbmdNZXRob2Q+KERFRkFVTFRfU05BUFBJTkdfTUVUSE9EKTtcclxuICByZWFkb25seSAkc25hcHBpbmdNZXRob2QgPSB0aGlzLl8kc25hcHBpbmdNZXRob2QuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIFNuYXBwaW5nIG1ldGhvZC5cclxuICAgKiAnZGVmYXVsdCcgLSBOb3JtYWwgZ3JvdXAgcmVuZGVyaW5nLlxyXG4gICAqICdhZHZhbmNlZCcgLSBUaGUgZ3JvdXAgaXMgcmVuZGVyZWQgb24gYSB0cmFuc3BhcmVudCBiYWNrZ3JvdW5kLiBMaXN0IGl0ZW1zIGJlbG93IHRoZSBncm91cCBhcmUgbm90IHJlbmRlcmVkLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHNuYXBwaW5nTWV0aG9kKHY6IFNuYXBwaW5nTWV0aG9kKSB7XHJcbiAgICBpZiAodGhpcy5fJHNuYXBwaW5nTWV0aG9kLmdldFZhbHVlKCkgPT09IHYpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuXyRzbmFwcGluZ01ldGhvZC5uZXh0KHYpO1xyXG4gIH07XHJcbiAgZ2V0IHNuYXBwaW5nTWV0aG9kKCkgeyByZXR1cm4gdGhpcy5fJHNuYXBwaW5nTWV0aG9kLmdldFZhbHVlKCk7IH1cclxuXHJcbiAgcHJpdmF0ZSBfaXNTbmFwcGluZ01ldGhvZEFkdmFuY2VkOiBib29sZWFuID0gdGhpcy5nZXRJc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQoKTtcclxuICBnZXQgaXNTbmFwcGluZ01ldGhvZEFkdmFuY2VkKCkgeyByZXR1cm4gdGhpcy5faXNTbmFwcGluZ01ldGhvZEFkdmFuY2VkOyB9XHJcblxyXG4gIHByaXZhdGUgX2Rpc3BsYXlDb21wb25lbnRzOiBBcnJheTxDb21wb25lbnRSZWY8QmFzZVZpcnR1YWxMaXN0SXRlbUNvbXBvbmVudD4+ID0gW107XHJcblxyXG4gIHByaXZhdGUgX3NuYXBlZERpc3BsYXlDb21wb25lbnQ6IENvbXBvbmVudFJlZjxCYXNlVmlydHVhbExpc3RJdGVtQ29tcG9uZW50PiB8IHVuZGVmaW5lZDtcclxuXHJcbiAgcHJpdmF0ZSBfJGJvdW5kcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SVNpemUgfCBudWxsPihudWxsKTtcclxuXHJcbiAgcHJpdmF0ZSBfJHNjcm9sbFNpemUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oMCk7XHJcblxyXG4gIHByaXZhdGUgX3Jlc2l6ZU9ic2VydmVyOiBSZXNpemVPYnNlcnZlciB8IG51bGwgPSBudWxsO1xyXG5cclxuICBwcml2YXRlIF9yZXNpemVTbmFwcGVkQ29tcG9uZW50SGFuZGxlciA9ICgpID0+IHtcclxuICAgIGNvbnN0IGxpc3QgPSB0aGlzLl9saXN0LCBjb250YWluZXIgPSB0aGlzLl9jb250YWluZXIsIHNuYXBwZWRDb21wb25lbnQgPSB0aGlzLl9zbmFwZWREaXNwbGF5Q29tcG9uZW50Py5pbnN0YW5jZTtcclxuICAgIGlmIChsaXN0ICYmIGNvbnRhaW5lciAmJiBzbmFwcGVkQ29tcG9uZW50KSB7XHJcbiAgICAgIGNvbnN0IGlzVmVydGljYWwgPSB0aGlzLl9pc1ZlcnRpY2FsLCBsaXN0Qm91bmRzID0gbGlzdC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBsaXN0RWxlbWVudCA9IGxpc3Q/Lm5hdGl2ZUVsZW1lbnQsXHJcbiAgICAgICAgeyB3aWR0aDogbFdpZHRoLCBoZWlnaHQ6IGxIZWlnaHQgfSA9IGxpc3RFbGVtZW50Py5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSA/PyB7IHdpZHRoOiAwLCBoZWlnaHQ6IDAgfSxcclxuICAgICAgICB7IHdpZHRoLCBoZWlnaHQgfSA9IHRoaXMuXyRib3VuZHMuZ2V0VmFsdWUoKSA/PyB7IHdpZHRoOiAwLCBoZWlnaHQ6IDAgfSxcclxuICAgICAgICBpc1Njcm9sbGFibGUgPSBpc1ZlcnRpY2FsID8gY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsSGVpZ2h0ID4gMCA6IGNvbnRhaW5lci5uYXRpdmVFbGVtZW50LnNjcm9sbFdpZHRoID4gMDtcclxuXHJcbiAgICAgIGxldCBzY3JvbGxCYXJTaXplID0gaXNWZXJ0aWNhbCA/IHdpZHRoIC0gbFdpZHRoIDogaGVpZ2h0IC0gbEhlaWdodCwgaXNTY3JvbGxCYXJPdmVybGFwID0gdHJ1ZSwgb3ZlcmxhcFNjcm9sbEJhclNpemUgPSAwO1xyXG4gICAgICBpZiAoc2Nyb2xsQmFyU2l6ZSA9PT0gMCAmJiBpc1Njcm9sbGFibGUpIHtcclxuICAgICAgICBpc1Njcm9sbEJhck92ZXJsYXAgPSB0cnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXNTY3JvbGxCYXJPdmVybGFwICYmIElTX0ZJUkVGT1gpIHtcclxuICAgICAgICBzY3JvbGxCYXJTaXplID0gb3ZlcmxhcFNjcm9sbEJhclNpemUgPSBGSVJFRk9YX1NDUk9MTEJBUl9PVkVSTEFQX1NJWkU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHsgd2lkdGg6IHNXaWR0aCwgaGVpZ2h0OiBzSGVpZ2h0IH0gPSBzbmFwcGVkQ29tcG9uZW50LmdldEJvdW5kcygpID8/IHsgd2lkdGg6IDAsIGhlaWdodDogMCB9O1xyXG4gICAgICBzbmFwcGVkQ29tcG9uZW50LmVsZW1lbnQuc3R5bGUuY2xpcFBhdGggPSBgcGF0aChcIk0gMCAwIEwgMCAke3NIZWlnaHR9IEwgJHtzV2lkdGggLSBvdmVybGFwU2Nyb2xsQmFyU2l6ZX0gJHtzSGVpZ2h0fSBMICR7c1dpZHRoIC0gb3ZlcmxhcFNjcm9sbEJhclNpemV9IDAgWlwiKWA7XHJcblxyXG4gICAgICBzbmFwcGVkQ29tcG9uZW50LnJlZ3VsYXJMZW5ndGggPSBgJHtpc1ZlcnRpY2FsID8gbGlzdEJvdW5kcy53aWR0aCA6IGxpc3RCb3VuZHMuaGVpZ2h0fSR7UFh9YDtcclxuICAgICAgY29uc3QgY29udGFpbmVyRWxlbWVudCA9IGNvbnRhaW5lci5uYXRpdmVFbGVtZW50LCBkZWx0YSA9IHNuYXBwZWRDb21wb25lbnQuaXRlbT8ubWVhc3VyZXMuZGVsdGEgPz8gMDtcclxuXHJcbiAgICAgIGxldCBsZWZ0OiBudW1iZXIsIHJpZ2h0OiBudW1iZXIsIHRvcDogbnVtYmVyLCBib3R0b206IG51bWJlcjtcclxuICAgICAgaWYgKGlzVmVydGljYWwpIHtcclxuICAgICAgICBsZWZ0ID0gMDtcclxuICAgICAgICByaWdodCA9IHdpZHRoIC0gc2Nyb2xsQmFyU2l6ZTtcclxuICAgICAgICB0b3AgPSBzSGVpZ2h0O1xyXG4gICAgICAgIGJvdHRvbSA9IGhlaWdodDtcclxuICAgICAgICBjb250YWluZXJFbGVtZW50LnN0eWxlLmNsaXBQYXRoID0gYHBhdGgoXCJNIDAgJHt0b3AgKyBkZWx0YX0gTCAwICR7aGVpZ2h0fSBMICR7d2lkdGh9ICR7aGVpZ2h0fSBMICR7d2lkdGh9IDAgTCAke3JpZ2h0fSAwIEwgJHtyaWdodH0gJHt0b3AgKyBkZWx0YX0gWlwiKWA7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbGVmdCA9IHNXaWR0aDtcclxuICAgICAgICByaWdodCA9IHdpZHRoO1xyXG4gICAgICAgIHRvcCA9IDA7XHJcbiAgICAgICAgYm90dG9tID0gaGVpZ2h0IC0gc2Nyb2xsQmFyU2l6ZTtcclxuICAgICAgICBjb250YWluZXJFbGVtZW50LnN0eWxlLmNsaXBQYXRoID0gYHBhdGgoXCJNICR7bGVmdCArIGRlbHRhfSAwIEwgJHtsZWZ0ICsgZGVsdGF9ICR7Ym90dG9tfSBMIDAgJHtib3R0b219IEwgMCAke2hlaWdodH0gTCAke3dpZHRofSAke2hlaWdodH0gTCAke3dpZHRofSAwIFpcIilgO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgcHJpdmF0ZSBfcmVzaXplU25hcHBlZE9ic2VydmVyOiBSZXNpemVPYnNlcnZlciB8IG51bGwgPSBudWxsO1xyXG5cclxuICBwcml2YXRlIF9vblJlc2l6ZUhhbmRsZXIgPSAoKSA9PiB7XHJcbiAgICBjb25zdCBib3VuZHMgPSB0aGlzLl9jb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQ/LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgaWYgKGJvdW5kcykge1xyXG4gICAgICB0aGlzLl8kYm91bmRzLm5leHQoeyB3aWR0aDogYm91bmRzLndpZHRoLCBoZWlnaHQ6IGJvdW5kcy5oZWlnaHQgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl8kYm91bmRzLm5leHQoeyB3aWR0aDogREVGQVVMVF9MSVNUX1NJWkUsIGhlaWdodDogREVGQVVMVF9MSVNUX1NJWkUgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX2lzU25hcHBpbmdNZXRob2RBZHZhbmNlZCkge1xyXG4gICAgICB0aGlzLnVwZGF0ZVJlZ3VsYXJSZW5kZXJlcigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfb25TY3JvbGxIYW5kbGVyID0gKGU/OiBFdmVudCkgPT4ge1xyXG4gICAgdGhpcy5jbGVhclNjcm9sbFRvUmVwZWF0RXhlY3V0aW9uVGltZW91dCgpO1xyXG5cclxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lcj8ubmF0aXZlRWxlbWVudDtcclxuICAgIGlmIChjb250YWluZXIpIHtcclxuICAgICAgY29uc3Qgc2Nyb2xsU2l6ZSA9ICh0aGlzLl9pc1ZlcnRpY2FsID8gY29udGFpbmVyLnNjcm9sbFRvcCA6IGNvbnRhaW5lci5zY3JvbGxMZWZ0KTtcclxuXHJcbiAgICAgIHRoaXMuXyRzY3JvbGxTaXplLm5leHQoc2Nyb2xsU2l6ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF8kaW5pdGlhbGl6ZWQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuXHJcbiAgcmVhZG9ubHkgJGluaXRpYWxpemVkOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xyXG5cclxuICAvKipcclxuICAgKiBCYXNlIGNsYXNzIG9mIHRoZSBlbGVtZW50IGNvbXBvbmVudFxyXG4gICAqL1xyXG4gIHByaXZhdGUgX2l0ZW1Db21wb25lbnRDbGFzczogQ29tcG9uZW50JDE8QmFzZVZpcnR1YWxMaXN0SXRlbUNvbXBvbmVudD4gPSBOZ1ZpcnR1YWxMaXN0SXRlbUNvbXBvbmVudDtcclxuXHJcbiAgLyoqXHJcbiAgICogQmFzZSBjbGFzcyB0cmFja0JveFxyXG4gICAqL1xyXG4gIHByaXZhdGUgX3RyYWNrQm94Q2xhc3M6IENvbXBvbmVudCQxPFRyYWNrQm94PiA9IFRyYWNrQm94O1xyXG5cclxuICAvKipcclxuICAgKiBEaWN0aW9uYXJ5IG9mIGVsZW1lbnQgc2l6ZXMgYnkgdGhlaXIgaWRcclxuICAgKi9cclxuICBwcml2YXRlIF90cmFja0JveDogVHJhY2tCb3ggPSBuZXcgdGhpcy5fdHJhY2tCb3hDbGFzcyh0aGlzLnRyYWNrQnkpO1xyXG5cclxuICBwcml2YXRlIF9vblRyYWNrQm94Q2hhbmdlSGFuZGxlciA9ICh2OiBudW1iZXIpID0+IHtcclxuICAgIHRoaXMuXyRjYWNoZVZlcnNpb24ubmV4dCh2KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgXyRjYWNoZVZlcnNpb24gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oLTEpO1xyXG4gIGdldCAkY2FjaGVWZXJzaW9uKCkgeyByZXR1cm4gdGhpcy5fJGNhY2hlVmVyc2lvbi5hc09ic2VydmFibGUoKTsgfVxyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgX2NkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PlxyXG4gICkge1xyXG4gICAgc3VwZXIoKTtcclxuICAgIE5nVmlydHVhbExpc3RDb21wb25lbnQuX19uZXh0SWQgPSBOZ1ZpcnR1YWxMaXN0Q29tcG9uZW50Ll9fbmV4dElkICsgMSA9PT0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJcclxuICAgICAgPyAwIDogTmdWaXJ0dWFsTGlzdENvbXBvbmVudC5fX25leHRJZCArIDE7XHJcbiAgICB0aGlzLl9pZCA9IE5nVmlydHVhbExpc3RDb21wb25lbnQuX19uZXh0SWQ7XHJcblxyXG4gICAgdGhpcy5fJGluaXRpYWxpemVkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XHJcbiAgICB0aGlzLiRpbml0aWFsaXplZCA9IHRoaXMuXyRpbml0aWFsaXplZC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgICB0aGlzLl90cmFja0JveC5kaXNwbGF5Q29tcG9uZW50cyA9IHRoaXMuX2Rpc3BsYXlDb21wb25lbnRzO1xyXG5cclxuICAgIGNvbnN0ICR0cmFja0J5ID0gdGhpcy4kdHJhY2tCeTtcclxuXHJcbiAgICAkdHJhY2tCeS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX3RyYWNrQm94LnRyYWNraW5nUHJvcGVydHlOYW1lID0gdjtcclxuICAgICAgfSksXHJcbiAgICApLnN1YnNjcmliZSgpO1xyXG5cclxuICAgIGNvbnN0ICRib3VuZHMgPSB0aGlzLl8kYm91bmRzLmFzT2JzZXJ2YWJsZSgpLnBpcGUoXHJcbiAgICAgIGZpbHRlcihiID0+ICEhYiksXHJcbiAgICApLCAkaXRlbXMgPSB0aGlzLiRpdGVtcy5waXBlKFxyXG4gICAgICBtYXAoaSA9PiAhaSA/IFtdIDogaSksXHJcbiAgICApLCAkc2Nyb2xsU2l6ZSA9IHRoaXMuXyRzY3JvbGxTaXplLmFzT2JzZXJ2YWJsZSgpLFxyXG4gICAgICAkaXRlbVNpemUgPSB0aGlzLiRpdGVtU2l6ZS5waXBlKFxyXG4gICAgICAgIG1hcCh2ID0+IHYgPD0gMCA/IERFRkFVTFRfSVRFTV9TSVpFIDogdiksXHJcbiAgICAgICksXHJcbiAgICAgICRidWZmZXJTaXplID0gdGhpcy4kYnVmZmVyU2l6ZS5waXBlKFxyXG4gICAgICAgIG1hcCh2ID0+IHYgPCAwID8gREVGQVVMVF9CVUZGRVJfU0laRSA6IHYpLFxyXG4gICAgICApLFxyXG4gICAgICAkbWF4QnVmZmVyU2l6ZSA9IHRoaXMuJG1heEJ1ZmZlclNpemUucGlwZShcclxuICAgICAgICBtYXAodiA9PiB2IDwgMCA/IERFRkFVTFRfTUFYX0JVRkZFUl9TSVpFIDogdiksXHJcbiAgICAgICksXHJcbiAgICAgICRzdGlja3lNYXAgPSB0aGlzLiRzdGlja3lNYXAucGlwZShcclxuICAgICAgICBtYXAodiA9PiAhdiA/IHt9IDogdiksXHJcbiAgICAgICksXHJcbiAgICAgICRzbmFwID0gdGhpcy4kc25hcCxcclxuICAgICAgJGlzVmVydGljYWwgPSB0aGlzLiRkaXJlY3Rpb24ucGlwZShcclxuICAgICAgICBtYXAodiA9PiB0aGlzLmdldElzVmVydGljYWwodiB8fCBERUZBVUxUX0RJUkVDVElPTikpLFxyXG4gICAgICApLFxyXG4gICAgICAkZHluYW1pY1NpemUgPSB0aGlzLiRkeW5hbWljU2l6ZSxcclxuICAgICAgJGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24gPSB0aGlzLiRlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uLFxyXG4gICAgICAkc25hcHBpbmdNZXRob2QgPSB0aGlzLiRzbmFwcGluZ01ldGhvZC5waXBlKFxyXG4gICAgICAgIG1hcCh2ID0+IHRoaXMuZ2V0SXNTbmFwcGluZ01ldGhvZEFkdmFuY2VkKHYgfHwgREVGQVVMVF9TTkFQUElOR19NRVRIT0QpKSxcclxuICAgICAgKSxcclxuICAgICAgJGNhY2hlVmVyc2lvbiA9IHRoaXMuJGNhY2hlVmVyc2lvbjtcclxuXHJcbiAgICAkaXNWZXJ0aWNhbC5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgdGFwKHYgPT4ge1xyXG4gICAgICAgIHRoaXMuX2lzVmVydGljYWwgPSB2O1xyXG4gICAgICAgIGNvbnN0IGVsOiBIVE1MRWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcclxuICAgICAgICB0b2dnbGVDbGFzc05hbWUoZWwsIHYgPyBDTEFTU19MSVNUX1ZFUlRJQ0FMIDogQ0xBU1NfTElTVF9IT1JJWk9OVEFMLCB2ID8gQ0xBU1NfTElTVF9IT1JJWk9OVEFMIDogQ0xBU1NfTElTVF9WRVJUSUNBTCk7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAkc25hcHBpbmdNZXRob2QucGlwZShcclxuICAgICAgdGFrZVVudGlsKHRoaXMuXyR1bnN1YnNjcmliZSksXHJcbiAgICAgIHRhcCh2ID0+IHtcclxuICAgICAgICB0aGlzLl9pc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQgPSB0aGlzLl90cmFja0JveC5pc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQgPSB2O1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgJGR5bmFtaWNTaXplLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICB0YXAoZHluYW1pY1NpemUgPT4ge1xyXG4gICAgICAgIHRoaXMubGlzdGVuQ2FjaGVDaGFuZ2VzSWZOZWVkKGR5bmFtaWNTaXplKTtcclxuICAgICAgfSlcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29tYmluZUxhdGVzdChbdGhpcy4kaW5pdGlhbGl6ZWQsICRib3VuZHMsICRpdGVtcywgJHN0aWNreU1hcCwgJHNjcm9sbFNpemUsICRpdGVtU2l6ZSxcclxuICAgICAgJGJ1ZmZlclNpemUsICRtYXhCdWZmZXJTaXplLCAkc25hcCwgJGlzVmVydGljYWwsICRkeW5hbWljU2l6ZSwgJGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24sICRjYWNoZVZlcnNpb24sXHJcbiAgICBdKS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy5fJHVuc3Vic2NyaWJlKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgZmlsdGVyKChbaW5pdGlhbGl6ZWRdKSA9PiAhIWluaXRpYWxpemVkKSxcclxuICAgICAgc3dpdGNoTWFwKChbLFxyXG4gICAgICAgIGJvdW5kcywgaXRlbXMsIHN0aWNreU1hcCwgc2Nyb2xsU2l6ZSwgaXRlbVNpemUsXHJcbiAgICAgICAgYnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgc25hcCwgaXNWZXJ0aWNhbCwgZHluYW1pY1NpemUsIGVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24sIGNhY2hlVmVyc2lvbixcclxuICAgICAgXSkgPT4ge1xyXG4gICAgICAgIGxldCBhY3R1YWxTY3JvbGxTaXplID0gKHRoaXMuX2lzVmVydGljYWwgPyB0aGlzLl9jb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wID8/IDAgOiB0aGlzLl9jb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdCkgPz8gMDtcclxuICAgICAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGJvdW5kcyEsXHJcbiAgICAgICAgICBvcHRzOiBJVXBkYXRlQ29sbGVjdGlvbk9wdGlvbnM8SVZpcnR1YWxMaXN0SXRlbSwgSVZpcnR1YWxMaXN0Q29sbGVjdGlvbj4gPSB7XHJcbiAgICAgICAgICAgIGJvdW5kczogeyB3aWR0aCwgaGVpZ2h0IH0sIGR5bmFtaWNTaXplLCBpc1ZlcnRpY2FsLCBpdGVtU2l6ZSxcclxuICAgICAgICAgICAgYnVmZmVyU2l6ZSwgbWF4QnVmZmVyU2l6ZSwgc2Nyb2xsU2l6ZTogYWN0dWFsU2Nyb2xsU2l6ZSwgc25hcCwgZW5hYmxlZEJ1ZmZlck9wdGltaXphdGlvbixcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICB7IGRpc3BsYXlJdGVtcywgdG90YWxTaXplIH0gPSB0aGlzLl90cmFja0JveC51cGRhdGVDb2xsZWN0aW9uKGl0ZW1zLCBzdGlja3lNYXAsIG9wdHMpO1xyXG5cclxuICAgICAgICB0aGlzLnJlc2V0Qm91bmRzU2l6ZShpc1ZlcnRpY2FsLCB0b3RhbFNpemUpO1xyXG5cclxuICAgICAgICB0aGlzLmNyZWF0ZURpc3BsYXlDb21wb25lbnRzSWZOZWVkKGRpc3BsYXlJdGVtcyk7XHJcblxyXG4gICAgICAgIHRoaXMudHJhY2tpbmcoKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX2lzU25hcHBpbmdNZXRob2RBZHZhbmNlZCkge1xyXG4gICAgICAgICAgdGhpcy51cGRhdGVSZWd1bGFyUmVuZGVyZXIoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lcjtcclxuXHJcbiAgICAgICAgaWYgKGNvbnRhaW5lcikge1xyXG4gICAgICAgICAgY29uc3QgZGVsdGEgPSB0aGlzLl90cmFja0JveC5kZWx0YTtcclxuICAgICAgICAgIGFjdHVhbFNjcm9sbFNpemUgPSBhY3R1YWxTY3JvbGxTaXplICsgZGVsdGE7XHJcblxyXG4gICAgICAgICAgdGhpcy5fdHJhY2tCb3guY2xlYXJEZWx0YSgpO1xyXG5cclxuICAgICAgICAgIGlmIChzY3JvbGxTaXplICE9PSBhY3R1YWxTY3JvbGxTaXplKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtczogU2Nyb2xsVG9PcHRpb25zID0ge1xyXG4gICAgICAgICAgICAgIFt0aGlzLl9pc1ZlcnRpY2FsID8gVE9QX1BST1BfTkFNRSA6IExFRlRfUFJPUF9OQU1FXTogYWN0dWFsU2Nyb2xsU2l6ZSxcclxuICAgICAgICAgICAgICBiZWhhdmlvcjogQkVIQVZJT1JfSU5TVEFOVCBhcyBTY3JvbGxCZWhhdmlvclxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG8ocGFyYW1zKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBvZihkaXNwbGF5SXRlbXMpO1xyXG4gICAgICB9KSxcclxuICAgICkuc3Vic2NyaWJlKCk7XHJcblxyXG4gICAgY29uc3QgJGl0ZW1SZW5kZXJlciA9IHRoaXMuJGl0ZW1SZW5kZXJlcjtcclxuXHJcbiAgICAkaXRlbVJlbmRlcmVyLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLl8kdW5zdWJzY3JpYmUpLFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICBmaWx0ZXIodiA9PiAhIXYpLFxyXG4gICAgICB0YXAodiA9PiB7XHJcbiAgICAgICAgdGhpcy5fJHJlbmRlcmVyLm5leHQodik7XHJcbiAgICAgIH0pLFxyXG4gICAgKS5zdWJzY3JpYmUoKTtcclxuICB9XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgKi9cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMub25Jbml0KCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG9uSW5pdCgpIHtcclxuICAgIHRoaXMuXyRpbml0aWFsaXplZC5uZXh0KHRydWUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBsaXN0ZW5DYWNoZUNoYW5nZXNJZk5lZWQodmFsdWU6IGJvb2xlYW4pIHtcclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICBpZiAoIXRoaXMuX3RyYWNrQm94Lmhhc0V2ZW50TGlzdGVuZXIoVFJBQ0tfQk9YX0NIQU5HRV9FVkVOVF9OQU1FLCB0aGlzLl9vblRyYWNrQm94Q2hhbmdlSGFuZGxlcikpIHtcclxuICAgICAgICB0aGlzLl90cmFja0JveC5hZGRFdmVudExpc3RlbmVyKFRSQUNLX0JPWF9DSEFOR0VfRVZFTlRfTkFNRSwgdGhpcy5fb25UcmFja0JveENoYW5nZUhhbmRsZXIpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAodGhpcy5fdHJhY2tCb3guaGFzRXZlbnRMaXN0ZW5lcihUUkFDS19CT1hfQ0hBTkdFX0VWRU5UX05BTUUsIHRoaXMuX29uVHJhY2tCb3hDaGFuZ2VIYW5kbGVyKSkge1xyXG4gICAgICAgIHRoaXMuX3RyYWNrQm94LnJlbW92ZUV2ZW50TGlzdGVuZXIoVFJBQ0tfQk9YX0NIQU5HRV9FVkVOVF9OQU1FLCB0aGlzLl9vblRyYWNrQm94Q2hhbmdlSGFuZGxlcik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0SXNTbmFwcGluZ01ldGhvZEFkdmFuY2VkKG0/OiBTbmFwcGluZ01ldGhvZCkge1xyXG4gICAgY29uc3QgbWV0aG9kID0gbSB8fCB0aGlzLl8kc25hcHBpbmdNZXRob2QuZ2V0VmFsdWUoKTtcclxuICAgIHJldHVybiBpc1NuYXBwaW5nTWV0aG9kQWR2ZW5jZWQobWV0aG9kKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0SXNWZXJ0aWNhbChkPzogRGlyZWN0aW9uKSB7XHJcbiAgICBjb25zdCBkaXIgPSBkIHx8IHRoaXMuZGlyZWN0aW9uO1xyXG4gICAgcmV0dXJuIGlzRGlyZWN0aW9uKGRpciwgRGlyZWN0aW9ucy5WRVJUSUNBTCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9jb21wb25lbnRzUmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xyXG4gICAgdGhpcy5fdHJhY2tCb3guY2hhbmdlcygpO1xyXG4gIH0pO1xyXG5cclxuICBwcml2YXRlIGNyZWF0ZURpc3BsYXlDb21wb25lbnRzSWZOZWVkKGRpc3BsYXlJdGVtczogSVJlbmRlclZpcnR1YWxMaXN0Q29sbGVjdGlvbiB8IG51bGwpIHtcclxuICAgIGlmICghZGlzcGxheUl0ZW1zIHx8ICF0aGlzLl9saXN0Q29udGFpbmVyUmVmKSB7XHJcbiAgICAgIHRoaXMuX3RyYWNrQm94LnNldERpc3BsYXlPYmplY3RJbmRleE1hcEJ5SWQoe30pO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX2lzU25hcHBpbmdNZXRob2RBZHZhbmNlZCAmJiB0aGlzLnNuYXApIHtcclxuICAgICAgaWYgKCF0aGlzLl9zbmFwZWREaXNwbGF5Q29tcG9uZW50ICYmIHRoaXMuX3NuYXBDb250YWluZXJSZWYpIHtcclxuICAgICAgICBjb25zdCBjb21wID0gdGhpcy5fc25hcENvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQodGhpcy5faXRlbUNvbXBvbmVudENsYXNzKTtcclxuICAgICAgICBjb21wLmluc3RhbmNlLnJlZ3VsYXIgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX3NuYXBlZERpc3BsYXlDb21wb25lbnQgPSBjb21wO1xyXG4gICAgICAgIHRoaXMuX3RyYWNrQm94LnNuYXBlZERpc3BsYXlDb21wb25lbnQgPSB0aGlzLl9zbmFwZWREaXNwbGF5Q29tcG9uZW50O1xyXG5cclxuICAgICAgICB0aGlzLl9yZXNpemVTbmFwcGVkT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIodGhpcy5fcmVzaXplU25hcHBlZENvbXBvbmVudEhhbmRsZXIpO1xyXG4gICAgICAgIHRoaXMuX3Jlc2l6ZVNuYXBwZWRPYnNlcnZlci5vYnNlcnZlKGNvbXAuaW5zdGFuY2UuZWxlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl90cmFja0JveC5pdGVtcyA9IGRpc3BsYXlJdGVtcztcclxuXHJcbiAgICBjb25zdCBfbGlzdENvbnRhaW5lclJlZiA9IHRoaXMuX2xpc3RDb250YWluZXJSZWY7XHJcblxyXG4gICAgY29uc3QgbWF4TGVuZ3RoID0gZGlzcGxheUl0ZW1zLmxlbmd0aCwgY29tcG9uZW50cyA9IHRoaXMuX2Rpc3BsYXlDb21wb25lbnRzO1xyXG5cclxuICAgIHdoaWxlIChjb21wb25lbnRzLmxlbmd0aCA8IG1heExlbmd0aCkge1xyXG4gICAgICBpZiAoX2xpc3RDb250YWluZXJSZWYpIHtcclxuICAgICAgICBjb25zdCBjb21wID0gX2xpc3RDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KHRoaXMuX2l0ZW1Db21wb25lbnRDbGFzcyk7XHJcbiAgICAgICAgY29tcG9uZW50cy5wdXNoKGNvbXApO1xyXG5cclxuICAgICAgICB0aGlzLl9jb21wb25lbnRzUmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShjb21wLmluc3RhbmNlLmVsZW1lbnQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5yZXNldFJlbmRlcmVycygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVSZWd1bGFyUmVuZGVyZXIoKSB7XHJcbiAgICB0aGlzLl9yZXNpemVTbmFwcGVkQ29tcG9uZW50SGFuZGxlcigpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZXNldFJlbmRlcmVycyhpdGVtUmVuZGVyZXI/OiBUZW1wbGF0ZVJlZjxIVE1MRWxlbWVudD4pIHtcclxuICAgIGNvbnN0IGRvTWFwOiB7IFtpZDogbnVtYmVyXTogbnVtYmVyIH0gPSB7fTtcclxuICAgIGZvciAobGV0IGkgPSAwLCBsID0gdGhpcy5fZGlzcGxheUNvbXBvbmVudHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9kaXNwbGF5Q29tcG9uZW50c1tpXTtcclxuICAgICAgaXRlbS5pbnN0YW5jZS5yZW5kZXJlciA9IGl0ZW1SZW5kZXJlciB8fCB0aGlzLml0ZW1SZW5kZXJlcjtcclxuICAgICAgZG9NYXBbaXRlbS5pbnN0YW5jZS5pZF0gPSBpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9pc1NuYXBwaW5nTWV0aG9kQWR2YW5jZWQgJiYgdGhpcy5zbmFwICYmIHRoaXMuX3NuYXBlZERpc3BsYXlDb21wb25lbnQgJiYgdGhpcy5fc25hcENvbnRhaW5lclJlZikge1xyXG4gICAgICBjb25zdCBjb21wID0gdGhpcy5fc25hcGVkRGlzcGxheUNvbXBvbmVudDtcclxuICAgICAgY29tcC5pbnN0YW5jZS5yZW5kZXJlciA9IGl0ZW1SZW5kZXJlciB8fCB0aGlzLml0ZW1SZW5kZXJlcjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl90cmFja0JveC5zZXREaXNwbGF5T2JqZWN0SW5kZXhNYXBCeUlkKGRvTWFwKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRyYWNraW5nIGJ5IGlkXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB0cmFja2luZygpIHtcclxuICAgIHRoaXMuX3RyYWNrQm94LnRyYWNrKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHJlc2V0Qm91bmRzU2l6ZShpc1ZlcnRpY2FsOiBib29sZWFuLCB0b3RhbFNpemU6IG51bWJlcikge1xyXG4gICAgY29uc3QgbCA9IHRoaXMuX2xpc3Q7XHJcbiAgICBpZiAobCkge1xyXG4gICAgICBsLm5hdGl2ZUVsZW1lbnQuc3R5bGVbaXNWZXJ0aWNhbCA/IEhFSUdIVF9QUk9QX05BTUUgOiBXSURUSF9QUk9QX05BTUVdID0gYCR7dG90YWxTaXplfSR7UFh9YDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgdGhlIGJvdW5kcyBvZiBhbiBlbGVtZW50IHdpdGggYSBnaXZlbiBpZFxyXG4gICAqL1xyXG4gIGdldEl0ZW1Cb3VuZHMoaWQ6IElkKTogSVNpemUgfCB1bmRlZmluZWQge1xyXG4gICAgcmV0dXJuIHRoaXMuX3RyYWNrQm94LmdldEl0ZW1Cb3VuZHMoaWQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIG1ldGhvZCBzY3JvbGxzIHRoZSBsaXN0IHRvIHRoZSBlbGVtZW50IHdpdGggdGhlIGdpdmVuIGlkIGFuZCByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgc2Nyb2xsZWQgYXJlYS5cclxuICAgKiBCZWhhdmlvciBhY2NlcHRzIHRoZSB2YWx1ZXMg4oCL4oCLXCJhdXRvXCIsIFwiaW5zdGFudFwiIGFuZCBcInNtb290aFwiLlxyXG4gICAqL1xyXG4gIHNjcm9sbFRvKGlkOiBJZCwgYmVoYXZpb3I6IFNjcm9sbEJlaGF2aW9yID0gQkVIQVZJT1JfQVVUTyBhcyBTY3JvbGxCZWhhdmlvcikge1xyXG4gICAgdGhpcy5zY3JvbGxUb0V4ZWN1dG9yKGlkLCBiZWhhdmlvcik7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9zY3JvbGxUb1JlcGVhdEV4ZWN1dGlvblRpbWVvdXQ6IGFueTtcclxuXHJcbiAgcHJpdmF0ZSBjbGVhclNjcm9sbFRvUmVwZWF0RXhlY3V0aW9uVGltZW91dCgpIHtcclxuICAgIGNsZWFyVGltZW91dCh0aGlzLl9zY3JvbGxUb1JlcGVhdEV4ZWN1dGlvblRpbWVvdXQpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzY3JvbGxUb0V4ZWN1dG9yKGlkOiBJZCwgYmVoYXZpb3I6IFNjcm9sbEJlaGF2aW9yLCBpdGVyYXRpb246IG51bWJlciA9IDAsIGlzTGFzdEl0ZXJhdGlvbiA9IGZhbHNlKSB7XHJcbiAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXM7XHJcbiAgICBpZiAoIWl0ZW1zIHx8ICFpdGVtcy5sZW5ndGgpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGR5bmFtaWNTaXplID0gdGhpcy5keW5hbWljU2l6ZSwgY29udGFpbmVyID0gdGhpcy5fY29udGFpbmVyLCBpdGVtU2l6ZSA9IHRoaXMuaXRlbVNpemU7XHJcbiAgICBpZiAoY29udGFpbmVyKSB7XHJcbiAgICAgIHRoaXMuY2xlYXJTY3JvbGxUb1JlcGVhdEV4ZWN1dGlvblRpbWVvdXQoKTtcclxuXHJcbiAgICAgIGlmIChkeW5hbWljU2l6ZSkge1xyXG4gICAgICAgIGlmIChjb250YWluZXIpIHtcclxuICAgICAgICAgIGNvbnRhaW5lci5uYXRpdmVFbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoU0NST0xMLCB0aGlzLl9vblNjcm9sbEhhbmRsZXIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSB0aGlzLl8kYm91bmRzLmdldFZhbHVlKCkgfHwgeyB3aWR0aDogMCwgaGVpZ2h0OiAwIH0sXHJcbiAgICAgICAgICBzdGlja3lNYXAgPSB0aGlzLnN0aWNreU1hcCwgaXRlbXMgPSB0aGlzLml0ZW1zLCBpc1ZlcnRpY2FsID0gdGhpcy5faXNWZXJ0aWNhbCwgZGVsdGEgPSB0aGlzLl90cmFja0JveC5kZWx0YSxcclxuICAgICAgICAgIG9wdHM6IElHZXRJdGVtUG9zaXRpb25PcHRpb25zPElWaXJ0dWFsTGlzdEl0ZW0sIElWaXJ0dWFsTGlzdENvbGxlY3Rpb24+ID0ge1xyXG4gICAgICAgICAgICBib3VuZHM6IHsgd2lkdGgsIGhlaWdodCB9LCBjb2xsZWN0aW9uOiBpdGVtcywgZHluYW1pY1NpemUsIGlzVmVydGljYWw6IHRoaXMuX2lzVmVydGljYWwsIGl0ZW1TaXplLFxyXG4gICAgICAgICAgICBidWZmZXJTaXplOiB0aGlzLmJ1ZmZlclNpemUsIG1heEJ1ZmZlclNpemU6IHRoaXMubWF4QnVmZmVyU2l6ZSwgc2Nyb2xsU2l6ZTogKGlzVmVydGljYWwgPyBjb250YWluZXIubmF0aXZlRWxlbWVudC5zY3JvbGxUb3AgOiBjb250YWluZXIubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0KSArIGRlbHRhLFxyXG4gICAgICAgICAgICBzbmFwOiB0aGlzLnNuYXAsIGZyb21JdGVtSWQ6IGlkLCBlbmFibGVkQnVmZmVyT3B0aW1pemF0aW9uOiB0aGlzLmVuYWJsZWRCdWZmZXJPcHRpbWl6YXRpb24sXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgc2Nyb2xsU2l6ZSA9IHRoaXMuX3RyYWNrQm94LmdldEl0ZW1Qb3NpdGlvbihpZCwgc3RpY2t5TWFwLCBvcHRzKSxcclxuICAgICAgICAgIHBhcmFtczogU2Nyb2xsVG9PcHRpb25zID0geyBbaXNWZXJ0aWNhbCA/IFRPUF9QUk9QX05BTUUgOiBMRUZUX1BST1BfTkFNRV06IHNjcm9sbFNpemUsIGJlaGF2aW9yIH07XHJcblxyXG4gICAgICAgIGlmIChzY3JvbGxTaXplID09PSAtMSkge1xyXG4gICAgICAgICAgY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihTQ1JPTEwsIHRoaXMuX29uU2Nyb2xsSGFuZGxlcik7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl90cmFja0JveC5jbGVhckRlbHRhKCk7XHJcblxyXG4gICAgICAgIGlmIChjb250YWluZXIpIHtcclxuICAgICAgICAgIGNvbnN0IHsgZGlzcGxheUl0ZW1zLCB0b3RhbFNpemUgfSA9IHRoaXMuX3RyYWNrQm94LnVwZGF0ZUNvbGxlY3Rpb24oaXRlbXMsIHN0aWNreU1hcCwge1xyXG4gICAgICAgICAgICAuLi5vcHRzLCBzY3JvbGxTaXplLCBmcm9tSXRlbUlkOiBpc0xhc3RJdGVyYXRpb24gPyB1bmRlZmluZWQgOiBpZCxcclxuICAgICAgICAgIH0pLCBkZWx0YSA9IHRoaXMuX3RyYWNrQm94LmRlbHRhO1xyXG5cclxuICAgICAgICAgIHRoaXMuX3RyYWNrQm94LmNsZWFyRGVsdGEoKTtcclxuXHJcbiAgICAgICAgICBsZXQgYWN0dWFsU2Nyb2xsU2l6ZSA9IHNjcm9sbFNpemUgKyBkZWx0YTtcclxuXHJcbiAgICAgICAgICB0aGlzLnJlc2V0Qm91bmRzU2l6ZShpc1ZlcnRpY2FsLCB0b3RhbFNpemUpO1xyXG5cclxuICAgICAgICAgIHRoaXMuY3JlYXRlRGlzcGxheUNvbXBvbmVudHNJZk5lZWQoZGlzcGxheUl0ZW1zKTtcclxuXHJcbiAgICAgICAgICB0aGlzLnRyYWNraW5nKCk7XHJcblxyXG4gICAgICAgICAgY29uc3QgX3Njcm9sbFNpemUgPSB0aGlzLl90cmFja0JveC5nZXRJdGVtUG9zaXRpb24oaWQsIHN0aWNreU1hcCwgeyAuLi5vcHRzLCBzY3JvbGxTaXplOiBhY3R1YWxTY3JvbGxTaXplLCBmcm9tSXRlbUlkOiBpZCB9KTtcclxuXHJcbiAgICAgICAgICBpZiAoX3Njcm9sbFNpemUgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5uYXRpdmVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoU0NST0xMLCB0aGlzLl9vblNjcm9sbEhhbmRsZXIpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgY29uc3Qgbm90Q2hhbmdlZCA9IGFjdHVhbFNjcm9sbFNpemUgPT09IF9zY3JvbGxTaXplXHJcblxyXG4gICAgICAgICAgaWYgKCFub3RDaGFuZ2VkIHx8IGl0ZXJhdGlvbiA8IE1BWF9TQ1JPTExfVE9fSVRFUkFUSU9OUykge1xyXG4gICAgICAgICAgICB0aGlzLmNsZWFyU2Nyb2xsVG9SZXBlYXRFeGVjdXRpb25UaW1lb3V0KCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3Njcm9sbFRvUmVwZWF0RXhlY3V0aW9uVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9FeGVjdXRvcihpZCwgQkVIQVZJT1JfSU5TVEFOVCBhcyBTY3JvbGxCZWhhdmlvciwgaXRlcmF0aW9uICsgMSwgbm90Q2hhbmdlZCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fJHNjcm9sbFNpemUubmV4dChhY3R1YWxTY3JvbGxTaXplKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5uYXRpdmVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoU0NST0xMLCB0aGlzLl9vblNjcm9sbEhhbmRsZXIpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG8ocGFyYW1zKTtcclxuXHJcbiAgICAgICAgdGhpcy5fJHNjcm9sbFNpemUubmV4dChzY3JvbGxTaXplKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zdCBpbmRleCA9IGl0ZW1zLmZpbmRJbmRleChpdGVtID0+IGl0ZW0uaWQgPT09IGlkKTtcclxuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xyXG4gICAgICAgICAgY29uc3Qgc2Nyb2xsU2l6ZSA9IGluZGV4ICogdGhpcy5pdGVtU2l6ZTtcclxuICAgICAgICAgIGNvbnN0IHBhcmFtczogU2Nyb2xsVG9PcHRpb25zID0geyBbdGhpcy5faXNWZXJ0aWNhbCA/IFRPUF9QUk9QX05BTUUgOiBMRUZUX1BST1BfTkFNRV06IHNjcm9sbFNpemUsIGJlaGF2aW9yIH07XHJcbiAgICAgICAgICBjb250YWluZXIubmF0aXZlRWxlbWVudC5zY3JvbGxUbyhwYXJhbXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2Nyb2xscyB0aGUgc2Nyb2xsIGFyZWEgdG8gdGhlIGRlc2lyZWQgZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgSUQuXHJcbiAgICovXHJcbiAgc2Nyb2xsVG9FbmQoYmVoYXZpb3I6IFNjcm9sbEJlaGF2aW9yID0gQkVIQVZJT1JfSU5TVEFOVCBhcyBTY3JvbGxCZWhhdmlvcikge1xyXG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zLCBsYXRJdGVtID0gaXRlbXNbaXRlbXMubGVuZ3RoID4gMCA/IGl0ZW1zLmxlbmd0aCAtIDEgOiAwXTtcclxuICAgIHRoaXMuc2Nyb2xsVG8obGF0SXRlbS5pZCwgYmVoYXZpb3IpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfb25Db250YWluZXJTY3JvbGxIYW5kbGVyID0gKGU6IEV2ZW50KSA9PiB7XHJcbiAgICBjb25zdCBjb250YWluZXJFbCA9IHRoaXMuX2NvbnRhaW5lcjtcclxuICAgIGlmIChjb250YWluZXJFbCkge1xyXG4gICAgICBjb25zdCBzY3JvbGxTaXplID0gKHRoaXMuX2lzVmVydGljYWwgPyBjb250YWluZXJFbC5uYXRpdmVFbGVtZW50LnNjcm9sbFRvcCA6IGNvbnRhaW5lckVsLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdCk7XHJcbiAgICAgIHRoaXMuX3RyYWNrQm94LmRlbHRhRGlyZWN0aW9uID0gdGhpcy5fJHNjcm9sbFNpemUuZ2V0VmFsdWUoKSA+IHNjcm9sbFNpemUgPyAtMSA6IHRoaXMuXyRzY3JvbGxTaXplLmdldFZhbHVlKCkgPCBzY3JvbGxTaXplID8gMSA6IDA7XHJcblxyXG4gICAgICBjb25zdCBldmVudCA9IG5ldyBTY3JvbGxFdmVudCh7XHJcbiAgICAgICAgZGlyZWN0aW9uOiB0aGlzLl90cmFja0JveC5zY3JvbGxEaXJlY3Rpb24sIGNvbnRhaW5lcjogY29udGFpbmVyRWwubmF0aXZlRWxlbWVudCxcclxuICAgICAgICBsaXN0OiB0aGlzLl9saXN0IS5uYXRpdmVFbGVtZW50LCBkZWx0YTogdGhpcy5fdHJhY2tCb3guZGVsdGEsXHJcbiAgICAgICAgc2Nyb2xsRGVsdGE6IHRoaXMuX3RyYWNrQm94LnNjcm9sbERlbHRhLCBpc1ZlcnRpY2FsOiB0aGlzLl9pc1ZlcnRpY2FsLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHRoaXMub25TY3JvbGwuZW1pdChldmVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9vbkNvbnRhaW5lclNjcm9sbEVuZEhhbmRsZXIgPSAoZTogRXZlbnQpID0+IHtcclxuICAgIGNvbnN0IGNvbnRhaW5lckVsID0gdGhpcy5fY29udGFpbmVyO1xyXG4gICAgaWYgKGNvbnRhaW5lckVsKSB7XHJcbiAgICAgIGNvbnN0IHNjcm9sbFNpemUgPSAodGhpcy5faXNWZXJ0aWNhbCA/IGNvbnRhaW5lckVsLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wIDogY29udGFpbmVyRWwubmF0aXZlRWxlbWVudC5zY3JvbGxMZWZ0KTtcclxuICAgICAgdGhpcy5fdHJhY2tCb3guZGVsdGFEaXJlY3Rpb24gPSB0aGlzLl8kc2Nyb2xsU2l6ZS5nZXRWYWx1ZSgpID4gc2Nyb2xsU2l6ZSA/IC0xIDogMDtcclxuXHJcbiAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IFNjcm9sbEV2ZW50KHtcclxuICAgICAgICBkaXJlY3Rpb246IHRoaXMuX3RyYWNrQm94LnNjcm9sbERpcmVjdGlvbiwgY29udGFpbmVyOiBjb250YWluZXJFbC5uYXRpdmVFbGVtZW50LFxyXG4gICAgICAgIGxpc3Q6IHRoaXMuX2xpc3QhLm5hdGl2ZUVsZW1lbnQsIGRlbHRhOiB0aGlzLl90cmFja0JveC5kZWx0YSxcclxuICAgICAgICBzY3JvbGxEZWx0YTogdGhpcy5fdHJhY2tCb3guc2Nyb2xsRGVsdGEsIGlzVmVydGljYWw6IHRoaXMuX2lzVmVydGljYWwsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgdGhpcy5vblNjcm9sbEVuZC5lbWl0KGV2ZW50KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBAaW50ZXJuYWwgKi9cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmFmdGVyVmlld0luaXQoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIGNvbnN0IGNvbnRhaW5lckVsID0gdGhpcy5fY29udGFpbmVyO1xyXG4gICAgaWYgKGNvbnRhaW5lckVsKSB7XHJcbiAgICAgIC8vIGZvciBkaXJlY3Rpb24gY2FsY3VsYXRpb25cclxuICAgICAgY29udGFpbmVyRWwubmF0aXZlRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFNDUk9MTCwgdGhpcy5fb25Db250YWluZXJTY3JvbGxIYW5kbGVyKTtcclxuICAgICAgY29udGFpbmVyRWwubmF0aXZlRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFNDUk9MTF9FTkQsIHRoaXMuX29uQ29udGFpbmVyU2Nyb2xsRW5kSGFuZGxlcik7XHJcblxyXG4gICAgICBjb250YWluZXJFbC5uYXRpdmVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoU0NST0xMLCB0aGlzLl9vblNjcm9sbEhhbmRsZXIpO1xyXG5cclxuICAgICAgdGhpcy5fcmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIodGhpcy5fb25SZXNpemVIYW5kbGVyKTtcclxuICAgICAgdGhpcy5fcmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShjb250YWluZXJFbC5uYXRpdmVFbGVtZW50KTtcclxuXHJcbiAgICAgIHRoaXMuX29uUmVzaXplSGFuZGxlcigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIG92ZXJyaWRlIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgc3VwZXIubmdPbkRlc3Ryb3koKTtcclxuICAgIHRoaXMuZGlzcG9zZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkaXNwb3NlKCkge1xyXG4gICAgdGhpcy5jbGVhclNjcm9sbFRvUmVwZWF0RXhlY3V0aW9uVGltZW91dCgpO1xyXG5cclxuICAgIGlmICh0aGlzLl90cmFja0JveCkge1xyXG4gICAgICB0aGlzLl90cmFja0JveC5kaXNwb3NlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX2NvbXBvbmVudHNSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICB0aGlzLl9jb21wb25lbnRzUmVzaXplT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9yZXNpemVPYnNlcnZlcikge1xyXG4gICAgICB0aGlzLl9yZXNpemVPYnNlcnZlci5kaXNjb25uZWN0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX3Jlc2l6ZVNuYXBwZWRPYnNlcnZlcikge1xyXG4gICAgICB0aGlzLl9yZXNpemVTbmFwcGVkT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNvbnRhaW5lckVsID0gdGhpcy5fY29udGFpbmVyO1xyXG4gICAgaWYgKGNvbnRhaW5lckVsKSB7XHJcbiAgICAgIGNvbnRhaW5lckVsLm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihTQ1JPTEwsIHRoaXMuX29uU2Nyb2xsSGFuZGxlcik7XHJcbiAgICAgIGNvbnRhaW5lckVsLm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihTQ1JPTEwsIHRoaXMuX29uQ29udGFpbmVyU2Nyb2xsSGFuZGxlcik7XHJcbiAgICAgIGNvbnRhaW5lckVsLm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihTQ1JPTExfRU5ELCB0aGlzLl9vbkNvbnRhaW5lclNjcm9sbEVuZEhhbmRsZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9zbmFwZWREaXNwbGF5Q29tcG9uZW50KSB7XHJcbiAgICAgIHRoaXMuX3NuYXBlZERpc3BsYXlDb21wb25lbnQuZGVzdHJveSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9kaXNwbGF5Q29tcG9uZW50cykge1xyXG4gICAgICB3aGlsZSAodGhpcy5fZGlzcGxheUNvbXBvbmVudHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNvbnN0IGNvbXAgPSB0aGlzLl9kaXNwbGF5Q29tcG9uZW50cy5wb3AoKTtcclxuICAgICAgICBjb21wPy5kZXN0cm95KCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPGRpdiAqbmdJZj1cInNuYXBcIiAjc25hcHBlZCBwYXJ0PVwic25hcHBlZC1pdGVtXCIgY2xhc3M9XCJuZ3ZsX19saXN0LXNuYXBwZXJcIj5cclxuICA8bmctY29udGFpbmVyICNzbmFwUmVuZGVyZXJDb250YWluZXI+PC9uZy1jb250YWluZXI+XHJcbjwvZGl2PlxyXG48ZGl2ICNjb250YWluZXIgcGFydD1cInNjcm9sbGVyXCIgY2xhc3M9XCJuZ3ZsX19zY3JvbGxlclwiPlxyXG4gIDx1bCAjbGlzdCBwYXJ0PVwibGlzdFwiIGNsYXNzPVwibmd2bF9fbGlzdFwiPlxyXG4gICAgPG5nLWNvbnRhaW5lciAjcmVuZGVyZXJzQ29udGFpbmVyPjwvbmctY29udGFpbmVyPlxyXG4gIDwvdWw+XHJcbjwvZGl2PiJdfQ==