angular-multiselect3 10.0.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.
- package/LICENSE +20 -0
- package/README.md +306 -0
- package/esm2022/angular-multiselect.mjs +5 -0
- package/esm2022/lib/clickOutside.mjs +58 -0
- package/esm2022/lib/list-filter.mjs +59 -0
- package/esm2022/lib/menu-item.mjs +352 -0
- package/esm2022/lib/multiselect.component.mjs +1038 -0
- package/esm2022/lib/multiselect.interface.mjs +2 -0
- package/esm2022/lib/multiselect.model.mjs +9 -0
- package/esm2022/lib/multiselect.service.mjs +28 -0
- package/esm2022/lib/virtual-scroll/defaultoptions.mjs +2 -0
- package/esm2022/lib/virtual-scroll/idimension.mjs +2 -0
- package/esm2022/lib/virtual-scroll/ipageinfo.mjs +2 -0
- package/esm2022/lib/virtual-scroll/iviewport.mjs +2 -0
- package/esm2022/lib/virtual-scroll/virtual-scroll.mjs +1162 -0
- package/esm2022/lib/virtual-scroll/wrapgroupdimension.mjs +2 -0
- package/esm2022/lib/virtual-scroll/wrapgroupdimensions.mjs +2 -0
- package/esm2022/public_api.mjs +7 -0
- package/fesm2022/angular-multiselect.mjs +2689 -0
- package/fesm2022/angular-multiselect.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/clickOutside.d.ts +17 -0
- package/lib/list-filter.d.ts +12 -0
- package/lib/menu-item.d.ts +36 -0
- package/lib/multiselect.component.d.ts +134 -0
- package/lib/multiselect.interface.d.ts +34 -0
- package/lib/multiselect.model.d.ts +5 -0
- package/lib/multiselect.service.d.ts +11 -0
- package/lib/virtual-scroll/defaultoptions.d.ts +11 -0
- package/lib/virtual-scroll/idimension.d.ts +12 -0
- package/lib/virtual-scroll/ipageinfo.d.ts +9 -0
- package/lib/virtual-scroll/iviewport.d.ts +5 -0
- package/lib/virtual-scroll/virtual-scroll.d.ts +132 -0
- package/lib/virtual-scroll/wrapgroupdimension.d.ts +5 -0
- package/lib/virtual-scroll/wrapgroupdimensions.d.ts +7 -0
- package/package.json +37 -0
- package/public_api.d.ts +6 -0
- package/themes/dark.theme.scss +113 -0
- package/themes/default.theme.css +107 -0
- package/themes/default.theme.scss +155 -0
|
@@ -0,0 +1,1162 @@
|
|
|
1
|
+
import { Component, ContentChild, ElementRef, EventEmitter, Inject, Optional, Input, NgModule, Output, ViewChild, } from '@angular/core';
|
|
2
|
+
import { PLATFORM_ID } from '@angular/core';
|
|
3
|
+
import { isPlatformServer } from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import * as tween from '@tweenjs/tween.js';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export function VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY() {
|
|
8
|
+
return {
|
|
9
|
+
scrollThrottlingTime: 0,
|
|
10
|
+
scrollDebounceTime: 0,
|
|
11
|
+
scrollAnimationTime: 750,
|
|
12
|
+
checkResizeInterval: 1000,
|
|
13
|
+
resizeBypassRefreshThreshold: 5,
|
|
14
|
+
modifyOverflowStyleOfParentScroll: true,
|
|
15
|
+
stripedTable: false,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export class VirtualScrollerComponent {
|
|
19
|
+
element;
|
|
20
|
+
renderer;
|
|
21
|
+
zone;
|
|
22
|
+
changeDetectorRef;
|
|
23
|
+
viewPortItems;
|
|
24
|
+
window = window;
|
|
25
|
+
get viewPortInfo() {
|
|
26
|
+
let pageInfo = this.previousViewPort || {};
|
|
27
|
+
return {
|
|
28
|
+
startIndex: pageInfo.startIndex || 0,
|
|
29
|
+
endIndex: pageInfo.endIndex || 0,
|
|
30
|
+
scrollStartPosition: pageInfo.scrollStartPosition || 0,
|
|
31
|
+
scrollEndPosition: pageInfo.scrollEndPosition || 0,
|
|
32
|
+
maxScrollPosition: pageInfo.maxScrollPosition || 0,
|
|
33
|
+
startIndexWithBuffer: pageInfo.startIndexWithBuffer || 0,
|
|
34
|
+
endIndexWithBuffer: pageInfo.endIndexWithBuffer || 0,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
executeRefreshOutsideAngularZone = false;
|
|
38
|
+
_enableUnequalChildrenSizes = false;
|
|
39
|
+
get enableUnequalChildrenSizes() {
|
|
40
|
+
return this._enableUnequalChildrenSizes;
|
|
41
|
+
}
|
|
42
|
+
set enableUnequalChildrenSizes(value) {
|
|
43
|
+
if (this._enableUnequalChildrenSizes === value) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this._enableUnequalChildrenSizes = value;
|
|
47
|
+
this.minMeasuredChildWidth = undefined;
|
|
48
|
+
this.minMeasuredChildHeight = undefined;
|
|
49
|
+
}
|
|
50
|
+
useMarginInsteadOfTranslate = false;
|
|
51
|
+
modifyOverflowStyleOfParentScroll;
|
|
52
|
+
stripedTable;
|
|
53
|
+
scrollbarWidth;
|
|
54
|
+
scrollbarHeight;
|
|
55
|
+
childWidth;
|
|
56
|
+
childHeight;
|
|
57
|
+
ssrChildWidth;
|
|
58
|
+
ssrChildHeight;
|
|
59
|
+
ssrViewportWidth = 1920;
|
|
60
|
+
ssrViewportHeight = 1080;
|
|
61
|
+
_bufferAmount = 0;
|
|
62
|
+
get bufferAmount() {
|
|
63
|
+
if (typeof this._bufferAmount === 'number' && this._bufferAmount >= 0) {
|
|
64
|
+
return this._bufferAmount;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return this.enableUnequalChildrenSizes ? 5 : 0;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
set bufferAmount(value) {
|
|
71
|
+
this._bufferAmount = value;
|
|
72
|
+
}
|
|
73
|
+
scrollAnimationTime;
|
|
74
|
+
resizeBypassRefreshThreshold;
|
|
75
|
+
_scrollThrottlingTime;
|
|
76
|
+
get scrollThrottlingTime() {
|
|
77
|
+
return this._scrollThrottlingTime;
|
|
78
|
+
}
|
|
79
|
+
set scrollThrottlingTime(value) {
|
|
80
|
+
this._scrollThrottlingTime = value;
|
|
81
|
+
this.updateOnScrollFunction();
|
|
82
|
+
}
|
|
83
|
+
_scrollDebounceTime;
|
|
84
|
+
get scrollDebounceTime() {
|
|
85
|
+
return this._scrollDebounceTime;
|
|
86
|
+
}
|
|
87
|
+
set scrollDebounceTime(value) {
|
|
88
|
+
this._scrollDebounceTime = value;
|
|
89
|
+
this.updateOnScrollFunction();
|
|
90
|
+
}
|
|
91
|
+
onScroll;
|
|
92
|
+
updateOnScrollFunction() {
|
|
93
|
+
if (this.scrollDebounceTime) {
|
|
94
|
+
this.onScroll = this.debounce(() => {
|
|
95
|
+
this.refresh_internal(false);
|
|
96
|
+
}, this.scrollDebounceTime);
|
|
97
|
+
}
|
|
98
|
+
else if (this.scrollThrottlingTime) {
|
|
99
|
+
this.onScroll = this.throttleTrailing(() => {
|
|
100
|
+
this.refresh_internal(false);
|
|
101
|
+
}, this.scrollThrottlingTime);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
this.onScroll = () => {
|
|
105
|
+
this.refresh_internal(false);
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
checkScrollElementResizedTimer;
|
|
110
|
+
_checkResizeInterval;
|
|
111
|
+
get checkResizeInterval() {
|
|
112
|
+
return this._checkResizeInterval;
|
|
113
|
+
}
|
|
114
|
+
set checkResizeInterval(value) {
|
|
115
|
+
if (this._checkResizeInterval === value) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this._checkResizeInterval = value;
|
|
119
|
+
this.addScrollEventHandlers();
|
|
120
|
+
}
|
|
121
|
+
_items = [];
|
|
122
|
+
get items() {
|
|
123
|
+
return this._items;
|
|
124
|
+
}
|
|
125
|
+
set items(value) {
|
|
126
|
+
if (value === this._items) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
this._items = value || [];
|
|
130
|
+
this.refresh_internal(true);
|
|
131
|
+
}
|
|
132
|
+
compareItems = (item1, item2) => item1 === item2;
|
|
133
|
+
_horizontal;
|
|
134
|
+
get horizontal() {
|
|
135
|
+
return this._horizontal;
|
|
136
|
+
}
|
|
137
|
+
set horizontal(value) {
|
|
138
|
+
this._horizontal = value;
|
|
139
|
+
this.updateDirection();
|
|
140
|
+
}
|
|
141
|
+
revertParentOverscroll() {
|
|
142
|
+
const scrollElement = this.getScrollElement();
|
|
143
|
+
if (scrollElement && this.oldParentScrollOverflow) {
|
|
144
|
+
scrollElement.style['overflow-y'] = this.oldParentScrollOverflow.y;
|
|
145
|
+
scrollElement.style['overflow-x'] = this.oldParentScrollOverflow.x;
|
|
146
|
+
}
|
|
147
|
+
this.oldParentScrollOverflow = undefined;
|
|
148
|
+
}
|
|
149
|
+
oldParentScrollOverflow;
|
|
150
|
+
_parentScroll;
|
|
151
|
+
get parentScroll() {
|
|
152
|
+
return this._parentScroll;
|
|
153
|
+
}
|
|
154
|
+
set parentScroll(value) {
|
|
155
|
+
if (this._parentScroll === value) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
this.revertParentOverscroll();
|
|
159
|
+
this._parentScroll = value;
|
|
160
|
+
this.addScrollEventHandlers();
|
|
161
|
+
const scrollElement = this.getScrollElement();
|
|
162
|
+
if (this.modifyOverflowStyleOfParentScroll &&
|
|
163
|
+
scrollElement !== this.element.nativeElement) {
|
|
164
|
+
this.oldParentScrollOverflow = {
|
|
165
|
+
x: scrollElement.style['overflow-x'],
|
|
166
|
+
y: scrollElement.style['overflow-y'],
|
|
167
|
+
};
|
|
168
|
+
scrollElement.style['overflow-y'] = this.horizontal ? 'visible' : 'auto';
|
|
169
|
+
scrollElement.style['overflow-x'] = this.horizontal ? 'auto' : 'visible';
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
vsUpdate = new EventEmitter();
|
|
173
|
+
vsChange = new EventEmitter();
|
|
174
|
+
vsStart = new EventEmitter();
|
|
175
|
+
vsEnd = new EventEmitter();
|
|
176
|
+
contentElementRef;
|
|
177
|
+
invisiblePaddingElementRef;
|
|
178
|
+
headerElementRef;
|
|
179
|
+
containerElementRef;
|
|
180
|
+
ngOnInit() {
|
|
181
|
+
this.addScrollEventHandlers();
|
|
182
|
+
}
|
|
183
|
+
ngOnDestroy() {
|
|
184
|
+
this.removeScrollEventHandlers();
|
|
185
|
+
this.revertParentOverscroll();
|
|
186
|
+
}
|
|
187
|
+
ngOnChanges(changes) {
|
|
188
|
+
let indexLengthChanged = this.cachedItemsLength !== this.items.length;
|
|
189
|
+
this.cachedItemsLength = this.items.length;
|
|
190
|
+
const firstRun = !changes.items ||
|
|
191
|
+
!changes.items.previousValue ||
|
|
192
|
+
changes.items.previousValue.length === 0;
|
|
193
|
+
this.refresh_internal(indexLengthChanged || firstRun);
|
|
194
|
+
}
|
|
195
|
+
ngDoCheck() {
|
|
196
|
+
if (this.cachedItemsLength !== this.items.length) {
|
|
197
|
+
this.cachedItemsLength = this.items.length;
|
|
198
|
+
this.refresh_internal(true);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (this.previousViewPort &&
|
|
202
|
+
this.viewPortItems &&
|
|
203
|
+
this.viewPortItems.length > 0) {
|
|
204
|
+
let itemsArrayChanged = false;
|
|
205
|
+
for (let i = 0; i < this.viewPortItems.length; ++i) {
|
|
206
|
+
if (!this.compareItems(this.items[this.previousViewPort.startIndexWithBuffer + i], this.viewPortItems[i])) {
|
|
207
|
+
itemsArrayChanged = true;
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (itemsArrayChanged) {
|
|
212
|
+
this.refresh_internal(true);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
refresh() {
|
|
217
|
+
this.refresh_internal(true);
|
|
218
|
+
}
|
|
219
|
+
invalidateAllCachedMeasurements() {
|
|
220
|
+
this.wrapGroupDimensions = {
|
|
221
|
+
maxChildSizePerWrapGroup: [],
|
|
222
|
+
numberOfKnownWrapGroupChildSizes: 0,
|
|
223
|
+
sumOfKnownWrapGroupChildWidths: 0,
|
|
224
|
+
sumOfKnownWrapGroupChildHeights: 0,
|
|
225
|
+
};
|
|
226
|
+
this.minMeasuredChildWidth = undefined;
|
|
227
|
+
this.minMeasuredChildHeight = undefined;
|
|
228
|
+
this.refresh_internal(false);
|
|
229
|
+
}
|
|
230
|
+
invalidateCachedMeasurementForItem(item) {
|
|
231
|
+
if (this.enableUnequalChildrenSizes) {
|
|
232
|
+
let index = this.items && this.items.indexOf(item);
|
|
233
|
+
if (index >= 0) {
|
|
234
|
+
this.invalidateCachedMeasurementAtIndex(index);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
this.minMeasuredChildWidth = undefined;
|
|
239
|
+
this.minMeasuredChildHeight = undefined;
|
|
240
|
+
}
|
|
241
|
+
this.refresh_internal(false);
|
|
242
|
+
}
|
|
243
|
+
invalidateCachedMeasurementAtIndex(index) {
|
|
244
|
+
if (this.enableUnequalChildrenSizes) {
|
|
245
|
+
let cachedMeasurement = this.wrapGroupDimensions.maxChildSizePerWrapGroup[index];
|
|
246
|
+
if (cachedMeasurement) {
|
|
247
|
+
this.wrapGroupDimensions.maxChildSizePerWrapGroup[index] = undefined;
|
|
248
|
+
--this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
249
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths -=
|
|
250
|
+
cachedMeasurement.childWidth || 0;
|
|
251
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights -=
|
|
252
|
+
cachedMeasurement.childHeight || 0;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
this.minMeasuredChildWidth = undefined;
|
|
257
|
+
this.minMeasuredChildHeight = undefined;
|
|
258
|
+
}
|
|
259
|
+
this.refresh_internal(false);
|
|
260
|
+
}
|
|
261
|
+
scrollInto(item, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
262
|
+
let index = this.items.indexOf(item);
|
|
263
|
+
if (index === -1) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
this.scrollToIndex(index, alignToBeginning, additionalOffset, animationMilliseconds, animationCompletedCallback);
|
|
267
|
+
}
|
|
268
|
+
scrollToIndex(index, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
269
|
+
let maxRetries = 5;
|
|
270
|
+
let retryIfNeeded = () => {
|
|
271
|
+
--maxRetries;
|
|
272
|
+
if (maxRetries <= 0) {
|
|
273
|
+
if (animationCompletedCallback) {
|
|
274
|
+
animationCompletedCallback();
|
|
275
|
+
}
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
let dimensions = this.calculateDimensions();
|
|
279
|
+
let desiredStartIndex = Math.min(Math.max(index, 0), dimensions.itemCount - 1);
|
|
280
|
+
if (this.previousViewPort.startIndex === desiredStartIndex) {
|
|
281
|
+
if (animationCompletedCallback) {
|
|
282
|
+
animationCompletedCallback();
|
|
283
|
+
}
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
this.scrollToIndex_internal(index, alignToBeginning, additionalOffset, 0, retryIfNeeded);
|
|
287
|
+
};
|
|
288
|
+
this.scrollToIndex_internal(index, alignToBeginning, additionalOffset, animationMilliseconds, retryIfNeeded);
|
|
289
|
+
}
|
|
290
|
+
scrollToIndex_internal(index, alignToBeginning = true, additionalOffset = 0, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
291
|
+
animationMilliseconds =
|
|
292
|
+
animationMilliseconds === undefined
|
|
293
|
+
? this.scrollAnimationTime
|
|
294
|
+
: animationMilliseconds;
|
|
295
|
+
let dimensions = this.calculateDimensions();
|
|
296
|
+
let scroll = this.calculatePadding(index, dimensions) + additionalOffset;
|
|
297
|
+
if (!alignToBeginning) {
|
|
298
|
+
scroll -= dimensions.wrapGroupsPerPage * dimensions[this._childScrollDim];
|
|
299
|
+
}
|
|
300
|
+
this.scrollToPosition(scroll, animationMilliseconds, animationCompletedCallback);
|
|
301
|
+
}
|
|
302
|
+
scrollToPosition(scrollPosition, animationMilliseconds = undefined, animationCompletedCallback = undefined) {
|
|
303
|
+
scrollPosition += this.getElementsOffset();
|
|
304
|
+
animationMilliseconds =
|
|
305
|
+
animationMilliseconds === undefined
|
|
306
|
+
? this.scrollAnimationTime
|
|
307
|
+
: animationMilliseconds;
|
|
308
|
+
let scrollElement = this.getScrollElement();
|
|
309
|
+
let animationRequest;
|
|
310
|
+
if (this.currentTween) {
|
|
311
|
+
this.currentTween.stop();
|
|
312
|
+
this.currentTween = undefined;
|
|
313
|
+
}
|
|
314
|
+
if (!animationMilliseconds) {
|
|
315
|
+
this.renderer.setProperty(scrollElement, this._scrollType, scrollPosition);
|
|
316
|
+
this.refresh_internal(false, animationCompletedCallback);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
const tweenConfigObj = { scrollPosition: scrollElement[this._scrollType] };
|
|
320
|
+
let newTween = new tween.Tween(tweenConfigObj)
|
|
321
|
+
.to({ scrollPosition }, animationMilliseconds)
|
|
322
|
+
.easing(tween.Easing.Quadratic.Out)
|
|
323
|
+
.onUpdate((data) => {
|
|
324
|
+
if (isNaN(data.scrollPosition)) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
this.renderer.setProperty(scrollElement, this._scrollType, data.scrollPosition);
|
|
328
|
+
this.refresh_internal(false);
|
|
329
|
+
})
|
|
330
|
+
.onStop(() => {
|
|
331
|
+
cancelAnimationFrame(animationRequest);
|
|
332
|
+
})
|
|
333
|
+
.start();
|
|
334
|
+
const animate = (time) => {
|
|
335
|
+
if (!newTween['isPlaying']()) {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
newTween.update(time);
|
|
339
|
+
if (tweenConfigObj.scrollPosition === scrollPosition) {
|
|
340
|
+
this.refresh_internal(false, animationCompletedCallback);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
this.zone.runOutsideAngular(() => {
|
|
344
|
+
animationRequest = requestAnimationFrame(animate);
|
|
345
|
+
});
|
|
346
|
+
};
|
|
347
|
+
animate();
|
|
348
|
+
this.currentTween = newTween;
|
|
349
|
+
}
|
|
350
|
+
isAngularUniversalSSR;
|
|
351
|
+
constructor(element, renderer, zone, changeDetectorRef, platformId, options) {
|
|
352
|
+
this.element = element;
|
|
353
|
+
this.renderer = renderer;
|
|
354
|
+
this.zone = zone;
|
|
355
|
+
this.changeDetectorRef = changeDetectorRef;
|
|
356
|
+
this.isAngularUniversalSSR = isPlatformServer(platformId);
|
|
357
|
+
this.scrollThrottlingTime = options.scrollThrottlingTime;
|
|
358
|
+
this.scrollDebounceTime = options.scrollDebounceTime;
|
|
359
|
+
this.scrollAnimationTime = options.scrollAnimationTime;
|
|
360
|
+
this.scrollbarWidth = options.scrollbarWidth;
|
|
361
|
+
this.scrollbarHeight = options.scrollbarHeight;
|
|
362
|
+
this.checkResizeInterval = options.checkResizeInterval;
|
|
363
|
+
this.resizeBypassRefreshThreshold = options.resizeBypassRefreshThreshold;
|
|
364
|
+
this.modifyOverflowStyleOfParentScroll =
|
|
365
|
+
options.modifyOverflowStyleOfParentScroll;
|
|
366
|
+
this.stripedTable = options.stripedTable;
|
|
367
|
+
this.horizontal = false;
|
|
368
|
+
this.resetWrapGroupDimensions();
|
|
369
|
+
}
|
|
370
|
+
getElementSize(element) {
|
|
371
|
+
let result = element.getBoundingClientRect();
|
|
372
|
+
let styles = getComputedStyle(element);
|
|
373
|
+
let marginTop = parseInt(styles['margin-top'], 10) || 0;
|
|
374
|
+
let marginBottom = parseInt(styles['margin-bottom'], 10) || 0;
|
|
375
|
+
let marginLeft = parseInt(styles['margin-left'], 10) || 0;
|
|
376
|
+
let marginRight = parseInt(styles['margin-right'], 10) || 0;
|
|
377
|
+
return {
|
|
378
|
+
top: result.top + marginTop,
|
|
379
|
+
bottom: result.bottom + marginBottom,
|
|
380
|
+
left: result.left + marginLeft,
|
|
381
|
+
right: result.right + marginRight,
|
|
382
|
+
width: result.width + marginLeft + marginRight,
|
|
383
|
+
height: result.height + marginTop + marginBottom,
|
|
384
|
+
y: result.top + marginTop,
|
|
385
|
+
x: result.left + marginLeft,
|
|
386
|
+
toJSON() {
|
|
387
|
+
result.toJSON();
|
|
388
|
+
},
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
previousScrollBoundingRect;
|
|
392
|
+
checkScrollElementResized() {
|
|
393
|
+
let boundingRect = this.getElementSize(this.getScrollElement());
|
|
394
|
+
let sizeChanged;
|
|
395
|
+
if (!this.previousScrollBoundingRect) {
|
|
396
|
+
sizeChanged = true;
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
let widthChange = Math.abs(boundingRect.width - this.previousScrollBoundingRect.width);
|
|
400
|
+
let heightChange = Math.abs(boundingRect.height - this.previousScrollBoundingRect.height);
|
|
401
|
+
sizeChanged =
|
|
402
|
+
widthChange > this.resizeBypassRefreshThreshold ||
|
|
403
|
+
heightChange > this.resizeBypassRefreshThreshold;
|
|
404
|
+
}
|
|
405
|
+
if (sizeChanged) {
|
|
406
|
+
this.previousScrollBoundingRect = boundingRect;
|
|
407
|
+
if (boundingRect.width > 0 && boundingRect.height > 0) {
|
|
408
|
+
this.refresh_internal(false);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
_invisiblePaddingProperty;
|
|
413
|
+
_offsetType;
|
|
414
|
+
_scrollType;
|
|
415
|
+
_pageOffsetType;
|
|
416
|
+
_childScrollDim;
|
|
417
|
+
_translateDir;
|
|
418
|
+
_marginDir;
|
|
419
|
+
updateDirection() {
|
|
420
|
+
if (this.horizontal) {
|
|
421
|
+
this._invisiblePaddingProperty = 'width';
|
|
422
|
+
this._offsetType = 'offsetLeft';
|
|
423
|
+
this._pageOffsetType = 'pageXOffset';
|
|
424
|
+
this._childScrollDim = 'childWidth';
|
|
425
|
+
this._marginDir = 'margin-left';
|
|
426
|
+
this._translateDir = 'translateX';
|
|
427
|
+
this._scrollType = 'scrollLeft';
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
this._invisiblePaddingProperty = 'height';
|
|
431
|
+
this._offsetType = 'offsetTop';
|
|
432
|
+
this._pageOffsetType = 'pageYOffset';
|
|
433
|
+
this._childScrollDim = 'childHeight';
|
|
434
|
+
this._marginDir = 'margin-top';
|
|
435
|
+
this._translateDir = 'translateY';
|
|
436
|
+
this._scrollType = 'scrollTop';
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
debounce(func, wait) {
|
|
440
|
+
const throttled = this.throttleTrailing(func, wait);
|
|
441
|
+
const result = function () {
|
|
442
|
+
throttled['cancel']();
|
|
443
|
+
throttled.apply(this, arguments);
|
|
444
|
+
};
|
|
445
|
+
result['cancel'] = function () {
|
|
446
|
+
throttled['cancel']();
|
|
447
|
+
};
|
|
448
|
+
return result;
|
|
449
|
+
}
|
|
450
|
+
throttleTrailing(func, wait) {
|
|
451
|
+
let timeout = undefined;
|
|
452
|
+
let _arguments = arguments;
|
|
453
|
+
const result = function () {
|
|
454
|
+
const _this = this;
|
|
455
|
+
_arguments = arguments;
|
|
456
|
+
if (timeout) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
if (wait <= 0) {
|
|
460
|
+
func.apply(_this, _arguments);
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
timeout = setTimeout(function () {
|
|
464
|
+
timeout = undefined;
|
|
465
|
+
func.apply(_this, _arguments);
|
|
466
|
+
}, wait);
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
result['cancel'] = function () {
|
|
470
|
+
if (timeout) {
|
|
471
|
+
clearTimeout(timeout);
|
|
472
|
+
timeout = undefined;
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
return result;
|
|
476
|
+
}
|
|
477
|
+
calculatedScrollbarWidth = 0;
|
|
478
|
+
calculatedScrollbarHeight = 0;
|
|
479
|
+
padding = 0;
|
|
480
|
+
previousViewPort = {};
|
|
481
|
+
currentTween;
|
|
482
|
+
cachedItemsLength;
|
|
483
|
+
disposeScrollHandler;
|
|
484
|
+
disposeResizeHandler;
|
|
485
|
+
refresh_internal(itemsArrayModified, refreshCompletedCallback = undefined, maxRunTimes = 2) {
|
|
486
|
+
//note: maxRunTimes is to force it to keep recalculating if the previous iteration caused a re-render (different sliced items in viewport or scrollPosition changed).
|
|
487
|
+
//The default of 2x max will probably be accurate enough without causing too large a performance bottleneck
|
|
488
|
+
//The code would typically quit out on the 2nd iteration anyways. The main time it'd think more than 2 runs would be necessary would be for vastly different sized child items or if this is the 1st time the items array was initialized.
|
|
489
|
+
//Without maxRunTimes, If the user is actively scrolling this code would become an infinite loop until they stopped scrolling. This would be okay, except each scroll event would start an additional infinte loop. We want to short-circuit it to prevent this.
|
|
490
|
+
if (itemsArrayModified &&
|
|
491
|
+
this.previousViewPort &&
|
|
492
|
+
this.previousViewPort.scrollStartPosition > 0) {
|
|
493
|
+
//if items were prepended, scroll forward to keep same items visible
|
|
494
|
+
let oldViewPort = this.previousViewPort;
|
|
495
|
+
let oldViewPortItems = this.viewPortItems;
|
|
496
|
+
let oldRefreshCompletedCallback = refreshCompletedCallback;
|
|
497
|
+
refreshCompletedCallback = () => {
|
|
498
|
+
let scrollLengthDelta = this.previousViewPort.scrollLength - oldViewPort.scrollLength;
|
|
499
|
+
if (scrollLengthDelta > 0 && this.viewPortItems) {
|
|
500
|
+
let oldStartItem = oldViewPortItems[0];
|
|
501
|
+
let oldStartItemIndex = this.items.findIndex((x) => this.compareItems(oldStartItem, x));
|
|
502
|
+
if (oldStartItemIndex > this.previousViewPort.startIndexWithBuffer) {
|
|
503
|
+
let itemOrderChanged = false;
|
|
504
|
+
for (let i = 1; i < this.viewPortItems.length; ++i) {
|
|
505
|
+
if (!this.compareItems(this.items[oldStartItemIndex + i], oldViewPortItems[i])) {
|
|
506
|
+
itemOrderChanged = true;
|
|
507
|
+
break;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (!itemOrderChanged) {
|
|
511
|
+
this.scrollToPosition(this.previousViewPort.scrollStartPosition + scrollLengthDelta, 0, oldRefreshCompletedCallback);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (oldRefreshCompletedCallback) {
|
|
517
|
+
oldRefreshCompletedCallback();
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
this.zone.runOutsideAngular(() => {
|
|
522
|
+
requestAnimationFrame(() => {
|
|
523
|
+
if (itemsArrayModified) {
|
|
524
|
+
this.resetWrapGroupDimensions();
|
|
525
|
+
}
|
|
526
|
+
let viewport = this.calculateViewport();
|
|
527
|
+
let startChanged = itemsArrayModified ||
|
|
528
|
+
viewport.startIndex !== this.previousViewPort.startIndex;
|
|
529
|
+
let endChanged = itemsArrayModified ||
|
|
530
|
+
viewport.endIndex !== this.previousViewPort.endIndex;
|
|
531
|
+
let scrollLengthChanged = viewport.scrollLength !== this.previousViewPort.scrollLength;
|
|
532
|
+
let paddingChanged = viewport.padding !== this.previousViewPort.padding;
|
|
533
|
+
let scrollPositionChanged = viewport.scrollStartPosition !==
|
|
534
|
+
this.previousViewPort.scrollStartPosition ||
|
|
535
|
+
viewport.scrollEndPosition !==
|
|
536
|
+
this.previousViewPort.scrollEndPosition ||
|
|
537
|
+
viewport.maxScrollPosition !==
|
|
538
|
+
this.previousViewPort.maxScrollPosition;
|
|
539
|
+
this.previousViewPort = viewport;
|
|
540
|
+
if (scrollLengthChanged) {
|
|
541
|
+
this.renderer.setStyle(this.invisiblePaddingElementRef.nativeElement, this._invisiblePaddingProperty, `${viewport.scrollLength}px`);
|
|
542
|
+
}
|
|
543
|
+
if (paddingChanged) {
|
|
544
|
+
if (this.useMarginInsteadOfTranslate) {
|
|
545
|
+
this.renderer.setStyle(this.contentElementRef.nativeElement, this._marginDir, `${viewport.padding}px`);
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
this.renderer.setStyle(this.contentElementRef.nativeElement, 'transform', `${this._translateDir}(${viewport.padding}px)`);
|
|
549
|
+
this.renderer.setStyle(this.contentElementRef.nativeElement, 'webkitTransform', `${this._translateDir}(${viewport.padding}px)`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
if (this.headerElementRef) {
|
|
553
|
+
let scrollPosition = this.getScrollElement()[this._scrollType];
|
|
554
|
+
let containerOffset = this.getElementsOffset();
|
|
555
|
+
let offset = Math.max(scrollPosition -
|
|
556
|
+
viewport.padding -
|
|
557
|
+
containerOffset +
|
|
558
|
+
this.headerElementRef.nativeElement.clientHeight, 0);
|
|
559
|
+
this.renderer.setStyle(this.headerElementRef.nativeElement, 'transform', `${this._translateDir}(${offset}px)`);
|
|
560
|
+
this.renderer.setStyle(this.headerElementRef.nativeElement, 'webkitTransform', `${this._translateDir}(${offset}px)`);
|
|
561
|
+
}
|
|
562
|
+
const changeEventArg = startChanged || endChanged
|
|
563
|
+
? {
|
|
564
|
+
startIndex: viewport.startIndex,
|
|
565
|
+
endIndex: viewport.endIndex,
|
|
566
|
+
scrollStartPosition: viewport.scrollStartPosition,
|
|
567
|
+
scrollEndPosition: viewport.scrollEndPosition,
|
|
568
|
+
startIndexWithBuffer: viewport.startIndexWithBuffer,
|
|
569
|
+
endIndexWithBuffer: viewport.endIndexWithBuffer,
|
|
570
|
+
maxScrollPosition: viewport.maxScrollPosition,
|
|
571
|
+
}
|
|
572
|
+
: undefined;
|
|
573
|
+
if (startChanged || endChanged || scrollPositionChanged) {
|
|
574
|
+
const handleChanged = () => {
|
|
575
|
+
// update the scroll list to trigger re-render of components in viewport
|
|
576
|
+
this.viewPortItems =
|
|
577
|
+
viewport.startIndexWithBuffer >= 0 &&
|
|
578
|
+
viewport.endIndexWithBuffer >= 0
|
|
579
|
+
? this.items.slice(viewport.startIndexWithBuffer, viewport.endIndexWithBuffer + 1)
|
|
580
|
+
: [];
|
|
581
|
+
this.vsUpdate.emit(this.viewPortItems);
|
|
582
|
+
if (startChanged) {
|
|
583
|
+
this.vsStart.emit(changeEventArg);
|
|
584
|
+
}
|
|
585
|
+
if (endChanged) {
|
|
586
|
+
this.vsEnd.emit(changeEventArg);
|
|
587
|
+
}
|
|
588
|
+
if (startChanged || endChanged) {
|
|
589
|
+
this.changeDetectorRef.markForCheck();
|
|
590
|
+
this.vsChange.emit(changeEventArg);
|
|
591
|
+
}
|
|
592
|
+
if (maxRunTimes > 0) {
|
|
593
|
+
this.refresh_internal(false, refreshCompletedCallback, maxRunTimes - 1);
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
if (refreshCompletedCallback) {
|
|
597
|
+
refreshCompletedCallback();
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
if (this.executeRefreshOutsideAngularZone) {
|
|
601
|
+
handleChanged();
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
this.zone.run(handleChanged);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
if (maxRunTimes > 0 && (scrollLengthChanged || paddingChanged)) {
|
|
609
|
+
this.refresh_internal(false, refreshCompletedCallback, maxRunTimes - 1);
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
if (refreshCompletedCallback) {
|
|
613
|
+
refreshCompletedCallback();
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
getScrollElement() {
|
|
620
|
+
return this.parentScroll instanceof Window
|
|
621
|
+
? document.scrollingElement || document.documentElement || document.body
|
|
622
|
+
: this.parentScroll || this.element.nativeElement;
|
|
623
|
+
}
|
|
624
|
+
addScrollEventHandlers() {
|
|
625
|
+
if (this.isAngularUniversalSSR) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
let scrollElement = this.getScrollElement();
|
|
629
|
+
this.removeScrollEventHandlers();
|
|
630
|
+
this.zone.runOutsideAngular(() => {
|
|
631
|
+
if (this.parentScroll instanceof Window) {
|
|
632
|
+
this.disposeScrollHandler = this.renderer.listen('window', 'scroll', this.onScroll);
|
|
633
|
+
this.disposeResizeHandler = this.renderer.listen('window', 'resize', this.onScroll);
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
this.disposeScrollHandler = this.renderer.listen(scrollElement, 'scroll', this.onScroll);
|
|
637
|
+
if (this._checkResizeInterval > 0) {
|
|
638
|
+
this.checkScrollElementResizedTimer = setInterval(() => {
|
|
639
|
+
this.checkScrollElementResized();
|
|
640
|
+
}, this._checkResizeInterval);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
removeScrollEventHandlers() {
|
|
646
|
+
if (this.checkScrollElementResizedTimer) {
|
|
647
|
+
clearInterval(this.checkScrollElementResizedTimer);
|
|
648
|
+
}
|
|
649
|
+
if (this.disposeScrollHandler) {
|
|
650
|
+
this.disposeScrollHandler();
|
|
651
|
+
this.disposeScrollHandler = undefined;
|
|
652
|
+
}
|
|
653
|
+
if (this.disposeResizeHandler) {
|
|
654
|
+
this.disposeResizeHandler();
|
|
655
|
+
this.disposeResizeHandler = undefined;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
getElementsOffset() {
|
|
659
|
+
if (this.isAngularUniversalSSR) {
|
|
660
|
+
return 0;
|
|
661
|
+
}
|
|
662
|
+
let offset = 0;
|
|
663
|
+
if (this.containerElementRef && this.containerElementRef.nativeElement) {
|
|
664
|
+
offset += this.containerElementRef.nativeElement[this._offsetType];
|
|
665
|
+
}
|
|
666
|
+
if (this.parentScroll) {
|
|
667
|
+
let scrollElement = this.getScrollElement();
|
|
668
|
+
let elementClientRect = this.getElementSize(this.element.nativeElement);
|
|
669
|
+
let scrollClientRect = this.getElementSize(scrollElement);
|
|
670
|
+
if (this.horizontal) {
|
|
671
|
+
offset += elementClientRect.left - scrollClientRect.left;
|
|
672
|
+
}
|
|
673
|
+
else {
|
|
674
|
+
offset += elementClientRect.top - scrollClientRect.top;
|
|
675
|
+
}
|
|
676
|
+
if (!(this.parentScroll instanceof Window)) {
|
|
677
|
+
offset += scrollElement[this._scrollType];
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return offset;
|
|
681
|
+
}
|
|
682
|
+
countItemsPerWrapGroup() {
|
|
683
|
+
if (this.isAngularUniversalSSR) {
|
|
684
|
+
return Math.round(this.horizontal
|
|
685
|
+
? this.ssrViewportHeight / this.ssrChildHeight
|
|
686
|
+
: this.ssrViewportWidth / this.ssrChildWidth);
|
|
687
|
+
}
|
|
688
|
+
let propertyName = this.horizontal ? 'offsetLeft' : 'offsetTop';
|
|
689
|
+
let children = ((this.containerElementRef && this.containerElementRef.nativeElement) ||
|
|
690
|
+
this.contentElementRef.nativeElement).children;
|
|
691
|
+
let childrenLength = children ? children.length : 0;
|
|
692
|
+
if (childrenLength === 0) {
|
|
693
|
+
return 1;
|
|
694
|
+
}
|
|
695
|
+
let firstOffset = children[0][propertyName];
|
|
696
|
+
let result = 1;
|
|
697
|
+
while (result < childrenLength &&
|
|
698
|
+
firstOffset === children[result][propertyName]) {
|
|
699
|
+
++result;
|
|
700
|
+
}
|
|
701
|
+
return result;
|
|
702
|
+
}
|
|
703
|
+
getScrollStartPosition() {
|
|
704
|
+
let windowScrollValue = undefined;
|
|
705
|
+
if (this.parentScroll instanceof Window) {
|
|
706
|
+
windowScrollValue = window[this._pageOffsetType];
|
|
707
|
+
}
|
|
708
|
+
return windowScrollValue || this.getScrollElement()[this._scrollType] || 0;
|
|
709
|
+
}
|
|
710
|
+
minMeasuredChildWidth;
|
|
711
|
+
minMeasuredChildHeight;
|
|
712
|
+
wrapGroupDimensions;
|
|
713
|
+
resetWrapGroupDimensions() {
|
|
714
|
+
const oldWrapGroupDimensions = this.wrapGroupDimensions;
|
|
715
|
+
this.invalidateAllCachedMeasurements();
|
|
716
|
+
if (!this.enableUnequalChildrenSizes ||
|
|
717
|
+
!oldWrapGroupDimensions ||
|
|
718
|
+
oldWrapGroupDimensions.numberOfKnownWrapGroupChildSizes === 0) {
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
const itemsPerWrapGroup = this.countItemsPerWrapGroup();
|
|
722
|
+
for (let wrapGroupIndex = 0; wrapGroupIndex < oldWrapGroupDimensions.maxChildSizePerWrapGroup.length; ++wrapGroupIndex) {
|
|
723
|
+
const oldWrapGroupDimension = oldWrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex];
|
|
724
|
+
if (!oldWrapGroupDimension ||
|
|
725
|
+
!oldWrapGroupDimension.items ||
|
|
726
|
+
!oldWrapGroupDimension.items.length) {
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
if (oldWrapGroupDimension.items.length !== itemsPerWrapGroup) {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
let itemsChanged = false;
|
|
733
|
+
let arrayStartIndex = itemsPerWrapGroup * wrapGroupIndex;
|
|
734
|
+
for (let i = 0; i < itemsPerWrapGroup; ++i) {
|
|
735
|
+
if (!this.compareItems(oldWrapGroupDimension.items[i], this.items[arrayStartIndex + i])) {
|
|
736
|
+
itemsChanged = true;
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
if (!itemsChanged) {
|
|
741
|
+
++this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
742
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths +=
|
|
743
|
+
oldWrapGroupDimension.childWidth || 0;
|
|
744
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights +=
|
|
745
|
+
oldWrapGroupDimension.childHeight || 0;
|
|
746
|
+
this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex] =
|
|
747
|
+
oldWrapGroupDimension;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
calculateDimensions() {
|
|
752
|
+
let scrollElement = this.getScrollElement();
|
|
753
|
+
const maxCalculatedScrollBarSize = 25; // Note: Formula to auto-calculate doesn't work for ParentScroll, so we default to this if not set by consuming application
|
|
754
|
+
this.calculatedScrollbarHeight = Math.max(Math.min(scrollElement.offsetHeight - scrollElement.clientHeight, maxCalculatedScrollBarSize), this.calculatedScrollbarHeight);
|
|
755
|
+
this.calculatedScrollbarWidth = Math.max(Math.min(scrollElement.offsetWidth - scrollElement.clientWidth, maxCalculatedScrollBarSize), this.calculatedScrollbarWidth);
|
|
756
|
+
let viewportWidth = scrollElement.offsetWidth -
|
|
757
|
+
(this.scrollbarWidth ||
|
|
758
|
+
this.calculatedScrollbarWidth ||
|
|
759
|
+
(this.horizontal ? 0 : maxCalculatedScrollBarSize));
|
|
760
|
+
let viewportHeight = scrollElement.offsetHeight -
|
|
761
|
+
(this.scrollbarHeight ||
|
|
762
|
+
this.calculatedScrollbarHeight ||
|
|
763
|
+
(this.horizontal ? maxCalculatedScrollBarSize : 0));
|
|
764
|
+
let content = (this.containerElementRef && this.containerElementRef.nativeElement) ||
|
|
765
|
+
this.contentElementRef.nativeElement;
|
|
766
|
+
let itemsPerWrapGroup = this.countItemsPerWrapGroup();
|
|
767
|
+
let wrapGroupsPerPage;
|
|
768
|
+
let defaultChildWidth;
|
|
769
|
+
let defaultChildHeight;
|
|
770
|
+
if (this.isAngularUniversalSSR) {
|
|
771
|
+
viewportWidth = this.ssrViewportWidth;
|
|
772
|
+
viewportHeight = this.ssrViewportHeight;
|
|
773
|
+
defaultChildWidth = this.ssrChildWidth;
|
|
774
|
+
defaultChildHeight = this.ssrChildHeight;
|
|
775
|
+
let itemsPerRow = Math.max(Math.ceil(viewportWidth / defaultChildWidth), 1);
|
|
776
|
+
let itemsPerCol = Math.max(Math.ceil(viewportHeight / defaultChildHeight), 1);
|
|
777
|
+
wrapGroupsPerPage = this.horizontal ? itemsPerRow : itemsPerCol;
|
|
778
|
+
}
|
|
779
|
+
else if (!this.enableUnequalChildrenSizes) {
|
|
780
|
+
if (content.children.length > 0) {
|
|
781
|
+
if (!this.childWidth || !this.childHeight) {
|
|
782
|
+
if (!this.minMeasuredChildWidth && viewportWidth > 0) {
|
|
783
|
+
this.minMeasuredChildWidth = viewportWidth;
|
|
784
|
+
}
|
|
785
|
+
if (!this.minMeasuredChildHeight && viewportHeight > 0) {
|
|
786
|
+
this.minMeasuredChildHeight = viewportHeight;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
let child = content.children[0];
|
|
790
|
+
let clientRect = this.getElementSize(child);
|
|
791
|
+
this.minMeasuredChildWidth = Math.min(this.minMeasuredChildWidth, clientRect.width);
|
|
792
|
+
this.minMeasuredChildHeight = Math.min(this.minMeasuredChildHeight, clientRect.height);
|
|
793
|
+
}
|
|
794
|
+
defaultChildWidth =
|
|
795
|
+
this.childWidth || this.minMeasuredChildWidth || viewportWidth;
|
|
796
|
+
defaultChildHeight =
|
|
797
|
+
this.childHeight || this.minMeasuredChildHeight || viewportHeight;
|
|
798
|
+
let itemsPerRow = Math.max(Math.ceil(viewportWidth / defaultChildWidth), 1);
|
|
799
|
+
let itemsPerCol = Math.max(Math.ceil(viewportHeight / defaultChildHeight), 1);
|
|
800
|
+
wrapGroupsPerPage = this.horizontal ? itemsPerRow : itemsPerCol;
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
let scrollOffset = scrollElement[this._scrollType] -
|
|
804
|
+
(this.previousViewPort ? this.previousViewPort.padding : 0);
|
|
805
|
+
let arrayStartIndex = this.previousViewPort.startIndexWithBuffer || 0;
|
|
806
|
+
let wrapGroupIndex = Math.ceil(arrayStartIndex / itemsPerWrapGroup);
|
|
807
|
+
let maxWidthForWrapGroup = 0;
|
|
808
|
+
let maxHeightForWrapGroup = 0;
|
|
809
|
+
let sumOfVisibleMaxWidths = 0;
|
|
810
|
+
let sumOfVisibleMaxHeights = 0;
|
|
811
|
+
wrapGroupsPerPage = 0;
|
|
812
|
+
for (let i = 0; i < content.children.length; ++i) {
|
|
813
|
+
++arrayStartIndex;
|
|
814
|
+
let child = content.children[i];
|
|
815
|
+
let clientRect = this.getElementSize(child);
|
|
816
|
+
maxWidthForWrapGroup = Math.max(maxWidthForWrapGroup, clientRect.width);
|
|
817
|
+
maxHeightForWrapGroup = Math.max(maxHeightForWrapGroup, clientRect.height);
|
|
818
|
+
if (arrayStartIndex % itemsPerWrapGroup === 0) {
|
|
819
|
+
let oldValue = this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex];
|
|
820
|
+
if (oldValue) {
|
|
821
|
+
--this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
822
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths -=
|
|
823
|
+
oldValue.childWidth || 0;
|
|
824
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights -=
|
|
825
|
+
oldValue.childHeight || 0;
|
|
826
|
+
}
|
|
827
|
+
++this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
828
|
+
const items = this.items.slice(arrayStartIndex - itemsPerWrapGroup, arrayStartIndex);
|
|
829
|
+
this.wrapGroupDimensions.maxChildSizePerWrapGroup[wrapGroupIndex] = {
|
|
830
|
+
childWidth: maxWidthForWrapGroup,
|
|
831
|
+
childHeight: maxHeightForWrapGroup,
|
|
832
|
+
items: items,
|
|
833
|
+
};
|
|
834
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths +=
|
|
835
|
+
maxWidthForWrapGroup;
|
|
836
|
+
this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights +=
|
|
837
|
+
maxHeightForWrapGroup;
|
|
838
|
+
if (this.horizontal) {
|
|
839
|
+
let maxVisibleWidthForWrapGroup = Math.min(maxWidthForWrapGroup, Math.max(viewportWidth - sumOfVisibleMaxWidths, 0));
|
|
840
|
+
if (scrollOffset > 0) {
|
|
841
|
+
let scrollOffsetToRemove = Math.min(scrollOffset, maxVisibleWidthForWrapGroup);
|
|
842
|
+
maxVisibleWidthForWrapGroup -= scrollOffsetToRemove;
|
|
843
|
+
scrollOffset -= scrollOffsetToRemove;
|
|
844
|
+
}
|
|
845
|
+
sumOfVisibleMaxWidths += maxVisibleWidthForWrapGroup;
|
|
846
|
+
if (maxVisibleWidthForWrapGroup > 0 &&
|
|
847
|
+
viewportWidth >= sumOfVisibleMaxWidths) {
|
|
848
|
+
++wrapGroupsPerPage;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
else {
|
|
852
|
+
let maxVisibleHeightForWrapGroup = Math.min(maxHeightForWrapGroup, Math.max(viewportHeight - sumOfVisibleMaxHeights, 0));
|
|
853
|
+
if (scrollOffset > 0) {
|
|
854
|
+
let scrollOffsetToRemove = Math.min(scrollOffset, maxVisibleHeightForWrapGroup);
|
|
855
|
+
maxVisibleHeightForWrapGroup -= scrollOffsetToRemove;
|
|
856
|
+
scrollOffset -= scrollOffsetToRemove;
|
|
857
|
+
}
|
|
858
|
+
sumOfVisibleMaxHeights += maxVisibleHeightForWrapGroup;
|
|
859
|
+
if (maxVisibleHeightForWrapGroup > 0 &&
|
|
860
|
+
viewportHeight >= sumOfVisibleMaxHeights) {
|
|
861
|
+
++wrapGroupsPerPage;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
++wrapGroupIndex;
|
|
865
|
+
maxWidthForWrapGroup = 0;
|
|
866
|
+
maxHeightForWrapGroup = 0;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
let averageChildWidth = this.wrapGroupDimensions.sumOfKnownWrapGroupChildWidths /
|
|
870
|
+
this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
871
|
+
let averageChildHeight = this.wrapGroupDimensions.sumOfKnownWrapGroupChildHeights /
|
|
872
|
+
this.wrapGroupDimensions.numberOfKnownWrapGroupChildSizes;
|
|
873
|
+
defaultChildWidth = this.childWidth || averageChildWidth || viewportWidth;
|
|
874
|
+
defaultChildHeight =
|
|
875
|
+
this.childHeight || averageChildHeight || viewportHeight;
|
|
876
|
+
if (this.horizontal) {
|
|
877
|
+
if (viewportWidth > sumOfVisibleMaxWidths) {
|
|
878
|
+
wrapGroupsPerPage += Math.ceil((viewportWidth - sumOfVisibleMaxWidths) / defaultChildWidth);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
else {
|
|
882
|
+
if (viewportHeight > sumOfVisibleMaxHeights) {
|
|
883
|
+
wrapGroupsPerPage += Math.ceil((viewportHeight - sumOfVisibleMaxHeights) / defaultChildHeight);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
let itemCount = this.items.length;
|
|
888
|
+
let itemsPerPage = itemsPerWrapGroup * wrapGroupsPerPage;
|
|
889
|
+
let pageCount_fractional = itemCount / itemsPerPage;
|
|
890
|
+
let numberOfWrapGroups = Math.ceil(itemCount / itemsPerWrapGroup);
|
|
891
|
+
let scrollLength = 0;
|
|
892
|
+
let defaultScrollLengthPerWrapGroup = this.horizontal
|
|
893
|
+
? defaultChildWidth
|
|
894
|
+
: defaultChildHeight;
|
|
895
|
+
if (this.enableUnequalChildrenSizes) {
|
|
896
|
+
let numUnknownChildSizes = 0;
|
|
897
|
+
for (let i = 0; i < numberOfWrapGroups; ++i) {
|
|
898
|
+
let childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] &&
|
|
899
|
+
this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
|
|
900
|
+
if (childSize) {
|
|
901
|
+
scrollLength += childSize;
|
|
902
|
+
}
|
|
903
|
+
else {
|
|
904
|
+
++numUnknownChildSizes;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
scrollLength += Math.round(numUnknownChildSizes * defaultScrollLengthPerWrapGroup);
|
|
908
|
+
}
|
|
909
|
+
else {
|
|
910
|
+
scrollLength = numberOfWrapGroups * defaultScrollLengthPerWrapGroup;
|
|
911
|
+
}
|
|
912
|
+
if (this.headerElementRef) {
|
|
913
|
+
scrollLength += this.headerElementRef.nativeElement.clientHeight;
|
|
914
|
+
}
|
|
915
|
+
let viewportLength = this.horizontal ? viewportWidth : viewportHeight;
|
|
916
|
+
let maxScrollPosition = Math.max(scrollLength - viewportLength, 0);
|
|
917
|
+
return {
|
|
918
|
+
itemCount: itemCount,
|
|
919
|
+
itemsPerWrapGroup: itemsPerWrapGroup,
|
|
920
|
+
wrapGroupsPerPage: wrapGroupsPerPage,
|
|
921
|
+
itemsPerPage: itemsPerPage,
|
|
922
|
+
pageCount_fractional: pageCount_fractional,
|
|
923
|
+
childWidth: defaultChildWidth,
|
|
924
|
+
childHeight: defaultChildHeight,
|
|
925
|
+
scrollLength: scrollLength,
|
|
926
|
+
viewportLength: viewportLength,
|
|
927
|
+
maxScrollPosition: maxScrollPosition,
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
cachedPageSize = 0;
|
|
931
|
+
previousScrollNumberElements = 0;
|
|
932
|
+
calculatePadding(arrayStartIndexWithBuffer, dimensions) {
|
|
933
|
+
if (dimensions.itemCount === 0) {
|
|
934
|
+
return 0;
|
|
935
|
+
}
|
|
936
|
+
let defaultScrollLengthPerWrapGroup = dimensions[this._childScrollDim];
|
|
937
|
+
let startingWrapGroupIndex = Math.floor(arrayStartIndexWithBuffer / dimensions.itemsPerWrapGroup) || 0;
|
|
938
|
+
if (!this.enableUnequalChildrenSizes) {
|
|
939
|
+
return defaultScrollLengthPerWrapGroup * startingWrapGroupIndex;
|
|
940
|
+
}
|
|
941
|
+
let numUnknownChildSizes = 0;
|
|
942
|
+
let result = 0;
|
|
943
|
+
for (let i = 0; i < startingWrapGroupIndex; ++i) {
|
|
944
|
+
let childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] &&
|
|
945
|
+
this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
|
|
946
|
+
if (childSize) {
|
|
947
|
+
result += childSize;
|
|
948
|
+
}
|
|
949
|
+
else {
|
|
950
|
+
++numUnknownChildSizes;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
result += Math.round(numUnknownChildSizes * defaultScrollLengthPerWrapGroup);
|
|
954
|
+
return result;
|
|
955
|
+
}
|
|
956
|
+
calculatePageInfo(scrollPosition, dimensions) {
|
|
957
|
+
let scrollPercentage = 0;
|
|
958
|
+
if (this.enableUnequalChildrenSizes) {
|
|
959
|
+
const numberOfWrapGroups = Math.ceil(dimensions.itemCount / dimensions.itemsPerWrapGroup);
|
|
960
|
+
let totalScrolledLength = 0;
|
|
961
|
+
let defaultScrollLengthPerWrapGroup = dimensions[this._childScrollDim];
|
|
962
|
+
for (let i = 0; i < numberOfWrapGroups; ++i) {
|
|
963
|
+
let childSize = this.wrapGroupDimensions.maxChildSizePerWrapGroup[i] &&
|
|
964
|
+
this.wrapGroupDimensions.maxChildSizePerWrapGroup[i][this._childScrollDim];
|
|
965
|
+
if (childSize) {
|
|
966
|
+
totalScrolledLength += childSize;
|
|
967
|
+
}
|
|
968
|
+
else {
|
|
969
|
+
totalScrolledLength += defaultScrollLengthPerWrapGroup;
|
|
970
|
+
}
|
|
971
|
+
if (scrollPosition < totalScrolledLength) {
|
|
972
|
+
scrollPercentage = i / numberOfWrapGroups;
|
|
973
|
+
break;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
else {
|
|
978
|
+
scrollPercentage = scrollPosition / dimensions.scrollLength;
|
|
979
|
+
}
|
|
980
|
+
let startingArrayIndex_fractional = Math.min(Math.max(scrollPercentage * dimensions.pageCount_fractional, 0), dimensions.pageCount_fractional) * dimensions.itemsPerPage;
|
|
981
|
+
let maxStart = dimensions.itemCount - dimensions.itemsPerPage - 1;
|
|
982
|
+
let arrayStartIndex = Math.min(Math.floor(startingArrayIndex_fractional), maxStart);
|
|
983
|
+
arrayStartIndex -= arrayStartIndex % dimensions.itemsPerWrapGroup; // round down to start of wrapGroup
|
|
984
|
+
if (this.stripedTable) {
|
|
985
|
+
let bufferBoundary = 2 * dimensions.itemsPerWrapGroup;
|
|
986
|
+
if (arrayStartIndex % bufferBoundary !== 0) {
|
|
987
|
+
arrayStartIndex = Math.max(arrayStartIndex - (arrayStartIndex % bufferBoundary), 0);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
let arrayEndIndex = Math.ceil(startingArrayIndex_fractional) + dimensions.itemsPerPage - 1;
|
|
991
|
+
let endIndexWithinWrapGroup = (arrayEndIndex + 1) % dimensions.itemsPerWrapGroup;
|
|
992
|
+
if (endIndexWithinWrapGroup > 0) {
|
|
993
|
+
arrayEndIndex += dimensions.itemsPerWrapGroup - endIndexWithinWrapGroup; // round up to end of wrapGroup
|
|
994
|
+
}
|
|
995
|
+
if (isNaN(arrayStartIndex)) {
|
|
996
|
+
arrayStartIndex = 0;
|
|
997
|
+
}
|
|
998
|
+
if (isNaN(arrayEndIndex)) {
|
|
999
|
+
arrayEndIndex = 0;
|
|
1000
|
+
}
|
|
1001
|
+
arrayStartIndex = Math.min(Math.max(arrayStartIndex, 0), dimensions.itemCount - 1);
|
|
1002
|
+
arrayEndIndex = Math.min(Math.max(arrayEndIndex, 0), dimensions.itemCount - 1);
|
|
1003
|
+
let bufferSize = this.bufferAmount * dimensions.itemsPerWrapGroup;
|
|
1004
|
+
let startIndexWithBuffer = Math.min(Math.max(arrayStartIndex - bufferSize, 0), dimensions.itemCount - 1);
|
|
1005
|
+
let endIndexWithBuffer = Math.min(Math.max(arrayEndIndex + bufferSize, 0), dimensions.itemCount - 1);
|
|
1006
|
+
return {
|
|
1007
|
+
startIndex: arrayStartIndex,
|
|
1008
|
+
endIndex: arrayEndIndex,
|
|
1009
|
+
startIndexWithBuffer: startIndexWithBuffer,
|
|
1010
|
+
endIndexWithBuffer: endIndexWithBuffer,
|
|
1011
|
+
scrollStartPosition: scrollPosition,
|
|
1012
|
+
scrollEndPosition: scrollPosition + dimensions.viewportLength,
|
|
1013
|
+
maxScrollPosition: dimensions.maxScrollPosition,
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
calculateViewport() {
|
|
1017
|
+
let dimensions = this.calculateDimensions();
|
|
1018
|
+
let offset = this.getElementsOffset();
|
|
1019
|
+
let scrollStartPosition = this.getScrollStartPosition();
|
|
1020
|
+
if (scrollStartPosition > dimensions.scrollLength + offset &&
|
|
1021
|
+
!(this.parentScroll instanceof Window)) {
|
|
1022
|
+
scrollStartPosition = dimensions.scrollLength;
|
|
1023
|
+
}
|
|
1024
|
+
else {
|
|
1025
|
+
scrollStartPosition -= offset;
|
|
1026
|
+
}
|
|
1027
|
+
scrollStartPosition = Math.max(0, scrollStartPosition);
|
|
1028
|
+
let pageInfo = this.calculatePageInfo(scrollStartPosition, dimensions);
|
|
1029
|
+
let newPadding = this.calculatePadding(pageInfo.startIndexWithBuffer, dimensions);
|
|
1030
|
+
let newScrollLength = dimensions.scrollLength;
|
|
1031
|
+
return {
|
|
1032
|
+
startIndex: pageInfo.startIndex,
|
|
1033
|
+
endIndex: pageInfo.endIndex,
|
|
1034
|
+
startIndexWithBuffer: pageInfo.startIndexWithBuffer,
|
|
1035
|
+
endIndexWithBuffer: pageInfo.endIndexWithBuffer,
|
|
1036
|
+
padding: Math.round(newPadding),
|
|
1037
|
+
scrollLength: Math.round(newScrollLength),
|
|
1038
|
+
scrollStartPosition: pageInfo.scrollStartPosition,
|
|
1039
|
+
scrollEndPosition: pageInfo.scrollEndPosition,
|
|
1040
|
+
maxScrollPosition: pageInfo.maxScrollPosition,
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VirtualScrollerComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }, { token: 'virtual-scroller-default-options', optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
1044
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: VirtualScrollerComponent, selector: "virtual-scroller,[virtualScroller]", inputs: { executeRefreshOutsideAngularZone: "executeRefreshOutsideAngularZone", enableUnequalChildrenSizes: "enableUnequalChildrenSizes", useMarginInsteadOfTranslate: "useMarginInsteadOfTranslate", modifyOverflowStyleOfParentScroll: "modifyOverflowStyleOfParentScroll", stripedTable: "stripedTable", scrollbarWidth: "scrollbarWidth", scrollbarHeight: "scrollbarHeight", childWidth: "childWidth", childHeight: "childHeight", ssrChildWidth: "ssrChildWidth", ssrChildHeight: "ssrChildHeight", ssrViewportWidth: "ssrViewportWidth", ssrViewportHeight: "ssrViewportHeight", bufferAmount: "bufferAmount", scrollAnimationTime: "scrollAnimationTime", resizeBypassRefreshThreshold: "resizeBypassRefreshThreshold", scrollThrottlingTime: "scrollThrottlingTime", scrollDebounceTime: "scrollDebounceTime", checkResizeInterval: "checkResizeInterval", items: "items", compareItems: "compareItems", horizontal: "horizontal", parentScroll: "parentScroll" }, outputs: { vsUpdate: "vsUpdate", vsChange: "vsChange", vsStart: "vsStart", vsEnd: "vsEnd" }, host: { properties: { "class.horizontal": "horizontal", "class.vertical": "!horizontal", "class.selfScroll": "!parentScroll" } }, queries: [{ propertyName: "headerElementRef", first: true, predicate: ["header"], descendants: true, read: ElementRef }, { propertyName: "containerElementRef", first: true, predicate: ["container"], descendants: true, read: ElementRef }], viewQueries: [{ propertyName: "contentElementRef", first: true, predicate: ["content"], descendants: true, read: ElementRef }, { propertyName: "invisiblePaddingElementRef", first: true, predicate: ["invisiblePadding"], descendants: true, read: ElementRef }], exportAs: ["virtualScroller"], usesOnChanges: true, ngImport: i0, template: `
|
|
1045
|
+
<div class="total-padding" #invisiblePadding></div>
|
|
1046
|
+
<div class="scrollable-content" #content>
|
|
1047
|
+
<ng-content></ng-content>
|
|
1048
|
+
</div>
|
|
1049
|
+
`, isInline: true, styles: [":host{position:relative;display:block;-webkit-overflow-scrolling:touch}:host.horizontal.selfScroll{overflow-y:visible;overflow-x:auto}:host.vertical.selfScroll{overflow-y:auto;overflow-x:visible}.scrollable-content{top:0;left:0;width:100%;height:100%;max-width:100vw;max-height:100vh;position:absolute}.scrollable-content ::ng-deep>*{box-sizing:border-box}:host.horizontal{white-space:nowrap}:host.horizontal .scrollable-content{display:flex}:host.horizontal .scrollable-content ::ng-deep>*{flex-shrink:0;flex-grow:0;white-space:initial}.total-padding{width:1px;opacity:0}:host.horizontal .total-padding{height:100%}\n"] });
|
|
1050
|
+
}
|
|
1051
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VirtualScrollerComponent, decorators: [{
|
|
1052
|
+
type: Component,
|
|
1053
|
+
args: [{ selector: 'virtual-scroller,[virtualScroller]', exportAs: 'virtualScroller', template: `
|
|
1054
|
+
<div class="total-padding" #invisiblePadding></div>
|
|
1055
|
+
<div class="scrollable-content" #content>
|
|
1056
|
+
<ng-content></ng-content>
|
|
1057
|
+
</div>
|
|
1058
|
+
`, host: {
|
|
1059
|
+
'[class.horizontal]': 'horizontal',
|
|
1060
|
+
'[class.vertical]': '!horizontal',
|
|
1061
|
+
'[class.selfScroll]': '!parentScroll',
|
|
1062
|
+
}, styles: [":host{position:relative;display:block;-webkit-overflow-scrolling:touch}:host.horizontal.selfScroll{overflow-y:visible;overflow-x:auto}:host.vertical.selfScroll{overflow-y:auto;overflow-x:visible}.scrollable-content{top:0;left:0;width:100%;height:100%;max-width:100vw;max-height:100vh;position:absolute}.scrollable-content ::ng-deep>*{box-sizing:border-box}:host.horizontal{white-space:nowrap}:host.horizontal .scrollable-content{display:flex}:host.horizontal .scrollable-content ::ng-deep>*{flex-shrink:0;flex-grow:0;white-space:initial}.total-padding{width:1px;opacity:0}:host.horizontal .total-padding{height:100%}\n"] }]
|
|
1063
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: Object, decorators: [{
|
|
1064
|
+
type: Inject,
|
|
1065
|
+
args: [PLATFORM_ID]
|
|
1066
|
+
}] }, { type: undefined, decorators: [{
|
|
1067
|
+
type: Optional
|
|
1068
|
+
}, {
|
|
1069
|
+
type: Inject,
|
|
1070
|
+
args: ['virtual-scroller-default-options']
|
|
1071
|
+
}] }], propDecorators: { executeRefreshOutsideAngularZone: [{
|
|
1072
|
+
type: Input
|
|
1073
|
+
}], enableUnequalChildrenSizes: [{
|
|
1074
|
+
type: Input
|
|
1075
|
+
}], useMarginInsteadOfTranslate: [{
|
|
1076
|
+
type: Input
|
|
1077
|
+
}], modifyOverflowStyleOfParentScroll: [{
|
|
1078
|
+
type: Input
|
|
1079
|
+
}], stripedTable: [{
|
|
1080
|
+
type: Input
|
|
1081
|
+
}], scrollbarWidth: [{
|
|
1082
|
+
type: Input
|
|
1083
|
+
}], scrollbarHeight: [{
|
|
1084
|
+
type: Input
|
|
1085
|
+
}], childWidth: [{
|
|
1086
|
+
type: Input
|
|
1087
|
+
}], childHeight: [{
|
|
1088
|
+
type: Input
|
|
1089
|
+
}], ssrChildWidth: [{
|
|
1090
|
+
type: Input
|
|
1091
|
+
}], ssrChildHeight: [{
|
|
1092
|
+
type: Input
|
|
1093
|
+
}], ssrViewportWidth: [{
|
|
1094
|
+
type: Input
|
|
1095
|
+
}], ssrViewportHeight: [{
|
|
1096
|
+
type: Input
|
|
1097
|
+
}], bufferAmount: [{
|
|
1098
|
+
type: Input
|
|
1099
|
+
}], scrollAnimationTime: [{
|
|
1100
|
+
type: Input
|
|
1101
|
+
}], resizeBypassRefreshThreshold: [{
|
|
1102
|
+
type: Input
|
|
1103
|
+
}], scrollThrottlingTime: [{
|
|
1104
|
+
type: Input
|
|
1105
|
+
}], scrollDebounceTime: [{
|
|
1106
|
+
type: Input
|
|
1107
|
+
}], checkResizeInterval: [{
|
|
1108
|
+
type: Input
|
|
1109
|
+
}], items: [{
|
|
1110
|
+
type: Input
|
|
1111
|
+
}], compareItems: [{
|
|
1112
|
+
type: Input
|
|
1113
|
+
}], horizontal: [{
|
|
1114
|
+
type: Input
|
|
1115
|
+
}], parentScroll: [{
|
|
1116
|
+
type: Input
|
|
1117
|
+
}], vsUpdate: [{
|
|
1118
|
+
type: Output
|
|
1119
|
+
}], vsChange: [{
|
|
1120
|
+
type: Output
|
|
1121
|
+
}], vsStart: [{
|
|
1122
|
+
type: Output
|
|
1123
|
+
}], vsEnd: [{
|
|
1124
|
+
type: Output
|
|
1125
|
+
}], contentElementRef: [{
|
|
1126
|
+
type: ViewChild,
|
|
1127
|
+
args: ['content', { read: ElementRef, static: false }]
|
|
1128
|
+
}], invisiblePaddingElementRef: [{
|
|
1129
|
+
type: ViewChild,
|
|
1130
|
+
args: ['invisiblePadding', { read: ElementRef, static: false }]
|
|
1131
|
+
}], headerElementRef: [{
|
|
1132
|
+
type: ContentChild,
|
|
1133
|
+
args: ['header', { read: ElementRef, static: false }]
|
|
1134
|
+
}], containerElementRef: [{
|
|
1135
|
+
type: ContentChild,
|
|
1136
|
+
args: ['container', { read: ElementRef, static: false }]
|
|
1137
|
+
}] } });
|
|
1138
|
+
export class VirtualScrollerModule {
|
|
1139
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VirtualScrollerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1140
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: VirtualScrollerModule, declarations: [VirtualScrollerComponent], imports: [CommonModule], exports: [VirtualScrollerComponent] });
|
|
1141
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VirtualScrollerModule, providers: [
|
|
1142
|
+
{
|
|
1143
|
+
provide: 'virtual-scroller-default-options',
|
|
1144
|
+
useFactory: VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY,
|
|
1145
|
+
},
|
|
1146
|
+
], imports: [CommonModule] });
|
|
1147
|
+
}
|
|
1148
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VirtualScrollerModule, decorators: [{
|
|
1149
|
+
type: NgModule,
|
|
1150
|
+
args: [{
|
|
1151
|
+
exports: [VirtualScrollerComponent],
|
|
1152
|
+
declarations: [VirtualScrollerComponent],
|
|
1153
|
+
imports: [CommonModule],
|
|
1154
|
+
providers: [
|
|
1155
|
+
{
|
|
1156
|
+
provide: 'virtual-scroller-default-options',
|
|
1157
|
+
useFactory: VIRTUAL_SCROLLER_DEFAULT_OPTIONS_FACTORY,
|
|
1158
|
+
},
|
|
1159
|
+
],
|
|
1160
|
+
}]
|
|
1161
|
+
}] });
|
|
1162
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlydHVhbC1zY3JvbGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyMi1tdWx0aXNlbGVjdC1kcm9wZG93bi1saWIvc3JjL2xpYi92aXJ0dWFsLXNjcm9sbC92aXJ0dWFsLXNjcm9sbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixRQUFRLEVBQ1IsS0FBSyxFQUNMLFFBQVEsRUFLUixNQUFNLEVBRU4sU0FBUyxHQUVWLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFbkQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRS9DLE9BQU8sS0FBSyxLQUFLLE1BQU0sbUJBQW1CLENBQUM7O0FBVTNDLE1BQU0sVUFBVSx3Q0FBd0M7SUFDdEQsT0FBTztRQUNMLG9CQUFvQixFQUFFLENBQUM7UUFDdkIsa0JBQWtCLEVBQUUsQ0FBQztRQUNyQixtQkFBbUIsRUFBRSxHQUFHO1FBQ3hCLG1CQUFtQixFQUFFLElBQUk7UUFDekIsNEJBQTRCLEVBQUUsQ0FBQztRQUMvQixpQ0FBaUMsRUFBRSxJQUFJO1FBQ3ZDLFlBQVksRUFBRSxLQUFLO0tBQ3BCLENBQUM7QUFDSixDQUFDO0FBd0VELE1BQU0sT0FBTyx3QkFBd0I7SUF1ZmQ7SUFDQTtJQUNBO0lBQ1Q7SUF6ZkwsYUFBYSxDQUFRO0lBQ3JCLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFFdkIsSUFBVyxZQUFZO1FBQ3JCLElBQUksUUFBUSxHQUFjLElBQUksQ0FBQyxnQkFBZ0IsSUFBUyxFQUFFLENBQUM7UUFDM0QsT0FBTztZQUNMLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVSxJQUFJ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QWlCO3NCQUQxQixTQUFTO3VCQUFDLFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFJL0MsMEJBQTBCO3NCQURuQyxTQUFTO3VCQUFDLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUl4RCxnQkFBZ0I7c0JBRHpCLFlBQVk7dUJBQUMsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUlqRCxtQkFBbUI7c0JBRDVCLFlBQVk7dUJBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFOztBQTJ3Q2hFLE1BQU0sT0FBTyxxQkFBcUI7d0dBQXJCLHFCQUFxQjt5R0FBckIscUJBQXFCLGlCQWgvQ3JCLHdCQUF3QixhQXcrQ3pCLFlBQVksYUF4K0NYLHdCQUF3Qjt5R0FnL0N4QixxQkFBcUIsYUFQckI7WUFDVDtnQkFDRSxPQUFPLEVBQUUsa0NBQWtDO2dCQUMzQyxVQUFVLEVBQUUsd0NBQXdDO2FBQ3JEO1NBQ0YsWUFOUyxZQUFZOzs0RkFRWCxxQkFBcUI7a0JBWGpDLFFBQVE7bUJBQUM7b0JBQ1IsT0FBTyxFQUFFLENBQUMsd0JBQXdCLENBQUM7b0JBQ25DLFlBQVksRUFBRSxDQUFDLHdCQUF3QixDQUFDO29CQUN4QyxPQUFPLEVBQUUsQ0FBQyxZQUFZLENBQUM7b0JBQ3ZCLFNBQVMsRUFBRTt3QkFDVDs0QkFDRSxPQUFPLEVBQUUsa0NBQWtDOzRCQUMzQyxVQUFVLEVBQUUsd0NBQXdDO3lCQUNyRDtxQkFDRjtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgT3B0aW9uYWwsXG4gIElucHV0LFxuICBOZ01vZHVsZSxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFJlbmRlcmVyMixcbiAgVmlld0NoaWxkLFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IFBMQVRGT1JNX0lEIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc1BsYXRmb3JtU2VydmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuaW1wb3J0ICogYXMgdHdlZW4gZnJvbSAnQHR3ZWVuanMvdHdlZW4uanMnO1xuaW1wb3J0IHsgVmlydHVhbFNjcm9sbGVyRGVmYXVsdE9wdGlvbnMgfSBmcm9tICcuL2RlZmF1bHRvcHRpb25zJztcbmltcG9ydCB7IElQYWdlSW5mbyB9IGZyb20gJy4vaXBhZ2VpbmZvJztcbmltcG9ydCB7IElWaWV3cG9ydCB9IGZyb20gJy4vaXZpZXdwb3J0JztcblxuaW1wb3J0IHsgV3JhcEdyb3VwRGltZW5zaW9ucyB9IGZyb20gJy4vd3JhcGdyb3VwZGltZW5zaW9ucyc7XG5pbXBvcnQgeyBXcmFwR3JvdXBEaW1lbnNpb24gfSBmcm9tICcuL3dyYXBncm91cGRpbWVuc2lvbic7XG5cbmltcG9ydCB7IElEaW1lbnNpb25zIH0gZnJvbSAnLi9pZGltZW5zaW9uJztcblxuZXhwb3J0IGZ1bmN0aW9uIFZJUlRVQUxfU0NST0xMRVJfREVGQVVMVF9PUFRJT05TX0ZBQ1RPUlkoKTogVmlydHVhbFNjcm9sbGVyRGVmYXVsdE9wdGlvbnMge1xuICByZXR1cm4ge1xuICAgIHNjcm9sbFRocm90dGxpbmdUaW1lOiAwLFxuICAgIHNjcm9sbERlYm91bmNlVGltZTogMCxcbiAgICBzY3JvbGxBbmltYXRpb25UaW1lOiA3NTAsXG4gICAgY2hlY2tSZXNpemVJbnRlcnZhbDogMTAwMCxcbiAgICByZXNpemVCeXBhc3NSZWZyZXNoVGhyZXNob2xkOiA1LFxuICAgIG1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbDogdHJ1ZSxcbiAgICBzdHJpcGVkVGFibGU6IGZhbHNlLFxuICB9O1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2aXJ0dWFsLXNjcm9sbGVyLFt2aXJ0dWFsU2Nyb2xsZXJdJyxcbiAgZXhwb3J0QXM6ICd2aXJ0dWFsU2Nyb2xsZXInLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJ0b3RhbC1wYWRkaW5nXCIgI2ludmlzaWJsZVBhZGRpbmc+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInNjcm9sbGFibGUtY29udGVudFwiICNjb250ZW50PlxuICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgIDwvZGl2PlxuICBgLFxuICBob3N0OiB7XG4gICAgJ1tjbGFzcy5ob3Jpem9udGFsXSc6ICdob3Jpem9udGFsJyxcbiAgICAnW2NsYXNzLnZlcnRpY2FsXSc6ICchaG9yaXpvbnRhbCcsXG4gICAgJ1tjbGFzcy5zZWxmU2Nyb2xsXSc6ICchcGFyZW50U2Nyb2xsJyxcbiAgfSxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgOmhvc3Qge1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7XG4gICAgICB9XG5cbiAgICAgIDpob3N0Lmhvcml6b250YWwuc2VsZlNjcm9sbCB7XG4gICAgICAgIG92ZXJmbG93LXk6IHZpc2libGU7XG4gICAgICAgIG92ZXJmbG93LXg6IGF1dG87XG4gICAgICB9XG4gICAgICA6aG9zdC52ZXJ0aWNhbC5zZWxmU2Nyb2xsIHtcbiAgICAgICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICAgICAgb3ZlcmZsb3cteDogdmlzaWJsZTtcbiAgICAgIH1cblxuICAgICAgLnNjcm9sbGFibGUtY29udGVudCB7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgbWF4LXdpZHRoOiAxMDB2dztcbiAgICAgICAgbWF4LWhlaWdodDogMTAwdmg7XG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIH1cblxuICAgICAgLnNjcm9sbGFibGUtY29udGVudCA6Om5nLWRlZXAgPiAqIHtcbiAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgIH1cblxuICAgICAgOmhvc3QuaG9yaXpvbnRhbCB7XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICB9XG5cbiAgICAgIDpob3N0Lmhvcml6b250YWwgLnNjcm9sbGFibGUtY29udGVudCB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICB9XG5cbiAgICAgIDpob3N0Lmhvcml6b250YWwgLnNjcm9sbGFibGUtY29udGVudCA6Om5nLWRlZXAgPiAqIHtcbiAgICAgICAgZmxleC1zaHJpbms6IDA7XG4gICAgICAgIGZsZXgtZ3JvdzogMDtcbiAgICAgICAgd2hpdGUtc3BhY2U6IGluaXRpYWw7XG4gICAgICB9XG5cbiAgICAgIC50b3RhbC1wYWRkaW5nIHtcbiAgICAgICAgd2lkdGg6IDFweDtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICAgIH1cblxuICAgICAgOmhvc3QuaG9yaXpvbnRhbCAudG90YWwtcGFkZGluZyB7XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgIH1cbiAgICBgLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBWaXJ0dWFsU2Nyb2xsZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgcHVibGljIHZpZXdQb3J0SXRlbXM6IGFueVtdO1xuICBwdWJsaWMgd2luZG93ID0gd2luZG93O1xuXG4gIHB1YmxpYyBnZXQgdmlld1BvcnRJbmZvKCk6IElQYWdlSW5mbyB7XG4gICAgbGV0IHBhZ2VJbmZvOiBJVmlld3BvcnQgPSB0aGlzLnByZXZpb3VzVmlld1BvcnQgfHwgPGFueT57fTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhcnRJbmRleDogcGFnZUluZm8uc3RhcnRJbmRleCB8fCAwLFxuICAgICAgZW5kSW5kZXg6IHBhZ2VJbmZvLmVuZEluZGV4IHx8IDAsXG4gICAgICBzY3JvbGxTdGFydFBvc2l0aW9uOiBwYWdlSW5mby5zY3JvbGxTdGFydFBvc2l0aW9uIHx8IDAsXG4gICAgICBzY3JvbGxFbmRQb3NpdGlvbjogcGFnZUluZm8uc2Nyb2xsRW5kUG9zaXRpb24gfHwgMCxcbiAgICAgIG1heFNjcm9sbFBvc2l0aW9uOiBwYWdlSW5mby5tYXhTY3JvbGxQb3NpdGlvbiB8fCAwLFxuICAgICAgc3RhcnRJbmRleFdpdGhCdWZmZXI6IHBhZ2VJbmZvLnN0YXJ0SW5kZXhXaXRoQnVmZmVyIHx8IDAsXG4gICAgICBlbmRJbmRleFdpdGhCdWZmZXI6IHBhZ2VJbmZvLmVuZEluZGV4V2l0aEJ1ZmZlciB8fCAwLFxuICAgIH07XG4gIH1cblxuICBASW5wdXQoKVxuICBwdWJsaWMgZXhlY3V0ZVJlZnJlc2hPdXRzaWRlQW5ndWxhclpvbmU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgX2VuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBnZXQgZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2VuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzO1xuICB9XG4gIHB1YmxpYyBzZXQgZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXModmFsdWU6IGJvb2xlYW4pIHtcbiAgICBpZiAodGhpcy5fZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMgPT09IHZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMgPSB2YWx1ZTtcbiAgICB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRXaWR0aCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBASW5wdXQoKVxuICBwdWJsaWMgdXNlTWFyZ2luSW5zdGVhZE9mVHJhbnNsYXRlOiBib29sZWFuID0gZmFsc2U7XG5cbiAgQElucHV0KClcbiAgcHVibGljIG1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbDogYm9vbGVhbjtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgc3RyaXBlZFRhYmxlOiBib29sZWFuO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzY3JvbGxiYXJXaWR0aDogbnVtYmVyO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzY3JvbGxiYXJIZWlnaHQ6IG51bWJlcjtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgY2hpbGRXaWR0aDogbnVtYmVyO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBjaGlsZEhlaWdodDogbnVtYmVyO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzc3JDaGlsZFdpZHRoOiBudW1iZXI7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNzckNoaWxkSGVpZ2h0OiBudW1iZXI7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNzclZpZXdwb3J0V2lkdGg6IG51bWJlciA9IDE5MjA7XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNzclZpZXdwb3J0SGVpZ2h0OiBudW1iZXIgPSAxMDgwO1xuXG4gIHByb3RlY3RlZCBfYnVmZmVyQW1vdW50OiBudW1iZXIgPSAwO1xuICBASW5wdXQoKVxuICBwdWJsaWMgZ2V0IGJ1ZmZlckFtb3VudCgpOiBudW1iZXIge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fYnVmZmVyQW1vdW50ID09PSAnbnVtYmVyJyAmJiB0aGlzLl9idWZmZXJBbW91bnQgPj0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlckFtb3VudDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMgPyA1IDogMDtcbiAgICB9XG4gIH1cbiAgcHVibGljIHNldCBidWZmZXJBbW91bnQodmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuX2J1ZmZlckFtb3VudCA9IHZhbHVlO1xuICB9XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNjcm9sbEFuaW1hdGlvblRpbWU6IG51bWJlcjtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgcmVzaXplQnlwYXNzUmVmcmVzaFRocmVzaG9sZDogbnVtYmVyO1xuXG4gIHByb3RlY3RlZCBfc2Nyb2xsVGhyb3R0bGluZ1RpbWU6IG51bWJlcjtcbiAgQElucHV0KClcbiAgcHVibGljIGdldCBzY3JvbGxUaHJvdHRsaW5nVGltZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9zY3JvbGxUaHJvdHRsaW5nVGltZTtcbiAgfVxuICBwdWJsaWMgc2V0IHNjcm9sbFRocm90dGxpbmdUaW1lKHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLl9zY3JvbGxUaHJvdHRsaW5nVGltZSA9IHZhbHVlO1xuICAgIHRoaXMudXBkYXRlT25TY3JvbGxGdW5jdGlvbigpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9zY3JvbGxEZWJvdW5jZVRpbWU6IG51bWJlcjtcbiAgQElucHV0KClcbiAgcHVibGljIGdldCBzY3JvbGxEZWJvdW5jZVRpbWUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fc2Nyb2xsRGVib3VuY2VUaW1lO1xuICB9XG4gIHB1YmxpYyBzZXQgc2Nyb2xsRGVib3VuY2VUaW1lKHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLl9zY3JvbGxEZWJvdW5jZVRpbWUgPSB2YWx1ZTtcbiAgICB0aGlzLnVwZGF0ZU9uU2Nyb2xsRnVuY3Rpb24oKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblNjcm9sbDogKCkgPT4gdm9pZDtcbiAgcHJvdGVjdGVkIHVwZGF0ZU9uU2Nyb2xsRnVuY3Rpb24oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2Nyb2xsRGVib3VuY2VUaW1lKSB7XG4gICAgICB0aGlzLm9uU2Nyb2xsID0gPGFueT50aGlzLmRlYm91bmNlKCgpID0+IHtcbiAgICAgICAgdGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlKTtcbiAgICAgIH0sIHRoaXMuc2Nyb2xsRGVib3VuY2VUaW1lKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc2Nyb2xsVGhyb3R0bGluZ1RpbWUpIHtcbiAgICAgIHRoaXMub25TY3JvbGwgPSA8YW55PnRoaXMudGhyb3R0bGVUcmFpbGluZygoKSA9PiB7XG4gICAgICAgIHRoaXMucmVmcmVzaF9pbnRlcm5hbChmYWxzZSk7XG4gICAgICB9LCB0aGlzLnNjcm9sbFRocm90dGxpbmdUaW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vblNjcm9sbCA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlKTtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGNoZWNrU2Nyb2xsRWxlbWVudFJlc2l6ZWRUaW1lcjogbnVtYmVyO1xuICBwcm90ZWN0ZWQgX2NoZWNrUmVzaXplSW50ZXJ2YWw6IG51bWJlcjtcbiAgQElucHV0KClcbiAgcHVibGljIGdldCBjaGVja1Jlc2l6ZUludGVydmFsKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX2NoZWNrUmVzaXplSW50ZXJ2YWw7XG4gIH1cbiAgcHVibGljIHNldCBjaGVja1Jlc2l6ZUludGVydmFsKHZhbHVlOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5fY2hlY2tSZXNpemVJbnRlcnZhbCA9PT0gdmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9jaGVja1Jlc2l6ZUludGVydmFsID0gdmFsdWU7XG4gICAgdGhpcy5hZGRTY3JvbGxFdmVudEhhbmRsZXJzKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2l0ZW1zOiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKVxuICBwdWJsaWMgZ2V0IGl0ZW1zKCk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5faXRlbXM7XG4gIH1cbiAgcHVibGljIHNldCBpdGVtcyh2YWx1ZTogYW55W10pIHtcbiAgICBpZiAodmFsdWUgPT09IHRoaXMuX2l0ZW1zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5faXRlbXMgPSB2YWx1ZSB8fCBbXTtcbiAgICB0aGlzLnJlZnJlc2hfaW50ZXJuYWwodHJ1ZSk7XG4gIH1cblxuICBASW5wdXQoKVxuICBwdWJsaWMgY29tcGFyZUl0ZW1zOiAoaXRlbTE6IGFueSwgaXRlbTI6IGFueSkgPT4gYm9vbGVhbiA9IChcbiAgICBpdGVtMTogYW55LFxuICAgIGl0ZW0yOiBhbnksXG4gICkgPT4gaXRlbTEgPT09IGl0ZW0yO1xuXG4gIHByb3RlY3RlZCBfaG9yaXpvbnRhbDogYm9vbGVhbjtcbiAgQElucHV0KClcbiAgcHVibGljIGdldCBob3Jpem9udGFsKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9ob3Jpem9udGFsO1xuICB9XG4gIHB1YmxpYyBzZXQgaG9yaXpvbnRhbCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2hvcml6b250YWwgPSB2YWx1ZTtcbiAgICB0aGlzLnVwZGF0ZURpcmVjdGlvbigpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJldmVydFBhcmVudE92ZXJzY3JvbGwoKTogdm9pZCB7XG4gICAgY29uc3Qgc2Nyb2xsRWxlbWVudCA9IHRoaXMuZ2V0U2Nyb2xsRWxlbWVudCgpO1xuICAgIGlmIChzY3JvbGxFbGVtZW50ICYmIHRoaXMub2xkUGFyZW50U2Nyb2xsT3ZlcmZsb3cpIHtcbiAgICAgIHNjcm9sbEVsZW1lbnQuc3R5bGVbJ292ZXJmbG93LXknXSA9IHRoaXMub2xkUGFyZW50U2Nyb2xsT3ZlcmZsb3cueTtcbiAgICAgIHNjcm9sbEVsZW1lbnQuc3R5bGVbJ292ZXJmbG93LXgnXSA9IHRoaXMub2xkUGFyZW50U2Nyb2xsT3ZlcmZsb3cueDtcbiAgICB9XG5cbiAgICB0aGlzLm9sZFBhcmVudFNjcm9sbE92ZXJmbG93ID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9sZFBhcmVudFNjcm9sbE92ZXJmbG93OiB7IHg6IHN0cmluZzsgeTogc3RyaW5nIH07XG4gIHByb3RlY3RlZCBfcGFyZW50U2Nyb2xsOiBFbGVtZW50IHwgV2luZG93O1xuICBASW5wdXQoKVxuICBwdWJsaWMgZ2V0IHBhcmVudFNjcm9sbCgpOiBFbGVtZW50IHwgV2luZG93IHtcbiAgICByZXR1cm4gdGhpcy5fcGFyZW50U2Nyb2xsO1xuICB9XG4gIHB1YmxpYyBzZXQgcGFyZW50U2Nyb2xsKHZhbHVlOiBFbGVtZW50IHwgV2luZG93KSB7XG4gICAgaWYgKHRoaXMuX3BhcmVudFNjcm9sbCA9PT0gdmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnJldmVydFBhcmVudE92ZXJzY3JvbGwoKTtcbiAgICB0aGlzLl9wYXJlbnRTY3JvbGwgPSB2YWx1ZTtcbiAgICB0aGlzLmFkZFNjcm9sbEV2ZW50SGFuZGxlcnMoKTtcblxuICAgIGNvbnN0IHNjcm9sbEVsZW1lbnQgPSB0aGlzLmdldFNjcm9sbEVsZW1lbnQoKTtcbiAgICBpZiAoXG4gICAgICB0aGlzLm1vZGlmeU92ZXJmbG93U3R5bGVPZlBhcmVudFNjcm9sbCAmJlxuICAgICAgc2Nyb2xsRWxlbWVudCAhPT0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnRcbiAgICApIHtcbiAgICAgIHRoaXMub2xkUGFyZW50U2Nyb2xsT3ZlcmZsb3cgPSB7XG4gICAgICAgIHg6IHNjcm9sbEVsZW1lbnQuc3R5bGVbJ292ZXJmbG93LXgnXSxcbiAgICAgICAgeTogc2Nyb2xsRWxlbWVudC5zdHlsZVsnb3ZlcmZsb3cteSddLFxuICAgICAgfTtcbiAgICAgIHNjcm9sbEVsZW1lbnQuc3R5bGVbJ292ZXJmbG93LXknXSA9IHRoaXMuaG9yaXpvbnRhbCA/ICd2aXNpYmxlJyA6ICdhdXRvJztcbiAgICAgIHNjcm9sbEVsZW1lbnQuc3R5bGVbJ292ZXJmbG93LXgnXSA9IHRoaXMuaG9yaXpvbnRhbCA/ICdhdXRvJyA6ICd2aXNpYmxlJztcbiAgICB9XG4gIH1cblxuICBAT3V0cHV0KClcbiAgcHVibGljIHZzVXBkYXRlOiBFdmVudEVtaXR0ZXI8YW55W10+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnlbXT4oKTtcblxuICBAT3V0cHV0KClcbiAgcHVibGljIHZzQ2hhbmdlOiBFdmVudEVtaXR0ZXI8SVBhZ2VJbmZvPiA9IG5ldyBFdmVudEVtaXR0ZXI8SVBhZ2VJbmZvPigpO1xuXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgdnNTdGFydDogRXZlbnRFbWl0dGVyPElQYWdlSW5mbz4gPSBuZXcgRXZlbnRFbWl0dGVyPElQYWdlSW5mbz4oKTtcblxuICBAT3V0cHV0KClcbiAgcHVibGljIHZzRW5kOiBFdmVudEVtaXR0ZXI8SVBhZ2VJbmZvPiA9IG5ldyBFdmVudEVtaXR0ZXI8SVBhZ2VJbmZvPigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2NvbnRlbnQnLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogZmFsc2UgfSlcbiAgcHJvdGVjdGVkIGNvbnRlbnRFbGVtZW50UmVmOiBFbGVtZW50UmVmO1xuXG4gIEBWaWV3Q2hpbGQoJ2ludmlzaWJsZVBhZGRpbmcnLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogZmFsc2UgfSlcbiAgcHJvdGVjdGVkIGludmlzaWJsZVBhZGRpbmdFbGVtZW50UmVmOiBFbGVtZW50UmVmO1xuXG4gIEBDb250ZW50Q2hpbGQoJ2hlYWRlcicsIHsgcmVhZDogRWxlbWVudFJlZiwgc3RhdGljOiBmYWxzZSB9KVxuICBwcm90ZWN0ZWQgaGVhZGVyRWxlbWVudFJlZjogRWxlbWVudFJlZjtcblxuICBAQ29udGVudENoaWxkKCdjb250YWluZXInLCB7IHJlYWQ6IEVsZW1lbnRSZWYsIHN0YXRpYzogZmFsc2UgfSlcbiAgcHJvdGVjdGVkIGNvbnRhaW5lckVsZW1lbnRSZWY6IEVsZW1lbnRSZWY7XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuYWRkU2Nyb2xsRXZlbnRIYW5kbGVycygpO1xuICB9XG5cbiAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMucmVtb3ZlU2Nyb2xsRXZlbnRIYW5kbGVycygpO1xuICAgIHRoaXMucmV2ZXJ0UGFyZW50T3ZlcnNjcm9sbCgpO1xuICB9XG5cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IGFueSk6IHZvaWQge1xuICAgIGxldCBpbmRleExlbmd0aENoYW5nZWQgPSB0aGlzLmNhY2hlZEl0ZW1zTGVuZ3RoICE9PSB0aGlzLml0ZW1zLmxlbmd0aDtcbiAgICB0aGlzLmNhY2hlZEl0ZW1zTGVuZ3RoID0gdGhpcy5pdGVtcy5sZW5ndGg7XG5cbiAgICBjb25zdCBmaXJzdFJ1bjogYm9vbGVhbiA9XG4gICAgICAhY2hhbmdlcy5pdGVtcyB8fFxuICAgICAgIWNoYW5nZXMuaXRlbXMucHJldmlvdXNWYWx1ZSB8fFxuICAgICAgY2hhbmdlcy5pdGVtcy5wcmV2aW91c1ZhbHVlLmxlbmd0aCA9PT0gMDtcbiAgICB0aGlzLnJlZnJlc2hfaW50ZXJuYWwoaW5kZXhMZW5ndGhDaGFuZ2VkIHx8IGZpcnN0UnVuKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ0RvQ2hlY2soKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2FjaGVkSXRlbXNMZW5ndGggIT09IHRoaXMuaXRlbXMubGVuZ3RoKSB7XG4gICAgICB0aGlzLmNhY2hlZEl0ZW1zTGVuZ3RoID0gdGhpcy5pdGVtcy5sZW5ndGg7XG4gICAgICB0aGlzLnJlZnJlc2hfaW50ZXJuYWwodHJ1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5wcmV2aW91c1ZpZXdQb3J0ICYmXG4gICAgICB0aGlzLnZpZXdQb3J0SXRlbXMgJiZcbiAgICAgIHRoaXMudmlld1BvcnRJdGVtcy5sZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICBsZXQgaXRlbXNBcnJheUNoYW5nZWQgPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52aWV3UG9ydEl0ZW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhdGhpcy5jb21wYXJlSXRlbXMoXG4gICAgICAgICAgICB0aGlzLml0ZW1zW3RoaXMucHJldmlvdXNWaWV3UG9ydC5zdGFydEluZGV4V2l0aEJ1ZmZlciArIGldLFxuICAgICAgICAgICAgdGhpcy52aWV3UG9ydEl0ZW1zW2ldLFxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgaXRlbXNBcnJheUNoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXRlbXNBcnJheUNoYW5nZWQpIHtcbiAgICAgICAgdGhpcy5yZWZyZXNoX2ludGVybmFsKHRydWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyByZWZyZXNoKCk6IHZvaWQge1xuICAgIHRoaXMucmVmcmVzaF9pbnRlcm5hbCh0cnVlKTtcbiAgfVxuXG4gIHB1YmxpYyBpbnZhbGlkYXRlQWxsQ2FjaGVkTWVhc3VyZW1lbnRzKCk6IHZvaWQge1xuICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucyA9IHtcbiAgICAgIG1heENoaWxkU2l6ZVBlcldyYXBHcm91cDogW10sXG4gICAgICBudW1iZXJPZktub3duV3JhcEdyb3VwQ2hpbGRTaXplczogMCxcbiAgICAgIHN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRoczogMCxcbiAgICAgIHN1bU9mS25vd25XcmFwR3JvdXBDaGlsZEhlaWdodHM6IDAsXG4gICAgfTtcblxuICAgIHRoaXMubWluTWVhc3VyZWRDaGlsZFdpZHRoID0gdW5kZWZpbmVkO1xuICAgIHRoaXMubWluTWVhc3VyZWRDaGlsZEhlaWdodCA9IHVuZGVmaW5lZDtcblxuICAgIHRoaXMucmVmcmVzaF9pbnRlcm5hbChmYWxzZSk7XG4gIH1cblxuICBwdWJsaWMgaW52YWxpZGF0ZUNhY2hlZE1lYXN1cmVtZW50Rm9ySXRlbShpdGVtOiBhbnkpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xuICAgICAgbGV0IGluZGV4ID0gdGhpcy5pdGVtcyAmJiB0aGlzLml0ZW1zLmluZGV4T2YoaXRlbSk7XG4gICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICB0aGlzLmludmFsaWRhdGVDYWNoZWRNZWFzdXJlbWVudEF0SW5kZXgoaW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRXaWR0aCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMubWluTWVhc3VyZWRDaGlsZEhlaWdodCA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICB0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xuICB9XG5cbiAgcHVibGljIGludmFsaWRhdGVDYWNoZWRNZWFzdXJlbWVudEF0SW5kZXgoaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLmVuYWJsZVVuZXF1YWxDaGlsZHJlblNpemVzKSB7XG4gICAgICBsZXQgY2FjaGVkTWVhc3VyZW1lbnQgPVxuICAgICAgICB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwW2luZGV4XTtcbiAgICAgIGlmIChjYWNoZWRNZWFzdXJlbWVudCkge1xuICAgICAgICB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwW2luZGV4XSA9IHVuZGVmaW5lZDtcbiAgICAgICAgLS10aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XG4gICAgICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRXaWR0aHMgLT1cbiAgICAgICAgICBjYWNoZWRNZWFzdXJlbWVudC5jaGlsZFdpZHRoIHx8IDA7XG4gICAgICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRIZWlnaHRzIC09XG4gICAgICAgICAgY2FjaGVkTWVhc3VyZW1lbnQuY2hpbGRIZWlnaHQgfHwgMDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlKTtcbiAgfVxuXG4gIHB1YmxpYyBzY3JvbGxJbnRvKFxuICAgIGl0ZW06IGFueSxcbiAgICBhbGlnblRvQmVnaW5uaW5nOiBib29sZWFuID0gdHJ1ZSxcbiAgICBhZGRpdGlvbmFsT2Zmc2V0OiBudW1iZXIgPSAwLFxuICAgIGFuaW1hdGlvbk1pbGxpc2Vjb25kczogbnVtYmVyID0gdW5kZWZpbmVkLFxuICAgIGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrOiAoKSA9PiB2b2lkID0gdW5kZWZpbmVkLFxuICApOiB2b2lkIHtcbiAgICBsZXQgaW5kZXg6IG51bWJlciA9IHRoaXMuaXRlbXMuaW5kZXhPZihpdGVtKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zY3JvbGxUb0luZGV4KFxuICAgICAgaW5kZXgsXG4gICAgICBhbGlnblRvQmVnaW5uaW5nLFxuICAgICAgYWRkaXRpb25hbE9mZnNldCxcbiAgICAgIGFuaW1hdGlvbk1pbGxpc2Vjb25kcyxcbiAgICAgIGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgc2Nyb2xsVG9JbmRleChcbiAgICBpbmRleDogbnVtYmVyLFxuICAgIGFsaWduVG9CZWdpbm5pbmc6IGJvb2xlYW4gPSB0cnVlLFxuICAgIGFkZGl0aW9uYWxPZmZzZXQ6IG51bWJlciA9IDAsXG4gICAgYW5pbWF0aW9uTWlsbGlzZWNvbmRzOiBudW1iZXIgPSB1bmRlZmluZWQsXG4gICAgYW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSB1bmRlZmluZWQsXG4gICk6IHZvaWQge1xuICAgIGxldCBtYXhSZXRyaWVzOiBudW1iZXIgPSA1O1xuXG4gICAgbGV0IHJldHJ5SWZOZWVkZWQgPSAoKSA9PiB7XG4gICAgICAtLW1heFJldHJpZXM7XG4gICAgICBpZiAobWF4UmV0cmllcyA8PSAwKSB7XG4gICAgICAgIGlmIChhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjaykge1xuICAgICAgICAgIGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlRGltZW5zaW9ucygpO1xuICAgICAgbGV0IGRlc2lyZWRTdGFydEluZGV4ID0gTWF0aC5taW4oXG4gICAgICAgIE1hdGgubWF4KGluZGV4LCAwKSxcbiAgICAgICAgZGltZW5zaW9ucy5pdGVtQ291bnQgLSAxLFxuICAgICAgKTtcbiAgICAgIGlmICh0aGlzLnByZXZpb3VzVmlld1BvcnQuc3RhcnRJbmRleCA9PT0gZGVzaXJlZFN0YXJ0SW5kZXgpIHtcbiAgICAgICAgaWYgKGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrKSB7XG4gICAgICAgICAgYW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2Nyb2xsVG9JbmRleF9pbnRlcm5hbChcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIGFsaWduVG9CZWdpbm5pbmcsXG4gICAgICAgIGFkZGl0aW9uYWxPZmZzZXQsXG4gICAgICAgIDAsXG4gICAgICAgIHJldHJ5SWZOZWVkZWQsXG4gICAgICApO1xuICAgIH07XG5cbiAgICB0aGlzLnNjcm9sbFRvSW5kZXhfaW50ZXJuYWwoXG4gICAgICBpbmRleCxcbiAgICAgIGFsaWduVG9CZWdpbm5pbmcsXG4gICAgICBhZGRpdGlvbmFsT2Zmc2V0LFxuICAgICAgYW5pbWF0aW9uTWlsbGlzZWNvbmRzLFxuICAgICAgcmV0cnlJZk5lZWRlZCxcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNjcm9sbFRvSW5kZXhfaW50ZXJuYWwoXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBhbGlnblRvQmVnaW5uaW5nOiBib29sZWFuID0gdHJ1ZSxcbiAgICBhZGRpdGlvbmFsT2Zmc2V0OiBudW1iZXIgPSAwLFxuICAgIGFuaW1hdGlvbk1pbGxpc2Vjb25kczogbnVtYmVyID0gdW5kZWZpbmVkLFxuICAgIGFuaW1hdGlvbkNvbXBsZXRlZENhbGxiYWNrOiAoKSA9PiB2b2lkID0gdW5kZWZpbmVkLFxuICApOiB2b2lkIHtcbiAgICBhbmltYXRpb25NaWxsaXNlY29uZHMgPVxuICAgICAgYW5pbWF0aW9uTWlsbGlzZWNvbmRzID09PSB1bmRlZmluZWRcbiAgICAgICAgPyB0aGlzLnNjcm9sbEFuaW1hdGlvblRpbWVcbiAgICAgICAgOiBhbmltYXRpb25NaWxsaXNlY29uZHM7XG5cbiAgICBsZXQgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlRGltZW5zaW9ucygpO1xuICAgIGxldCBzY3JvbGwgPSB0aGlzLmNhbGN1bGF0ZVBhZGRpbmcoaW5kZXgsIGRpbWVuc2lvbnMpICsgYWRkaXRpb25hbE9mZnNldDtcbiAgICBpZiAoIWFsaWduVG9CZWdpbm5pbmcpIHtcbiAgICAgIHNjcm9sbCAtPSBkaW1lbnNpb25zLndyYXBHcm91cHNQZXJQYWdlICogZGltZW5zaW9uc1t0aGlzLl9jaGlsZFNjcm9sbERpbV07XG4gICAgfVxuXG4gICAgdGhpcy5zY3JvbGxUb1Bvc2l0aW9uKFxuICAgICAgc2Nyb2xsLFxuICAgICAgYW5pbWF0aW9uTWlsbGlzZWNvbmRzLFxuICAgICAgYW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2ssXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBzY3JvbGxUb1Bvc2l0aW9uKFxuICAgIHNjcm9sbFBvc2l0aW9uOiBudW1iZXIsXG4gICAgYW5pbWF0aW9uTWlsbGlzZWNvbmRzOiBudW1iZXIgPSB1bmRlZmluZWQsXG4gICAgYW5pbWF0aW9uQ29tcGxldGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSB1bmRlZmluZWQsXG4gICk6IHZvaWQge1xuICAgIHNjcm9sbFBvc2l0aW9uICs9IHRoaXMuZ2V0RWxlbWVudHNPZmZzZXQoKTtcblxuICAgIGFuaW1hdGlvbk1pbGxpc2Vjb25kcyA9XG4gICAgICBhbmltYXRpb25NaWxsaXNlY29uZHMgPT09IHVuZGVmaW5lZFxuICAgICAgICA/IHRoaXMuc2Nyb2xsQW5pbWF0aW9uVGltZVxuICAgICAgICA6IGFuaW1hdGlvbk1pbGxpc2Vjb25kcztcblxuICAgIGxldCBzY3JvbGxFbGVtZW50ID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KCk7XG5cbiAgICBsZXQgYW5pbWF0aW9uUmVxdWVzdDogbnVtYmVyO1xuXG4gICAgaWYgKHRoaXMuY3VycmVudFR3ZWVuKSB7XG4gICAgICB0aGlzLmN1cnJlbnRUd2Vlbi5zdG9wKCk7XG4gICAgICB0aGlzLmN1cnJlbnRUd2VlbiA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoIWFuaW1hdGlvbk1pbGxpc2Vjb25kcykge1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRQcm9wZXJ0eShcbiAgICAgICAgc2Nyb2xsRWxlbWVudCxcbiAgICAgICAgdGhpcy5fc2Nyb2xsVHlwZSxcbiAgICAgICAgc2Nyb2xsUG9zaXRpb24sXG4gICAgICApO1xuICAgICAgdGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjayk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdHdlZW5Db25maWdPYmogPSB7IHNjcm9sbFBvc2l0aW9uOiBzY3JvbGxFbGVtZW50W3RoaXMuX3Njcm9sbFR5cGVdIH07XG5cbiAgICBsZXQgbmV3VHdlZW4gPSBuZXcgdHdlZW4uVHdlZW4odHdlZW5Db25maWdPYmopXG4gICAgICAudG8oeyBzY3JvbGxQb3NpdGlvbiB9LCBhbmltYXRpb25NaWxsaXNlY29uZHMpXG4gICAgICAuZWFzaW5nKHR3ZWVuLkVhc2luZy5RdWFkcmF0aWMuT3V0KVxuICAgICAgLm9uVXBkYXRlKChkYXRhKSA9PiB7XG4gICAgICAgIGlmIChpc05hTihkYXRhLnNjcm9sbFBvc2l0aW9uKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KFxuICAgICAgICAgIHNjcm9sbEVsZW1lbnQsXG4gICAgICAgICAgdGhpcy5fc2Nyb2xsVHlwZSxcbiAgICAgICAgICBkYXRhLnNjcm9sbFBvc2l0aW9uLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlZnJlc2hfaW50ZXJuYWwoZmFsc2UpO1xuICAgICAgfSlcbiAgICAgIC5vblN0b3AoKCkgPT4ge1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShhbmltYXRpb25SZXF1ZXN0KTtcbiAgICAgIH0pXG4gICAgICAuc3RhcnQoKTtcblxuICAgIGNvbnN0IGFuaW1hdGUgPSAodGltZT86IG51bWJlcikgPT4ge1xuICAgICAgaWYgKCFuZXdUd2VlblsnaXNQbGF5aW5nJ10oKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIG5ld1R3ZWVuLnVwZGF0ZSh0aW1lKTtcbiAgICAgIGlmICh0d2VlbkNvbmZpZ09iai5zY3JvbGxQb3NpdGlvbiA9PT0gc2Nyb2xsUG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlLCBhbmltYXRpb25Db21wbGV0ZWRDYWxsYmFjayk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgYW5pbWF0aW9uUmVxdWVzdCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShhbmltYXRlKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBhbmltYXRlKCk7XG4gICAgdGhpcy5jdXJyZW50VHdlZW4gPSBuZXdUd2VlbjtcbiAgfVxuXG4gIHByb3RlY3RlZCBpc0FuZ3VsYXJVbml2ZXJzYWxTU1I6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGVsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHpvbmU6IE5nWm9uZSxcbiAgICBwcm90ZWN0ZWQgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgICBAT3B0aW9uYWwoKVxuICAgIEBJbmplY3QoJ3ZpcnR1YWwtc2Nyb2xsZXItZGVmYXVsdC1vcHRpb25zJylcbiAgICBvcHRpb25zOiBWaXJ0dWFsU2Nyb2xsZXJEZWZhdWx0T3B0aW9ucyxcbiAgKSB7XG4gICAgdGhpcy5pc0FuZ3VsYXJVbml2ZXJzYWxTU1IgPSBpc1BsYXRmb3JtU2VydmVyKHBsYXRmb3JtSWQpO1xuXG4gICAgdGhpcy5zY3JvbGxUaHJvdHRsaW5nVGltZSA9IG9wdGlvbnMuc2Nyb2xsVGhyb3R0bGluZ1RpbWU7XG4gICAgdGhpcy5zY3JvbGxEZWJvdW5jZVRpbWUgPSBvcHRpb25zLnNjcm9sbERlYm91bmNlVGltZTtcbiAgICB0aGlzLnNjcm9sbEFuaW1hdGlvblRpbWUgPSBvcHRpb25zLnNjcm9sbEFuaW1hdGlvblRpbWU7XG4gICAgdGhpcy5zY3JvbGxiYXJXaWR0aCA9IG9wdGlvbnMuc2Nyb2xsYmFyV2lkdGg7XG4gICAgdGhpcy5zY3JvbGxiYXJIZWlnaHQgPSBvcHRpb25zLnNjcm9sbGJhckhlaWdodDtcbiAgICB0aGlzLmNoZWNrUmVzaXplSW50ZXJ2YWwgPSBvcHRpb25zLmNoZWNrUmVzaXplSW50ZXJ2YWw7XG4gICAgdGhpcy5yZXNpemVCeXBhc3NSZWZyZXNoVGhyZXNob2xkID0gb3B0aW9ucy5yZXNpemVCeXBhc3NSZWZyZXNoVGhyZXNob2xkO1xuICAgIHRoaXMubW9kaWZ5T3ZlcmZsb3dTdHlsZU9mUGFyZW50U2Nyb2xsID1cbiAgICAgIG9wdGlvbnMubW9kaWZ5T3ZlcmZsb3dTdHlsZU9mUGFyZW50U2Nyb2xsO1xuICAgIHRoaXMuc3RyaXBlZFRhYmxlID0gb3B0aW9ucy5zdHJpcGVkVGFibGU7XG5cbiAgICB0aGlzLmhvcml6b250YWwgPSBmYWxzZTtcbiAgICB0aGlzLnJlc2V0V3JhcEdyb3VwRGltZW5zaW9ucygpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEVsZW1lbnRTaXplKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogQ2xpZW50UmVjdCB7XG4gICAgbGV0IHJlc3VsdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgbGV0IHN0eWxlcyA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG4gICAgbGV0IG1hcmdpblRvcCA9IHBhcnNlSW50KHN0eWxlc1snbWFyZ2luLXRvcCddLCAxMCkgfHwgMDtcbiAgICBsZXQgbWFyZ2luQm90dG9tID0gcGFyc2VJbnQoc3R5bGVzWydtYXJnaW4tYm90dG9tJ10sIDEwKSB8fCAwO1xuICAgIGxldCBtYXJnaW5MZWZ0ID0gcGFyc2VJbnQoc3R5bGVzWydtYXJnaW4tbGVmdCddLCAxMCkgfHwgMDtcbiAgICBsZXQgbWFyZ2luUmlnaHQgPSBwYXJzZUludChzdHlsZXNbJ21hcmdpbi1yaWdodCddLCAxMCkgfHwgMDtcblxuICAgIHJldHVybiB7XG4gICAgICB0b3A6IHJlc3VsdC50b3AgKyBtYXJnaW5Ub3AsXG4gICAgICBib3R0b206IHJlc3VsdC5ib3R0b20gKyBtYXJnaW5Cb3R0b20sXG4gICAgICBsZWZ0OiByZXN1bHQubGVmdCArIG1hcmdpbkxlZnQsXG4gICAgICByaWdodDogcmVzdWx0LnJpZ2h0ICsgbWFyZ2luUmlnaHQsXG4gICAgICB3aWR0aDogcmVzdWx0LndpZHRoICsgbWFyZ2luTGVmdCArIG1hcmdpblJpZ2h0LFxuICAgICAgaGVpZ2h0OiByZXN1bHQuaGVpZ2h0ICsgbWFyZ2luVG9wICsgbWFyZ2luQm90dG9tLFxuICAgICAgeTogcmVzdWx0LnRvcCArIG1hcmdpblRvcCxcbiAgICAgIHg6IHJlc3VsdC5sZWZ0ICsgbWFyZ2luTGVmdCxcbiAgICAgIHRvSlNPTigpOiBhbnkge1xuICAgICAgICByZXN1bHQudG9KU09OKCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgcHJldmlvdXNTY3JvbGxCb3VuZGluZ1JlY3Q6IENsaWVudFJlY3Q7XG4gIHByb3RlY3RlZCBjaGVja1Njcm9sbEVsZW1lbnRSZXNpemVkKCk6IHZvaWQge1xuICAgIGxldCBib3VuZGluZ1JlY3QgPSB0aGlzLmdldEVsZW1lbnRTaXplKHRoaXMuZ2V0U2Nyb2xsRWxlbWVudCgpKTtcblxuICAgIGxldCBzaXplQ2hhbmdlZDogYm9vbGVhbjtcbiAgICBpZiAoIXRoaXMucHJldmlvdXNTY3JvbGxCb3VuZGluZ1JlY3QpIHtcbiAgICAgIHNpemVDaGFuZ2VkID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHdpZHRoQ2hhbmdlID0gTWF0aC5hYnMoXG4gICAgICAgIGJvdW5kaW5nUmVjdC53aWR0aCAtIHRoaXMucHJldmlvdXNTY3JvbGxCb3VuZGluZ1JlY3Qud2lkdGgsXG4gICAgICApO1xuICAgICAgbGV0IGhlaWdodENoYW5nZSA9IE1hdGguYWJzKFxuICAgICAgICBib3VuZGluZ1JlY3QuaGVpZ2h0IC0gdGhpcy5wcmV2aW91c1Njcm9sbEJvdW5kaW5nUmVjdC5oZWlnaHQsXG4gICAgICApO1xuICAgICAgc2l6ZUNoYW5nZWQgPVxuICAgICAgICB3aWR0aENoYW5nZSA+IHRoaXMucmVzaXplQnlwYXNzUmVmcmVzaFRocmVzaG9sZCB8fFxuICAgICAgICBoZWlnaHRDaGFuZ2UgPiB0aGlzLnJlc2l6ZUJ5cGFzc1JlZnJlc2hUaHJlc2hvbGQ7XG4gICAgfVxuXG4gICAgaWYgKHNpemVDaGFuZ2VkKSB7XG4gICAgICB0aGlzLnByZXZpb3VzU2Nyb2xsQm91bmRpbmdSZWN0ID0gYm91bmRpbmdSZWN0O1xuICAgICAgaWYgKGJvdW5kaW5nUmVjdC53aWR0aCA+IDAgJiYgYm91bmRpbmdSZWN0LmhlaWdodCA+IDApIHtcbiAgICAgICAgdGhpcy5yZWZyZXNoX2ludGVybmFsKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX2ludmlzaWJsZVBhZGRpbmdQcm9wZXJ0eTtcbiAgcHJvdGVjdGVkIF9vZmZzZXRUeXBlO1xuICBwcm90ZWN0ZWQgX3Njcm9sbFR5cGU7XG4gIHByb3RlY3RlZCBfcGFnZU9mZnNldFR5cGU7XG4gIHByb3RlY3RlZCBfY2hpbGRTY3JvbGxEaW07XG4gIHByb3RlY3RlZCBfdHJhbnNsYXRlRGlyO1xuICBwcm90ZWN0ZWQgX21hcmdpbkRpcjtcbiAgcHJvdGVjdGVkIHVwZGF0ZURpcmVjdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5ob3Jpem9udGFsKSB7XG4gICAgICB0aGlzLl9pbnZpc2libGVQYWRkaW5nUHJvcGVydHkgPSAnd2lkdGgnO1xuICAgICAgdGhpcy5fb2Zmc2V0VHlwZSA9ICdvZmZzZXRMZWZ0JztcbiAgICAgIHRoaXMuX3BhZ2VPZmZzZXRUeXBlID0gJ3BhZ2VYT2Zmc2V0JztcbiAgICAgIHRoaXMuX2NoaWxkU2Nyb2xsRGltID0gJ2NoaWxkV2lkdGgnO1xuICAgICAgdGhpcy5fbWFyZ2luRGlyID0gJ21hcmdpbi1sZWZ0JztcbiAgICAgIHRoaXMuX3RyYW5zbGF0ZURpciA9ICd0cmFuc2xhdGVYJztcbiAgICAgIHRoaXMuX3Njcm9sbFR5cGUgPSAnc2Nyb2xsTGVmdCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2ludmlzaWJsZVBhZGRpbmdQcm9wZXJ0eSA9ICdoZWlnaHQnO1xuICAgICAgdGhpcy5fb2Zmc2V0VHlwZSA9ICdvZmZzZXRUb3AnO1xuICAgICAgdGhpcy5fcGFnZU9mZnNldFR5cGUgPSAncGFnZVlPZmZzZXQnO1xuICAgICAgdGhpcy5fY2hpbGRTY3JvbGxEaW0gPSAnY2hpbGRIZWlnaHQnO1xuICAgICAgdGhpcy5fbWFyZ2luRGlyID0gJ21hcmdpbi10b3AnO1xuICAgICAgdGhpcy5fdHJhbnNsYXRlRGlyID0gJ3RyYW5zbGF0ZVknO1xuICAgICAgdGhpcy5fc2Nyb2xsVHlwZSA9ICdzY3JvbGxUb3AnO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBkZWJvdW5jZShmdW5jOiBGdW5jdGlvbiwgd2FpdDogbnVtYmVyKTogRnVuY3Rpb24ge1xuICAgIGNvbnN0IHRocm90dGxlZCA9IHRoaXMudGhyb3R0bGVUcmFpbGluZyhmdW5jLCB3YWl0KTtcbiAgICBjb25zdCByZXN1bHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdHRsZWRbJ2NhbmNlbCddKCk7XG4gICAgICB0aHJvdHRsZWQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICAgIHJlc3VsdFsnY2FuY2VsJ10gPSBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdHRsZWRbJ2NhbmNlbCddKCk7XG4gICAgfTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgdGhyb3R0bGVUcmFpbGluZyhmdW5jOiBGdW5jdGlvbiwgd2FpdDogbnVtYmVyKTogRnVuY3Rpb24ge1xuICAgIGxldCB0aW1lb3V0ID0gdW5kZWZpbmVkO1xuICAgIGxldCBfYXJndW1lbnRzID0gYXJndW1lbnRzO1xuICAgIGNvbnN0IHJlc3VsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IF90aGlzID0gdGhpcztcbiAgICAgIF9hcmd1bWVudHMgPSBhcmd1bWVudHM7XG5cbiAgICAgIGlmICh0aW1lb3V0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHdhaXQgPD0gMCkge1xuICAgICAgICBmdW5jLmFwcGx5KF90aGlzLCBfYXJndW1lbnRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aW1lb3V0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGZ1bmMuYXBwbHkoX3RoaXMsIF9hcmd1bWVudHMpO1xuICAgICAgICB9LCB3YWl0KTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHJlc3VsdFsnY2FuY2VsJ10gPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAodGltZW91dCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHRpbWVvdXQgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2FsY3VsYXRlZFNjcm9sbGJhcldpZHRoOiBudW1iZXIgPSAwO1xuICBwcm90ZWN0ZWQgY2FsY3VsYXRlZFNjcm9sbGJhckhlaWdodDogbnVtYmVyID0gMDtcblxuICBwcm90ZWN0ZWQgcGFkZGluZzogbnVtYmVyID0gMDtcbiAgcHJvdGVjdGVkIHByZXZpb3VzVmlld1BvcnQ6IElWaWV3cG9ydCA9IDxhbnk+e307XG4gIHByb3RlY3RlZCBjdXJyZW50VHdlZW46IGFueTtcbiAgcHJvdGVjdGVkIGNhY2hlZEl0ZW1zTGVuZ3RoOiBudW1iZXI7XG5cbiAgcHJvdGVjdGVkIGRpc3Bvc2VTY3JvbGxIYW5kbGVyOiAoKSA9PiB2b2lkIHwgdW5kZWZpbmVkO1xuICBwcm90ZWN0ZWQgZGlzcG9zZVJlc2l6ZUhhbmRsZXI6ICgpID0+IHZvaWQgfCB1bmRlZmluZWQ7XG5cbiAgcHJvdGVjdGVkIHJlZnJlc2hfaW50ZXJuYWwoXG4gICAgaXRlbXNBcnJheU1vZGlmaWVkOiBib29sZWFuLFxuICAgIHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjazogKCkgPT4gdm9pZCA9IHVuZGVmaW5lZCxcbiAgICBtYXhSdW5UaW1lczogbnVtYmVyID0gMixcbiAgKTogdm9pZCB7XG4gICAgLy9ub3RlOiBtYXhSdW5UaW1lcyBpcyB0byBmb3JjZSBpdCB0byBrZWVwIHJlY2FsY3VsYXRpbmcgaWYgdGhlIHByZXZpb3VzIGl0ZXJhdGlvbiBjYXVzZWQgYSByZS1yZW5kZXIgKGRpZmZlcmVudCBzbGljZWQgaXRlbXMgaW4gdmlld3BvcnQgb3Igc2Nyb2xsUG9zaXRpb24gY2hhbmdlZCkuXG4gICAgLy9UaGUgZGVmYXVsdCBvZiAyeCBtYXggd2lsbCBwcm9iYWJseSBiZSBhY2N1cmF0ZSBlbm91Z2ggd2l0aG91dCBjYXVzaW5nIHRvbyBsYXJnZSBhIHBlcmZvcm1hbmNlIGJvdHRsZW5lY2tcbiAgICAvL1RoZSBjb2RlIHdvdWxkIHR5cGljYWxseSBxdWl0IG91dCBvbiB0aGUgMm5kIGl0ZXJhdGlvbiBhbnl3YXlzLiBUaGUgbWFpbiB0aW1lIGl0J2QgdGhpbmsgbW9yZSB0aGFuIDIgcnVucyB3b3VsZCBiZSBuZWNlc3Nhcnkgd291bGQgYmUgZm9yIHZhc3RseSBkaWZmZXJlbnQgc2l6ZWQgY2hpbGQgaXRlbXMgb3IgaWYgdGhpcyBpcyB0aGUgMXN0IHRpbWUgdGhlIGl0ZW1zIGFycmF5IHdhcyBpbml0aWFsaXplZC5cbiAgICAvL1dpdGhvdXQgbWF4UnVuVGltZXMsIElmIHRoZSB1c2VyIGlzIGFjdGl2ZWx5IHNjcm9sbGluZyB0aGlzIGNvZGUgd291bGQgYmVjb21lIGFuIGluZmluaXRlIGxvb3AgdW50aWwgdGhleSBzdG9wcGVkIHNjcm9sbGluZy4gVGhpcyB3b3VsZCBiZSBva2F5LCBleGNlcHQgZWFjaCBzY3JvbGwgZXZlbnQgd291bGQgc3RhcnQgYW4gYWRkaXRpb25hbCBpbmZpbnRlIGxvb3AuIFdlIHdhbnQgdG8gc2hvcnQtY2lyY3VpdCBpdCB0byBwcmV2ZW50IHRoaXMuXG5cbiAgICBpZiAoXG4gICAgICBpdGVtc0FycmF5TW9kaWZpZWQgJiZcbiAgICAgIHRoaXMucHJldmlvdXNWaWV3UG9ydCAmJlxuICAgICAgdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnNjcm9sbFN0YXJ0UG9zaXRpb24gPiAwXG4gICAgKSB7XG4gICAgICAvL2lmIGl0ZW1zIHdlcmUgcHJlcGVuZGVkLCBzY3JvbGwgZm9yd2FyZCB0byBrZWVwIHNhbWUgaXRlbXMgdmlzaWJsZVxuICAgICAgbGV0IG9sZFZpZXdQb3J0ID0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0O1xuICAgICAgbGV0IG9sZFZpZXdQb3J0SXRlbXMgPSB0aGlzLnZpZXdQb3J0SXRlbXM7XG5cbiAgICAgIGxldCBvbGRSZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2sgPSByZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2s7XG4gICAgICByZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICAgIGxldCBzY3JvbGxMZW5ndGhEZWx0YSA9XG4gICAgICAgICAgdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnNjcm9sbExlbmd0aCAtIG9sZFZpZXdQb3J0LnNjcm9sbExlbmd0aDtcbiAgICAgICAgaWYgKHNjcm9sbExlbmd0aERlbHRhID4gMCAmJiB0aGlzLnZpZXdQb3J0SXRlbXMpIHtcbiAgICAgICAgICBsZXQgb2xkU3RhcnRJdGVtID0gb2xkVmlld1BvcnRJdGVtc1swXTtcbiAgICAgICAgICBsZXQgb2xkU3RhcnRJdGVtSW5kZXggPSB0aGlzLml0ZW1zLmZpbmRJbmRleCgoeCkgPT5cbiAgICAgICAgICAgIHRoaXMuY29tcGFyZUl0ZW1zKG9sZFN0YXJ0SXRlbSwgeCksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAob2xkU3RhcnRJdGVtSW5kZXggPiB0aGlzLnByZXZpb3VzVmlld1BvcnQuc3RhcnRJbmRleFdpdGhCdWZmZXIpIHtcbiAgICAgICAgICAgIGxldCBpdGVtT3JkZXJDaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHRoaXMudmlld1BvcnRJdGVtcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgIXRoaXMuY29tcGFyZUl0ZW1zKFxuICAgICAgICAgICAgICAgICAgdGhpcy5pdGVtc1tvbGRTdGFydEl0ZW1JbmRleCArIGldLFxuICAgICAgICAgICAgICAgICAgb2xkVmlld1BvcnRJdGVtc1tpXSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGl0ZW1PcmRlckNoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghaXRlbU9yZGVyQ2hhbmdlZCkge1xuICAgICAgICAgICAgICB0aGlzLnNjcm9sbFRvUG9zaXRpb24oXG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnNjcm9sbFN0YXJ0UG9zaXRpb24gKyBzY3JvbGxMZW5ndGhEZWx0YSxcbiAgICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgICAgIG9sZFJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjayxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvbGRSZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2spIHtcbiAgICAgICAgICBvbGRSZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgaWYgKGl0ZW1zQXJyYXlNb2RpZmllZCkge1xuICAgICAgICAgIHRoaXMucmVzZXRXcmFwR3JvdXBEaW1lbnNpb25zKCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHZpZXdwb3J0ID0gdGhpcy5jYWxjdWxhdGVWaWV3cG9ydCgpO1xuXG4gICAgICAgIGxldCBzdGFydENoYW5nZWQgPVxuICAgICAgICAgIGl0ZW1zQXJyYXlNb2RpZmllZCB8fFxuICAgICAgICAgIHZpZXdwb3J0LnN0YXJ0SW5kZXggIT09IHRoaXMucHJldmlvdXNWaWV3UG9ydC5zdGFydEluZGV4O1xuICAgICAgICBsZXQgZW5kQ2hhbmdlZCA9XG4gICAgICAgICAgaXRlbXNBcnJheU1vZGlmaWVkIHx8XG4gICAgICAgICAgdmlld3BvcnQuZW5kSW5kZXggIT09IHRoaXMucHJldmlvdXNWaWV3UG9ydC5lbmRJbmRleDtcbiAgICAgICAgbGV0IHNjcm9sbExlbmd0aENoYW5nZWQgPVxuICAgICAgICAgIHZpZXdwb3J0LnNjcm9sbExlbmd0aCAhPT0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnNjcm9sbExlbmd0aDtcbiAgICAgICAgbGV0IHBhZGRpbmdDaGFuZ2VkID0gdmlld3BvcnQucGFkZGluZyAhPT0gdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnBhZGRpbmc7XG4gICAgICAgIGxldCBzY3JvbGxQb3NpdGlvbkNoYW5nZWQgPVxuICAgICAgICAgIHZpZXdwb3J0LnNjcm9sbFN0YXJ0UG9zaXRpb24gIT09XG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzVmlld1BvcnQuc2Nyb2xsU3RhcnRQb3NpdGlvbiB8fFxuICAgICAgICAgIHZpZXdwb3J0LnNjcm9sbEVuZFBvc2l0aW9uICE9PVxuICAgICAgICAgICAgdGhpcy5wcmV2aW91c1ZpZXdQb3J0LnNjcm9sbEVuZFBvc2l0aW9uIHx8XG4gICAgICAgICAgdmlld3BvcnQubWF4U2Nyb2xsUG9zaXRpb24gIT09XG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzVmlld1BvcnQubWF4U2Nyb2xsUG9zaXRpb247XG5cbiAgICAgICAgdGhpcy5wcmV2aW91c1ZpZXdQb3J0ID0gdmlld3BvcnQ7XG5cbiAgICAgICAgaWYgKHNjcm9sbExlbmd0aENoYW5nZWQpIHtcbiAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICAgICAgdGhpcy5pbnZpc2libGVQYWRkaW5nRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5faW52aXNpYmxlUGFkZGluZ1Byb3BlcnR5LFxuICAgICAgICAgICAgYCR7dmlld3BvcnQuc2Nyb2xsTGVuZ3RofXB4YCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhZGRpbmdDaGFuZ2VkKSB7XG4gICAgICAgICAgaWYgKHRoaXMudXNlTWFyZ2luSW5zdGVhZE9mVHJhbnNsYXRlKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgICAgIHRoaXMuX21hcmdpbkRpcixcbiAgICAgICAgICAgICAgYCR7dmlld3BvcnQucGFkZGluZ31weGAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgICAgICd0cmFuc2Zvcm0nLFxuICAgICAgICAgICAgICBgJHt0aGlzLl90cmFuc2xhdGVEaXJ9KCR7dmlld3BvcnQucGFkZGluZ31weClgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICAgICAgICAgIHRoaXMuY29udGVudEVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgICAgJ3dlYmtpdFRyYW5zZm9ybScsXG4gICAgICAgICAgICAgIGAke3RoaXMuX3RyYW5zbGF0ZURpcn0oJHt2aWV3cG9ydC5wYWRkaW5nfXB4KWAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmhlYWRlckVsZW1lbnRSZWYpIHtcbiAgICAgICAgICBsZXQgc2Nyb2xsUG9zaXRpb24gPSB0aGlzLmdldFNjcm9sbEVsZW1lbnQoKVt0aGlzLl9zY3JvbGxUeXBlXTtcbiAgICAgICAgICBsZXQgY29udGFpbmVyT2Zmc2V0ID0gdGhpcy5nZXRFbGVtZW50c09mZnNldCgpO1xuICAgICAgICAgIGxldCBvZmZzZXQgPSBNYXRoLm1heChcbiAgICAgICAgICAgIHNjcm9sbFBvc2l0aW9uIC1cbiAgICAgICAgICAgICAgdmlld3BvcnQucGFkZGluZyAtXG4gICAgICAgICAgICAgIGNvbnRhaW5lck9mZnNldCArXG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsaWVudEhlaWdodCxcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICAgICAgdGhpcy5oZWFkZXJFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICAgICAgICAndHJhbnNmb3JtJyxcbiAgICAgICAgICAgIGAke3RoaXMuX3RyYW5zbGF0ZURpcn0oJHtvZmZzZXR9cHgpYCxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICAgICAgICB0aGlzLmhlYWRlckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgICd3ZWJraXRUcmFuc2Zvcm0nLFxuICAgICAgICAgICAgYCR7dGhpcy5fdHJhbnNsYXRlRGlyfSgke29mZnNldH1weClgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjaGFuZ2VFdmVudEFyZzogSVBhZ2VJbmZvID1cbiAgICAgICAgICBzdGFydENoYW5nZWQgfHwgZW5kQ2hhbmdlZFxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgc3RhcnRJbmRleDogdmlld3BvcnQuc3RhcnRJbmRleCxcbiAgICAgICAgICAgICAgICBlbmRJbmRleDogdmlld3BvcnQuZW5kSW5kZXgsXG4gICAgICAgICAgICAgICAgc2Nyb2xsU3RhcnRQb3NpdGlvbjogdmlld3BvcnQuc2Nyb2xsU3RhcnRQb3NpdGlvbixcbiAgICAgICAgICAgICAgICBzY3JvbGxFbmRQb3NpdGlvbjogdmlld3BvcnQuc2Nyb2xsRW5kUG9zaXRpb24sXG4gICAgICAgICAgICAgICAgc3RhcnRJbmRleFdpdGhCdWZmZXI6IHZpZXdwb3J0LnN0YXJ0SW5kZXhXaXRoQnVmZmVyLFxuICAgICAgICAgICAgICAgIGVuZEluZGV4V2l0aEJ1ZmZlcjogdmlld3BvcnQuZW5kSW5kZXhXaXRoQnVmZmVyLFxuICAgICAgICAgICAgICAgIG1heFNjcm9sbFBvc2l0aW9uOiB2aWV3cG9ydC5tYXhTY3JvbGxQb3NpdGlvbixcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKHN0YXJ0Q2hhbmdlZCB8fCBlbmRDaGFuZ2VkIHx8IHNjcm9sbFBvc2l0aW9uQ2hhbmdlZCkge1xuICAgICAgICAgIGNvbnN0IGhhbmRsZUNoYW5nZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAvLyB1cGRhdGUgdGhlIHNjcm9sbCBsaXN0IHRvIHRyaWdnZXIgcmUtcmVuZGVyIG9mIGNvbXBvbmVudHMgaW4gdmlld3BvcnRcbiAgICAgICAgICAgIHRoaXMudmlld1BvcnRJdGVtcyA9XG4gICAgICAgICAgICAgIHZpZXdwb3J0LnN0YXJ0SW5kZXhXaXRoQnVmZmVyID49IDAgJiZcbiAgICAgICAgICAgICAgdmlld3BvcnQuZW5kSW5kZXhXaXRoQnVmZmVyID49IDBcbiAgICAgICAgICAgICAgICA/IHRoaXMuaXRlbXMuc2xpY2UoXG4gICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0LnN0YXJ0SW5kZXhXaXRoQnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydC5lbmRJbmRleFdpdGhCdWZmZXIgKyAxLFxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIDogW107XG4gICAgICAgICAgICB0aGlzLnZzVXBkYXRlLmVtaXQodGhpcy52aWV3UG9ydEl0ZW1zKTtcblxuICAgICAgICAgICAgaWYgKHN0YXJ0Q2hhbmdlZCkge1xuICAgICAgICAgICAgICB0aGlzLnZzU3RhcnQuZW1pdChjaGFuZ2VFdmVudEFyZyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChlbmRDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgIHRoaXMudnNFbmQuZW1pdChjaGFuZ2VFdmVudEFyZyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdGFydENoYW5nZWQgfHwgZW5kQ2hhbmdlZCkge1xuICAgICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgICB0aGlzLnZzQ2hhbmdlLmVtaXQoY2hhbmdlRXZlbnRBcmcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobWF4UnVuVGltZXMgPiAwKSB7XG4gICAgICAgICAgICAgIHRoaXMucmVmcmVzaF9pbnRlcm5hbChcbiAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICByZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2ssXG4gICAgICAgICAgICAgICAgbWF4UnVuVGltZXMgLSAxLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgcmVmcmVzaENvbXBsZXRlZENhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGlmICh0aGlzLmV4ZWN1dGVSZWZyZXNoT3V0c2lkZUFuZ3VsYXJab25lKSB7XG4gICAgICAgICAgICBoYW5kbGVDaGFuZ2VkKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuem9uZS5ydW4oaGFuZGxlQ2hhbmdlZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChtYXhSdW5UaW1lcyA+IDAgJiYgKHNjcm9sbExlbmd0aENoYW5nZWQgfHwgcGFkZGluZ0NoYW5nZWQpKSB7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hfaW50ZXJuYWwoXG4gICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICByZWZyZXNoQ29tcGxldGVkQ2FsbGJhY2ssXG4gICAgICAgICAgICAgIG1heFJ1blRpbWVzIC0gMSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHJlZnJlc2hDb21wbGV0ZWRDYWxsYmFjaykge1xuICAgICAgICAgICAgcmVmcmVzaENvbXBsZXRlZENhbGxiYWNrKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRTY3JvbGxFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnRTY3JvbGwgaW5zdGFuY2VvZiBXaW5kb3dcbiAgICAgID8gZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwgZG9jdW1lbnQuYm9keVxuICAgICAgOiB0aGlzLnBhcmVudFNjcm9sbCB8fCB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhZGRTY3JvbGxFdmVudEhhbmRsZXJzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW5ndWxhclVuaXZlcnNhbFNTUikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBzY3JvbGxFbGVtZW50ID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KCk7XG5cbiAgICB0aGlzLnJlbW92ZVNjcm9sbEV2ZW50SGFuZGxlcnMoKTtcblxuICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBpZiAodGhpcy5wYXJlbnRTY3JvbGwgaW5zdGFuY2VvZiBXaW5kb3cpIHtcbiAgICAgICAgdGhpcy5kaXNwb3NlU2Nyb2xsSGFuZGxlciA9IHRoaXMucmVuZGVyZXIubGlzdGVuKFxuICAgICAgICAgICd3aW5kb3cnLFxuICAgICAgICAgICdzY3JvbGwnLFxuICAgICAgICAgIHRoaXMub25TY3JvbGwsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuZGlzcG9zZVJlc2l6ZUhhbmRsZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3RlbihcbiAgICAgICAgICAnd2luZG93JyxcbiAgICAgICAgICAncmVzaXplJyxcbiAgICAgICAgICB0aGlzLm9uU2Nyb2xsLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kaXNwb3NlU2Nyb2xsSGFuZGxlciA9IHRoaXMucmVuZGVyZXIubGlzdGVuKFxuICAgICAgICAgIHNjcm9sbEVsZW1lbnQsXG4gICAgICAgICAgJ3Njcm9sbCcsXG4gICAgICAgICAgdGhpcy5vblNjcm9sbCxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHRoaXMuX2NoZWNrUmVzaXplSW50ZXJ2YWwgPiAwKSB7XG4gICAgICAgICAgdGhpcy5jaGVja1Njcm9sbEVsZW1lbnRSZXNpemVkVGltZXIgPSA8YW55PnNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tTY3JvbGxFbGVtZW50UmVzaXplZCgpO1xuICAgICAgICAgIH0sIHRoaXMuX2NoZWNrUmVzaXplSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlU2Nyb2xsRXZlbnRIYW5kbGVycygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jaGVja1Njcm9sbEVsZW1lbnRSZXNpemVkVGltZXIpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jaGVja1Njcm9sbEVsZW1lbnRSZXNpemVkVGltZXIpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmRpc3Bvc2VTY3JvbGxIYW5kbGVyKSB7XG4gICAgICB0aGlzLmRpc3Bvc2VTY3JvbGxIYW5kbGVyKCk7XG4gICAgICB0aGlzLmRpc3Bvc2VTY3JvbGxIYW5kbGVyID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmRpc3Bvc2VSZXNpemVIYW5kbGVyKSB7XG4gICAgICB0aGlzLmRpc3Bvc2VSZXNpemVIYW5kbGVyKCk7XG4gICAgICB0aGlzLmRpc3Bvc2VSZXNpemVIYW5kbGVyID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRFbGVtZW50c09mZnNldCgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLmlzQW5ndWxhclVuaXZlcnNhbFNTUikge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgbGV0IG9mZnNldCA9IDA7XG5cbiAgICBpZiAodGhpcy5jb250YWluZXJFbGVtZW50UmVmICYmIHRoaXMuY29udGFpbmVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KSB7XG4gICAgICBvZmZzZXQgKz0gdGhpcy5jb250YWluZXJFbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnRbdGhpcy5fb2Zmc2V0VHlwZV07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucGFyZW50U2Nyb2xsKSB7XG4gICAgICBsZXQgc2Nyb2xsRWxlbWVudCA9IHRoaXMuZ2V0U2Nyb2xsRWxlbWVudCgpO1xuICAgICAgbGV0IGVsZW1lbnRDbGllbnRSZWN0ID0gdGhpcy5nZXRFbGVtZW50U2l6ZSh0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCk7XG4gICAgICBsZXQgc2Nyb2xsQ2xpZW50UmVjdCA9IHRoaXMuZ2V0RWxlbWVudFNpemUoc2Nyb2xsRWxlbWVudCk7XG4gICAgICBpZiAodGhpcy5ob3Jpem9udGFsKSB7XG4gICAgICAgIG9mZnNldCArPSBlbGVtZW50Q2xpZW50UmVjdC5sZWZ0IC0gc2Nyb2xsQ2xpZW50UmVjdC5sZWZ0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2Zmc2V0ICs9IGVsZW1lbnRDbGllbnRSZWN0LnRvcCAtIHNjcm9sbENsaWVudFJlY3QudG9wO1xuICAgICAgfVxuXG4gICAgICBpZiAoISh0aGlzLnBhcmVudFNjcm9sbCBpbnN0YW5jZW9mIFdpbmRvdykpIHtcbiAgICAgICAgb2Zmc2V0ICs9IHNjcm9sbEVsZW1lbnRbdGhpcy5fc2Nyb2xsVHlwZV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb3VudEl0ZW1zUGVyV3JhcEdyb3VwKCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuaXNBbmd1bGFyVW5pdmVyc2FsU1NSKSB7XG4gICAgICByZXR1cm4gTWF0aC5yb3VuZChcbiAgICAgICAgdGhpcy5ob3Jpem9udGFsXG4gICAgICAgICAgPyB0aGlzLnNzclZpZXdwb3J0SGVpZ2h0IC8gdGhpcy5zc3JDaGlsZEhlaWdodFxuICAgICAgICAgIDogdGhpcy5zc3JWaWV3cG9ydFdpZHRoIC8gdGhpcy5zc3JDaGlsZFdpZHRoLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBsZXQgcHJvcGVydHlOYW1lID0gdGhpcy5ob3Jpem9udGFsID8gJ29mZnNldExlZnQnIDogJ29mZnNldFRvcCc7XG4gICAgbGV0IGNoaWxkcmVuID0gKFxuICAgICAgKHRoaXMuY29udGFpbmVyRWxlbWVudFJlZiAmJiB0aGlzLmNvbnRhaW5lckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCkgfHxcbiAgICAgIHRoaXMuY29udGVudEVsZW1lbnRSZWYubmF0aXZlRWxlbWVudFxuICAgICkuY2hpbGRyZW47XG5cbiAgICBsZXQgY2hpbGRyZW5MZW5ndGggPSBjaGlsZHJlbiA/IGNoaWxkcmVuLmxlbmd0aCA6IDA7XG4gICAgaWYgKGNoaWxkcmVuTGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG5cbiAgICBsZXQgZmlyc3RPZmZzZXQgPSBjaGlsZHJlblswXVtwcm9wZXJ0eU5hbWVdO1xuICAgIGxldCByZXN1bHQgPSAxO1xuICAgIHdoaWxlIChcbiAgICAgIHJlc3VsdCA8IGNoaWxkcmVuTGVuZ3RoICYmXG4gICAgICBmaXJzdE9mZnNldCA9PT0gY2hpbGRyZW5bcmVzdWx0XVtwcm9wZXJ0eU5hbWVdXG4gICAgKSB7XG4gICAgICArK3Jlc3VsdDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldFNjcm9sbFN0YXJ0UG9zaXRpb24oKTogbnVtYmVyIHtcbiAgICBsZXQgd2luZG93U2Nyb2xsVmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMucGFyZW50U2Nyb2xsIGluc3RhbmNlb2YgV2luZG93KSB7XG4gICAgICB3aW5kb3dTY3JvbGxWYWx1ZSA9IHdpbmRvd1t0aGlzLl9wYWdlT2Zmc2V0VHlwZV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHdpbmRvd1Njcm9sbFZhbHVlIHx8IHRoaXMuZ2V0U2Nyb2xsRWxlbWVudCgpW3RoaXMuX3Njcm9sbFR5cGVdIHx8IDA7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWluTWVhc3VyZWRDaGlsZFdpZHRoOiBudW1iZXI7XG4gIHByb3RlY3RlZCBtaW5NZWFzdXJlZENoaWxkSGVpZ2h0OiBudW1iZXI7XG5cbiAgcHJvdGVjdGVkIHdyYXBHcm91cERpbWVuc2lvbnM6IFdyYXBHcm91cERpbWVuc2lvbnM7XG5cbiAgcHJvdGVjdGVkIHJlc2V0V3JhcEdyb3VwRGltZW5zaW9ucygpOiB2b2lkIHtcbiAgICBjb25zdCBvbGRXcmFwR3JvdXBEaW1lbnNpb25zID0gdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zO1xuICAgIHRoaXMuaW52YWxpZGF0ZUFsbENhY2hlZE1lYXN1cmVtZW50cygpO1xuXG4gICAgaWYgKFxuICAgICAgIXRoaXMuZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMgfHxcbiAgICAgICFvbGRXcmFwR3JvdXBEaW1lbnNpb25zIHx8XG4gICAgICBvbGRXcmFwR3JvdXBEaW1lbnNpb25zLm51bWJlck9mS25vd25XcmFwR3JvdXBDaGlsZFNpemVzID09PSAwXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaXRlbXNQZXJXcmFwR3JvdXA6IG51bWJlciA9IHRoaXMuY291bnRJdGVtc1BlcldyYXBHcm91cCgpO1xuICAgIGZvciAoXG4gICAgICBsZXQgd3JhcEdyb3VwSW5kZXggPSAwO1xuICAgICAgd3JhcEdyb3VwSW5kZXggPCBvbGRXcmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cC5sZW5ndGg7XG4gICAgICArK3dyYXBHcm91cEluZGV4XG4gICAgKSB7XG4gICAgICBjb25zdCBvbGRXcmFwR3JvdXBEaW1lbnNpb246IFdyYXBHcm91cERpbWVuc2lvbiA9XG4gICAgICAgIG9sZFdyYXBHcm91cERpbWVuc2lvbnMubWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwW3dyYXBHcm91cEluZGV4XTtcbiAgICAgIGlmIChcbiAgICAgICAgIW9sZFdyYXBHcm91cERpbWVuc2lvbiB8fFxuICAgICAgICAhb2xkV3JhcEdyb3VwRGltZW5zaW9uLml0ZW1zIHx8XG4gICAgICAgICFvbGRXcmFwR3JvdXBEaW1lbnNpb24uaXRlbXMubGVuZ3RoXG4gICAgICApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChvbGRXcmFwR3JvdXBEaW1lbnNpb24uaXRlbXMubGVuZ3RoICE9PSBpdGVtc1BlcldyYXBHcm91cCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCBpdGVtc0NoYW5nZWQgPSBmYWxzZTtcbiAgICAgIGxldCBhcnJheVN0YXJ0SW5kZXggPSBpdGVtc1BlcldyYXBHcm91cCAqIHdyYXBHcm91cEluZGV4O1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtc1BlcldyYXBHcm91cDsgKytpKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhdGhpcy5jb21wYXJlSXRlbXMoXG4gICAgICAgICAgICBvbGRXcmFwR3JvdXBEaW1lbnNpb24uaXRlbXNbaV0sXG4gICAgICAgICAgICB0aGlzLml0ZW1zW2FycmF5U3RhcnRJbmRleCArIGldLFxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgaXRlbXNDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWl0ZW1zQ2hhbmdlZCkge1xuICAgICAgICArK3RoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5udW1iZXJPZktub3duV3JhcEdyb3VwQ2hpbGRTaXplcztcbiAgICAgICAgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRocyArPVxuICAgICAgICAgIG9sZFdyYXBHcm91cERpbWVuc2lvbi5jaGlsZFdpZHRoIHx8IDA7XG4gICAgICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRIZWlnaHRzICs9XG4gICAgICAgICAgb2xkV3JhcEdyb3VwRGltZW5zaW9uLmNoaWxkSGVpZ2h0IHx8IDA7XG4gICAgICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbd3JhcEdyb3VwSW5kZXhdID1cbiAgICAgICAgICBvbGRXcmFwR3JvdXBEaW1lbnNpb247XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGNhbGN1bGF0ZURpbWVuc2lvbnMoKTogSURpbWVuc2lvbnMge1xuICAgIGxldCBzY3JvbGxFbGVtZW50ID0gdGhpcy5nZXRTY3JvbGxFbGVtZW50KCk7XG5cbiAgICBjb25zdCBtYXhDYWxjdWxhdGVkU2Nyb2xsQmFyU2l6ZTogbnVtYmVyID0gMjU7IC8vIE5vdGU6IEZvcm11bGEgdG8gYXV0by1jYWxjdWxhdGUgZG9lc24ndCB3b3JrIGZvciBQYXJlbnRTY3JvbGwsIHNvIHdlIGRlZmF1bHQgdG8gdGhpcyBpZiBub3Qgc2V0IGJ5IGNvbnN1bWluZyBhcHBsaWNhdGlvblxuICAgIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhckhlaWdodCA9IE1hdGgubWF4KFxuICAgICAgTWF0aC5taW4oXG4gICAgICAgIHNjcm9sbEVsZW1lbnQub2Zmc2V0SGVpZ2h0IC0gc2Nyb2xsRWxlbWVudC5jbGllbnRIZWlnaHQsXG4gICAgICAgIG1heENhbGN1bGF0ZWRTY3JvbGxCYXJTaXplLFxuICAgICAgKSxcbiAgICAgIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhckhlaWdodCxcbiAgICApO1xuICAgIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhcldpZHRoID0gTWF0aC5tYXgoXG4gICAgICBNYXRoLm1pbihcbiAgICAgICAgc2Nyb2xsRWxlbWVudC5vZmZzZXRXaWR0aCAtIHNjcm9sbEVsZW1lbnQuY2xpZW50V2lkdGgsXG4gICAgICAgIG1heENhbGN1bGF0ZWRTY3JvbGxCYXJTaXplLFxuICAgICAgKSxcbiAgICAgIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhcldpZHRoLFxuICAgICk7XG5cbiAgICBsZXQgdmlld3BvcnRXaWR0aCA9XG4gICAgICBzY3JvbGxFbGVtZW50Lm9mZnNldFdpZHRoIC1cbiAgICAgICh0aGlzLnNjcm9sbGJhcldpZHRoIHx8XG4gICAgICAgIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhcldpZHRoIHx8XG4gICAgICAgICh0aGlzLmhvcml6b250YWwgPyAwIDogbWF4Q2FsY3VsYXRlZFNjcm9sbEJhclNpemUpKTtcbiAgICBsZXQgdmlld3BvcnRIZWlnaHQgPVxuICAgICAgc2Nyb2xsRWxlbWVudC5vZmZzZXRIZWlnaHQgLVxuICAgICAgKHRoaXMuc2Nyb2xsYmFySGVpZ2h0IHx8XG4gICAgICAgIHRoaXMuY2FsY3VsYXRlZFNjcm9sbGJhckhlaWdodCB8fFxuICAgICAgICAodGhpcy5ob3Jpem9udGFsID8gbWF4Q2FsY3VsYXRlZFNjcm9sbEJhclNpemUgOiAwKSk7XG5cbiAgICBsZXQgY29udGVudCA9XG4gICAgICAodGhpcy5jb250YWluZXJFbGVtZW50UmVmICYmIHRoaXMuY29udGFpbmVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KSB8fFxuICAgICAgdGhpcy5jb250ZW50RWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuXG4gICAgbGV0IGl0ZW1zUGVyV3JhcEdyb3VwID0gdGhpcy5jb3VudEl0ZW1zUGVyV3JhcEdyb3VwKCk7XG4gICAgbGV0IHdyYXBHcm91cHNQZXJQYWdlO1xuXG4gICAgbGV0IGRlZmF1bHRDaGlsZFdpZHRoO1xuICAgIGxldCBkZWZhdWx0Q2hpbGRIZWlnaHQ7XG5cbiAgICBpZiAodGhpcy5pc0FuZ3VsYXJVbml2ZXJzYWxTU1IpIHtcbiAgICAgIHZpZXdwb3J0V2lkdGggPSB0aGlzLnNzclZpZXdwb3J0V2lkdGg7XG4gICAgICB2aWV3cG9ydEhlaWdodCA9IHRoaXMuc3NyVmlld3BvcnRIZWlnaHQ7XG4gICAgICBkZWZhdWx0Q2hpbGRXaWR0aCA9IHRoaXMuc3NyQ2hpbGRXaWR0aDtcbiAgICAgIGRlZmF1bHRDaGlsZEhlaWdodCA9IHRoaXMuc3NyQ2hpbGRIZWlnaHQ7XG4gICAgICBsZXQgaXRlbXNQZXJSb3cgPSBNYXRoLm1heChcbiAgICAgICAgTWF0aC5jZWlsKHZpZXdwb3J0V2lkdGggLyBkZWZhdWx0Q2hpbGRXaWR0aCksXG4gICAgICAgIDEsXG4gICAgICApO1xuICAgICAgbGV0IGl0ZW1zUGVyQ29sID0gTWF0aC5tYXgoXG4gICAgICAgIE1hdGguY2VpbCh2aWV3cG9ydEhlaWdodCAvIGRlZmF1bHRDaGlsZEhlaWdodCksXG4gICAgICAgIDEsXG4gICAgICApO1xuICAgICAgd3JhcEdyb3Vwc1BlclBhZ2UgPSB0aGlzLmhvcml6b250YWwgPyBpdGVtc1BlclJvdyA6IGl0ZW1zUGVyQ29sO1xuICAgIH0gZWxzZSBpZiAoIXRoaXMuZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMpIHtcbiAgICAgIGlmIChjb250ZW50LmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaWYgKCF0aGlzLmNoaWxkV2lkdGggfHwgIXRoaXMuY2hpbGRIZWlnaHQpIHtcbiAgICAgICAgICBpZiAoIXRoaXMubWluTWVhc3VyZWRDaGlsZFdpZHRoICYmIHZpZXdwb3J0V2lkdGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRXaWR0aCA9IHZpZXdwb3J0V2lkdGg7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghdGhpcy5taW5NZWFzdXJlZENoaWxkSGVpZ2h0ICYmIHZpZXdwb3J0SGVpZ2h0ID4gMCkge1xuICAgICAgICAgICAgdGhpcy5taW5NZWFzdXJlZENoaWxkSGVpZ2h0ID0gdmlld3BvcnRIZWlnaHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNoaWxkID0gY29udGVudC5jaGlsZHJlblswXTtcbiAgICAgICAgbGV0IGNsaWVudFJlY3QgPSB0aGlzLmdldEVsZW1lbnRTaXplKGNoaWxkKTtcbiAgICAgICAgdGhpcy5taW5NZWFzdXJlZENoaWxkV2lkdGggPSBNYXRoLm1pbihcbiAgICAgICAgICB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRXaWR0aCxcbiAgICAgICAgICBjbGllbnRSZWN0LndpZHRoLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQgPSBNYXRoLm1pbihcbiAgICAgICAgICB0aGlzLm1pbk1lYXN1cmVkQ2hpbGRIZWlnaHQsXG4gICAgICAgICAgY2xpZW50UmVjdC5oZWlnaHQsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGRlZmF1bHRDaGlsZFdpZHRoID1cbiAgICAgICAgdGhpcy5jaGlsZFdpZHRoIHx8IHRoaXMubWluTWVhc3VyZWRDaGlsZFdpZHRoIHx8IHZpZXdwb3J0V2lkdGg7XG4gICAgICBkZWZhdWx0Q2hpbGRIZWlnaHQgPVxuICAgICAgICB0aGlzLmNoaWxkSGVpZ2h0IHx8IHRoaXMubWluTWVhc3VyZWRDaGlsZEhlaWdodCB8fCB2aWV3cG9ydEhlaWdodDtcbiAgICAgIGxldCBpdGVtc1BlclJvdyA9IE1hdGgubWF4KFxuICAgICAgICBNYXRoLmNlaWwodmlld3BvcnRXaWR0aCAvIGRlZmF1bHRDaGlsZFdpZHRoKSxcbiAgICAgICAgMSxcbiAgICAgICk7XG4gICAgICBsZXQgaXRlbXNQZXJDb2wgPSBNYXRoLm1heChcbiAgICAgICAgTWF0aC5jZWlsKHZpZXdwb3J0SGVpZ2h0IC8gZGVmYXVsdENoaWxkSGVpZ2h0KSxcbiAgICAgICAgMSxcbiAgICAgICk7XG4gICAgICB3cmFwR3JvdXBzUGVyUGFnZSA9IHRoaXMuaG9yaXpvbnRhbCA/IGl0ZW1zUGVyUm93IDogaXRlbXNQZXJDb2w7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBzY3JvbGxPZmZzZXQgPVxuICAgICAgICBzY3JvbGxFbGVtZW50W3RoaXMuX3Njcm9sbFR5cGVdIC1cbiAgICAgICAgKHRoaXMucHJldmlvdXNWaWV3UG9ydCA/IHRoaXMucHJldmlvdXNWaWV3UG9ydC5wYWRkaW5nIDogMCk7XG5cbiAgICAgIGxldCBhcnJheVN0YXJ0SW5kZXggPSB0aGlzLnByZXZpb3VzVmlld1BvcnQuc3RhcnRJbmRleFdpdGhCdWZmZXIgfHwgMDtcbiAgICAgIGxldCB3cmFwR3JvdXBJbmRleCA9IE1hdGguY2VpbChhcnJheVN0YXJ0SW5kZXggLyBpdGVtc1BlcldyYXBHcm91cCk7XG5cbiAgICAgIGxldCBtYXhXaWR0aEZvcldyYXBHcm91cCA9IDA7XG4gICAgICBsZXQgbWF4SGVpZ2h0Rm9yV3JhcEdyb3VwID0gMDtcbiAgICAgIGxldCBzdW1PZlZpc2libGVNYXhXaWR0aHMgPSAwO1xuICAgICAgbGV0IHN1bU9mVmlzaWJsZU1heEhlaWdodHMgPSAwO1xuICAgICAgd3JhcEdyb3Vwc1BlclBhZ2UgPSAwO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnRlbnQuY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgKythcnJheVN0YXJ0SW5kZXg7XG4gICAgICAgIGxldCBjaGlsZCA9IGNvbnRlbnQuY2hpbGRyZW5baV07XG4gICAgICAgIGxldCBjbGllbnRSZWN0ID0gdGhpcy5nZXRFbGVtZW50U2l6ZShjaGlsZCk7XG5cbiAgICAgICAgbWF4V2lkdGhGb3JXcmFwR3JvdXAgPSBNYXRoLm1heChtYXhXaWR0aEZvcldyYXBHcm91cCwgY2xpZW50UmVjdC53aWR0aCk7XG4gICAgICAgIG1heEhlaWdodEZvcldyYXBHcm91cCA9IE1hdGgubWF4KFxuICAgICAgICAgIG1heEhlaWdodEZvcldyYXBHcm91cCxcbiAgICAgICAgICBjbGllbnRSZWN0LmhlaWdodCxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoYXJyYXlTdGFydEluZGV4ICUgaXRlbXNQZXJXcmFwR3JvdXAgPT09IDApIHtcbiAgICAgICAgICBsZXQgb2xkVmFsdWUgPVxuICAgICAgICAgICAgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFt3cmFwR3JvdXBJbmRleF07XG4gICAgICAgICAgaWYgKG9sZFZhbHVlKSB7XG4gICAgICAgICAgICAtLXRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5udW1iZXJPZktub3duV3JhcEdyb3VwQ2hpbGRTaXplcztcbiAgICAgICAgICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRXaWR0aHMgLT1cbiAgICAgICAgICAgICAgb2xkVmFsdWUuY2hpbGRXaWR0aCB8fCAwO1xuICAgICAgICAgICAgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZEhlaWdodHMgLT1cbiAgICAgICAgICAgICAgb2xkVmFsdWUuY2hpbGRIZWlnaHQgfHwgMDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICArK3RoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5udW1iZXJPZktub3duV3JhcEdyb3VwQ2hpbGRTaXplcztcbiAgICAgICAgICBjb25zdCBpdGVtcyA9IHRoaXMuaXRlbXMuc2xpY2UoXG4gICAgICAgICAgICBhcnJheVN0YXJ0SW5kZXggLSBpdGVtc1BlcldyYXBHcm91cCxcbiAgICAgICAgICAgIGFycmF5U3RhcnRJbmRleCxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbd3JhcEdyb3VwSW5kZXhdID0ge1xuICAgICAgICAgICAgY2hpbGRXaWR0aDogbWF4V2lkdGhGb3JXcmFwR3JvdXAsXG4gICAgICAgICAgICBjaGlsZEhlaWdodDogbWF4SGVpZ2h0Rm9yV3JhcEdyb3VwLFxuICAgICAgICAgICAgaXRlbXM6IGl0ZW1zLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZFdpZHRocyArPVxuICAgICAgICAgICAgbWF4V2lkdGhGb3JXcmFwR3JvdXA7XG4gICAgICAgICAgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZEhlaWdodHMgKz1cbiAgICAgICAgICAgIG1heEhlaWdodEZvcldyYXBHcm91cDtcblxuICAgICAgICAgIGlmICh0aGlzLmhvcml6b250YWwpIHtcbiAgICAgICAgICAgIGxldCBtYXhWaXNpYmxlV2lkdGhGb3JXcmFwR3JvdXAgPSBNYXRoLm1pbihcbiAgICAgICAgICAgICAgbWF4V2lkdGhGb3JXcmFwR3JvdXAsXG4gICAgICAgICAgICAgIE1hdGgubWF4KHZpZXdwb3J0V2lkdGggLSBzdW1PZlZpc2libGVNYXhXaWR0aHMsIDApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChzY3JvbGxPZmZzZXQgPiAwKSB7XG4gICAgICAgICAgICAgIGxldCBzY3JvbGxPZmZzZXRUb1JlbW92ZSA9IE1hdGgubWluKFxuICAgICAgICAgICAgICAgIHNjcm9sbE9mZnNldCxcbiAgICAgICAgICAgICAgICBtYXhWaXNpYmxlV2lkdGhGb3JXcmFwR3JvdXAsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIG1heFZpc2libGVXaWR0aEZvcldyYXBHcm91cCAtPSBzY3JvbGxPZmZzZXRUb1JlbW92ZTtcbiAgICAgICAgICAgICAgc2Nyb2xsT2Zmc2V0IC09IHNjcm9sbE9mZnNldFRvUmVtb3ZlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzdW1PZlZpc2libGVNYXhXaWR0aHMgKz0gbWF4VmlzaWJsZVdpZHRoRm9yV3JhcEdyb3VwO1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBtYXhWaXNpYmxlV2lkdGhGb3JXcmFwR3JvdXAgPiAwICYmXG4gICAgICAgICAgICAgIHZpZXdwb3J0V2lkdGggPj0gc3VtT2ZWaXNpYmxlTWF4V2lkdGhzXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgKyt3cmFwR3JvdXBzUGVyUGFnZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IG1heFZpc2libGVIZWlnaHRGb3JXcmFwR3JvdXAgPSBNYXRoLm1pbihcbiAgICAgICAgICAgICAgbWF4SGVpZ2h0Rm9yV3JhcEdyb3VwLFxuICAgICAgICAgICAgICBNYXRoLm1heCh2aWV3cG9ydEhlaWdodCAtIHN1bU9mVmlzaWJsZU1heEhlaWdodHMsIDApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChzY3JvbGxPZmZzZXQgPiAwKSB7XG4gICAgICAgICAgICAgIGxldCBzY3JvbGxPZmZzZXRUb1JlbW92ZSA9IE1hdGgubWluKFxuICAgICAgICAgICAgICAgIHNjcm9sbE9mZnNldCxcbiAgICAgICAgICAgICAgICBtYXhWaXNpYmxlSGVpZ2h0Rm9yV3JhcEdyb3VwLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBtYXhWaXNpYmxlSGVpZ2h0Rm9yV3JhcEdyb3VwIC09IHNjcm9sbE9mZnNldFRvUmVtb3ZlO1xuICAgICAgICAgICAgICBzY3JvbGxPZmZzZXQgLT0gc2Nyb2xsT2Zmc2V0VG9SZW1vdmU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN1bU9mVmlzaWJsZU1heEhlaWdodHMgKz0gbWF4VmlzaWJsZUhlaWdodEZvcldyYXBHcm91cDtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgbWF4VmlzaWJsZUhlaWdodEZvcldyYXBHcm91cCA+IDAgJiZcbiAgICAgICAgICAgICAgdmlld3BvcnRIZWlnaHQgPj0gc3VtT2ZWaXNpYmxlTWF4SGVpZ2h0c1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICsrd3JhcEdyb3Vwc1BlclBhZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgKyt3cmFwR3JvdXBJbmRleDtcblxuICAgICAgICAgIG1heFdpZHRoRm9yV3JhcEdyb3VwID0gMDtcbiAgICAgICAgICBtYXhIZWlnaHRGb3JXcmFwR3JvdXAgPSAwO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxldCBhdmVyYWdlQ2hpbGRXaWR0aCA9XG4gICAgICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5zdW1PZktub3duV3JhcEdyb3VwQ2hpbGRXaWR0aHMgL1xuICAgICAgICB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XG4gICAgICBsZXQgYXZlcmFnZUNoaWxkSGVpZ2h0ID1cbiAgICAgICAgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLnN1bU9mS25vd25XcmFwR3JvdXBDaGlsZEhlaWdodHMgL1xuICAgICAgICB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubnVtYmVyT2ZLbm93bldyYXBHcm91cENoaWxkU2l6ZXM7XG4gICAgICBkZWZhdWx0Q2hpbGRXaWR0aCA9IHRoaXMuY2hpbGRXaWR0aCB8fCBhdmVyYWdlQ2hpbGRXaWR0aCB8fCB2aWV3cG9ydFdpZHRoO1xuICAgICAgZGVmYXVsdENoaWxkSGVpZ2h0ID1cbiAgICAgICAgdGhpcy5jaGlsZEhlaWdodCB8fCBhdmVyYWdlQ2hpbGRIZWlnaHQgfHwgdmlld3BvcnRIZWlnaHQ7XG5cbiAgICAgIGlmICh0aGlzLmhvcml6b250YWwpIHtcbiAgICAgICAgaWYgKHZpZXdwb3J0V2lkdGggPiBzdW1PZlZpc2libGVNYXhXaWR0aHMpIHtcbiAgICAgICAgICB3cmFwR3JvdXBzUGVyUGFnZSArPSBNYXRoLmNlaWwoXG4gICAgICAgICAgICAodmlld3BvcnRXaWR0aCAtIHN1bU9mVmlzaWJsZU1heFdpZHRocykgLyBkZWZhdWx0Q2hpbGRXaWR0aCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodmlld3BvcnRIZWlnaHQgPiBzdW1PZlZpc2libGVNYXhIZWlnaHRzKSB7XG4gICAgICAgICAgd3JhcEdyb3Vwc1BlclBhZ2UgKz0gTWF0aC5jZWlsKFxuICAgICAgICAgICAgKHZpZXdwb3J0SGVpZ2h0IC0gc3VtT2ZWaXNpYmxlTWF4SGVpZ2h0cykgLyBkZWZhdWx0Q2hpbGRIZWlnaHQsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBpdGVtQ291bnQgPSB0aGlzLml0ZW1zLmxlbmd0aDtcbiAgICBsZXQgaXRlbXNQZXJQYWdlID0gaXRlbXNQZXJXcmFwR3JvdXAgKiB3cmFwR3JvdXBzUGVyUGFnZTtcbiAgICBsZXQgcGFnZUNvdW50X2ZyYWN0aW9uYWwgPSBpdGVtQ291bnQgLyBpdGVtc1BlclBhZ2U7XG4gICAgbGV0IG51bWJlck9mV3JhcEdyb3VwcyA9IE1hdGguY2VpbChpdGVtQ291bnQgLyBpdGVtc1BlcldyYXBHcm91cCk7XG5cbiAgICBsZXQgc2Nyb2xsTGVuZ3RoID0gMDtcblxuICAgIGxldCBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwID0gdGhpcy5ob3Jpem9udGFsXG4gICAgICA/IGRlZmF1bHRDaGlsZFdpZHRoXG4gICAgICA6IGRlZmF1bHRDaGlsZEhlaWdodDtcbiAgICBpZiAodGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xuICAgICAgbGV0IG51bVVua25vd25DaGlsZFNpemVzID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZXcmFwR3JvdXBzOyArK2kpIHtcbiAgICAgICAgbGV0IGNoaWxkU2l6ZSA9XG4gICAgICAgICAgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFtpXSAmJlxuICAgICAgICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbaV1bXG4gICAgICAgICAgICB0aGlzLl9jaGlsZFNjcm9sbERpbVxuICAgICAgICAgIF07XG4gICAgICAgIGlmIChjaGlsZFNpemUpIHtcbiAgICAgICAgICBzY3JvbGxMZW5ndGggKz0gY2hpbGRTaXplO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICsrbnVtVW5rbm93bkNoaWxkU2l6ZXM7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc2Nyb2xsTGVuZ3RoICs9IE1hdGgucm91bmQoXG4gICAgICAgIG51bVVua25vd25DaGlsZFNpemVzICogZGVmYXVsdFNjcm9sbExlbmd0aFBlcldyYXBHcm91cCxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjcm9sbExlbmd0aCA9IG51bWJlck9mV3JhcEdyb3VwcyAqIGRlZmF1bHRTY3JvbGxMZW5ndGhQZXJXcmFwR3JvdXA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaGVhZGVyRWxlbWVudFJlZikge1xuICAgICAgc2Nyb2xsTGVuZ3RoICs9IHRoaXMuaGVhZGVyRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsaWVudEhlaWdodDtcbiAgICB9XG5cbiAgICBsZXQgdmlld3BvcnRMZW5ndGggPSB0aGlzLmhvcml6b250YWwgPyB2aWV3cG9ydFdpZHRoIDogdmlld3BvcnRIZWlnaHQ7XG4gICAgbGV0IG1heFNjcm9sbFBvc2l0aW9uID0gTWF0aC5tYXgoc2Nyb2xsTGVuZ3RoIC0gdmlld3BvcnRMZW5ndGgsIDApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGl0ZW1Db3VudDogaXRlbUNvdW50LFxuICAgICAgaXRlbXNQZXJXcmFwR3JvdXA6IGl0ZW1zUGVyV3JhcEdyb3VwLFxuICAgICAgd3JhcEdyb3Vwc1BlclBhZ2U6IHdyYXBHcm91cHNQZXJQYWdlLFxuICAgICAgaXRlbXNQZXJQYWdlOiBpdGVtc1BlclBhZ2UsXG4gICAgICBwYWdlQ291bnRfZnJhY3Rpb25hbDogcGFnZUNvdW50X2ZyYWN0aW9uYWwsXG4gICAgICBjaGlsZFdpZHRoOiBkZWZhdWx0Q2hpbGRXaWR0aCxcbiAgICAgIGNoaWxkSGVpZ2h0OiBkZWZhdWx0Q2hpbGRIZWlnaHQsXG4gICAgICBzY3JvbGxMZW5ndGg6IHNjcm9sbExlbmd0aCxcbiAgICAgIHZpZXdwb3J0TGVuZ3RoOiB2aWV3cG9ydExlbmd0aCxcbiAgICAgIG1heFNjcm9sbFBvc2l0aW9uOiBtYXhTY3JvbGxQb3NpdGlvbixcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGNhY2hlZFBhZ2VTaXplOiBudW1iZXIgPSAwO1xuICBwcm90ZWN0ZWQgcHJldmlvdXNTY3JvbGxOdW1iZXJFbGVtZW50czogbnVtYmVyID0gMDtcblxuICBwcm90ZWN0ZWQgY2FsY3VsYXRlUGFkZGluZyhcbiAgICBhcnJheVN0YXJ0SW5kZXhXaXRoQnVmZmVyOiBudW1iZXIsXG4gICAgZGltZW5zaW9uczogSURpbWVuc2lvbnMsXG4gICk6IG51bWJlciB7XG4gICAgaWYgKGRpbWVuc2lvbnMuaXRlbUNvdW50ID09PSAwKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBsZXQgZGVmYXVsdFNjcm9sbExlbmd0aFBlcldyYXBHcm91cCA9IGRpbWVuc2lvbnNbdGhpcy5fY2hpbGRTY3JvbGxEaW1dO1xuICAgIGxldCBzdGFydGluZ1dyYXBHcm91cEluZGV4ID1cbiAgICAgIE1hdGguZmxvb3IoYXJyYXlTdGFydEluZGV4V2l0aEJ1ZmZlciAvIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXApIHx8IDA7XG5cbiAgICBpZiAoIXRoaXMuZW5hYmxlVW5lcXVhbENoaWxkcmVuU2l6ZXMpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0U2Nyb2xsTGVuZ3RoUGVyV3JhcEdyb3VwICogc3RhcnRpbmdXcmFwR3JvdXBJbmRleDtcbiAgICB9XG5cbiAgICBsZXQgbnVtVW5rbm93bkNoaWxkU2l6ZXMgPSAwO1xuICAgIGxldCByZXN1bHQgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhcnRpbmdXcmFwR3JvdXBJbmRleDsgKytpKSB7XG4gICAgICBsZXQgY2hpbGRTaXplID1cbiAgICAgICAgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFtpXSAmJlxuICAgICAgICB0aGlzLndyYXBHcm91cERpbWVuc2lvbnMubWF4Q2hpbGRTaXplUGVyV3JhcEdyb3VwW2ldW1xuICAgICAgICAgIHRoaXMuX2NoaWxkU2Nyb2xsRGltXG4gICAgICAgIF07XG4gICAgICBpZiAoY2hpbGRTaXplKSB7XG4gICAgICAgIHJlc3VsdCArPSBjaGlsZFNpemU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICArK251bVVua25vd25DaGlsZFNpemVzO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQgKz0gTWF0aC5yb3VuZChcbiAgICAgIG51bVVua25vd25DaGlsZFNpemVzICogZGVmYXVsdFNjcm9sbExlbmd0aFBlcldyYXBHcm91cCxcbiAgICApO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByb3RlY3RlZCBjYWxjdWxhdGVQYWdlSW5mbyhcbiAgICBzY3JvbGxQb3NpdGlvbjogbnVtYmVyLFxuICAgIGRpbWVuc2lvbnM6IElEaW1lbnNpb25zLFxuICApOiBJUGFnZUluZm8ge1xuICAgIGxldCBzY3JvbGxQZXJjZW50YWdlID0gMDtcbiAgICBpZiAodGhpcy5lbmFibGVVbmVxdWFsQ2hpbGRyZW5TaXplcykge1xuICAgICAgY29uc3QgbnVtYmVyT2ZXcmFwR3JvdXBzID0gTWF0aC5jZWlsKFxuICAgICAgICBkaW1lbnNpb25zLml0ZW1Db3VudCAvIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXAsXG4gICAgICApO1xuICAgICAgbGV0IHRvdGFsU2Nyb2xsZWRMZW5ndGggPSAwO1xuICAgICAgbGV0IGRlZmF1bHRTY3JvbGxMZW5ndGhQZXJXcmFwR3JvdXAgPSBkaW1lbnNpb25zW3RoaXMuX2NoaWxkU2Nyb2xsRGltXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZXcmFwR3JvdXBzOyArK2kpIHtcbiAgICAgICAgbGV0IGNoaWxkU2l6ZSA9XG4gICAgICAgICAgdGhpcy53cmFwR3JvdXBEaW1lbnNpb25zLm1heENoaWxkU2l6ZVBlcldyYXBHcm91cFtpXSAmJlxuICAgICAgICAgIHRoaXMud3JhcEdyb3VwRGltZW5zaW9ucy5tYXhDaGlsZFNpemVQZXJXcmFwR3JvdXBbaV1bXG4gICAgICAgICAgICB0aGlzLl9jaGlsZFNjcm9sbERpbVxuICAgICAgICAgIF07XG4gICAgICAgIGlmIChjaGlsZFNpemUpIHtcbiAgICAgICAgICB0b3RhbFNjcm9sbGVkTGVuZ3RoICs9IGNoaWxkU2l6ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0b3RhbFNjcm9sbGVkTGVuZ3RoICs9IGRlZmF1bHRTY3JvbGxMZW5ndGhQZXJXcmFwR3JvdXA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2Nyb2xsUG9zaXRpb24gPCB0b3RhbFNjcm9sbGVkTGVuZ3RoKSB7XG4gICAgICAgICAgc2Nyb2xsUGVyY2VudGFnZSA9IGkgLyBudW1iZXJPZldyYXBHcm91cHM7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc2Nyb2xsUGVyY2VudGFnZSA9IHNjcm9sbFBvc2l0aW9uIC8gZGltZW5zaW9ucy5zY3JvbGxMZW5ndGg7XG4gICAgfVxuXG4gICAgbGV0IHN0YXJ0aW5nQXJyYXlJbmRleF9mcmFjdGlvbmFsID1cbiAgICAgIE1hdGgubWluKFxuICAgICAgICBNYXRoLm1heChzY3JvbGxQZXJjZW50YWdlICogZGltZW5zaW9ucy5wYWdlQ291bnRfZnJhY3Rpb25hbCwgMCksXG4gICAgICAgIGRpbWVuc2lvbnMucGFnZUNvdW50X2ZyYWN0aW9uYWwsXG4gICAgICApICogZGltZW5zaW9ucy5pdGVtc1BlclBhZ2U7XG5cbiAgICBsZXQgbWF4U3RhcnQgPSBkaW1lbnNpb25zLml0ZW1Db3VudCAtIGRpbWVuc2lvbnMuaXRlbXNQZXJQYWdlIC0gMTtcbiAgICBsZXQgYXJyYXlTdGFydEluZGV4ID0gTWF0aC5taW4oXG4gICAgICBNYXRoLmZsb29yKHN0YXJ0aW5nQXJyYXlJbmRleF9mcmFjdGlvbmFsKSxcbiAgICAgIG1heFN0YXJ0LFxuICAgICk7XG4gICAgYXJyYXlTdGFydEluZGV4IC09IGFycmF5U3RhcnRJbmRleCAlIGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXA7IC8vIHJvdW5kIGRvd24gdG8gc3RhcnQgb2Ygd3JhcEdyb3VwXG5cbiAgICBpZiAodGhpcy5zdHJpcGVkVGFibGUpIHtcbiAgICAgIGxldCBidWZmZXJCb3VuZGFyeSA9IDIgKiBkaW1lbnNpb25zLml0ZW1zUGVyV3JhcEdyb3VwO1xuICAgICAgaWYgKGFycmF5U3RhcnRJbmRleCAlIGJ1ZmZlckJvdW5kYXJ5ICE9PSAwKSB7XG4gICAgICAgIGFycmF5U3RhcnRJbmRleCA9IE1hdGgubWF4KFxuICAgICAgICAgIGFycmF5U3RhcnRJbmRleCAtIChhcnJheVN0YXJ0SW5kZXggJSBidWZmZXJCb3VuZGFyeSksXG4gICAgICAgICAgMCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgYXJyYXlFbmRJbmRleCA9XG4gICAgICBNYXRoLmNlaWwoc3RhcnRpbmdBcnJheUluZGV4X2ZyYWN0aW9uYWwpICsgZGltZW5zaW9ucy5pdGVtc1BlclBhZ2UgLSAxO1xuICAgIGxldCBlbmRJbmRleFdpdGhpbldyYXBHcm91cCA9XG4gICAgICAoYXJyYXlFbmRJbmRleCArIDEpICUgZGltZW5zaW9ucy5pdGVtc1BlcldyYXBHcm91cDtcbiAgICBpZiAoZW5kSW5kZXhXaXRoaW5XcmFwR3JvdXAgPiAwKSB7XG4gICAgICBhcnJheUVuZEluZGV4ICs9IGRpbWVuc2lvbnMuaXRlbXNQZXJXcmFwR3JvdXAgLSBlbmRJbmRleFdpdGhpbldyYXBHcm91cDsgLy8gcm91bmQgdXAgdG8gZW5kIG9mIHdyYXBHcm91cFxuICAgIH1cblxuICAgIGlmIChpc05hTihhcnJheVN0YXJ0SW5kZXgpKSB7XG4gICAgICBhcnJheVN0YXJ0SW5kZXggPSAwO1xuICAgIH1cbiAgICBpZiAoaXNOYU4oYXJyYXlFbmRJbmRleCkpIHtcbiAgICAgIGFycmF5RW5kSW5kZXggPSAwO1xuICAgIH1cblxuICAgIGFycmF5U3RhcnRJbmRleCA9IE1hdGgubWluKFxuICAgICAgTWF0aC5tYXgoYXJyYXlTdGFydEluZGV4LCAwKSxcbiAgICAgIGRpbWVuc2lvbnMuaXRlbUNvdW50IC0gMSxcbiAgICApO1xuICAgIGFycmF5RW5kSW5kZXggPSBNYXRoLm1pbihcbiAgICAgIE1hdGgubWF4KGFycmF5RW5kSW5kZXgsIDApLFxuICAgICAgZGltZW5zaW9ucy5pdGVtQ291bnQgLSAxLFxuICAgICk7XG5cbiAgICBsZXQgYnVmZmVyU2l6ZSA9IHRoaXMuYnVmZmVyQW1vdW50ICogZGltZW5zaW9ucy5pdGVtc1BlcldyYXBHcm91cDtcbiAgICBsZXQgc3RhcnRJbmRleFdpdGhCdWZmZXIgPSBNYXRoLm1pbihcbiAgICAgIE1hdGgubWF4KGFycmF5U3RhcnRJbmRleCAtIGJ1ZmZlclNpemUsIDApLFxuICAgICAgZGltZW5zaW9ucy5pdGVtQ291bnQgLSAxLFxuICAgICk7XG4gICAgbGV0IGVuZEluZGV4V2l0aEJ1ZmZlciA9IE1hdGgubWluKFxuICAgICAgTWF0aC5tYXgoYXJyYXlFbmRJbmRleCArIGJ1ZmZlclNpemUsIDApLFxuICAgICAgZGltZW5zaW9ucy5pdGVtQ291bnQgLSAxLFxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3RhcnRJbmRleDogYXJyYXlTdGFydEluZGV4LFxuICAgICAgZW5kSW5kZXg6IGFycmF5RW5kSW5kZXgsXG4gICAgICBzdGFydEluZGV4V2l0aEJ1ZmZlcjogc3RhcnRJbmRleFdpdGhCdWZmZXIsXG4gICAgICBlbmRJbmRleFdpdGhCdWZmZXI6IGVuZEluZGV4V2l0aEJ1ZmZlcixcbiAgICAgIHNjcm9sbFN0YXJ0UG9zaXRpb246IHNjcm9sbFBvc2l0aW9uLFxuICAgICAgc2Nyb2xsRW5kUG9zaXRpb246IHNjcm9sbFBvc2l0aW9uICsgZGltZW5zaW9ucy52aWV3cG9ydExlbmd0aCxcbiAgICAgIG1heFNjcm9sbFBvc2l0aW9uOiBkaW1lbnNpb25zLm1heFNjcm9sbFBvc2l0aW9uLFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgY2FsY3VsYXRlVmlld3BvcnQoKTogSVZpZXdwb3J0IHtcbiAgICBsZXQgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlRGltZW5zaW9ucygpO1xuICAgIGxldCBvZmZzZXQgPSB0aGlzLmdldEVsZW1lbnRzT2Zmc2V0KCk7XG5cbiAgICBsZXQgc2Nyb2xsU3RhcnRQb3NpdGlvbiA9IHRoaXMuZ2V0U2Nyb2xsU3RhcnRQb3NpdGlvbigpO1xuICAgIGlmIChcbiAgICAgIHNjcm9sbFN0YXJ0UG9zaXRpb24gPiBkaW1lbnNpb25zLnNjcm9sbExlbmd0aCArIG9mZnNldCAmJlxuICAgICAgISh0aGlzLnBhcmVudFNjcm9sbCBpbnN0YW5jZW9mIFdpbmRvdylcbiAgICApIHtcbiAgICAgIHNjcm9sbFN0YXJ0UG9zaXRpb24gPSBkaW1lbnNpb25zLnNjcm9sbExlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2Nyb2xsU3RhcnRQb3NpdGlvbiAtPSBvZmZzZXQ7XG4gICAgfVxuICAgIHNjcm9sbFN0YXJ0UG9zaXRpb24gPSBNYXRoLm1heCgwLCBzY3JvbGxTdGFydFBvc2l0aW9uKTtcblxuICAgIGxldCBwYWdlSW5mbyA9IHRoaXMuY2FsY3VsYXRlUGFnZUluZm8oc2Nyb2xsU3RhcnRQb3NpdGlvbiwgZGltZW5zaW9ucyk7XG4gICAgbGV0IG5ld1BhZGRpbmcgPSB0aGlzLmNhbGN1bGF0ZVBhZGRpbmcoXG4gICAgICBwYWdlSW5mby5zdGFydEluZGV4V2l0aEJ1ZmZlcixcbiAgICAgIGRpbWVuc2lvbnMsXG4gICAgKTtcbiAgICBsZXQgbmV3U2Nyb2xsTGVuZ3RoID0gZGltZW5zaW9ucy5zY3JvbGxMZW5ndGg7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3RhcnRJbmRleDogcGFnZUluZm8uc3RhcnRJbmRleCxcbiAgICAgIGVuZEluZGV4OiBwYWdlSW5mby5lbmRJbmRleCxcbiAgICAgIHN0YXJ0SW5kZXhXaXRoQnVmZmVyOiBwYWdlSW5mby5zdGFydEluZGV4V2l0aEJ1ZmZlcixcbiAgICAgIGVuZEluZGV4V2l0aEJ1ZmZlcjogcGFnZUluZm8uZW5kSW5kZXhXaXRoQnVmZmVyLFxuICAgICAgcGFkZGluZzogTWF0aC5yb3VuZChuZXdQYWRkaW5nKSxcbiAgICAgIHNjcm9sbExlbmd0aDogTWF0aC5yb3VuZChuZXdTY3JvbGxMZW5ndGgpLFxuICAgICAgc2Nyb2xsU3RhcnRQb3NpdGlvbjogcGFnZUluZm8uc2Nyb2xsU3RhcnRQb3NpdGlvbixcbiAgICAgIHNjcm9sbEVuZFBvc2l0aW9uOiBwYWdlSW5mby5zY3JvbGxFbmRQb3NpdGlvbixcbiAgICAgIG1heFNjcm9sbFBvc2l0aW9uOiBwYWdlSW5mby5tYXhTY3JvbGxQb3NpdGlvbixcbiAgICB9O1xuICB9XG59XG5cbkBOZ01vZHVsZSh7XG4gIGV4cG9ydHM6IFtWaXJ0dWFsU2Nyb2xsZXJDb21wb25lbnRdLFxuICBkZWNsYXJhdGlvbnM6IFtWaXJ0dWFsU2Nyb2xsZXJDb21wb25lbnRdLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogJ3ZpcnR1YWwtc2Nyb2xsZXItZGVmYXVsdC1vcHRpb25zJyxcbiAgICAgIHVzZUZhY3Rvcnk6IFZJUlRVQUxfU0NST0xMRVJfREVGQVVMVF9PUFRJT05TX0ZBQ1RPUlksXG4gICAgfSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgVmlydHVhbFNjcm9sbGVyTW9kdWxlIHt9XG4iXX0=
|