raise-common-lib 0.0.217 → 0.0.219

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +57 -57
  2. package/bundles/raise-common-lib.umd.js +1208 -0
  3. package/bundles/raise-common-lib.umd.js.map +1 -1
  4. package/bundles/raise-common-lib.umd.min.js +1 -1
  5. package/bundles/raise-common-lib.umd.min.js.map +1 -1
  6. package/esm2015/lib/raise-common-lib.module.js +4 -1
  7. package/esm2015/lib/smart-popup/index.component.js +1089 -0
  8. package/esm2015/public-api.js +2 -1
  9. package/esm2015/raise-common-lib.js +2 -2
  10. package/esm5/lib/raise-common-lib.module.js +4 -1
  11. package/esm5/lib/smart-popup/index.component.js +1208 -0
  12. package/esm5/public-api.js +2 -1
  13. package/esm5/raise-common-lib.js +2 -2
  14. package/fesm2015/raise-common-lib.js +1091 -1
  15. package/fesm2015/raise-common-lib.js.map +1 -1
  16. package/fesm5/raise-common-lib.js +1208 -1
  17. package/fesm5/raise-common-lib.js.map +1 -1
  18. package/lib/smart-popup/index.component.d.ts +57 -0
  19. package/package.json +1 -1
  20. package/public-api.d.ts +1 -0
  21. package/raise-common-lib.metadata.json +1 -1
  22. package/src/assets/img/arrow_right.svg +4 -4
  23. package/src/assets/img/calendar-disabled.svg +6 -6
  24. package/src/assets/img/calendar.svg +6 -6
  25. package/src/assets/img/calendar_arrow_left.svg +3 -3
  26. package/src/assets/img/calendar_arrow_right.svg +3 -3
  27. package/src/assets/img/checked-vector.svg +3 -3
  28. package/src/assets/img/dialog-close.svg +4 -4
  29. package/src/assets/img/dialog-grow.svg +6 -6
  30. package/src/assets/img/dialog-shrink.svg +6 -6
  31. package/src/assets/img/plus.svg +4 -4
  32. package/src/assets/img/search.svg +4 -4
  33. package/src/assets/img/shrink-icon.svg +6 -6
  34. package/src/assets/img/time-disabled.svg +4 -4
  35. package/src/assets/img/time.svg +4 -4
  36. package/src/assets/img/toolbar-action-addFolder.svg +17 -17
  37. package/src/assets/img/toolbar-action-calculator.svg +11 -11
  38. package/src/assets/img/toolbar-action-collapse.svg +7 -7
  39. package/src/assets/img/toolbar-action-combine.svg +4 -4
  40. package/src/assets/img/toolbar-action-edit.svg +4 -4
  41. package/src/assets/img/toolbar-action-expand.svg +7 -7
  42. package/src/assets/img/toolbar-action-folderMove.svg +8 -8
  43. package/src/assets/img/toolbar-action-lock.svg +6 -6
  44. package/src/assets/img/toolbar-action-preview.svg +7 -7
  45. package/src/assets/img/toolbar-action-publish.svg +5 -5
  46. package/src/assets/img/toolbar-action-reminders.svg +10 -10
  47. package/src/assets/img/toolbar-action-rename.svg +7 -7
  48. package/src/assets/img/toolbar-action-saveSequence.svg +5 -5
  49. package/src/assets/img/toolbar-action-send-file.svg +5 -5
  50. package/src/assets/img/toolbar-action-settle.svg +7 -7
  51. package/src/assets/img/toolbar-action-share.svg +5 -5
  52. package/src/assets/img/toolbar-action-submitForApproval.svg +4 -4
  53. package/src/assets/img/toolbar-action-sync.svg +4 -4
  54. package/src/assets/img/toolbar-action-template.svg +6 -6
  55. package/src/assets/img/toolbar-action-workflow.svg +9 -9
@@ -0,0 +1,1089 @@
1
+ /**
2
+ * @fileoverview added by tsickle
3
+ * Generated from: lib/smart-popup/index.component.ts
4
+ * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
+ */
6
+ import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, Output, ViewChild, HostListener, } from "@angular/core";
7
+ export class SmartPopupComponent {
8
+ /**
9
+ * @param {?} ref
10
+ */
11
+ constructor(ref) {
12
+ this.ref = ref;
13
+ this._placement = "BottomLeft";
14
+ this._offset = 8;
15
+ this._autoAdjust = "yes";
16
+ this.triggerElementRef = null;
17
+ this.loading = false;
18
+ this._open = false;
19
+ this._width = null;
20
+ this._height = null;
21
+ this.openChange = new EventEmitter();
22
+ this.contentLoad = new EventEmitter();
23
+ this.currentTriggerElement = null;
24
+ this.FIXED_CONTAINER_ID = "rs-smart-popup-fixed-container";
25
+ this.opened = "no";
26
+ this.positioning = "no";
27
+ this.actualPlacement = "bottom";
28
+ this.actualPosition = "start";
29
+ this.onClickOutside = (/**
30
+ * @param {?} event
31
+ * @return {?}
32
+ */
33
+ (event) => {
34
+ /** @type {?} */
35
+ const target = (/** @type {?} */ (event.target));
36
+ /** @type {?} */
37
+ const isClickOnTrigger = this.currentTriggerElement && this.currentTriggerElement.contains(target);
38
+ /** @type {?} */
39
+ const isClickOnPopup = this.popupElement &&
40
+ this.popupElement.nativeElement &&
41
+ this.popupElement.nativeElement.contains(target);
42
+ if (!isClickOnTrigger && !isClickOnPopup) {
43
+ this.close();
44
+ }
45
+ });
46
+ this.onWindowScroll = (/**
47
+ * @param {?} event
48
+ * @return {?}
49
+ */
50
+ (event) => {
51
+ if (this.opened === "yes") {
52
+ // 检查滚动是否发生在弹窗内部
53
+ /** @type {?} */
54
+ const target = (/** @type {?} */ (event.target));
55
+ /** @type {?} */
56
+ const isScrollOnPopup = this.popupElement &&
57
+ this.popupElement.nativeElement &&
58
+ this.popupElement.nativeElement.contains(target);
59
+ // 如果滚动发生在弹窗内部,不更新位置(避免不必要的计算)
60
+ // 如果滚动发生在外部,更新位置(因为触发元素位置可能改变)
61
+ if (!isScrollOnPopup) {
62
+ this.updatePopupPosition();
63
+ }
64
+ }
65
+ });
66
+ }
67
+ // 解析placement格式
68
+ /**
69
+ * @return {?}
70
+ */
71
+ get placementInfo() {
72
+ /** @type {?} */
73
+ const placementMap = {
74
+ TopLeft: { placement: "top", position: "start" },
75
+ TopCenter: { placement: "top", position: "center" },
76
+ TopRight: { placement: "top", position: "end" },
77
+ BottomLeft: { placement: "bottom", position: "start" },
78
+ BottomCenter: { placement: "bottom", position: "center" },
79
+ BottomRight: { placement: "bottom", position: "end" },
80
+ LeftTop: { placement: "left", position: "start" },
81
+ LeftCenter: { placement: "left", position: "center" },
82
+ LeftBottom: { placement: "left", position: "end" },
83
+ RightTop: { placement: "right", position: "start" },
84
+ RightCenter: { placement: "right", position: "center" },
85
+ RightBottom: { placement: "right", position: "end" },
86
+ };
87
+ return (placementMap[this._placement] || {
88
+ placement: "bottom",
89
+ position: "start",
90
+ });
91
+ }
92
+ /**
93
+ * @return {?}
94
+ */
95
+ get offset() {
96
+ return this._offset || 8;
97
+ }
98
+ /**
99
+ * @return {?}
100
+ */
101
+ get autoAdjust() {
102
+ return this._autoAdjust === "yes";
103
+ }
104
+ /**
105
+ * @return {?}
106
+ */
107
+ ngAfterViewInit() {
108
+ this.fixedContainerEl = this.getFixedContainer();
109
+ this.fixedContainerEl.append(this.popupElement.nativeElement);
110
+ this.updateTriggerElement();
111
+ // 如果提供了固定尺寸,立即应用
112
+ if (this._width !== null &&
113
+ this._height !== null &&
114
+ this.popupElement &&
115
+ this.popupElement.nativeElement) {
116
+ /** @type {?} */
117
+ const popupEl = this.popupElement.nativeElement;
118
+ popupEl.style.width = this._width + "px";
119
+ popupEl.style.height = this._height + "px";
120
+ popupEl.style.minWidth = this._width + "px";
121
+ popupEl.style.maxWidth = this._width + "px";
122
+ popupEl.style.minHeight = this._height + "px";
123
+ popupEl.style.maxHeight = this._height + "px";
124
+ }
125
+ // 如果外部传入 open 属性为 true,自动打开
126
+ if (this._open) {
127
+ setTimeout((/**
128
+ * @return {?}
129
+ */
130
+ () => this.open()), 0);
131
+ }
132
+ }
133
+ /**
134
+ * @param {?} changes
135
+ * @return {?}
136
+ */
137
+ ngOnChanges(changes) {
138
+ // 处理固定尺寸变化
139
+ if ((changes._width || changes._height) &&
140
+ this.popupElement &&
141
+ this.popupElement.nativeElement) {
142
+ /** @type {?} */
143
+ const popupEl = this.popupElement.nativeElement;
144
+ if (this._width !== null) {
145
+ popupEl.style.width = this._width + "px";
146
+ popupEl.style.minWidth = this._width + "px";
147
+ popupEl.style.maxWidth = this._width + "px";
148
+ }
149
+ if (this._height !== null) {
150
+ popupEl.style.height = this._height + "px";
151
+ popupEl.style.minHeight = this._height + "px";
152
+ popupEl.style.maxHeight = this._height + "px";
153
+ }
154
+ }
155
+ // 先处理触发元素变化(确保在打开前更新触发元素)
156
+ if (changes.triggerElementRef) {
157
+ /** @type {?} */
158
+ const previousTrigger = this.currentTriggerElement;
159
+ this.updateTriggerElement();
160
+ // 如果弹窗已经打开,且触发元素发生了变化,立即更新位置
161
+ if (this.opened === "yes" &&
162
+ previousTrigger !== this.currentTriggerElement &&
163
+ this.currentTriggerElement) {
164
+ // 使用新的打开方式更新位置
165
+ this.positioning = "yes";
166
+ this.ref.markForCheck();
167
+ requestAnimationFrame((/**
168
+ * @return {?}
169
+ */
170
+ () => {
171
+ requestAnimationFrame((/**
172
+ * @return {?}
173
+ */
174
+ () => {
175
+ this.updatePopupPosition();
176
+ this.positioning = "no";
177
+ this.ref.markForCheck();
178
+ }));
179
+ }));
180
+ }
181
+ }
182
+ // 处理 open 变化(确保在触发元素更新后处理)
183
+ if (changes._open) {
184
+ if (this._open && this.opened === "no") {
185
+ // 确保触发元素已更新
186
+ this.updateTriggerElement();
187
+ // 使用 setTimeout 确保所有变更都已处理
188
+ setTimeout((/**
189
+ * @return {?}
190
+ */
191
+ () => {
192
+ // 再次确保触发元素已更新
193
+ this.updateTriggerElement();
194
+ this.open();
195
+ }), 0);
196
+ }
197
+ else if (!this._open && this.opened === "yes") {
198
+ this.close();
199
+ }
200
+ }
201
+ // 当加载完成时,更新位置(如果提供了固定尺寸,不需要更新位置)
202
+ if (changes.loading &&
203
+ !changes.loading.currentValue &&
204
+ changes.loading.previousValue) {
205
+ if (this.opened === "yes") {
206
+ // 如果提供了固定尺寸,位置已经计算好了,不需要更新
207
+ if (this._width !== null && this._height !== null) {
208
+ this.contentLoad.emit();
209
+ }
210
+ else {
211
+ // 如果正在定位,不需要更新位置
212
+ if (this.positioning === "no") {
213
+ requestAnimationFrame((/**
214
+ * @return {?}
215
+ */
216
+ () => {
217
+ this.updatePopupPosition();
218
+ this.contentLoad.emit();
219
+ }));
220
+ }
221
+ else {
222
+ // 如果正在定位,等待定位完成后再触发事件
223
+ /** @type {?} */
224
+ const checkPositioning = (/**
225
+ * @return {?}
226
+ */
227
+ () => {
228
+ if (this.positioning === "no") {
229
+ this.contentLoad.emit();
230
+ }
231
+ else {
232
+ setTimeout(checkPositioning, 10);
233
+ }
234
+ });
235
+ checkPositioning();
236
+ }
237
+ }
238
+ }
239
+ }
240
+ }
241
+ /**
242
+ * @return {?}
243
+ */
244
+ ngOnDestroy() {
245
+ if (this.popupElement && this.popupElement.nativeElement) {
246
+ this.popupElement.nativeElement.remove();
247
+ }
248
+ window.removeEventListener("click", this.onClickOutside);
249
+ window.removeEventListener("scroll", this.onWindowScroll, true);
250
+ }
251
+ /**
252
+ * @return {?}
253
+ */
254
+ updateTriggerElement() {
255
+ if (this.triggerElementRef) {
256
+ this.currentTriggerElement = this.triggerElementRef;
257
+ }
258
+ else if (this.internalTriggerElement &&
259
+ this.internalTriggerElement.nativeElement) {
260
+ this.currentTriggerElement = this.internalTriggerElement.nativeElement;
261
+ }
262
+ else {
263
+ this.currentTriggerElement = null;
264
+ }
265
+ }
266
+ /**
267
+ * @return {?}
268
+ */
269
+ getFixedContainer() {
270
+ /** @type {?} */
271
+ let containerElement = document.getElementById(this.FIXED_CONTAINER_ID);
272
+ if (!containerElement) {
273
+ containerElement = document.createElement("div");
274
+ containerElement.setAttribute("id", this.FIXED_CONTAINER_ID);
275
+ document.body.append(containerElement);
276
+ }
277
+ return containerElement;
278
+ }
279
+ /**
280
+ * @param {?=} triggerElement
281
+ * @return {?}
282
+ */
283
+ open(triggerElement) {
284
+ // 如果传入了触发元素,使用它
285
+ if (triggerElement) {
286
+ this.currentTriggerElement = triggerElement;
287
+ }
288
+ else {
289
+ this.updateTriggerElement();
290
+ }
291
+ if (!this.currentTriggerElement) {
292
+ console.warn("SmartPopupComponent: No trigger element found");
293
+ return;
294
+ }
295
+ // 如果已经打开,先关闭再打开(更新位置)
296
+ if (this.opened === "yes") {
297
+ // 先关闭弹窗
298
+ this.opened = "no";
299
+ this.positioning = "no";
300
+ this.ref.markForCheck();
301
+ // 立即在新位置打开
302
+ requestAnimationFrame((/**
303
+ * @return {?}
304
+ */
305
+ () => {
306
+ // 再次确保触发元素已更新
307
+ this.updateTriggerElement();
308
+ this.openPopup();
309
+ }));
310
+ return;
311
+ }
312
+ // 确保触发元素已更新
313
+ this.updateTriggerElement();
314
+ this.openPopup();
315
+ }
316
+ /**
317
+ * @private
318
+ * @return {?}
319
+ */
320
+ openPopup() {
321
+ // 再次确保触发元素已更新
322
+ this.updateTriggerElement();
323
+ if (!this.currentTriggerElement) {
324
+ console.warn("SmartPopupComponent: No trigger element found when opening popup");
325
+ return;
326
+ }
327
+ // 如果提供了固定尺寸,可以在打开前就计算好位置
328
+ if (this._width !== null && this._height !== null) {
329
+ // 先计算位置(不依赖DOM渲染,直接根据triggerElement计算)
330
+ /** @type {?} */
331
+ const triggerRect = this.currentTriggerElement.getBoundingClientRect();
332
+ /** @type {?} */
333
+ const viewportWidth = window.innerWidth;
334
+ /** @type {?} */
335
+ const viewportHeight = window.innerHeight;
336
+ /** @type {?} */
337
+ const popupSize = {
338
+ width: this._width,
339
+ height: this._height,
340
+ };
341
+ /** @type {?} */
342
+ const popupRect = (/** @type {?} */ ({
343
+ width: popupSize.width,
344
+ height: popupSize.height,
345
+ top: 0,
346
+ left: 0,
347
+ right: popupSize.width,
348
+ bottom: popupSize.height,
349
+ x: 0,
350
+ y: 0,
351
+ toJSON: (/**
352
+ * @return {?}
353
+ */
354
+ () => ({})),
355
+ }));
356
+ /** @type {?} */
357
+ const targetInfo = this.placementInfo;
358
+ /** @type {?} */
359
+ let finalPlacement = targetInfo.placement;
360
+ /** @type {?} */
361
+ let finalPosition = targetInfo.position;
362
+ if (this.autoAdjust) {
363
+ /** @type {?} */
364
+ const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight);
365
+ finalPlacement = optimal.placement;
366
+ finalPosition = optimal.position;
367
+ }
368
+ this.actualPlacement = finalPlacement;
369
+ this.actualPosition = finalPosition;
370
+ // 计算位置坐标(不依赖DOM,直接计算)
371
+ /** @type {?} */
372
+ const position = this.calculatePositionCoordinates(triggerRect, finalPlacement, finalPosition, popupSize);
373
+ // 先设置打开状态,但保持隐藏(positioning = yes)
374
+ this.opened = "yes";
375
+ this.positioning = "yes";
376
+ this.openChange.emit(true);
377
+ this.ref.markForCheck();
378
+ // 强制更新视图,确保DOM已更新
379
+ this.ref.detectChanges();
380
+ // 如果元素已经存在,立即设置位置(不等待 requestAnimationFrame)
381
+ if (this.popupElement && this.popupElement.nativeElement) {
382
+ /** @type {?} */
383
+ const popupEl = this.popupElement.nativeElement;
384
+ // 立即设置尺寸和位置
385
+ popupEl.style.width = this._width + "px";
386
+ popupEl.style.height = this._height + "px";
387
+ popupEl.style.minWidth = this._width + "px";
388
+ popupEl.style.maxWidth = this._width + "px";
389
+ popupEl.style.minHeight = this._height + "px";
390
+ popupEl.style.maxHeight = this._height + "px";
391
+ popupEl.style.top = position.top;
392
+ popupEl.style.left = position.left;
393
+ popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
394
+ // 强制同步应用样式
395
+ popupEl.offsetHeight;
396
+ // 位置设置完成后,立即显示弹窗
397
+ this.positioning = "no";
398
+ this.ref.markForCheck();
399
+ }
400
+ else {
401
+ // 如果元素还不存在,等待渲染
402
+ requestAnimationFrame((/**
403
+ * @return {?}
404
+ */
405
+ () => {
406
+ if (this.popupElement && this.popupElement.nativeElement) {
407
+ /** @type {?} */
408
+ const popupEl = this.popupElement.nativeElement;
409
+ // 立即设置尺寸和位置
410
+ popupEl.style.width = this._width + "px";
411
+ popupEl.style.height = this._height + "px";
412
+ popupEl.style.minWidth = this._width + "px";
413
+ popupEl.style.maxWidth = this._width + "px";
414
+ popupEl.style.minHeight = this._height + "px";
415
+ popupEl.style.maxHeight = this._height + "px";
416
+ popupEl.style.top = position.top;
417
+ popupEl.style.left = position.left;
418
+ popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
419
+ // 强制同步应用样式
420
+ popupEl.offsetHeight;
421
+ // 位置设置完成后,立即显示弹窗
422
+ this.positioning = "no";
423
+ this.ref.markForCheck();
424
+ }
425
+ }));
426
+ }
427
+ }
428
+ else {
429
+ // 没有固定尺寸,需要等待DOM渲染
430
+ this.positioning = "yes";
431
+ this.ref.markForCheck();
432
+ // 立即强制更新视图,确保DOM已更新
433
+ this.ref.detectChanges();
434
+ // 使用 requestAnimationFrame 确保在浏览器渲染之前更新位置
435
+ requestAnimationFrame((/**
436
+ * @return {?}
437
+ */
438
+ () => {
439
+ // 确保元素已渲染并获取尺寸
440
+ if (this.popupElement && this.popupElement.nativeElement) {
441
+ // 强制重新计算布局,确保元素尺寸已计算
442
+ this.popupElement.nativeElement.offsetHeight;
443
+ // 计算并设置位置
444
+ this.updatePopupPosition();
445
+ // 位置设置完成后,移除定位状态,显示弹窗
446
+ this.positioning = "no";
447
+ this.ref.markForCheck();
448
+ }
449
+ }));
450
+ }
451
+ window.addEventListener("click", this.onClickOutside);
452
+ window.addEventListener("scroll", this.onWindowScroll, true);
453
+ }
454
+ /**
455
+ * @return {?}
456
+ */
457
+ close() {
458
+ if (this.opened === "no") {
459
+ return;
460
+ }
461
+ this.opened = "no";
462
+ this.positioning = "no";
463
+ this.openChange.emit(false);
464
+ window.removeEventListener("click", this.onClickOutside);
465
+ window.removeEventListener("scroll", this.onWindowScroll, true);
466
+ this.ref.markForCheck();
467
+ }
468
+ /**
469
+ * @return {?}
470
+ */
471
+ toggle() {
472
+ if (this.opened === "yes") {
473
+ this.close();
474
+ }
475
+ else {
476
+ this.open();
477
+ }
478
+ }
479
+ /**
480
+ * @param {?} event
481
+ * @return {?}
482
+ */
483
+ onClickTrigger(event) {
484
+ event.stopPropagation();
485
+ this.toggle();
486
+ }
487
+ // 处理弹窗内部的滚轮事件
488
+ /**
489
+ * @param {?} event
490
+ * @return {?}
491
+ */
492
+ onPopupWheel(event) {
493
+ // 阻止滚轮事件冒泡,避免触发外部滚动处理
494
+ event.stopPropagation();
495
+ }
496
+ // 处理弹窗内部的滚动事件
497
+ /**
498
+ * @param {?} event
499
+ * @return {?}
500
+ */
501
+ onPopupScroll(event) {
502
+ // 阻止滚动事件冒泡,避免触发外部滚动处理
503
+ event.stopPropagation();
504
+ }
505
+ // 计算并设置位置(支持固定尺寸,可在打开前调用)
506
+ /**
507
+ * @private
508
+ * @return {?}
509
+ */
510
+ calculateAndSetPosition() {
511
+ if (!this.currentTriggerElement) {
512
+ return;
513
+ }
514
+ /** @type {?} */
515
+ const triggerRect = this.currentTriggerElement.getBoundingClientRect();
516
+ /** @type {?} */
517
+ const viewportWidth = window.innerWidth;
518
+ /** @type {?} */
519
+ const viewportHeight = window.innerHeight;
520
+ // 获取弹窗尺寸(优先使用固定尺寸)
521
+ /** @type {?} */
522
+ const popupSize = {
523
+ width: this._width !== null
524
+ ? this._width
525
+ : this.popupElement && this.popupElement.nativeElement
526
+ ? this.popupElement.nativeElement.offsetWidth
527
+ : 300,
528
+ height: this._height !== null
529
+ ? this._height
530
+ : this.popupElement && this.popupElement.nativeElement
531
+ ? this.popupElement.nativeElement.offsetHeight
532
+ : 200,
533
+ };
534
+ // 创建虚拟的 popupRect(用于计算)
535
+ /** @type {?} */
536
+ const popupRect = (/** @type {?} */ ({
537
+ width: popupSize.width,
538
+ height: popupSize.height,
539
+ top: 0,
540
+ left: 0,
541
+ right: popupSize.width,
542
+ bottom: popupSize.height,
543
+ x: 0,
544
+ y: 0,
545
+ toJSON: (/**
546
+ * @return {?}
547
+ */
548
+ () => ({})),
549
+ }));
550
+ // 获取目标位置信息
551
+ /** @type {?} */
552
+ const targetInfo = this.placementInfo;
553
+ /** @type {?} */
554
+ let finalPlacement = targetInfo.placement;
555
+ /** @type {?} */
556
+ let finalPosition = targetInfo.position;
557
+ if (this.autoAdjust) {
558
+ /** @type {?} */
559
+ const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight);
560
+ finalPlacement = optimal.placement;
561
+ finalPosition = optimal.position;
562
+ }
563
+ this.actualPlacement = finalPlacement;
564
+ this.actualPosition = finalPosition;
565
+ // 立即设置位置(即使元素还没完全渲染,也要先设置位置)
566
+ if (this.popupElement && this.popupElement.nativeElement) {
567
+ this.setPopupPosition(triggerRect, popupRect, finalPlacement, finalPosition, popupSize);
568
+ // 强制应用样式,确保位置立即生效
569
+ this.ref.detectChanges();
570
+ }
571
+ else {
572
+ // 如果元素还不存在,延迟设置位置
573
+ setTimeout((/**
574
+ * @return {?}
575
+ */
576
+ () => {
577
+ if (this.popupElement && this.popupElement.nativeElement) {
578
+ this.setPopupPosition(triggerRect, popupRect, finalPlacement, finalPosition, popupSize);
579
+ this.ref.detectChanges();
580
+ }
581
+ }), 0);
582
+ }
583
+ this.ref.markForCheck();
584
+ }
585
+ /**
586
+ * @return {?}
587
+ */
588
+ updatePopupPosition() {
589
+ if (!this.currentTriggerElement ||
590
+ !this.popupElement ||
591
+ !this.popupElement.nativeElement) {
592
+ return;
593
+ }
594
+ // 如果提供了固定尺寸,使用固定尺寸计算
595
+ if (this._width !== null && this._height !== null) {
596
+ this.calculateAndSetPosition();
597
+ return;
598
+ }
599
+ /** @type {?} */
600
+ const triggerRect = this.currentTriggerElement.getBoundingClientRect();
601
+ /** @type {?} */
602
+ const popupRect = this.popupElement.nativeElement.getBoundingClientRect();
603
+ /** @type {?} */
604
+ const viewportWidth = window.innerWidth;
605
+ /** @type {?} */
606
+ const viewportHeight = window.innerHeight;
607
+ // 获取目标位置信息
608
+ /** @type {?} */
609
+ const targetInfo = this.placementInfo;
610
+ /** @type {?} */
611
+ let finalPlacement = targetInfo.placement;
612
+ /** @type {?} */
613
+ let finalPosition = targetInfo.position;
614
+ if (this.autoAdjust) {
615
+ /** @type {?} */
616
+ const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight);
617
+ finalPlacement = optimal.placement;
618
+ finalPosition = optimal.position;
619
+ }
620
+ this.actualPlacement = finalPlacement;
621
+ this.actualPosition = finalPosition;
622
+ this.setPopupPosition(triggerRect, popupRect, finalPlacement, finalPosition);
623
+ this.ref.markForCheck();
624
+ }
625
+ /**
626
+ * @param {?} triggerRect
627
+ * @param {?} popupRect
628
+ * @param {?} viewportWidth
629
+ * @param {?} viewportHeight
630
+ * @return {?}
631
+ */
632
+ calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight) {
633
+ /** @type {?} */
634
+ const targetInfo = this.placementInfo;
635
+ /** @type {?} */
636
+ const preferred = targetInfo.placement;
637
+ /** @type {?} */
638
+ const preferredPosition = targetInfo.position;
639
+ /** @type {?} */
640
+ const space = {
641
+ top: triggerRect.top,
642
+ bottom: viewportHeight - triggerRect.bottom,
643
+ left: triggerRect.left,
644
+ right: viewportWidth - triggerRect.right,
645
+ };
646
+ /** @type {?} */
647
+ const popupSize = {
648
+ width: popupRect.width || 300,
649
+ // 默认宽度,如果还没有渲染
650
+ height: popupRect.height || 200,
651
+ };
652
+ // 检查首选位置是否有足够空间
653
+ /** @type {?} */
654
+ const hasEnoughSpace = (/**
655
+ * @param {?} placement
656
+ * @return {?}
657
+ */
658
+ (placement) => {
659
+ switch (placement) {
660
+ case "top":
661
+ return space.top >= popupSize.height + this.offset;
662
+ case "bottom":
663
+ return space.bottom >= popupSize.height + this.offset;
664
+ case "left":
665
+ return space.left >= popupSize.width + this.offset;
666
+ case "right":
667
+ return space.right >= popupSize.width + this.offset;
668
+ }
669
+ });
670
+ // 检查指定位置是否有足够空间
671
+ /** @type {?} */
672
+ const checkPositionSpace = (/**
673
+ * @param {?} placement
674
+ * @param {?} position
675
+ * @return {?}
676
+ */
677
+ (placement, position) => {
678
+ if (placement === "top" || placement === "bottom") {
679
+ // 对于上下位置,检查水平对齐空间
680
+ /** @type {?} */
681
+ const popupWidth = popupSize.width;
682
+ /** @type {?} */
683
+ const spaceLeft = triggerRect.left;
684
+ /** @type {?} */
685
+ const spaceRight = viewportWidth - triggerRect.right;
686
+ if (position === "center") {
687
+ return spaceLeft >= popupWidth / 2 && spaceRight >= popupWidth / 2;
688
+ }
689
+ else if (position === "start") {
690
+ return spaceLeft >= popupWidth;
691
+ }
692
+ else {
693
+ // end
694
+ return spaceRight >= popupWidth;
695
+ }
696
+ }
697
+ else {
698
+ // 对于左右位置,检查垂直对齐空间
699
+ /** @type {?} */
700
+ const popupHeight = popupSize.height;
701
+ /** @type {?} */
702
+ const spaceTop = triggerRect.top;
703
+ /** @type {?} */
704
+ const spaceBottom = viewportHeight - triggerRect.bottom;
705
+ if (position === "center") {
706
+ return spaceTop >= popupHeight / 2 && spaceBottom >= popupHeight / 2;
707
+ }
708
+ else if (position === "start") {
709
+ return spaceTop >= popupHeight;
710
+ }
711
+ else {
712
+ // end
713
+ return spaceBottom >= popupHeight;
714
+ }
715
+ }
716
+ });
717
+ // 计算位置是否合适(考虑水平/垂直对齐)
718
+ /** @type {?} */
719
+ const calculatePosition = (/**
720
+ * @param {?} placement
721
+ * @return {?}
722
+ */
723
+ (placement) => {
724
+ if (placement === "top" || placement === "bottom") {
725
+ // 对于上下位置,检查水平对齐
726
+ /** @type {?} */
727
+ const popupWidth = popupSize.width;
728
+ /** @type {?} */
729
+ const spaceLeft = triggerRect.left;
730
+ /** @type {?} */
731
+ const spaceRight = viewportWidth - triggerRect.right;
732
+ // 优先尝试使用用户指定的position
733
+ if (checkPositionSpace(placement, preferredPosition)) {
734
+ return preferredPosition;
735
+ }
736
+ // 如果中心对齐有足够空间,优先使用中心
737
+ if (spaceLeft >= popupWidth / 2 && spaceRight >= popupWidth / 2) {
738
+ return "center";
739
+ }
740
+ // 如果左侧空间不足,使用右对齐
741
+ if (spaceLeft < popupWidth / 2) {
742
+ return "end";
743
+ }
744
+ // 如果右侧空间不足,使用左对齐
745
+ if (spaceRight < popupWidth / 2) {
746
+ return "start";
747
+ }
748
+ return preferredPosition;
749
+ }
750
+ else {
751
+ // 对于左右位置,检查垂直对齐
752
+ /** @type {?} */
753
+ const popupHeight = popupSize.height;
754
+ /** @type {?} */
755
+ const spaceTop = triggerRect.top;
756
+ /** @type {?} */
757
+ const spaceBottom = viewportHeight - triggerRect.bottom;
758
+ // 优先尝试使用用户指定的position
759
+ if (checkPositionSpace(placement, preferredPosition)) {
760
+ return preferredPosition;
761
+ }
762
+ // 如果中心对齐有足够空间,优先使用中心
763
+ if (spaceTop >= popupHeight / 2 && spaceBottom >= popupHeight / 2) {
764
+ return "center";
765
+ }
766
+ // 如果上方空间不足,使用下对齐
767
+ if (spaceTop < popupHeight / 2) {
768
+ return "end";
769
+ }
770
+ // 如果下方空间不足,使用上对齐
771
+ if (spaceBottom < popupHeight / 2) {
772
+ return "start";
773
+ }
774
+ return preferredPosition;
775
+ }
776
+ });
777
+ // 如果首选位置有足够空间,优先使用用户指定的position
778
+ if (hasEnoughSpace(preferred)) {
779
+ // 检查用户指定的position是否有足够空间
780
+ if (checkPositionSpace(preferred, preferredPosition)) {
781
+ return {
782
+ placement: preferred,
783
+ position: preferredPosition,
784
+ };
785
+ }
786
+ // 如果指定的position空间不足,自动计算最佳position
787
+ return {
788
+ placement: preferred,
789
+ position: calculatePosition(preferred),
790
+ };
791
+ }
792
+ // 根据首选位置选择备选位置
793
+ /** @type {?} */
794
+ const alternatives = {
795
+ bottom: ["top", "right", "left"],
796
+ top: ["bottom", "right", "left"],
797
+ right: ["left", "bottom", "top"],
798
+ left: ["right", "bottom", "top"],
799
+ };
800
+ /** @type {?} */
801
+ const altList = alternatives[preferred] || [];
802
+ // 尝试找到第一个有足够空间的备选位置
803
+ for (const alt of altList) {
804
+ if (hasEnoughSpace(alt)) {
805
+ return {
806
+ placement: alt,
807
+ position: calculatePosition(alt),
808
+ };
809
+ }
810
+ }
811
+ // 如果都没有足够空间,选择空间最大的位置
812
+ /** @type {?} */
813
+ const maxSpace = Math.max(space.top, space.bottom, space.left, space.right);
814
+ /** @type {?} */
815
+ let bestPlacement;
816
+ if (maxSpace === space.top)
817
+ bestPlacement = "top";
818
+ else if (maxSpace === space.bottom)
819
+ bestPlacement = "bottom";
820
+ else if (maxSpace === space.left)
821
+ bestPlacement = "left";
822
+ else
823
+ bestPlacement = "right";
824
+ return {
825
+ placement: bestPlacement,
826
+ position: calculatePosition(bestPlacement),
827
+ };
828
+ }
829
+ // 计算位置坐标(纯计算,不依赖DOM,包含边界约束)
830
+ /**
831
+ * @private
832
+ * @param {?} triggerRect
833
+ * @param {?} placement
834
+ * @param {?} position
835
+ * @param {?} popupSize
836
+ * @return {?}
837
+ */
838
+ calculatePositionCoordinates(triggerRect, placement, position, popupSize) {
839
+ /** @type {?} */
840
+ const triggerWidth = triggerRect.width;
841
+ /** @type {?} */
842
+ const triggerHeight = triggerRect.height;
843
+ /** @type {?} */
844
+ const viewportWidth = window.innerWidth;
845
+ /** @type {?} */
846
+ const viewportHeight = window.innerHeight;
847
+ /** @type {?} */
848
+ const scrollX = window.scrollX;
849
+ /** @type {?} */
850
+ const scrollY = window.scrollY;
851
+ /** @type {?} */
852
+ let top = 0;
853
+ /** @type {?} */
854
+ let left = 0;
855
+ /** @type {?} */
856
+ let translateX = "0";
857
+ /** @type {?} */
858
+ let translateY = "0";
859
+ switch (placement) {
860
+ case "top":
861
+ top = triggerRect.top + scrollY - this.offset;
862
+ translateY = "-100%";
863
+ if (position === "start") {
864
+ left = triggerRect.left + scrollX;
865
+ }
866
+ else if (position === "center") {
867
+ left = triggerRect.left + scrollX + triggerWidth / 2;
868
+ translateX = "-50%";
869
+ }
870
+ else {
871
+ left = triggerRect.left + scrollX + triggerWidth;
872
+ translateX = "-100%";
873
+ }
874
+ // 边界约束:确保弹窗不超出视口
875
+ if (top - popupSize.height < scrollY) {
876
+ top = scrollY + 8; // 距离顶部至少8px
877
+ }
878
+ if (left < scrollX) {
879
+ left = scrollX + 8;
880
+ translateX = "0";
881
+ }
882
+ else if (left + popupSize.width > scrollX + viewportWidth) {
883
+ left = scrollX + viewportWidth - popupSize.width - 8;
884
+ translateX = "0";
885
+ }
886
+ break;
887
+ case "bottom":
888
+ top = triggerRect.bottom + scrollY + this.offset;
889
+ if (position === "start") {
890
+ left = triggerRect.left + scrollX;
891
+ }
892
+ else if (position === "center") {
893
+ left = triggerRect.left + scrollX + triggerWidth / 2;
894
+ translateX = "-50%";
895
+ }
896
+ else {
897
+ left = triggerRect.left + scrollX + triggerWidth;
898
+ translateX = "-100%";
899
+ }
900
+ // 边界约束:确保弹窗不超出视口
901
+ if (top + popupSize.height > scrollY + viewportHeight) {
902
+ top = scrollY + viewportHeight - popupSize.height - 8; // 距离底部至少8px
903
+ }
904
+ if (left < scrollX) {
905
+ left = scrollX + 8;
906
+ translateX = "0";
907
+ }
908
+ else if (left + popupSize.width > scrollX + viewportWidth) {
909
+ left = scrollX + viewportWidth - popupSize.width - 8;
910
+ translateX = "0";
911
+ }
912
+ break;
913
+ case "left":
914
+ left = triggerRect.left + scrollX - this.offset;
915
+ translateX = "-100%";
916
+ if (position === "start") {
917
+ top = triggerRect.top + scrollY;
918
+ }
919
+ else if (position === "center") {
920
+ top = triggerRect.top + scrollY + triggerHeight / 2;
921
+ translateY = "-50%";
922
+ }
923
+ else {
924
+ top = triggerRect.top + scrollY + triggerHeight;
925
+ translateY = "-100%";
926
+ }
927
+ // 边界约束:确保弹窗不超出视口
928
+ if (left - popupSize.width < scrollX) {
929
+ left = scrollX + 8; // 距离左侧至少8px
930
+ }
931
+ if (top < scrollY) {
932
+ top = scrollY + 8;
933
+ translateY = "0";
934
+ }
935
+ else if (top + popupSize.height > scrollY + viewportHeight) {
936
+ top = scrollY + viewportHeight - popupSize.height - 8;
937
+ translateY = "0";
938
+ }
939
+ break;
940
+ case "right":
941
+ left = triggerRect.right + scrollX + this.offset;
942
+ if (position === "start") {
943
+ top = triggerRect.top + scrollY;
944
+ }
945
+ else if (position === "center") {
946
+ top = triggerRect.top + scrollY + triggerHeight / 2;
947
+ translateY = "-50%";
948
+ }
949
+ else {
950
+ top = triggerRect.top + scrollY + triggerHeight;
951
+ translateY = "-100%";
952
+ }
953
+ // 边界约束:确保弹窗不超出视口
954
+ if (left + popupSize.width > scrollX + viewportWidth) {
955
+ left = scrollX + viewportWidth - popupSize.width - 8; // 距离右侧至少8px
956
+ }
957
+ if (top < scrollY) {
958
+ top = scrollY + 8;
959
+ translateY = "0";
960
+ }
961
+ else if (top + popupSize.height > scrollY + viewportHeight) {
962
+ top = scrollY + viewportHeight - popupSize.height - 8;
963
+ translateY = "0";
964
+ }
965
+ break;
966
+ }
967
+ return {
968
+ top: top + "px",
969
+ left: left + "px",
970
+ translateX,
971
+ translateY,
972
+ };
973
+ }
974
+ /**
975
+ * @param {?} triggerRect
976
+ * @param {?} popupRect
977
+ * @param {?} placement
978
+ * @param {?} position
979
+ * @param {?=} popupSize
980
+ * @return {?}
981
+ */
982
+ setPopupPosition(triggerRect, popupRect, placement, position, popupSize) {
983
+ /** @type {?} */
984
+ const popupEl = this.popupElement && this.popupElement.nativeElement
985
+ ? this.popupElement.nativeElement
986
+ : null;
987
+ if (!popupEl) {
988
+ return; // 如果元素还不存在,无法设置位置
989
+ }
990
+ // 优先使用传入的固定尺寸,否则从DOM获取
991
+ /** @type {?} */
992
+ const popupWidth = popupSize && popupSize.width !== null && popupSize.width !== undefined
993
+ ? popupSize.width
994
+ : popupRect.width || popupEl.offsetWidth || 300;
995
+ /** @type {?} */
996
+ const popupHeight = popupSize && popupSize.height !== null && popupSize.height !== undefined
997
+ ? popupSize.height
998
+ : popupRect.height || popupEl.offsetHeight || 200;
999
+ /** @type {?} */
1000
+ const coordinates = this.calculatePositionCoordinates(triggerRect, placement, position, { width: popupWidth, height: popupHeight });
1001
+ popupEl.style.top = coordinates.top;
1002
+ popupEl.style.left = coordinates.left;
1003
+ popupEl.style.transform = `translate(${coordinates.translateX}, ${coordinates.translateY})`;
1004
+ }
1005
+ /**
1006
+ * @return {?}
1007
+ */
1008
+ onWindowResize() {
1009
+ if (this.opened === "yes") {
1010
+ this.updatePopupPosition();
1011
+ }
1012
+ }
1013
+ }
1014
+ SmartPopupComponent.decorators = [
1015
+ { type: Component, args: [{
1016
+ selector: "rs-smart-popup",
1017
+ template: "<!-- \u89E6\u53D1\u5143\u7D20\u63D2\u69FD -->\r\n<ng-container #trigger>\r\n <ng-content select=\"[trigger]\"></ng-content>\r\n</ng-container>\r\n\r\n<!-- \u5F39\u7A97\u5185\u5BB9 -->\r\n<div\r\n #popup\r\n class=\"rs-smart-popup-content\"\r\n [attr.data-opened]=\"opened\"\r\n [attr.data-positioning]=\"positioning\"\r\n (wheel)=\"onPopupWheel($event)\"\r\n (scroll)=\"onPopupScroll($event)\"\r\n>\r\n <div *ngIf=\"loading\" class=\"rs-smart-popup-loading\">\r\n <div class=\"loading-spinner\"></div>\r\n </div>\r\n <div *ngIf=\"!loading\" class=\"rs-smart-popup-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>\r\n\r\n",
1018
+ styles: [".rs-smart-popup-trigger{display:inline-block;cursor:pointer}::ng-deep #rs-smart-popup-fixed-container{width:0;height:0;z-index:100000;pointer-events:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content{pointer-events:auto;position:fixed;z-index:100001;padding:8px;border-radius:8px;background:#fff;box-shadow:0 0 8px 0 rgba(0,0,0,.25);min-width:200px;max-width:400px;max-height:500px;overflow:auto}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=no]{display:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes]{display:block}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=yes]{display:none!important}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=no]{display:block;visibility:visible;opacity:1;pointer-events:auto;-webkit-animation:.2s ease-out popup-fade-in;animation:.2s ease-out popup-fade-in}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;min-height:100px}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading .loading-spinner{width:24px;height:24px;border:3px solid #f3f3f3;border-top:3px solid #3498db;border-radius:50%;-webkit-animation:1s linear infinite spin;animation:1s linear infinite spin;margin-bottom:12px}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading .loading-text{color:#666;font-size:14px}@-webkit-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-body{width:100%}@-webkit-keyframes popup-fade-in{from{opacity:0;transform:translate(var(--translate-x,0),var(--translate-y,0)) scale(.95)}to{opacity:1;transform:translate(var(--translate-x,0),var(--translate-y,0)) scale(1)}}@keyframes popup-fade-in{from{opacity:0;transform:translate(var(--translate-x,0),var(--translate-y,0)) scale(.95)}to{opacity:1;transform:translate(var(--translate-x,0),var(--translate-y,0)) scale(1)}}"]
1019
+ }] }
1020
+ ];
1021
+ /** @nocollapse */
1022
+ SmartPopupComponent.ctorParameters = () => [
1023
+ { type: ChangeDetectorRef }
1024
+ ];
1025
+ SmartPopupComponent.propDecorators = {
1026
+ _placement: [{ type: Input, args: ["placement",] }],
1027
+ _offset: [{ type: Input, args: ["offset",] }],
1028
+ _autoAdjust: [{ type: Input, args: ["autoAdjust",] }],
1029
+ triggerElementRef: [{ type: Input, args: ["triggerElement",] }],
1030
+ loading: [{ type: Input, args: ["loading",] }],
1031
+ _open: [{ type: Input, args: ["open",] }],
1032
+ _width: [{ type: Input, args: ["width",] }],
1033
+ _height: [{ type: Input, args: ["height",] }],
1034
+ openChange: [{ type: Output, args: ["openChange",] }],
1035
+ contentLoad: [{ type: Output, args: ["contentLoad",] }],
1036
+ internalTriggerElement: [{ type: ViewChild, args: ["trigger", { static: false },] }],
1037
+ popupElement: [{ type: ViewChild, args: ["popup", { static: false },] }],
1038
+ onWindowResize: [{ type: HostListener, args: ["window:resize",] }]
1039
+ };
1040
+ if (false) {
1041
+ /** @type {?} */
1042
+ SmartPopupComponent.prototype._placement;
1043
+ /** @type {?} */
1044
+ SmartPopupComponent.prototype._offset;
1045
+ /** @type {?} */
1046
+ SmartPopupComponent.prototype._autoAdjust;
1047
+ /** @type {?} */
1048
+ SmartPopupComponent.prototype.triggerElementRef;
1049
+ /** @type {?} */
1050
+ SmartPopupComponent.prototype.loading;
1051
+ /** @type {?} */
1052
+ SmartPopupComponent.prototype._open;
1053
+ /** @type {?} */
1054
+ SmartPopupComponent.prototype._width;
1055
+ /** @type {?} */
1056
+ SmartPopupComponent.prototype._height;
1057
+ /** @type {?} */
1058
+ SmartPopupComponent.prototype.openChange;
1059
+ /** @type {?} */
1060
+ SmartPopupComponent.prototype.contentLoad;
1061
+ /** @type {?} */
1062
+ SmartPopupComponent.prototype.internalTriggerElement;
1063
+ /** @type {?} */
1064
+ SmartPopupComponent.prototype.popupElement;
1065
+ /** @type {?} */
1066
+ SmartPopupComponent.prototype.currentTriggerElement;
1067
+ /** @type {?} */
1068
+ SmartPopupComponent.prototype.FIXED_CONTAINER_ID;
1069
+ /** @type {?} */
1070
+ SmartPopupComponent.prototype.fixedContainerEl;
1071
+ /** @type {?} */
1072
+ SmartPopupComponent.prototype.opened;
1073
+ /** @type {?} */
1074
+ SmartPopupComponent.prototype.positioning;
1075
+ /** @type {?} */
1076
+ SmartPopupComponent.prototype.actualPlacement;
1077
+ /** @type {?} */
1078
+ SmartPopupComponent.prototype.actualPosition;
1079
+ /** @type {?} */
1080
+ SmartPopupComponent.prototype.onClickOutside;
1081
+ /** @type {?} */
1082
+ SmartPopupComponent.prototype.onWindowScroll;
1083
+ /**
1084
+ * @type {?}
1085
+ * @private
1086
+ */
1087
+ SmartPopupComponent.prototype.ref;
1088
+ }
1089
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vcmFpc2UtY29tbW9uLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9zbWFydC1wb3B1cC9pbmRleC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEVBQ04sU0FBUyxFQUNULFlBQVksR0FDYixNQUFNLGVBQWUsQ0FBQztBQXFCdkIsTUFBTSxPQUFPLG1CQUFtQjs7OztJQThEOUIsWUFBb0IsR0FBc0I7UUFBdEIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUEzRHRCLGVBQVUsR0FBa0IsWUFBWSxDQUFDO1FBQzVDLFlBQU8sR0FBVyxDQUFDLENBQUM7UUFDaEIsZ0JBQVcsR0FBaUIsS0FBSyxDQUFDO1FBQzlCLHNCQUFpQixHQUF1QixJQUFJLENBQUM7UUFDcEQsWUFBTyxHQUFZLEtBQUssQ0FBQztRQUM1QixVQUFLLEdBQVksS0FBSyxDQUFDO1FBQ3RCLFdBQU0sR0FBa0IsSUFBSSxDQUFDO1FBQzVCLFlBQU8sR0FBa0IsSUFBSSxDQUFDO1FBMEN6QixlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUN4QyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7UUFPOUQsMEJBQXFCLEdBQXVCLElBQUksQ0FBQztRQWlKakQsdUJBQWtCLEdBQUcsZ0NBQWdDLENBQUM7UUFZdEQsV0FBTSxHQUFpQixJQUFJLENBQUM7UUFDNUIsZ0JBQVcsR0FBaUIsSUFBSSxDQUFDO1FBQ2pDLG9CQUFlLEdBQXdDLFFBQVEsQ0FBQztRQUNoRSxtQkFBYyxHQUErQixPQUFPLENBQUM7UUErTXJELG1CQUFjOzs7O1FBQUcsQ0FBQyxLQUFpQixFQUFFLEVBQUU7O2tCQUMvQixNQUFNLEdBQUcsbUJBQUEsS0FBSyxDQUFDLE1BQU0sRUFBVzs7a0JBQ2hDLGdC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QXFEOztJQStNckQsNkNBWUU7O0lBRUYsNkNBZUU7Ozs7O0lBMVlVLGtDQUE4QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICBDb21wb25lbnQsXHJcbiAgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIE91dHB1dCxcclxuICBWaWV3Q2hpbGQsXHJcbiAgSG9zdExpc3RlbmVyLFxyXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcblxyXG5leHBvcnQgdHlwZSBQbGFjZW1lbnRUeXBlID1cclxuICB8IFwiVG9wTGVmdFwiXHJcbiAgfCBcIlRvcENlbnRlclwiXHJcbiAgfCBcIlRvcFJpZ2h0XCJcclxuICB8IFwiQm90dG9tTGVmdFwiXHJcbiAgfCBcIkJvdHRvbUNlbnRlclwiXHJcbiAgfCBcIkJvdHRvbVJpZ2h0XCJcclxuICB8IFwiTGVmdFRvcFwiXHJcbiAgfCBcIkxlZnRDZW50ZXJcIlxyXG4gIHwgXCJMZWZ0Qm90dG9tXCJcclxuICB8IFwiUmlnaHRUb3BcIlxyXG4gIHwgXCJSaWdodENlbnRlclwiXHJcbiAgfCBcIlJpZ2h0Qm90dG9tXCI7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogXCJycy1zbWFydC1wb3B1cFwiLFxyXG4gIHRlbXBsYXRlVXJsOiBcIi4vaW5kZXguY29tcG9uZW50Lmh0bWxcIixcclxuICBzdHlsZVVybHM6IFtcIi4vaW5kZXguY29tcG9uZW50LnNjc3NcIl0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTbWFydFBvcHVwQ29tcG9uZW50XHJcbiAgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlc1xyXG57XHJcbiAgQElucHV0KFwicGxhY2VtZW50XCIpIF9wbGFjZW1lbnQ6IFBsYWNlbWVudFR5cGUgPSBcIkJvdHRvbUxlZnRcIjtcclxuICBASW5wdXQoXCJvZmZzZXRcIikgX29mZnNldDogbnVtYmVyID0gODtcclxuICBASW5wdXQoXCJhdXRvQWRqdXN0XCIpIF9hdXRvQWRqdXN0OiBcInllc1wiIHwgXCJub1wiID0gXCJ5ZXNcIjtcclxuICBASW5wdXQoXCJ0cmlnZ2VyRWxlbWVudFwiKSB0cmlnZ2VyRWxlbWVudFJlZjogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuICBASW5wdXQoXCJsb2FkaW5nXCIpIGxvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoXCJvcGVuXCIpIF9vcGVuOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KFwid2lkdGhcIikgX3dpZHRoOiBudW1iZXIgfCBudWxsID0gbnVsbDtcclxuICBASW5wdXQoXCJoZWlnaHRcIikgX2hlaWdodDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8vIOino+aekHBsYWNlbWVudOagvOW8j1xyXG4gIGdldCBwbGFjZW1lbnRJbmZvKCk6IHtcclxuICAgIHBsYWNlbWVudDogXCJ0b3BcIiB8IFwibGVmdFwiIHwgXCJyaWdodFwiIHwgXCJib3R0b21cIjtcclxuICAgIHBvc2l0aW9uOiBcInN0YXJ0XCIgfCBcImNlbnRlclwiIHwgXCJlbmRcIjtcclxuICB9IHtcclxuICAgIGNvbnN0IHBsYWNlbWVudE1hcDoge1xyXG4gICAgICBba2V5OiBzdHJpbmddOiB7XHJcbiAgICAgICAgcGxhY2VtZW50OiBcInRvcFwiIHwgXCJsZWZ0XCIgfCBcInJpZ2h0XCIgfCBcImJvdHRvbVwiO1xyXG4gICAgICAgIHBvc2l0aW9uOiBcInN0YXJ0XCIgfCBcImNlbnRlclwiIHwgXCJlbmRcIjtcclxuICAgICAgfTtcclxuICAgIH0gPSB7XHJcbiAgICAgIFRvcExlZnQ6IHsgcGxhY2VtZW50OiBcInRvcFwiLCBwb3NpdGlvbjogXCJzdGFydFwiIH0sXHJcbiAgICAgIFRvcENlbnRlcjogeyBwbGFjZW1lbnQ6IFwidG9wXCIsIHBvc2l0aW9uOiBcImNlbnRlclwiIH0sXHJcbiAgICAgIFRvcFJpZ2h0OiB7IHBsYWNlbWVudDogXCJ0b3BcIiwgcG9zaXRpb246IFwiZW5kXCIgfSxcclxuICAgICAgQm90dG9tTGVmdDogeyBwbGFjZW1lbnQ6IFwiYm90dG9tXCIsIHBvc2l0aW9uOiBcInN0YXJ0XCIgfSxcclxuICAgICAgQm90dG9tQ2VudGVyOiB7IHBsYWNlbWVudDogXCJib3R0b21cIiwgcG9zaXRpb246IFwiY2VudGVyXCIgfSxcclxuICAgICAgQm90dG9tUmlnaHQ6IHsgcGxhY2VtZW50OiBcImJvdHRvbVwiLCBwb3NpdGlvbjogXCJlbmRcIiB9LFxyXG4gICAgICBMZWZ0VG9wOiB7IHBsYWNlbWVudDogXCJsZWZ0XCIsIHBvc2l0aW9uOiBcInN0YXJ0XCIgfSxcclxuICAgICAgTGVmdENlbnRlcjogeyBwbGFjZW1lbnQ6IFwibGVmdFwiLCBwb3NpdGlvbjogXCJjZW50ZXJcIiB9LFxyXG4gICAgICBMZWZ0Qm90dG9tOiB7IHBsYWNlbWVudDogXCJsZWZ0XCIsIHBvc2l0aW9uOiBcImVuZFwiIH0sXHJcbiAgICAgIFJpZ2h0VG9wOiB7IHBsYWNlbWVudDogXCJyaWdodFwiLCBwb3NpdGlvbjogXCJzdGFydFwiIH0sXHJcbiAgICAgIFJpZ2h0Q2VudGVyOiB7IHBsYWNlbWVudDogXCJyaWdodFwiLCBwb3NpdGlvbjogXCJjZW50ZXJcIiB9LFxyXG4gICAgICBSaWdodEJvdHRvbTogeyBwbGFjZW1lbnQ6IFwicmlnaHRcIiwgcG9zaXRpb246IFwiZW5kXCIgfSxcclxuICAgIH07XHJcbiAgICByZXR1cm4gKFxyXG4gICAgICBwbGFjZW1lbnRNYXBbdGhpcy5fcGxhY2VtZW50XSB8fCB7XHJcbiAgICAgICAgcGxhY2VtZW50OiBcImJvdHRvbVwiLFxyXG4gICAgICAgIHBvc2l0aW9uOiBcInN0YXJ0XCIsXHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBnZXQgb2Zmc2V0KCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX29mZnNldCB8fCA4O1xyXG4gIH1cclxuXHJcbiAgZ2V0IGF1dG9BZGp1c3QoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fYXV0b0FkanVzdCA9PT0gXCJ5ZXNcIjtcclxuICB9XHJcblxyXG4gIEBPdXRwdXQoXCJvcGVuQ2hhbmdlXCIpIG9wZW5DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XHJcbiAgQE91dHB1dChcImNvbnRlbnRMb2FkXCIpIGNvbnRlbnRMb2FkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICBAVmlld0NoaWxkKFwidHJpZ2dlclwiLCB7IHN0YXRpYzogZmFsc2UgfSlcclxuICBpbnRlcm5hbFRyaWdnZXJFbGVtZW50OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcclxuICBAVmlld0NoaWxkKFwicG9wdXBcIiwgeyBzdGF0aWM6IGZhbHNlIH0pXHJcbiAgcG9wdXBFbGVtZW50OiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcclxuXHJcbiAgY3VycmVudFRyaWdnZXJFbGVtZW50OiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMuZml4ZWRDb250YWluZXJFbCA9IHRoaXMuZ2V0Rml4ZWRDb250YWluZXIoKTtcclxuICAgIHRoaXMuZml4ZWRDb250YWluZXJFbC5hcHBlbmQodGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCk7XHJcbiAgICB0aGlzLnVwZGF0ZVRyaWdnZXJFbGVtZW50KCk7XHJcblxyXG4gICAgLy8g5aaC5p6c5o+Q5L6b5LqG5Zu65a6a5bC65a+477yM56uL5Y2z5bqU55SoXHJcbiAgICBpZiAoXHJcbiAgICAgIHRoaXMuX3dpZHRoICE9PSBudWxsICYmXHJcbiAgICAgIHRoaXMuX2hlaWdodCAhPT0gbnVsbCAmJlxyXG4gICAgICB0aGlzLnBvcHVwRWxlbWVudCAmJlxyXG4gICAgICB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50XHJcbiAgICApIHtcclxuICAgICAgY29uc3QgcG9wdXBFbCA9IHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgIHBvcHVwRWwuc3R5bGUud2lkdGggPSB0aGlzLl93aWR0aCArIFwicHhcIjtcclxuICAgICAgcG9wdXBFbC5zdHlsZS5oZWlnaHQgPSB0aGlzLl9oZWlnaHQgKyBcInB4XCI7XHJcbiAgICAgIHBvcHVwRWwuc3R5bGUubWluV2lkdGggPSB0aGlzLl93aWR0aCArIFwicHhcIjtcclxuICAgICAgcG9wdXBFbC5zdHlsZS5tYXhXaWR0aCA9IHRoaXMuX3dpZHRoICsgXCJweFwiO1xyXG4gICAgICBwb3B1cEVsLnN0eWxlLm1pbkhlaWdodCA9IHRoaXMuX2hlaWdodCArIFwicHhcIjtcclxuICAgICAgcG9wdXBFbC5zdHlsZS5tYXhIZWlnaHQgPSB0aGlzLl9oZWlnaHQgKyBcInB4XCI7XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5aaC5p6c5aSW6YOo5Lyg5YWlIG9wZW4g5bGe5oCn5Li6IHRydWXvvIzoh6rliqjmiZPlvIBcclxuICAgIGlmICh0aGlzLl9vcGVuKSB7XHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5vcGVuKCksIDApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgLy8g5aSE55CG5Zu65a6a5bC65a+45Y+Y5YyWXHJcbiAgICBpZiAoXHJcbiAgICAgIChjaGFuZ2VzLl93aWR0aCB8fCBjaGFuZ2VzLl9oZWlnaHQpICYmXHJcbiAgICAgIHRoaXMucG9wdXBFbGVtZW50ICYmXHJcbiAgICAgIHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnRcclxuICAgICkge1xyXG4gICAgICBjb25zdCBwb3B1cEVsID0gdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudDtcclxuICAgICAgaWYgKHRoaXMuX3dpZHRoICE9PSBudWxsKSB7XHJcbiAgICAgICAgcG9wdXBFbC5zdHlsZS53aWR0aCA9IHRoaXMuX3dpZHRoICsgXCJweFwiO1xyXG4gICAgICAgIHBvcHVwRWwuc3R5bGUubWluV2lkdGggPSB0aGlzLl93aWR0aCArIFwicHhcIjtcclxuICAgICAgICBwb3B1cEVsLnN0eWxlLm1heFdpZHRoID0gdGhpcy5fd2lkdGggKyBcInB4XCI7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHRoaXMuX2hlaWdodCAhPT0gbnVsbCkge1xyXG4gICAgICAgIHBvcHVwRWwuc3R5bGUuaGVpZ2h0ID0gdGhpcy5faGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgICAgIHBvcHVwRWwuc3R5bGUubWluSGVpZ2h0ID0gdGhpcy5faGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgICAgIHBvcHVwRWwuc3R5bGUubWF4SGVpZ2h0ID0gdGhpcy5faGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5YWI5aSE55CG6Kem5Y+R5YWD57Sg5Y+Y5YyW77yI56Gu5L+d5Zyo5omT5byA5YmN5pu05paw6Kem5Y+R5YWD57Sg77yJXHJcbiAgICBpZiAoY2hhbmdlcy50cmlnZ2VyRWxlbWVudFJlZikge1xyXG4gICAgICBjb25zdCBwcmV2aW91c1RyaWdnZXIgPSB0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudDtcclxuICAgICAgdGhpcy51cGRhdGVUcmlnZ2VyRWxlbWVudCgpO1xyXG5cclxuICAgICAgLy8g5aaC5p6c5by556qX5bey57uP5omT5byA77yM5LiU6Kem5Y+R5YWD57Sg5Y+R55Sf5LqG5Y+Y5YyW77yM56uL5Y2z5pu05paw5L2N572uXHJcbiAgICAgIGlmIChcclxuICAgICAgICB0aGlzLm9wZW5lZCA9PT0gXCJ5ZXNcIiAmJlxyXG4gICAgICAgIHByZXZpb3VzVHJpZ2dlciAhPT0gdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQgJiZcclxuICAgICAgICB0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudFxyXG4gICAgICApIHtcclxuICAgICAgICAvLyDkvb/nlKjmlrDnmoTmiZPlvIDmlrnlvI/mm7TmlrDkvY3nva5cclxuICAgICAgICB0aGlzLnBvc2l0aW9uaW5nID0gXCJ5ZXNcIjtcclxuICAgICAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVQb3B1cFBvc2l0aW9uKCk7XHJcbiAgICAgICAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcIm5vXCI7XHJcbiAgICAgICAgICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyDlpITnkIYgb3BlbiDlj5jljJbvvIjnoa7kv53lnKjop6blj5HlhYPntKDmm7TmlrDlkI7lpITnkIbvvIlcclxuICAgIGlmIChjaGFuZ2VzLl9vcGVuKSB7XHJcbiAgICAgIGlmICh0aGlzLl9vcGVuICYmIHRoaXMub3BlbmVkID09PSBcIm5vXCIpIHtcclxuICAgICAgICAvLyDnoa7kv53op6blj5HlhYPntKDlt7Lmm7TmlrBcclxuICAgICAgICB0aGlzLnVwZGF0ZVRyaWdnZXJFbGVtZW50KCk7XHJcbiAgICAgICAgLy8g5L2/55SoIHNldFRpbWVvdXQg56Gu5L+d5omA5pyJ5Y+Y5pu06YO95bey5aSE55CGXHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAvLyDlho3mrKHnoa7kv53op6blj5HlhYPntKDlt7Lmm7TmlrBcclxuICAgICAgICAgIHRoaXMudXBkYXRlVHJpZ2dlckVsZW1lbnQoKTtcclxuICAgICAgICAgIHRoaXMub3BlbigpO1xyXG4gICAgICAgIH0sIDApO1xyXG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLl9vcGVuICYmIHRoaXMub3BlbmVkID09PSBcInllc1wiKSB7XHJcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5b2T5Yqg6L295a6M5oiQ5pe277yM5pu05paw5L2N572u77yI5aaC5p6c5o+Q5L6b5LqG5Zu65a6a5bC65a+477yM5LiN6ZyA6KaB5pu05paw5L2N572u77yJXHJcbiAgICBpZiAoXHJcbiAgICAgIGNoYW5nZXMubG9hZGluZyAmJlxyXG4gICAgICAhY2hhbmdlcy5sb2FkaW5nLmN1cnJlbnRWYWx1ZSAmJlxyXG4gICAgICBjaGFuZ2VzLmxvYWRpbmcucHJldmlvdXNWYWx1ZVxyXG4gICAgKSB7XHJcbiAgICAgIGlmICh0aGlzLm9wZW5lZCA9PT0gXCJ5ZXNcIikge1xyXG4gICAgICAgIC8vIOWmguaenOaPkOS+m+S6huWbuuWumuWwuuWvuO+8jOS9jee9ruW3sue7j+iuoeeul+WlveS6hu+8jOS4jemcgOimgeabtOaWsFxyXG4gICAgICAgIGlmICh0aGlzLl93aWR0aCAhPT0gbnVsbCAmJiB0aGlzLl9oZWlnaHQgIT09IG51bGwpIHtcclxuICAgICAgICAgIHRoaXMuY29udGVudExvYWQuZW1pdCgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyDlpoLmnpzmraPlnKjlrprkvY3vvIzkuI3pnIDopoHmm7TmlrDkvY3nva5cclxuICAgICAgICAgIGlmICh0aGlzLnBvc2l0aW9uaW5nID09PSBcIm5vXCIpIHtcclxuICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVBvcHVwUG9zaXRpb24oKTtcclxuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRMb2FkLmVtaXQoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyDlpoLmnpzmraPlnKjlrprkvY3vvIznrYnlvoXlrprkvY3lrozmiJDlkI7lho3op6blj5Hkuovku7ZcclxuICAgICAgICAgICAgY29uc3QgY2hlY2tQb3NpdGlvbmluZyA9ICgpID0+IHtcclxuICAgICAgICAgICAgICBpZiAodGhpcy5wb3NpdGlvbmluZyA9PT0gXCJub1wiKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRMb2FkLmVtaXQoKTtcclxuICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChjaGVja1Bvc2l0aW9uaW5nLCAxMCk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjaGVja1Bvc2l0aW9uaW5nKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIGlmICh0aGlzLnBvcHVwRWxlbWVudCAmJiB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgIHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQucmVtb3ZlKCk7XHJcbiAgICB9XHJcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMub25DbGlja091dHNpZGUpO1xyXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vbldpbmRvd1Njcm9sbCwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICB1cGRhdGVUcmlnZ2VyRWxlbWVudCgpIHtcclxuICAgIGlmICh0aGlzLnRyaWdnZXJFbGVtZW50UmVmKSB7XHJcbiAgICAgIHRoaXMuY3VycmVudFRyaWdnZXJFbGVtZW50ID0gdGhpcy50cmlnZ2VyRWxlbWVudFJlZjtcclxuICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgIHRoaXMuaW50ZXJuYWxUcmlnZ2VyRWxlbWVudCAmJlxyXG4gICAgICB0aGlzLmludGVybmFsVHJpZ2dlckVsZW1lbnQubmF0aXZlRWxlbWVudFxyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMuY3VycmVudFRyaWdnZXJFbGVtZW50ID0gdGhpcy5pbnRlcm5hbFRyaWdnZXJFbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudCA9IG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBGSVhFRF9DT05UQUlORVJfSUQgPSBcInJzLXNtYXJ0LXBvcHVwLWZpeGVkLWNvbnRhaW5lclwiO1xyXG4gIGZpeGVkQ29udGFpbmVyRWw6IEhUTUxFbGVtZW50O1xyXG4gIGdldEZpeGVkQ29udGFpbmVyKCkge1xyXG4gICAgbGV0IGNvbnRhaW5lckVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLkZJWEVEX0NPTlRBSU5FUl9JRCk7XHJcbiAgICBpZiAoIWNvbnRhaW5lckVsZW1lbnQpIHtcclxuICAgICAgY29udGFpbmVyRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XHJcbiAgICAgIGNvbnRhaW5lckVsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgdGhpcy5GSVhFRF9DT05UQUlORVJfSUQpO1xyXG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChjb250YWluZXJFbGVtZW50KTtcclxuICAgIH1cclxuICAgIHJldHVybiBjb250YWluZXJFbGVtZW50O1xyXG4gIH1cclxuXHJcbiAgb3BlbmVkOiBcInllc1wiIHwgXCJub1wiID0gXCJub1wiO1xyXG4gIHBvc2l0aW9uaW5nOiBcInllc1wiIHwgXCJub1wiID0gXCJub1wiO1xyXG4gIGFjdHVhbFBsYWNlbWVudDogXCJ0b3BcIiB8IFwibGVmdFwiIHwgXCJyaWdodFwiIHwgXCJib3R0b21cIiA9IFwiYm90dG9tXCI7XHJcbiAgYWN0dWFsUG9zaXRpb246IFwic3RhcnRcIiB8IFwiY2VudGVyXCIgfCBcImVuZFwiID0gXCJzdGFydFwiO1xyXG5cclxuICBvcGVuKHRyaWdnZXJFbGVtZW50PzogSFRNTEVsZW1lbnQpIHtcclxuICAgIC8vIOWmguaenOS8oOWFpeS6huinpuWPkeWFg+e0oO+8jOS9v+eUqOWug1xyXG4gICAgaWYgKHRyaWdnZXJFbGVtZW50KSB7XHJcbiAgICAgIHRoaXMuY3VycmVudFRyaWdnZXJFbGVtZW50ID0gdHJpZ2dlckVsZW1lbnQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnVwZGF0ZVRyaWdnZXJFbGVtZW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudCkge1xyXG4gICAgICBjb25zb2xlLndhcm4oXCJTbWFydFBvcHVwQ29tcG9uZW50OiBObyB0cmlnZ2VyIGVsZW1lbnQgZm91bmRcIik7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyDlpoLmnpzlt7Lnu4/miZPlvIDvvIzlhYjlhbPpl63lho3miZPlvIDvvIjmm7TmlrDkvY3nva7vvIlcclxuICAgIGlmICh0aGlzLm9wZW5lZCA9PT0gXCJ5ZXNcIikge1xyXG4gICAgICAvLyDlhYjlhbPpl63lvLnnqpdcclxuICAgICAgdGhpcy5vcGVuZWQgPSBcIm5vXCI7XHJcbiAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcIm5vXCI7XHJcbiAgICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAvLyDnq4vljbPlnKjmlrDkvY3nva7miZPlvIBcclxuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICAvLyDlho3mrKHnoa7kv53op6blj5HlhYPntKDlt7Lmm7TmlrBcclxuICAgICAgICB0aGlzLnVwZGF0ZVRyaWdnZXJFbGVtZW50KCk7XHJcbiAgICAgICAgdGhpcy5vcGVuUG9wdXAoKTtcclxuICAgICAgfSk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyDnoa7kv53op6blj5HlhYPntKDlt7Lmm7TmlrBcclxuICAgIHRoaXMudXBkYXRlVHJpZ2dlckVsZW1lbnQoKTtcclxuICAgIHRoaXMub3BlblBvcHVwKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG9wZW5Qb3B1cCgpIHtcclxuICAgIC8vIOWGjeasoeehruS/neinpuWPkeWFg+e0oOW3suabtOaWsFxyXG4gICAgdGhpcy51cGRhdGVUcmlnZ2VyRWxlbWVudCgpO1xyXG5cclxuICAgIGlmICghdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQpIHtcclxuICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgIFwiU21hcnRQb3B1cENvbXBvbmVudDogTm8gdHJpZ2dlciBlbGVtZW50IGZvdW5kIHdoZW4gb3BlbmluZyBwb3B1cFwiXHJcbiAgICAgICk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyDlpoLmnpzmj5Dkvpvkuoblm7rlrprlsLrlr7jvvIzlj6/ku6XlnKjmiZPlvIDliY3lsLHorqHnrpflpb3kvY3nva5cclxuICAgIGlmICh0aGlzLl93aWR0aCAhPT0gbnVsbCAmJiB0aGlzLl9oZWlnaHQgIT09IG51bGwpIHtcclxuICAgICAgLy8g5YWI6K6h566X5L2N572u77yI5LiN5L6d6LWWRE9N5riy5p+T77yM55u05o6l5qC55o2udHJpZ2dlckVsZW1lbnTorqHnrpfvvIlcclxuICAgICAgY29uc3QgdHJpZ2dlclJlY3QgPSB0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgY29uc3Qgdmlld3BvcnRXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xyXG4gICAgICBjb25zdCB2aWV3cG9ydEhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcclxuXHJcbiAgICAgIGNvbnN0IHBvcHVwU2l6ZSA9IHtcclxuICAgICAgICB3aWR0aDogdGhpcy5fd2lkdGgsXHJcbiAgICAgICAgaGVpZ2h0OiB0aGlzLl9oZWlnaHQsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCBwb3B1cFJlY3Q6IERPTVJlY3QgPSB7XHJcbiAgICAgICAgd2lkdGg6IHBvcHVwU2l6ZS53aWR0aCxcclxuICAgICAgICBoZWlnaHQ6IHBvcHVwU2l6ZS5oZWlnaHQsXHJcbiAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgIGxlZnQ6IDAsXHJcbiAgICAgICAgcmlnaHQ6IHBvcHVwU2l6ZS53aWR0aCxcclxuICAgICAgICBib3R0b206IHBvcHVwU2l6ZS5oZWlnaHQsXHJcbiAgICAgICAgeDogMCxcclxuICAgICAgICB5OiAwLFxyXG4gICAgICAgIHRvSlNPTjogKCkgPT4gKHt9KSxcclxuICAgICAgfSBhcyBET01SZWN0O1xyXG5cclxuICAgICAgY29uc3QgdGFyZ2V0SW5mbyA9IHRoaXMucGxhY2VtZW50SW5mbztcclxuICAgICAgbGV0IGZpbmFsUGxhY2VtZW50ID0gdGFyZ2V0SW5mby5wbGFjZW1lbnQ7XHJcbiAgICAgIGxldCBmaW5hbFBvc2l0aW9uID0gdGFyZ2V0SW5mby5wb3NpdGlvbjtcclxuXHJcbiAgICAgIGlmICh0aGlzLmF1dG9BZGp1c3QpIHtcclxuICAgICAgICBjb25zdCBvcHRpbWFsID0gdGhpcy5jYWxjdWxhdGVPcHRpbWFsUGxhY2VtZW50KFxyXG4gICAgICAgICAgdHJpZ2dlclJlY3QsXHJcbiAgICAgICAgICBwb3B1cFJlY3QsXHJcbiAgICAgICAgICB2aWV3cG9ydFdpZHRoLFxyXG4gICAgICAgICAgdmlld3BvcnRIZWlnaHRcclxuICAgICAgICApO1xyXG4gICAgICAgIGZpbmFsUGxhY2VtZW50ID0gb3B0aW1hbC5wbGFjZW1lbnQ7XHJcbiAgICAgICAgZmluYWxQb3NpdGlvbiA9IG9wdGltYWwucG9zaXRpb247XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuYWN0dWFsUGxhY2VtZW50ID0gZmluYWxQbGFjZW1lbnQ7XHJcbiAgICAgIHRoaXMuYWN0dWFsUG9zaXRpb24gPSBmaW5hbFBvc2l0aW9uO1xyXG5cclxuICAgICAgLy8g6K6h566X5L2N572u5Z2Q5qCH77yI5LiN5L6d6LWWRE9N77yM55u05o6l6K6h566X77yJXHJcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5jYWxjdWxhdGVQb3NpdGlvbkNvb3JkaW5hdGVzKFxyXG4gICAgICAgIHRyaWdnZXJSZWN0LFxyXG4gICAgICAgIGZpbmFsUGxhY2VtZW50LFxyXG4gICAgICAgIGZpbmFsUG9zaXRpb24sXHJcbiAgICAgICAgcG9wdXBTaXplXHJcbiAgICAgICk7XHJcblxyXG4gICAgICAvLyDlhYjorr7nva7miZPlvIDnirbmgIHvvIzkvYbkv53mjIHpmpDol4/vvIhwb3NpdGlvbmluZyA9IHllc++8iVxyXG4gICAgICB0aGlzLm9wZW5lZCA9IFwieWVzXCI7XHJcbiAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcInllc1wiO1xyXG4gICAgICB0aGlzLm9wZW5DaGFuZ2UuZW1pdCh0cnVlKTtcclxuICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcblxyXG4gICAgICAvLyDlvLrliLbmm7TmlrDop4blm77vvIznoa7kv51ET03lt7Lmm7TmlrBcclxuICAgICAgdGhpcy5yZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG5cclxuICAgICAgLy8g5aaC5p6c5YWD57Sg5bey57uP5a2Y5Zyo77yM56uL5Y2z6K6+572u5L2N572u77yI5LiN562J5b6FIHJlcXVlc3RBbmltYXRpb25GcmFtZe+8iVxyXG4gICAgICBpZiAodGhpcy5wb3B1cEVsZW1lbnQgJiYgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICAgIGNvbnN0IHBvcHVwRWwgPSB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50O1xyXG5cclxuICAgICAgICAvLyDnq4vljbPorr7nva7lsLrlr7jlkozkvY3nva5cclxuICAgICAgICBwb3B1cEVsLnN0eWxlLndpZHRoID0gdGhpcy5fd2lkdGggKyBcInB4XCI7XHJcbiAgICAgICAgcG9wdXBFbC5zdHlsZS5oZWlnaHQgPSB0aGlzLl9oZWlnaHQgKyBcInB4XCI7XHJcbiAgICAgICAgcG9wdXBFbC5zdHlsZS5taW5XaWR0aCA9IHRoaXMuX3dpZHRoICsgXCJweFwiO1xyXG4gICAgICAgIHBvcHVwRWwuc3R5bGUubWF4V2lkdGggPSB0aGlzLl93aWR0aCArIFwicHhcIjtcclxuICAgICAgICBwb3B1cEVsLnN0eWxlLm1pbkhlaWdodCA9IHRoaXMuX2hlaWdodCArIFwicHhcIjtcclxuICAgICAgICBwb3B1cEVsLnN0eWxlLm1heEhlaWdodCA9IHRoaXMuX2hlaWdodCArIFwicHhcIjtcclxuICAgICAgICBwb3B1cEVsLnN0eWxlLnRvcCA9IHBvc2l0aW9uLnRvcDtcclxuICAgICAgICBwb3B1cEVsLnN0eWxlLmxlZnQgPSBwb3NpdGlvbi5sZWZ0O1xyXG4gICAgICAgIHBvcHVwRWwuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZSgke3Bvc2l0aW9uLnRyYW5zbGF0ZVh9LCAke3Bvc2l0aW9uLnRyYW5zbGF0ZVl9KWA7XHJcblxyXG4gICAgICAgIC8vIOW8uuWItuWQjOatpeW6lOeUqOagt+W8j1xyXG4gICAgICAgIHBvcHVwRWwub2Zmc2V0SGVpZ2h0O1xyXG5cclxuICAgICAgICAvLyDkvY3nva7orr7nva7lrozmiJDlkI7vvIznq4vljbPmmL7npLrlvLnnqpdcclxuICAgICAgICB0aGlzLnBvc2l0aW9uaW5nID0gXCJub1wiO1xyXG4gICAgICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIOWmguaenOWFg+e0oOi/mOS4jeWtmOWcqO+8jOetieW+hea4suafk1xyXG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcbiAgICAgICAgICBpZiAodGhpcy5wb3B1cEVsZW1lbnQgJiYgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICAgICAgICBjb25zdCBwb3B1cEVsID0gdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudDtcclxuXHJcbiAgICAgICAgICAgIC8vIOeri+WNs+iuvue9ruWwuuWvuOWSjOS9jee9rlxyXG4gICAgICAgICAgICBwb3B1cEVsLnN0eWxlLndpZHRoID0gdGhpcy5fd2lkdGggKyBcInB4XCI7XHJcbiAgICAgICAgICAgIHBvcHVwRWwuc3R5bGUuaGVpZ2h0ID0gdGhpcy5faGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgICAgICAgICBwb3B1cEVsLnN0eWxlLm1pbldpZHRoID0gdGhpcy5fd2lkdGggKyBcInB4XCI7XHJcbiAgICAgICAgICAgIHBvcHVwRWwuc3R5bGUubWF4V2lkdGggPSB0aGlzLl93aWR0aCArIFwicHhcIjtcclxuICAgICAgICAgICAgcG9wdXBFbC5zdHlsZS5taW5IZWlnaHQgPSB0aGlzLl9oZWlnaHQgKyBcInB4XCI7XHJcbiAgICAgICAgICAgIHBvcHVwRWwuc3R5bGUubWF4SGVpZ2h0ID0gdGhpcy5faGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgICAgICAgICBwb3B1cEVsLnN0eWxlLnRvcCA9IHBvc2l0aW9uLnRvcDtcclxuICAgICAgICAgICAgcG9wdXBFbC5zdHlsZS5sZWZ0ID0gcG9zaXRpb24ubGVmdDtcclxuICAgICAgICAgICAgcG9wdXBFbC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7cG9zaXRpb24udHJhbnNsYXRlWH0sICR7cG9zaXRpb24udHJhbnNsYXRlWX0pYDtcclxuXHJcbiAgICAgICAgICAgIC8vIOW8uuWItuWQjOatpeW6lOeUqOagt+W8j1xyXG4gICAgICAgICAgICBwb3B1cEVsLm9mZnNldEhlaWdodDtcclxuXHJcbiAgICAgICAgICAgIC8vIOS9jee9ruiuvue9ruWujOaIkOWQju+8jOeri+WNs+aYvuekuuW8ueeql1xyXG4gICAgICAgICAgICB0aGlzLnBvc2l0aW9uaW5nID0gXCJub1wiO1xyXG4gICAgICAgICAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8g5rKh5pyJ5Zu65a6a5bC65a+477yM6ZyA6KaB562J5b6FRE9N5riy5p+TXHJcbiAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcInllc1wiO1xyXG4gICAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcclxuXHJcbiAgICAgIC8vIOeri+WNs+W8uuWItuabtOaWsOinhuWbvu+8jOehruS/nURPTeW3suabtOaWsFxyXG4gICAgICB0aGlzLnJlZi5kZXRlY3RDaGFuZ2VzKCk7XHJcblxyXG4gICAgICAvLyDkvb/nlKggcmVxdWVzdEFuaW1hdGlvbkZyYW1lIOehruS/neWcqOa1j+iniOWZqOa4suafk+S5i+WJjeabtOaWsOS9jee9rlxyXG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgIC8vIOehruS/neWFg+e0oOW3sua4suafk+W5tuiOt+WPluWwuuWvuFxyXG4gICAgICAgIGlmICh0aGlzLnBvcHVwRWxlbWVudCAmJiB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgICAgICAvLyDlvLrliLbph43mlrDorqHnrpfluIPlsYDvvIznoa7kv53lhYPntKDlsLrlr7jlt7LorqHnrpdcclxuICAgICAgICAgIHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xyXG5cclxuICAgICAgICAgIC8vIOiuoeeul+W5tuiuvue9ruS9jee9rlxyXG4gICAgICAgICAgdGhpcy51cGRhdGVQb3B1cFBvc2l0aW9uKCk7XHJcblxyXG4gICAgICAgICAgLy8g5L2N572u6K6+572u5a6M5oiQ5ZCO77yM56e76Zmk5a6a5L2N54q25oCB77yM5pi+56S65by556qXXHJcbiAgICAgICAgICB0aGlzLnBvc2l0aW9uaW5nID0gXCJub1wiO1xyXG4gICAgICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMub25DbGlja091dHNpZGUpO1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vbldpbmRvd1Njcm9sbCwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBjbG9zZSgpIHtcclxuICAgIGlmICh0aGlzLm9wZW5lZCA9PT0gXCJub1wiKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLm9wZW5lZCA9IFwibm9cIjtcclxuICAgIHRoaXMucG9zaXRpb25pbmcgPSBcIm5vXCI7XHJcbiAgICB0aGlzLm9wZW5DaGFuZ2UuZW1pdChmYWxzZSk7XHJcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMub25DbGlja091dHNpZGUpO1xyXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vbldpbmRvd1Njcm9sbCwgdHJ1ZSk7XHJcbiAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICB9XHJcblxyXG4gIHRvZ2dsZSgpIHtcclxuICAgIGlmICh0aGlzLm9wZW5lZCA9PT0gXCJ5ZXNcIikge1xyXG4gICAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLm9wZW4oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uQ2xpY2tUcmlnZ2VyKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIHRoaXMudG9nZ2xlKCk7XHJcbiAgfVxyXG5cclxuICBvbkNsaWNrT3V0c2lkZSA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xyXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEVsZW1lbnQ7XHJcbiAgICBjb25zdCBpc0NsaWNrT25UcmlnZ2VyID1cclxuICAgICAgdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQgJiYgdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQuY29udGFpbnModGFyZ2V0KTtcclxuICAgIGNvbnN0IGlzQ2xpY2tPblBvcHVwID1cclxuICAgICAgdGhpcy5wb3B1cEVsZW1lbnQgJiZcclxuICAgICAgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCAmJlxyXG4gICAgICB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKHRhcmdldCk7XHJcblxyXG4gICAgaWYgKCFpc0NsaWNrT25UcmlnZ2VyICYmICFpc0NsaWNrT25Qb3B1cCkge1xyXG4gICAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgb25XaW5kb3dTY3JvbGwgPSAoZXZlbnQ6IEV2ZW50KSA9PiB7XHJcbiAgICBpZiAodGhpcy5vcGVuZWQgPT09IFwieWVzXCIpIHtcclxuICAgICAgLy8g5qOA5p+l5rua5Yqo5piv5ZCm5Y+R55Sf5Zyo5by556qX5YaF6YOoXHJcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBFbGVtZW50O1xyXG4gICAgICBjb25zdCBpc1Njcm9sbE9uUG9wdXAgPVxyXG4gICAgICAgIHRoaXMucG9wdXBFbGVtZW50ICYmXHJcbiAgICAgICAgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCAmJlxyXG4gICAgICAgIHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KTtcclxuXHJcbiAgICAgIC8vIOWmguaenOa7muWKqOWPkeeUn+WcqOW8ueeql+WGhemDqO+8jOS4jeabtOaWsOS9jee9ru+8iOmBv+WFjeS4jeW/heimgeeahOiuoeeul++8iVxyXG4gICAgICAvLyDlpoLmnpzmu5rliqjlj5HnlJ/lnKjlpJbpg6jvvIzmm7TmlrDkvY3nva7vvIjlm6DkuLrop6blj5HlhYPntKDkvY3nva7lj6/og73mlLnlj5jvvIlcclxuICAgICAgaWYgKCFpc1Njcm9sbE9uUG9wdXApIHtcclxuICAgICAgICB0aGlzLnVwZGF0ZVBvcHVwUG9zaXRpb24oKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIC8vIOWkhOeQhuW8ueeql+WGhemDqOeahOa7mui9ruS6i+S7tlxyXG4gIG9uUG9wdXBXaGVlbChldmVudDogV2hlZWxFdmVudCkge1xyXG4gICAgLy8g6Zi75q2i5rua6L2u5LqL5Lu25YaS5rOh77yM6YG/5YWN6Kem5Y+R5aSW6YOo5rua5Yqo5aSE55CGXHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICB9XHJcblxyXG4gIC8vIOWkhOeQhuW8ueeql+WGhemDqOeahOa7muWKqOS6i+S7tlxyXG4gIG9uUG9wdXBTY3JvbGwoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICAvLyDpmLvmraLmu5rliqjkuovku7blhpLms6HvvIzpgb/lhY3op6blj5HlpJbpg6jmu5rliqjlpITnkIZcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gIH1cclxuXHJcbiAgLy8g6K6h566X5bm26K6+572u5L2N572u77yI5pSv5oyB5Zu65a6a5bC65a+477yM5Y+v5Zyo5omT5byA5YmN6LCD55So77yJXHJcbiAgcHJpdmF0ZSBjYWxjdWxhdGVBbmRTZXRQb3NpdGlvbigpIHtcclxuICAgIGlmICghdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyaWdnZXJSZWN0ID0gdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICBjb25zdCB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgICBjb25zdCB2aWV3cG9ydEhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcclxuXHJcbiAgICAvLyDojrflj5blvLnnqpflsLrlr7jvvIjkvJjlhYjkvb/nlKjlm7rlrprlsLrlr7jvvIlcclxuICAgIGNvbnN0IHBvcHVwU2l6ZSA9IHtcclxuICAgICAgd2lkdGg6XHJcbiAgICAgICAgdGhpcy5fd2lkdGggIT09IG51bGxcclxuICAgICAgICAgID8gdGhpcy5fd2lkdGhcclxuICAgICAgICAgIDogdGhpcy5wb3B1cEVsZW1lbnQgJiYgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudFxyXG4gICAgICAgICAgPyB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoXHJcbiAgICAgICAgICA6IDMwMCxcclxuICAgICAgaGVpZ2h0OlxyXG4gICAgICAgIHRoaXMuX2hlaWdodCAhPT0gbnVsbFxyXG4gICAgICAgICAgPyB0aGlzLl9oZWlnaHRcclxuICAgICAgICAgIDogdGhpcy5wb3B1cEVsZW1lbnQgJiYgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudFxyXG4gICAgICAgICAgPyB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodFxyXG4gICAgICAgICAgOiAyMDAsXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIOWIm+W7uuiZmuaLn+eahCBwb3B1cFJlY3TvvIjnlKjkuo7orqHnrpfvvIlcclxuICAgIGNvbnN0IHBvcHVwUmVjdDogRE9NUmVjdCA9IHtcclxuICAgICAgd2lkdGg6IHBvcHVwU2l6ZS53aWR0aCxcclxuICAgICAgaGVpZ2h0OiBwb3B1cFNpemUuaGVpZ2h0LFxyXG4gICAgICB0b3A6IDAsXHJcbiAgICAgIGxlZnQ6IDAsXHJcbiAgICAgIHJpZ2h0OiBwb3B1cFNpemUud2lkdGgsXHJcbiAgICAgIGJvdHRvbTogcG9wdXBTaXplLmhlaWdodCxcclxuICAgICAgeDogMCxcclxuICAgICAgeTogMCxcclxuICAgICAgdG9KU09OOiAoKSA9PiAoe30pLFxyXG4gICAgfSBhcyBET01SZWN0O1xyXG5cclxuICAgIC8vIOiOt+WPluebruagh+S9jee9ruS/oeaBr1xyXG4gICAgY29uc3QgdGFyZ2V0SW5mbyA9IHRoaXMucGxhY2VtZW50SW5mbztcclxuICAgIGxldCBmaW5hbFBsYWNlbWVudCA9IHRhcmdldEluZm8ucGxhY2VtZW50O1xyXG4gICAgbGV0IGZpbmFsUG9zaXRpb24gPSB0YXJnZXRJbmZvLnBvc2l0aW9uO1xyXG5cclxuICAgIGlmICh0aGlzLmF1dG9BZGp1c3QpIHtcclxuICAgICAgY29uc3Qgb3B0aW1hbCA9IHRoaXMuY2FsY3VsYXRlT3B0aW1hbFBsYWNlbWVudChcclxuICAgICAgICB0cmlnZ2VyUmVjdCxcclxuICAgICAgICBwb3B1cFJlY3QsXHJcbiAgICAgICAgdmlld3BvcnRXaWR0aCxcclxuICAgICAgICB2aWV3cG9ydEhlaWdodFxyXG4gICAgICApO1xyXG4gICAgICBmaW5hbFBsYWNlbWVudCA9IG9wdGltYWwucGxhY2VtZW50O1xyXG4gICAgICBmaW5hbFBvc2l0aW9uID0gb3B0aW1hbC5wb3NpdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmFjdHVhbFBsYWNlbWVudCA9IGZpbmFsUGxhY2VtZW50O1xyXG4gICAgdGhpcy5hY3R1YWxQb3NpdGlvbiA9IGZpbmFsUG9zaXRpb247XHJcblxyXG4gICAgLy8g56uL5Y2z6K6+572u5L2N572u77yI5Y2z5L2/5YWD57Sg6L+Y5rKh5a6M5YWo5riy5p+T77yM5Lmf6KaB5YWI6K6+572u5L2N572u77yJXHJcbiAgICBpZiAodGhpcy5wb3B1cEVsZW1lbnQgJiYgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICB0aGlzLnNldFBvcHVwUG9zaXRpb24oXHJcbiAgICAgICAgdHJpZ2dlclJlY3QsXHJcbiAgICAgICAgcG9wdXBSZWN0LFxyXG4gICAgICAgIGZpbmFsUGxhY2VtZW50LFxyXG4gICAgICAgIGZpbmFsUG9zaXRpb24sXHJcbiAgICAgICAgcG9wdXBTaXplXHJcbiAgICAgICk7XHJcbiAgICAgIC8vIOW8uuWItuW6lOeUqOagt+W8j++8jOehruS/neS9jee9rueri+WNs+eUn+aViFxyXG4gICAgICB0aGlzLnJlZi5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyDlpoLmnpzlhYPntKDov5jkuI3lrZjlnKjvvIzlu7bov5/orr7nva7kvY3nva5cclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMucG9wdXBFbGVtZW50ICYmIHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgICAgIHRoaXMuc2V0UG9wdXBQb3NpdGlvbihcclxuICAgICAgICAgICAgdHJpZ2dlclJlY3QsXHJcbiAgICAgICAgICAgIHBvcHVwUmVjdCxcclxuICAgICAgICAgICAgZmluYWxQbGFjZW1lbnQsXHJcbiAgICAgICAgICAgIGZpbmFsUG9zaXRpb24sXHJcbiAgICAgICAgICAgIHBvcHVwU2l6ZVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHRoaXMucmVmLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIDApO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlUG9wdXBQb3NpdGlvbigpIHtcclxuICAgIGlmIChcclxuICAgICAgIXRoaXMuY3VycmVudFRyaWdnZXJFbGVtZW50IHx8XHJcbiAgICAgICF0aGlzLnBvcHVwRWxlbWVudCB8fFxyXG4gICAgICAhdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudFxyXG4gICAgKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyDlpoLmnpzmj5Dkvpvkuoblm7rlrprlsLrlr7jvvIzkvb/nlKjlm7rlrprlsLrlr7jorqHnrpdcclxuICAgIGlmICh0aGlzLl93aWR0aCAhPT0gbnVsbCAmJiB0aGlzLl9oZWlnaHQgIT09IG51bGwpIHtcclxuICAgICAgdGhpcy5jYWxjdWxhdGVBbmRTZXRQb3NpdGlvbigpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdHJpZ2dlclJlY3QgPSB0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGNvbnN0IHBvcHVwUmVjdCA9IHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICBjb25zdCB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgICBjb25zdCB2aWV3cG9ydEhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcclxuXHJcbiAgICAvLyDojrflj5bnm67moIfkvY3nva7kv6Hmga9cclxuICAgIGNvbnN0IHRhcmdldEluZm8gPSB0aGlzLnBsYWNlbWVudEluZm87XHJcbiAgICBsZXQgZmluYWxQbGFjZW1lbnQgPSB0YXJnZXRJbmZvLnBsYWNlbWVudDtcclxuICAgIGxldCBmaW5hbFBvc2l0aW9uID0gdGFyZ2V0SW5mby5wb3NpdGlvbjtcclxuXHJcbiAgICBpZiAodGhpcy5hdXRvQWRqdXN0KSB7XHJcbiAgICAgIGNvbnN0IG9wdGltYWwgPSB0aGlzLmNhbGN1bGF0ZU9wdGltYWxQbGFjZW1lbnQoXHJcbiAgICAgICAgdHJpZ2dlclJlY3QsXHJcbiAgICAgICAgcG9wdXBSZWN0LFxyXG4gICAgICAgIHZpZXdwb3J0V2lkdGgsXHJcbiAgICAgICAgdmlld3BvcnRIZWlnaHRcclxuICAgICAgKTtcclxuICAgICAgZmluYWxQbGFjZW1lbnQgPSBvcHRpbWFsLnBsYWNlbWVudDtcclxuICAgICAgZmluYWxQb3NpdGlvbiA9IG9wdGltYWwucG9zaXRpb247XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5hY3R1YWxQbGFjZW1lbnQgPSBmaW5hbFBsYWNlbWVudDtcclxuICAgIHRoaXMuYWN0dWFsUG9zaXRpb24gPSBmaW5hbFBvc2l0aW9uO1xyXG4gICAgdGhpcy5zZXRQb3B1cFBvc2l0aW9uKFxyXG4gICAgICB0cmlnZ2VyUmVjdCxcclxuICAgICAgcG9wdXBSZWN0LFxyXG4gICAgICBmaW5hbFBsYWNlbWVudCxcclxuICAgICAgZmluYWxQb3NpdGlvblxyXG4gICAgKTtcclxuICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gIH1cclxuXHJcbiAgY2FsY3VsYXRlT3B0aW1hbFBsYWNlbWVudChcclxuICAgIHRyaWdnZXJSZWN0OiBET01SZWN0IHwgQ2xpZW50UmVjdCxcclxuICAgIHBvcHVwUmVjdDogRE9NUmVjdCB8IENsaWVudFJlY3QsXHJcbiAgICB2aWV3cG9ydFdpZHRoOiBudW1iZXIsXHJcbiAgICB2aWV3cG9ydEhlaWdodDogbnVtYmVyXHJcbiAgKToge1xyXG4gICAgcGxhY2VtZW50OiBcInRvcFwiIHwgXCJsZWZ0XCIgfCBcInJpZ2h0XCIgfCBcImJvdHRvbVwiO1xyXG4gICAgcG9zaXRpb246IFwic3RhcnRcIiB8IFwiY2VudGVyXCIgfCBcImVuZFwiO1xyXG4gIH0ge1xyXG4gICAgY29uc3QgdGFyZ2V0SW5mbyA9IHRoaXMucGxhY2VtZW50SW5mbztcclxuICAgIGNvbnN0IHByZWZlcnJlZCA9IHRhcmdldEluZm8ucGxhY2VtZW50O1xyXG4gICAgY29uc3QgcHJlZmVycmVkUG9zaXRpb24gPSB0YXJnZXRJbmZvLnBvc2l0aW9uO1xyXG5cclxuICAgIGNvbnN0IHNwYWNlID0ge1xyXG4gICAgICB0b3A6IHRyaWdnZXJSZWN0LnRvcCxcclxuICAgICAgYm90dG9tOiB2aWV3cG9ydEhlaWdodCAtIHRyaWdnZXJSZWN0LmJvdHRvbSxcclxuICAgICAgbGVmdDogdHJpZ2dlclJlY3QubGVmdCxcclxuICAgICAgcmlnaHQ6IHZpZXdwb3J0V2lkdGggLSB0cmlnZ2VyUmVjdC5yaWdodCxcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgcG9wdXBTaXplID0ge1xyXG4gICAgICB3aWR0aDogcG9wdXBSZWN0LndpZHRoIHx8IDMwMCwgLy8g6buY6K6k5a695bqm77yM5aaC5p6c6L+Y5rKh5pyJ5riy5p+TXHJcbiAgICAgIGhlaWdodDogcG9wdXBSZWN0LmhlaWdodCB8fCAyMDAsIC8vIOm7mOiupOmrmOW6plxyXG4gICAgfTtcclxuXHJcbiAgICAvLyDmo4Dmn6XpppbpgInkvY3nva7mmK/lkKbmnInotrPlpJ/nqbrpl7RcclxuICAgIGNvbnN0IGhhc0Vub3VnaFNwYWNlID0gKHBsYWNlbWVudDogXCJ0b3BcIiB8IFwibGVmdFwiIHwgXCJyaWdodFwiIHwgXCJib3R0b21cIikgPT4ge1xyXG4gICAgICBzd2l0Y2ggKHBsYWNlbWVudCkge1xyXG4gICAgICAgIGNhc2UgXCJ0b3BcIjpcclxuICAgICAgICAgIHJldHVybiBzcGFjZS50b3AgPj0gcG9wdXBTaXplLmhlaWdodCArIHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGNhc2UgXCJib3R0b21cIjpcclxuICAgICAgICAgIHJldHVybiBzcGFjZS5ib3R0b20gPj0gcG9wdXBTaXplLmhlaWdodCArIHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGNhc2UgXCJsZWZ0XCI6XHJcbiAgICAgICAgICByZXR1cm4gc3BhY2UubGVmdCA+PSBwb3B1cFNpemUud2lkdGggKyB0aGlzLm9mZnNldDtcclxuICAgICAgICBjYXNlIFwicmlnaHRcIjpcclxuICAgICAgICAgIHJldHVybiBzcGFjZS5yaWdodCA+PSBwb3B1cFNpemUud2lkdGggKyB0aGlzLm9mZnNldDtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyDmo4Dmn6XmjIflrprkvY3nva7mmK/lkKbmnInotrPlpJ/nqbrpl7RcclxuICAgIGNvbnN0IGNoZWNrUG9zaXRpb25TcGFjZSA9IChcclxuICAgICAgcGxhY2VtZW50OiBcInRvcFwiIHwgXCJsZWZ0XCIgfCBcInJpZ2h0XCIgfCBcImJvdHRvbVwiLFxyXG4gICAgICBwb3NpdGlvbjogXCJzdGFydFwiIHwgXCJjZW50ZXJcIiB8IFwiZW5kXCJcclxuICAgICk6IGJvb2xlYW4gPT4ge1xyXG4gICAgICBpZiAocGxhY2VtZW50ID09PSBcInRvcFwiIHx8IHBsYWNlbWVudCA9PT0gXCJib3R0b21cIikge1xyXG4gICAgICAgIC8vIOWvueS6juS4iuS4i+S9jee9ru+8jOajgOafpeawtOW5s+Wvuem9kOepuumXtFxyXG4gICAgICAgIGNvbnN0IHBvcHVwV2lkdGggPSBwb3B1cFNpemUud2lkdGg7XHJcbiAgICAgICAgY29uc3Qgc3BhY2VMZWZ0ID0gdHJpZ2dlclJlY3QubGVmdDtcclxuICAgICAgICBjb25zdCBzcGFjZVJpZ2h0ID0gdmlld3BvcnRXaWR0aCAtIHRyaWdnZXJSZWN0LnJpZ2h0O1xyXG5cclxuICAgICAgICBpZiAocG9zaXRpb24gPT09IFwiY2VudGVyXCIpIHtcclxuICAgICAgICAgIHJldHVybiBzcGFjZUxlZnQgPj0gcG9wdXBXaWR0aCAvIDIgJiYgc3BhY2VSaWdodCA+PSBwb3B1cFdpZHRoIC8gMjtcclxuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSBcInN0YXJ0XCIpIHtcclxuICAgICAgICAgIHJldHVybiBzcGFjZUxlZnQgPj0gcG9wdXBXaWR0aDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gZW5kXHJcbiAgICAgICAgICByZXR1cm4gc3BhY2VSaWdodCA+PSBwb3B1cFdpZHRoO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyDlr7nkuo7lt6blj7PkvY3nva7vvIzmo4Dmn6XlnoLnm7Tlr7npvZDnqbrpl7RcclxuICAgICAgICBjb25zdCBwb3B1cEhlaWdodCA9IHBvcHVwU2l6ZS5oZWlnaHQ7XHJcbiAgICAgICAgY29uc3Qgc3BhY2VUb3AgPSB0cmlnZ2VyUmVjdC50b3A7XHJcbiAgICAgICAgY29uc3Qgc3BhY2VCb3R0b20gPSB2aWV3cG9ydEhlaWdodCAtIHRyaWdnZXJSZWN0LmJvdHRvbTtcclxuXHJcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSBcImNlbnRlclwiKSB7XHJcbiAgICAgICAgICByZXR1cm4gc3BhY2VUb3AgPj0gcG9wdXBIZWlnaHQgLyAyICYmIHNwYWNlQm90dG9tID49IHBvcHVwSGVpZ2h0IC8gMjtcclxuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSBcInN0YXJ0XCIpIHtcclxuICAgICAgICAgIHJldHVybiBzcGFjZVRvcCA+PSBwb3B1cEhlaWdodDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gZW5kXHJcbiAgICAgICAgICByZXR1cm4gc3BhY2VCb3R0b20gPj0gcG9wdXBIZWlnaHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIOiuoeeul+S9jee9ruaYr+WQpuWQiOmAgu+8iOiAg+iZkeawtOW5sy/lnoLnm7Tlr7npvZDvvIlcclxuICAgIGNvbnN0IGNhbGN1bGF0ZVBvc2l0aW9uID0gKFxyXG4gICAgICBwbGFjZW1lbnQ6IFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCJcclxuICAgICk6IFwic3RhcnRcIiB8IFwiY2VudGVyXCIgfCBcImVuZFwiID0+IHtcclxuICAgICAgaWYgKHBsYWNlbWVudCA9PT0gXCJ0b3BcIiB8fCBwbGFjZW1lbnQgPT09IFwiYm90dG9tXCIpIHtcclxuICAgICAgICAvLyDlr7nkuo7kuIrkuIvkvY3nva7vvIzmo4Dmn6XmsLTlubPlr7npvZBcclxuICAgICAgICBjb25zdCBwb3B1cFdpZHRoID0gcG9wdXBTaXplLndpZHRoO1xyXG4gICAgICAgIGNvbnN0IHNwYWNlTGVmdCA9IHRyaWdnZXJSZWN0LmxlZnQ7XHJcbiAgICAgICAgY29uc3Qgc3BhY2VSaWdodCA9IHZpZXdwb3J0V2lkdGggLSB0cmlnZ2VyUmVjdC5yaWdodDtcclxuXHJcbiAgICAgICAgLy8g5LyY5YWI5bCd6K+V5L2/55So55So5oi35oyH5a6a55qEcG9zaXRpb25cclxuICAgICAgICBpZiAoY2hlY2tQb3NpdGlvblNwYWNlKHBsYWNlbWVudCwgcHJlZmVycmVkUG9zaXRpb24pKSB7XHJcbiAgICAgICAgICByZXR1cm4gcHJlZmVycmVkUG9zaXRpb247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyDlpoLmnpzkuK3lv4Plr7npvZDmnInotrPlpJ/nqbrpl7TvvIzkvJjlhYjkvb/nlKjkuK3lv4NcclxuICAgICAgICBpZiAoc3BhY2VMZWZ0ID49IHBvcHVwV2lkdGggLyAyICYmIHNwYWNlUmlnaHQgPj0gcG9wdXBXaWR0aCAvIDIpIHtcclxuICAgICAgICAgIHJldHVybiBcImNlbnRlclwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyDlpoLmnpzlt6bkvqfnqbrpl7TkuI3otrPvvIzkvb/nlKjlj7Plr7npvZBcclxuICAgICAgICBpZiAoc3BhY2VMZWZ0IDwgcG9wdXBXaWR0aCAvIDIpIHtcclxuICAgICAgICAgIHJldHVybiBcImVuZFwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyDlpoLmnpzlj7Pkvqfnqbrpl7TkuI3otrPvvIzkvb/nlKjlt6blr7npvZBcclxuICAgICAgICBpZiAoc3BhY2VSaWdodCA8IHBvcHVwV2lkdGggLyAyKSB7XHJcbiAgICAgICAgICByZXR1cm4gXCJzdGFydFwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcHJlZmVycmVkUG9zaXRpb247XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8g5a+55LqO5bem5Y+z5L2N572u77yM5qOA5p+l5Z6C55u05a+56b2QXHJcbiAgICAgICAgY29uc3QgcG9wdXBIZWlnaHQgPSBwb3B1cFNpemUuaGVpZ2h0O1xyXG4gICAgICAgIGNvbnN0IHNwYWNlVG9wID0gdHJpZ2dlclJlY3QudG9wO1xyXG4gICAgICAgIGNvbnN0IHNwYWNlQm90dG9tID0gdmlld3BvcnRIZWlnaHQgLSB0cmlnZ2VyUmVjdC5ib3R0b207XHJcblxyXG4gICAgICAgIC8vIOS8mOWFiOWwneivleS9v+eUqOeUqOaIt+aMh+WumueahHBvc2l0aW9uXHJcbiAgICAgICAgaWYgKGNoZWNrUG9zaXRpb25TcGFjZShwbGFjZW1lbnQsIHByZWZlcnJlZFBvc2l0aW9uKSkge1xyXG4gICAgICAgICAgcmV0dXJuIHByZWZlcnJlZFBvc2l0aW9uO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8g5aaC5p6c5Lit5b+D5a+56b2Q5pyJ6Laz5aSf56m66Ze077yM5LyY5YWI5L2/55So5Lit5b+DXHJcbiAgICAgICAgaWYgKHNwYWNlVG9wID49IHBvcHVwSGVpZ2h0IC8gMiAmJiBzcGFjZUJvdHRvbSA+PSBwb3B1cEhlaWdodCAvIDIpIHtcclxuICAgICAgICAgIHJldHVybiBcImNlbnRlclwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyDlpoLmnpzkuIrmlrnnqbrpl7TkuI3otrPvvIzkvb/nlKjkuIvlr7npvZBcclxuICAgICAgICBpZiAoc3BhY2VUb3AgPCBwb3B1cEhlaWdodCAvIDIpIHtcclxuICAgICAgICAgIHJldHVybiBcImVuZFwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyDlpoLmnpzkuIvmlrnnqbrpl7TkuI3otrPvvIzkvb/nlKjkuIrlr7npvZBcclxuICAgICAgICBpZiAoc3BhY2VCb3R0b20gPCBwb3B1cEhlaWdodCAvIDIpIHtcclxuICAgICAgICAgIHJldHVybiBcInN0YXJ0XCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwcmVmZXJyZWRQb3NpdGlvbjtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyDlpoLmnpzpppbpgInkvY3nva7mnInotrPlpJ/nqbrpl7TvvIzkvJjlhYjkvb/nlKjnlKjmiLfmjIflrprnmoRwb3NpdGlvblxyXG4gICAgaWYgKGhhc0Vub3VnaFNwYWNlKHByZWZlcnJlZCkpIHtcclxuICAgICAgLy8g5qOA5p+l55So5oi35oyH5a6a55qEcG9zaXRpb27mmK/lkKbmnInotrPlpJ/nqbrpl7RcclxuICAgICAgaWYgKGNoZWNrUG9zaXRpb25TcGFjZShwcmVmZXJyZWQsIHByZWZlcnJlZFBvc2l0aW9uKSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICBwbGFjZW1lbnQ6IHByZWZlcnJlZCxcclxuICAgICAgICAgIHBvc2l0aW9uOiBwcmVmZXJyZWRQb3NpdGlvbixcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICAgIC8vIOWmguaenOaMh+WumueahHBvc2l0aW9u56m66Ze05LiN6Laz77yM6Ieq5Yqo6K6h566X5pyA5L2zcG9zaXRpb25cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBwbGFjZW1lbnQ6IHByZWZlcnJlZCxcclxuICAgICAgICBwb3NpdGlvbjogY2FsY3VsYXRlUG9zaXRpb24ocHJlZmVycmVkKSxcclxuICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvLyDmoLnmja7pppbpgInkvY3nva7pgInmi6nlpIfpgInkvY3nva5cclxuICAgIGNvbnN0IGFsdGVybmF0aXZlczoge1xyXG4gICAgICBba2V5OiBzdHJpbmddOiAoXCJ0b3BcIiB8IFwibGVmdFwiIHwgXCJyaWdodFwiIHwgXCJib3R0b21cIilbXTtcclxuICAgIH0gPSB7XHJcbiAgICAgIGJvdHRvbTogW1widG9wXCIsIFwicmlnaHRcIiwgXCJsZWZ0XCJdLFxyXG4gICAgICB0b3A6IFtcImJvdHRvbVwiLCBcInJpZ2h0XCIsIFwibGVmdFwiXSxcclxuICAgICAgcmlnaHQ6IFtcImxlZnRcIiwgXCJib3R0b21cIiwgXCJ0b3BcIl0sXHJcbiAgICAgIGxlZnQ6IFtcInJpZ2h0XCIsIFwiYm90dG9tXCIsIFwidG9wXCJdLFxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBhbHRMaXN0ID0gYWx0ZXJuYXRpdmVzW3ByZWZlcnJlZF0gfHwgW107XHJcblxyXG4gICAgLy8g5bCd6K+V5om+5Yiw56ys5LiA5Liq5pyJ6Laz5aSf56m66Ze055qE5aSH6YCJ5L2N572uXHJcbiAgICBmb3IgKGNvbnN0IGFsdCBvZiBhbHRMaXN0KSB7XHJcbiAgICAgIGlmIChoYXNFbm91Z2hTcGFjZShhbHQpKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgIHBsYWNlbWVudDogYWx0LFxyXG4gICAgICAgICAgcG9zaXRpb246IGNhbGN1bGF0ZVBvc2l0aW9uKGFsdCksXHJcbiAgICAgICAgfTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIOWmguaenOmDveayoeaciei2s+Wkn+epuumXtO+8jOmAieaLqeepuumXtOacgOWkp+eahOS9jee9rlxyXG4gICAgY29uc3QgbWF4U3BhY2UgPSBNYXRoLm1heChzcGFjZS50b3AsIHNwYWNlLmJvdHRvbSwgc3BhY2UubGVmdCwgc3BhY2UucmlnaHQpO1xyXG4gICAgbGV0IGJlc3RQbGFjZW1lbnQ6IFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCI7XHJcbiAgICBpZiAobWF4U3BhY2UgPT09IHNwYWNlLnRvcCkgYmVzdFBsYWNlbWVudCA9IFwidG9wXCI7XHJcbiAgICBlbHNlIGlmIChtYXhTcGFjZSA9PT0gc3BhY2UuYm90dG9tKSBiZXN0UGxhY2VtZW50ID0gXCJib3R0b21cIjtcclxuICAgIGVsc2UgaWYgKG1heFNwYWNlID09PSBzcGFjZS5sZWZ0KSBiZXN0UGxhY2VtZW50ID0gXCJsZWZ0XCI7XHJcbiAgICBlbHNlIGJlc3RQbGFjZW1lbnQgPSBcInJpZ2h0XCI7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgcGxhY2VtZW50OiBiZXN0UGxhY2VtZW50LFxyXG4gICAgICBwb3NpdGlvbjogY2FsY3VsYXRlUG9zaXRpb24oYmVzdFBsYWNlbWVudCksXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLy8g6K6h566X5L2N572u5Z2Q5qCH77yI57qv6K6h566X77yM5LiN5L6d6LWWRE9N77yM5YyF5ZCr6L6555WM57qm5p2f77yJXHJcbiAgcHJpdmF0ZSBjYWxjdWxhdGVQb3NpdGlvbkNvb3JkaW5hdGVzKFxyXG4gICAgdHJpZ2dlclJlY3Q6IERPTVJlY3QgfCBDbGllbnRSZWN0LFxyXG4gICAgcGxhY2VtZW50OiBcInRvcFwiIHwgXCJsZWZ0XCIgfCBcInJpZ2h0XCIgfCBcImJvdHRvbVwiLFxyXG4gICAgcG9zaXRpb246IFwic3RhcnRcIiB8IFwiY2VudGVyXCIgfCBcImVuZFwiLFxyXG4gICAgcG9wdXBTaXplOiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH1cclxuICApOiB7IHRvcDogc3RyaW5nOyBsZWZ0OiBzdHJpbmc7IHRyYW5zbGF0ZVg6IHN0cmluZzsgdHJhbnNsYXRlWTogc3RyaW5nIH0ge1xyXG4gICAgY29uc3QgdHJpZ2dlcldpZHRoID0gdHJpZ2dlclJlY3Qud2lkdGg7XHJcbiAgICBjb25zdCB0cmlnZ2VySGVpZ2h0ID0gdHJpZ2dlclJlY3QuaGVpZ2h0O1xyXG4gICAgY29uc3Qgdmlld3BvcnRXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xyXG4gICAgY29uc3Qgdmlld3BvcnRIZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XHJcbiAgICBjb25zdCBzY3JvbGxYID0gd2luZG93LnNjcm9sbFg7XHJcbiAgICBjb25zdCBzY3JvbGxZID0gd2luZG93LnNjcm9sbFk7XHJcblxyXG4gICAgbGV0IHRvcCA9IDA7XHJcbiAgICBsZXQgbGVmdCA9IDA7XHJcbiAgICBsZXQgdHJhbnNsYXRlWCA9IFwiMFwiO1xyXG4gICAgbGV0IHRyYW5zbGF0ZVkgPSBcIjBcIjtcclxuXHJcbiAgICBzd2l0Y2ggKHBsYWNlbWVudCkge1xyXG4gICAgICBjYXNlIFwidG9wXCI6XHJcbiAgICAgICAgdG9wID0gdHJpZ2dlclJlY3QudG9wICsgc2Nyb2xsWSAtIHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIHRyYW5zbGF0ZVkgPSBcIi0xMDAlXCI7XHJcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSBcInN0YXJ0XCIpIHtcclxuICAgICAgICAgIGxlZnQgPSB0cmlnZ2VyUmVjdC5sZWZ0ICsgc2Nyb2xsWDtcclxuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSBcImNlbnRlclwiKSB7XHJcbiAgICAgICAgICBsZWZ0ID0gdHJpZ2dlclJlY3QubGVmdCArIHNjcm9sbFggKyB0cmlnZ2VyV2lkdGggLyAyO1xyXG4gICAgICAgICAgdHJhbnNsYXRlWCA9IFwiLTUwJVwiO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBsZWZ0ID0gdHJpZ2dlclJlY3QubGVmdCArIHNjcm9sbFggKyB0cmlnZ2VyV2lkdGg7XHJcbiAgICAgICAgICB0cmFuc2xhdGVYID0gXCItMTAwJVwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyDovrnnlYznuqbmnZ/vvJrnoa7kv53lvLnnqpfkuI3otoXlh7rop4blj6NcclxuICAgICAgICBpZiAodG9wIC0gcG9wdXBTaXplLmhlaWdodCA8IHNjcm9sbFkpIHtcclxuICAgICAgICAgIHRvcCA9IHNjcm9sbFkgKyA4OyAvLyDot53nprvpobbpg6joh7PlsJE4cHhcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGxlZnQgPCBzY3JvbGxYKSB7XHJcbiAgICAgICAgICBsZWZ0ID0gc2Nyb2xsWCArIDg7XHJcbiAgICAgICAgICB0cmFuc2xhdGVYID0gXCIwXCI7XHJcbiAgICAgICAgfSBlbHNlIGlmIChsZWZ0ICsgcG9wdXBTaXplLndpZHRoID4gc2Nyb2xsWCArIHZpZXdwb3J0V2lkdGgpIHtcclxuICAgICAgICAgIGxlZnQgPSBzY3JvbGxYICsgdmlld3BvcnRXaWR0aCAtIHBvcHVwU2l6ZS53aWR0aCAtIDg7XHJcbiAgICAgICAgICB0cmFuc2xhdGVYID0gXCIwXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgY2FzZSBcImJvdHRvbVwiOlxyXG4gICAgICAgIHRvcCA9IHRyaWdnZXJSZWN0LmJvdHRvbSArIHNjcm9sbFkgKyB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAocG9zaXRpb24gPT09IFwic3RhcnRcIikge1xyXG4gICAgICAgICAgbGVmdCA9IHRyaWdnZXJSZWN0LmxlZnQgKyBzY3JvbGxYO1xyXG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IFwiY2VudGVyXCIpIHtcclxuICAgICAgICAgIGxlZnQgPSB0cmlnZ2VyUmVjdC5sZWZ0ICsgc2Nyb2xsWCArIHRyaWdnZXJXaWR0aCAvIDI7XHJcbiAgICAgICAgICB0cmFuc2xhdGVYID0gXCItNTAlXCI7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGxlZnQgPSB0cmlnZ2VyUmVjdC5sZWZ0ICsgc2Nyb2xsWCArIHRyaWdnZXJXaWR0aDtcclxuICAgICAgICAgIHRyYW5zbGF0ZVggPSBcIi0xMDAlXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOi+ueeVjOe6puadn++8muehruS/neW8ueeql+S4jei2heWHuuinhuWPo1xyXG4gICAgICAgIGlmICh0b3AgKyBwb3B1cFNpemUuaGVpZ2h0ID4gc2Nyb2xsWSArIHZpZXdwb3J0SGVpZ2h0KSB7XHJcbiAgICAgICAgICB0b3AgPSBzY3JvbGxZICsgdmlld3BvcnRIZWlnaHQgLSBwb3B1cFNpemUuaGVpZ2h0IC0gODsgLy8g6Led56a75bqV6YOo6Iez5bCROHB4XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChsZWZ0IDwgc2Nyb2xsWCkge1xyXG4gICAgICAgICAgbGVmdCA9IHNjcm9sbFggKyA4O1xyXG4gICAgICAgICAgdHJhbnNsYXRlWCA9IFwiMFwiO1xyXG4gICAgICAgIH0gZWxzZSBpZiAobGVmdCArIHBvcHVwU2l6ZS53aWR0aCA+IHNjcm9sbFggKyB2aWV3cG9ydFdpZHRoKSB7XHJcbiAgICAgICAgICBsZWZ0ID0gc2Nyb2xsWCArIHZpZXdwb3J0V2lkdGggLSBwb3B1cFNpemUud2lkdGggLSA4O1xyXG4gICAgICAgICAgdHJhbnNsYXRlWCA9IFwiMFwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgXCJsZWZ0XCI6XHJcbiAgICAgICAgbGVmdCA9IHRyaWdnZXJSZWN0LmxlZnQgKyBzY3JvbGxYIC0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgdHJhbnNsYXRlWCA9IFwiLTEwMCVcIjtcclxuICAgICAgICBpZiAocG9zaXRpb24gPT09IFwic3RhcnRcIikge1xyXG4gICAgICAgICAgdG9wID0gdHJpZ2dlclJlY3QudG9wICsgc2Nyb2xsWTtcclxuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSBcImNlbnRlclwiKSB7XHJcbiAgICAgICAgICB0b3AgPSB0cmlnZ2VyUmVjdC50b3AgKyBzY3JvbGxZICsgdHJpZ2dlckhlaWdodCAvIDI7XHJcbiAgICAgICAgICB0cmFuc2xhdGVZID0gXCItNTAlXCI7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRvcCA9IHRyaWdnZXJSZWN0LnRvcCArIHNjcm9sbFkgKyB0cmlnZ2VySGVpZ2h0O1xyXG4gICAgICAgICAgdHJhbnNsYXRlWSA9IFwiLTEwMCVcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8g6L6555WM57qm5p2f77ya56Gu5L+d5by556qX5LiN6LaF5Ye66KeG5Y+jXHJcbiAgICAgICAgaWYgKGxlZnQgLSBwb3B1cFNpemUud2lkdGggPCBzY3JvbGxYKSB7XHJcbiAgICAgICAgICBsZWZ0ID0gc2Nyb2xsWCArIDg7IC8vIOi3neemu+W3puS+p+iHs+WwkThweFxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodG9wIDwgc2Nyb2xsWSkge1xyXG4gICAgICAgICAgdG9wID0gc2Nyb2xsWSArIDg7XHJcbiAgICAgICAgICB0cmFuc2xhdGVZID0gXCIwXCI7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0b3AgKyBwb3B1cFNpemUuaGVpZ2h0ID4gc2Nyb2xsWSArIHZpZXdwb3J0SGVpZ2h0KSB7XHJcbiAgICAgICAgICB0b3AgPSBzY3JvbGxZICsgdmlld3BvcnRIZWlnaHQgLSBwb3B1cFNpemUuaGVpZ2h0IC0gODtcclxuICAgICAgICAgIHRyYW5zbGF0ZVkgPSBcIjBcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlIFwicmlnaHRcIjpcclxuICAgICAgICBsZWZ0ID0gdHJpZ2dlclJlY3QucmlnaHQgKyBzY3JvbGxYICsgdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSBcInN0YXJ0XCIpIHtcclxuICAgICAgICAgIHRvcCA9IHRyaWdnZXJSZWN0LnRvcCArIHNjcm9sbFk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gXCJjZW50ZXJcIikge1xyXG4gICAgICAgICAgdG9wID0gdHJpZ2dlclJlY3QudG9wICsgc2Nyb2xsWSArIHRyaWdnZXJIZWlnaHQgLyAyO1xyXG4gICAgICAgICAgdHJhbnNsYXRlWSA9IFwiLTUwJVwiO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0b3AgPSB0cmlnZ2VyUmVjdC50b3AgKyBzY3JvbGxZICsgdHJpZ2dlckhlaWdodDtcclxuICAgICAgICAgIHRyYW5zbGF0ZVkgPSBcIi0xMDAlXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOi+ueeVjOe6puadn++8muehruS/neW8ueeql+S4jei2heWHuuinhuWPo1xyXG4gICAgICAgIGlmIChsZWZ0ICsgcG9wdXBTaXplLndpZHRoID4gc2Nyb2xsWCArIHZpZXdwb3J0V2lkdGgpIHtcclxuICAgICAgICAgIGxlZnQgPSBzY3JvbGxYICsgdmlld3BvcnRXaWR0aCAtIHBvcHVwU2l6ZS53aWR0aCAtIDg7IC8vIOi3neemu+WPs+S+p+iHs+WwkThweFxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodG9wIDwgc2Nyb2xsWSkge1xyXG4gICAgICAgICAgdG9wID0gc2Nyb2xsWSArIDg7XHJcbiAgICAgICAgICB0cmFuc2xhdGVZID0gXCIwXCI7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0b3AgKyBwb3B1cFNpemUuaGVpZ2h0ID4gc2Nyb2xsWSArIHZpZXdwb3J0SGVpZ2h0KSB7XHJcbiAgICAgICAgICB0b3AgPSBzY3JvbGxZICsgdmlld3BvcnRIZWlnaHQgLSBwb3B1cFNpemUuaGVpZ2h0IC0gODtcclxuICAgICAgICAgIHRyYW5zbGF0ZVkgPSBcIjBcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgdG9wOiB0b3AgKyBcInB4XCIsXHJcbiAgICAgIGxlZnQ6IGxlZnQgKyBcInB4XCIsXHJcbiAgICAgIHRyYW5zbGF0ZVgsXHJcbiAgICAgIHRyYW5zbGF0ZVksXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgc2V0UG9wdXBQb3NpdGlvbihcclxuICAgIHRyaWdnZXJSZWN0OiBET01SZWN0IHwgQ2xpZW50UmVjdCxcclxuICAgIHBvcHVwUmVjdDogRE9NUmVjdCB8IENsaWVudFJlY3QsXHJcbiAgICBwbGFjZW1lbnQ6IFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCIsXHJcbiAgICBwb3NpdGlvbjogXCJzdGFydFwiIHwgXCJjZW50ZXJcIiB8IFwiZW5kXCIsXHJcbiAgICBwb3B1cFNpemU/OiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH1cclxuICApIHtcclxuICAgIGNvbnN0IHBvcHVwRWwgPVxyXG4gICAgICB0aGlzLnBvcHVwRWxlbWVudCAmJiB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50XHJcbiAgICAgICAgPyB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50XHJcbiAgICAgICAgOiBudWxsO1xyXG4gICAgaWYgKCFwb3B1cEVsKSB7XHJcbiAgICAgIHJldHVybjsgLy8g5aaC5p6c5YWD57Sg6L+Y5LiN5a2Y5Zyo77yM5peg5rOV6K6+572u5L2N572uXHJcbiAgICB9XHJcblxyXG4gICAgLy8g5LyY5YWI5L2/55So5Lyg5YWl55qE5Zu65a6a5bC65a+477yM5ZCm5YiZ5LuORE9N6I635Y+WXHJcbiAgICBjb25zdCBwb3B1cFdpZHRoID1cclxuICAgICAgcG9wdXBTaXplICYmIHBvcHVwU2l6ZS53aWR0aCAhPT0gbnVsbCAmJiBwb3B1cFNpemUud2lkdGggIT09IHVuZGVmaW5lZFxyXG4gICAgICAgID8gcG9wdXBTaXplLndpZHRoXHJcbiAgICAgICAgOiBwb3B1cFJlY3Qud2lkdGggfHwgcG9wdXBFbC5vZmZzZXRXaWR0aCB8fCAzMDA7XHJcbiAgICBjb25zdCBwb3B1cEhlaWdodCA9XHJcbiAgICAgIHBvcHVwU2l6ZSAmJiBwb3B1cFNpemUuaGVpZ2h0ICE9PSBudWxsICYmIHBvcHVwU2l6ZS5oZWlnaHQgIT09IHVuZGVmaW5lZFxyXG4gICAgICAgID8gcG9wdXBTaXplLmhlaWdodFxyXG4gICAgICAgIDogcG9wdXBSZWN0LmhlaWdodCB8fCBwb3B1cEVsLm9mZnNldEhlaWdodCB8fCAyMDA7XHJcblxyXG4gICAgY29uc3QgY29vcmRpbmF0ZXMgPSB0aGlzLmNhbGN1bGF0ZVBvc2l0aW9uQ29vcmRpbmF0ZXMoXHJcbiAgICAgIHRyaWdnZXJSZWN0LFxyXG4gICAgICBwbGFjZW1lbnQsXHJcbiAgICAgIHBvc2l0aW9uLFxyXG4gICAgICB7IHdpZHRoOiBwb3B1cFdpZHRoLCBoZWlnaHQ6IHBvcHVwSGVpZ2h0IH1cclxuICAgICk7XHJcblxyXG4gICAgcG9wdXBFbC5zdHlsZS50b3AgPSBjb29yZGluYXRlcy50b3A7XHJcbiAgICBwb3B1cEVsLnN0eWxlLmxlZnQgPSBjb29yZGluYXRlcy5sZWZ0O1xyXG4gICAgcG9wdXBFbC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7Y29vcmRpbmF0ZXMudHJhbnNsYXRlWH0sICR7Y29vcmRpbmF0ZXMudHJhbnNsYXRlWX0pYDtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoXCJ3aW5kb3c6cmVzaXplXCIpXHJcbiAgb25XaW5kb3dSZXNpemUoKSB7XHJcbiAgICBpZiAodGhpcy5vcGVuZWQgPT09IFwieWVzXCIpIHtcclxuICAgICAgdGhpcy51cGRhdGVQb3B1cFBvc2l0aW9uKCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiJdfQ==