@mintplayer/ng-bootstrap 13.1.24 → 13.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/esm2020/lib/components/accordion/accordion/accordion.component.mjs +3 -3
  2. package/esm2020/lib/components/accordion/accordion-tab/accordion-tab.component.mjs +3 -3
  3. package/esm2020/lib/components/accordion/accordion-tab-header/accordion-tab-header.component.mjs +3 -3
  4. package/esm2020/lib/components/accordion/accordion.module.mjs +4 -4
  5. package/esm2020/lib/components/alert/alert/alert.component.mjs +3 -3
  6. package/esm2020/lib/components/alert/alert-close/alert-close.component.mjs +3 -3
  7. package/esm2020/lib/components/alert/alert.module.mjs +4 -4
  8. package/esm2020/lib/components/calendar/calendar.component.mjs +3 -3
  9. package/esm2020/lib/components/calendar/calendar.module.mjs +4 -4
  10. package/esm2020/lib/components/card/card/card.component.mjs +3 -3
  11. package/esm2020/lib/components/card/card-header/card-header.component.mjs +3 -3
  12. package/esm2020/lib/components/card/card.module.mjs +4 -4
  13. package/esm2020/lib/components/carousel/carousel/carousel.component.mjs +3 -3
  14. package/esm2020/lib/components/carousel/carousel-image/carousel-image.directive.mjs +3 -3
  15. package/esm2020/lib/components/carousel/carousel.module.mjs +4 -4
  16. package/esm2020/lib/components/code-snippet/code-snippet.component.mjs +3 -3
  17. package/esm2020/lib/components/code-snippet/code-snippet.module.mjs +4 -4
  18. package/esm2020/lib/components/context-menu/context-menu.directive.mjs +4 -5
  19. package/esm2020/lib/components/context-menu/context-menu.module.mjs +4 -4
  20. package/esm2020/lib/components/copy/copy.directive.mjs +3 -3
  21. package/esm2020/lib/components/copy/copy.module.mjs +4 -4
  22. package/esm2020/lib/components/datatable/datatable/datatable.component.mjs +3 -3
  23. package/esm2020/lib/components/datatable/datatable-column/datatable-column.directive.mjs +3 -3
  24. package/esm2020/lib/components/datatable/datatable.module.mjs +4 -4
  25. package/esm2020/lib/components/datatable/row-template/row-template.directive.mjs +3 -3
  26. package/esm2020/lib/components/datepicker/datepicker.component.mjs +3 -3
  27. package/esm2020/lib/components/datepicker/datepicker.module.mjs +4 -4
  28. package/esm2020/lib/components/dropdown/dropdown/dropdown.directive.mjs +3 -3
  29. package/esm2020/lib/components/dropdown/dropdown-menu/dropdown-menu.directive.mjs +3 -3
  30. package/esm2020/lib/components/dropdown/dropdown-toggle/dropdown-toggle.directive.mjs +3 -3
  31. package/esm2020/lib/components/dropdown/dropdown.module.mjs +4 -4
  32. package/esm2020/lib/components/file-upload/component/file-upload.component.mjs +4 -5
  33. package/esm2020/lib/components/file-upload/directive/file-upload-template.directive.mjs +3 -3
  34. package/esm2020/lib/components/file-upload/file-upload.module.mjs +4 -4
  35. package/esm2020/lib/components/for/for.directive.mjs +3 -3
  36. package/esm2020/lib/components/for/for.module.mjs +4 -4
  37. package/esm2020/lib/components/index.mjs +2 -1
  38. package/esm2020/lib/components/list-group/list-group/list-group.component.mjs +3 -3
  39. package/esm2020/lib/components/list-group/list-group-item/list-group-item.component.mjs +3 -3
  40. package/esm2020/lib/components/list-group/list-group.module.mjs +4 -4
  41. package/esm2020/lib/components/modal/component/modal/modal.component.mjs +3 -3
  42. package/esm2020/lib/components/modal/component/modal-content/modal-content.component.mjs +3 -3
  43. package/esm2020/lib/components/modal/directives/modal-body/modal-body.directive.mjs +3 -3
  44. package/esm2020/lib/components/modal/directives/modal-footer/modal-footer.directive.mjs +3 -3
  45. package/esm2020/lib/components/modal/directives/modal-header/modal-header.directive.mjs +3 -3
  46. package/esm2020/lib/components/modal/modal.module.mjs +4 -4
  47. package/esm2020/lib/components/modal/service/modal.service.mjs +4 -5
  48. package/esm2020/lib/components/multiselect/component/multiselect.component.mjs +3 -3
  49. package/esm2020/lib/components/multiselect/directives/button-template/button-template.directive.mjs +3 -3
  50. package/esm2020/lib/components/multiselect/directives/footer-template/footer-template.directive.mjs +3 -3
  51. package/esm2020/lib/components/multiselect/directives/header-template/header-template.directive.mjs +3 -3
  52. package/esm2020/lib/components/multiselect/multiselect.module.mjs +4 -4
  53. package/esm2020/lib/components/navbar/dropdown-toggle/dropdown-toggle.directive.mjs +3 -3
  54. package/esm2020/lib/components/navbar/expand-button/expand-button.directive.mjs +3 -3
  55. package/esm2020/lib/components/navbar/nav-link/nav-link.directive.mjs +3 -3
  56. package/esm2020/lib/components/navbar/navbar/navbar.component.mjs +3 -3
  57. package/esm2020/lib/components/navbar/navbar-brand/navbar-brand.component.mjs +3 -3
  58. package/esm2020/lib/components/navbar/navbar-content/navbar-content.directive.mjs +3 -3
  59. package/esm2020/lib/components/navbar/navbar-dropdown/navbar-dropdown.component.mjs +3 -3
  60. package/esm2020/lib/components/navbar/navbar-item/navbar-item.component.mjs +3 -3
  61. package/esm2020/lib/components/navbar/navbar-nav/navbar-nav.component.mjs +3 -3
  62. package/esm2020/lib/components/navbar/navbar-toggler/navbar-toggler.component.mjs +3 -3
  63. package/esm2020/lib/components/navbar/navbar.module.mjs +4 -4
  64. package/esm2020/lib/components/pagination/pagination/pagination.component.mjs +3 -3
  65. package/esm2020/lib/components/pagination/pagination.module.mjs +4 -4
  66. package/esm2020/lib/components/progress-bar/progress/progress.component.mjs +3 -3
  67. package/esm2020/lib/components/progress-bar/progress-bar/progress-bar.component.mjs +3 -3
  68. package/esm2020/lib/components/progress-bar/progress-bar.module.mjs +4 -4
  69. package/esm2020/lib/components/rating/rating.component.mjs +3 -3
  70. package/esm2020/lib/components/rating/rating.module.mjs +4 -4
  71. package/esm2020/lib/components/scheduler/components/scheduler/scheduler.component.mjs +234 -74
  72. package/esm2020/lib/components/scheduler/interfaces/drag-operation.mjs +1 -1
  73. package/esm2020/lib/components/scheduler/interfaces/preview-event.mjs +2 -0
  74. package/esm2020/lib/components/scheduler/interfaces/scheduler-event-part.mjs +1 -1
  75. package/esm2020/lib/components/scheduler/interfaces/timeline-track.mjs +2 -0
  76. package/esm2020/lib/components/scheduler/pipes/bs-seconds-timespan.pipe/bs-seconds-timespan.pipe.mjs +3 -3
  77. package/esm2020/lib/components/scheduler/pipes/bs-seconds-today-offset/bs-seconds-today-offset.pipe.mjs +3 -3
  78. package/esm2020/lib/components/scheduler/pipes/date-offset/date-offset.pipe.mjs +3 -3
  79. package/esm2020/lib/components/scheduler/pipes/day-of-week/day-of-week.pipe.mjs +3 -3
  80. package/esm2020/lib/components/scheduler/scheduler.module.mjs +4 -4
  81. package/esm2020/lib/components/scheduler/services/timeline/timeline.service.mjs +65 -0
  82. package/esm2020/lib/components/scrollspy/component/scrollspy.component.mjs +3 -3
  83. package/esm2020/lib/components/scrollspy/directives/scrollspy.directive.mjs +3 -3
  84. package/esm2020/lib/components/scrollspy/scrollspy.module.mjs +4 -4
  85. package/esm2020/lib/components/select2/component/select2.component.mjs +3 -3
  86. package/esm2020/lib/components/select2/directive/item-template.directive.mjs +3 -3
  87. package/esm2020/lib/components/select2/select2.module.mjs +4 -4
  88. package/esm2020/lib/components/snackbar/component/snackbar.component.mjs +3 -3
  89. package/esm2020/lib/components/snackbar/directives/snackbar-close/snackbar-close.directive.mjs +3 -3
  90. package/esm2020/lib/components/snackbar/service/snackbar.service.mjs +3 -3
  91. package/esm2020/lib/components/snackbar/snackbar.module.mjs +4 -4
  92. package/esm2020/lib/components/tab-control/tab-control/tab-control.component.mjs +3 -3
  93. package/esm2020/lib/components/tab-control/tab-control.module.mjs +4 -4
  94. package/esm2020/lib/components/tab-control/tab-page/tab-page.component.mjs +3 -3
  95. package/esm2020/lib/components/timepicker/index.mjs +3 -0
  96. package/esm2020/lib/components/timepicker/timepicker.component.mjs +108 -0
  97. package/esm2020/lib/components/timepicker/timepicker.module.mjs +38 -0
  98. package/esm2020/lib/components/toggle-button/toggle-button.component.mjs +3 -3
  99. package/esm2020/lib/components/toggle-button/toggle-button.module.mjs +4 -4
  100. package/esm2020/lib/components/tooltip/component/tooltip.component.mjs +3 -3
  101. package/esm2020/lib/components/tooltip/directive/tooltip.directive.mjs +3 -3
  102. package/esm2020/lib/components/tooltip/tooltip.module.mjs +4 -4
  103. package/esm2020/lib/components/typeahead/typeahead.component.mjs +3 -3
  104. package/esm2020/lib/components/typeahead/typeahead.module.mjs +4 -4
  105. package/esm2020/lib/directives/enhanced-paste/enhanced-paste.directive.mjs +58 -0
  106. package/esm2020/lib/directives/enhanced-paste/enhanced-paste.module.mjs +26 -0
  107. package/esm2020/lib/interfaces/index.mjs +2 -1
  108. package/esm2020/lib/interfaces/number-overflow.mjs +2 -0
  109. package/esm2020/lib/pipes/font-color/font-color.module.mjs +4 -4
  110. package/esm2020/lib/pipes/font-color/font-color.pipe.mjs +3 -3
  111. package/esm2020/lib/pipes/format-bytes/format-bytes.module.mjs +4 -4
  112. package/esm2020/lib/pipes/format-bytes/format-bytes.pipe.mjs +3 -3
  113. package/esm2020/lib/pipes/in-list/in-list.module.mjs +4 -4
  114. package/esm2020/lib/pipes/in-list/in-list.pipe.mjs +3 -3
  115. package/esm2020/lib/pipes/month-name/month-name.module.mjs +4 -4
  116. package/esm2020/lib/pipes/month-name/month-name.pipe.mjs +3 -3
  117. package/esm2020/lib/pipes/uc-first/uc-first.module.mjs +4 -4
  118. package/esm2020/lib/pipes/uc-first/uc-first.pipe.mjs +3 -3
  119. package/esm2020/lib/pipes/weekday-name/weekday-name.module.mjs +4 -4
  120. package/esm2020/lib/pipes/weekday-name/weekday-name.pipe.mjs +3 -3
  121. package/esm2020/lib/services/calendar-month/calendar-month.service.mjs +3 -3
  122. package/esm2020/lib/services/scroll-offset/scroll-offset.service.mjs +3 -3
  123. package/fesm2015/mintplayer-ng-bootstrap.mjs +855 -430
  124. package/fesm2015/mintplayer-ng-bootstrap.mjs.map +1 -1
  125. package/fesm2020/mintplayer-ng-bootstrap.mjs +855 -430
  126. package/fesm2020/mintplayer-ng-bootstrap.mjs.map +1 -1
  127. package/lib/components/index.d.ts +1 -0
  128. package/lib/components/scheduler/components/scheduler/scheduler.component.d.ts +28 -5
  129. package/lib/components/scheduler/interfaces/drag-operation.d.ts +1 -0
  130. package/lib/components/scheduler/interfaces/preview-event.d.ts +4 -0
  131. package/lib/components/scheduler/interfaces/scheduler-event-part.d.ts +1 -1
  132. package/lib/components/scheduler/interfaces/timeline-track.d.ts +5 -0
  133. package/lib/components/scheduler/services/timeline/timeline.service.d.ts +14 -0
  134. package/lib/components/timepicker/index.d.ts +2 -0
  135. package/lib/components/timepicker/timepicker.component.d.ts +21 -0
  136. package/lib/components/timepicker/timepicker.module.d.ts +11 -0
  137. package/lib/directives/enhanced-paste/enhanced-paste.directive.d.ts +14 -0
  138. package/lib/directives/enhanced-paste/enhanced-paste.module.d.ts +8 -0
  139. package/lib/interfaces/index.d.ts +1 -0
  140. package/lib/interfaces/number-overflow.d.ts +5 -0
  141. package/package.json +12 -12
@@ -1,24 +1,33 @@
1
1
  import { Component, EventEmitter, HostListener, Input, Output, QueryList, ViewChildren } from '@angular/core';
2
- import { BehaviorSubject, combineLatest, map, Subject, take, takeUntil } from 'rxjs';
2
+ import { BehaviorSubject, combineLatest, filter, map, Subject, take, takeUntil } from 'rxjs';
3
3
  import { BsCalendarMonthService } from '../../../../services/calendar-month/calendar-month.service';
4
4
  import { EDragOperation } from '../../enums/drag-operation';
5
+ import { BsTimelineService } from '../../services/timeline/timeline.service';
5
6
  import * as i0 from "@angular/core";
6
7
  import * as i1 from "../../../../services/calendar-month/calendar-month.service";
7
- import * as i2 from "@angular/common";
8
- import * as i3 from "../../pipes/bs-seconds-today-offset/bs-seconds-today-offset.pipe";
9
- import * as i4 from "../../pipes/bs-seconds-timespan.pipe/bs-seconds-timespan.pipe";
10
- import * as i5 from "../../pipes/day-of-week/day-of-week.pipe";
8
+ import * as i2 from "../../services/timeline/timeline.service";
9
+ import * as i3 from "@angular/common";
10
+ import * as i4 from "../../pipes/bs-seconds-today-offset/bs-seconds-today-offset.pipe";
11
+ import * as i5 from "../../pipes/bs-seconds-timespan.pipe/bs-seconds-timespan.pipe";
12
+ import * as i6 from "../../pipes/day-of-week/day-of-week.pipe";
11
13
  export class BsSchedulerComponent {
12
- constructor(calendarMonthService) {
14
+ constructor(calendarMonthService, timelineService) {
13
15
  this.calendarMonthService = calendarMonthService;
14
- this.eventPartsForThisWeek$ = new BehaviorSubject([]);
16
+ this.timelineService = timelineService;
17
+ this.events$ = new BehaviorSubject([]);
18
+ this.previewEvent$ = new BehaviorSubject(null);
15
19
  this.timeSlotDuration$ = new BehaviorSubject(1800);
20
+ this.timeSlots$ = new BehaviorSubject([]);
16
21
  this.mouseState$ = new BehaviorSubject(false);
17
22
  this.hoveredTimeSlot$ = new BehaviorSubject(null);
23
+ this.hoveredEvent$ = new BehaviorSubject(null);
18
24
  this.destroyed$ = new Subject();
19
25
  //#region UnitHeight
20
26
  this.unitHeight$ = new BehaviorSubject(40);
21
27
  this.unitHeightChange = new EventEmitter();
28
+ //#endregion
29
+ //#region maxInnerHeight
30
+ this.maxInnerHeight = null;
22
31
  this.operation = null;
23
32
  this.dragStartTimeslot = null;
24
33
  const monday = this.calendarMonthService.getMondayBefore(new Date());
@@ -27,66 +36,97 @@ export class BsSchedulerComponent {
27
36
  weekMonday.setHours(0);
28
37
  weekMonday.setMinutes(0);
29
38
  weekMonday.setSeconds(0);
39
+ weekMonday.setMilliseconds(0);
30
40
  return Array.from(Array(7).keys()).map((x) => this.addDays(weekMonday, x));
31
41
  }));
32
- this.events$ = new BehaviorSubject([]);
33
- this.eventParts$ = this.events$.pipe(map((events) => {
34
- return events.map((ev) => {
35
- let startTime = ev.start;
36
- const result = [];
37
- while (!this.dateEquals(startTime, ev.end)) {
38
- const end = new Date(startTime.getFullYear(), startTime.getMonth(), startTime.getDate() + 1, 0, 0, 0);
39
- result.push({ start: startTime, end: end, event: ev });
40
- startTime = end;
41
- }
42
- if (startTime != ev.end) {
43
- result.push({ start: startTime, end: ev.end, event: ev });
44
- }
45
- return { event: ev, parts: result };
46
- });
42
+ this.daysOfWeekWithTimestamps$ = this.daysOfWeek$
43
+ .pipe(map((daysOfWeek) => {
44
+ return { start: daysOfWeek[0].getTime(), end: daysOfWeek[daysOfWeek.length - 1].getTime() + 24 * 60 * 60 * 1000 };
47
45
  }));
48
- combineLatest([
49
- this.daysOfWeek$
50
- .pipe(map((daysOfWeek) => {
51
- return { start: daysOfWeek[0].getTime(), end: daysOfWeek[daysOfWeek.length - 1].getTime() + 24 * 60 * 60 * 1000 };
52
- })),
46
+ this.eventParts$ = this.events$.pipe(map((events) => events.map((ev) => this.timelineService.splitInParts(ev))));
47
+ this.eventPartsForThisWeek$ = combineLatest([
48
+ this.daysOfWeekWithTimestamps$,
53
49
  this.eventParts$
54
50
  .pipe(map(eventParts => eventParts.map(evp => evp.parts)))
55
51
  .pipe(map(jaggedParts => {
56
52
  return jaggedParts.reduce((flat, toFlatten) => flat.concat(toFlatten), []);
57
- })),
58
- this.eventParts$
53
+ }))
59
54
  ])
60
- .pipe(map(([startAndEnd, eventParts, originalEventParts]) => {
55
+ .pipe(map(([startAndEnd, eventParts]) => {
61
56
  return eventParts.filter(eventPart => {
62
- return !((eventPart.end.getTime() < startAndEnd.start) || (eventPart.start.getTime() > startAndEnd.end));
57
+ return !((eventPart.end.getTime() <= startAndEnd.start) || (eventPart.start.getTime() >= startAndEnd.end));
63
58
  });
64
- }))
65
- .pipe(takeUntil(this.destroyed$))
66
- .subscribe((eventPartsForThisWeek) => {
67
- this.eventPartsForThisWeek$.next(eventPartsForThisWeek);
68
- });
69
- this.timeSlots$ = combineLatest([this.daysOfWeek$, this.timeSlotDuration$])
59
+ }));
60
+ this.previewEventParts$ = this.previewEvent$.pipe(map((event) => {
61
+ if (event) {
62
+ return this.timelineService.splitInParts(event);
63
+ }
64
+ else {
65
+ return null;
66
+ }
67
+ }));
68
+ this.previewEventPartsForThisWeek$ = combineLatest([this.daysOfWeekWithTimestamps$, this.previewEventParts$])
69
+ .pipe(map(([startAndEnd, previewEventParts]) => {
70
+ if (previewEventParts) {
71
+ return previewEventParts.parts.filter(eventPart => {
72
+ return !((eventPart.end.getTime() <= startAndEnd.start) || (eventPart.start.getTime() >= startAndEnd.end));
73
+ });
74
+ }
75
+ else {
76
+ return [];
77
+ }
78
+ }));
79
+ this.timelinedEventPartsForThisWeek$ = this.eventPartsForThisWeek$
80
+ .pipe(map(eventParts => {
81
+ // We'll only use the events for this week
82
+ const events = eventParts.map(ep => ep.event)
83
+ .filter((e, i, list) => list.indexOf(e) === i)
84
+ .filter((e) => !!e)
85
+ .map((e) => e);
86
+ const timeline = this.timelineService.getTimeline(events);
87
+ const result = timeline.map(track => {
88
+ return track.events.map(ev => {
89
+ return { event: ev, index: track.index };
90
+ });
91
+ })
92
+ .reduce((flat, toFlatten) => flat.concat(toFlatten), [])
93
+ .map((evi) => eventParts.filter(p => p.event === evi.event).map(p => {
94
+ return { part: p, index: evi.index };
95
+ }))
96
+ .reduce((flat, toFlatten) => flat.concat(toFlatten), []);
97
+ return {
98
+ total: timeline.length,
99
+ parts: result
100
+ };
101
+ }));
102
+ combineLatest([this.daysOfWeek$, this.timeSlotDuration$])
70
103
  .pipe(map(([daysOfWeek, duration]) => {
71
104
  const timeSlotsPerDay = Math.floor((60 * 60 * 24) / duration);
72
105
  return Array.from(Array(timeSlotsPerDay).keys()).map((index) => {
73
106
  const timeSlotStart = new Date(daysOfWeek[0]);
74
- timeSlotStart.setSeconds(timeSlotStart.getSeconds() + index * duration);
107
+ timeSlotStart.setTime(+timeSlotStart.getTime() + index * duration * 1000);
75
108
  const timeSlotEnd = new Date(timeSlotStart);
76
- timeSlotEnd.setSeconds(timeSlotEnd.getSeconds() + duration);
109
+ timeSlotEnd.setTime(+timeSlotEnd.getTime() + duration * 1000);
77
110
  return daysOfWeek.map((day) => {
78
111
  const start = new Date(day);
79
112
  start.setHours(timeSlotStart.getHours());
80
113
  start.setMinutes(timeSlotStart.getMinutes());
81
114
  start.setSeconds(timeSlotStart.getSeconds());
115
+ start.setMilliseconds(timeSlotStart.getMilliseconds());
82
116
  const end = new Date(day);
83
117
  end.setHours(timeSlotEnd.getHours());
84
118
  end.setMinutes(timeSlotEnd.getMinutes());
85
119
  end.setSeconds(timeSlotEnd.getSeconds());
120
+ end.setMilliseconds(timeSlotEnd.getMilliseconds());
121
+ end.setDate(end.getDate() + timeSlotEnd.getDate() - timeSlotStart.getDate());
86
122
  return { start, end };
87
123
  });
88
124
  });
89
- }));
125
+ }))
126
+ .subscribe((timeslots) => {
127
+ // For performance reasons, we're not using an observable here, but persist the timeslots in a BehaviorSubject.
128
+ this.timeSlots$.next(timeslots);
129
+ });
90
130
  this.unitHeight$
91
131
  .pipe(takeUntil(this.destroyed$))
92
132
  .subscribe((unitHeight) => {
@@ -100,11 +140,6 @@ export class BsSchedulerComponent {
100
140
  this.unitHeight$.next(value);
101
141
  }
102
142
  //#endregion
103
- dateEquals(date1, date2) {
104
- return (date1.getFullYear() === date2.getFullYear() &&
105
- date1.getMonth() === date2.getMonth() &&
106
- date1.getDate() === date2.getDate());
107
- }
108
143
  addDays(date, days) {
109
144
  const result = new Date(date);
110
145
  result.setDate(result.getDate() + days);
@@ -120,6 +155,13 @@ export class BsSchedulerComponent {
120
155
  .pipe(map((w) => this.addDays(w, 7)), take(1))
121
156
  .subscribe((w) => this.currentWeek$.next(w));
122
157
  }
158
+ onHoverEvent(ev) {
159
+ console.log('hovered', ev);
160
+ this.hoveredEvent$.next(ev);
161
+ }
162
+ onLeaveEvent(ev) {
163
+ this.hoveredEvent$.next(null);
164
+ }
123
165
  onCreateEvent(ev, slot) {
124
166
  ev.preventDefault();
125
167
  this.mouseState$.next(true);
@@ -131,20 +173,61 @@ export class BsSchedulerComponent {
131
173
  end: slot.end,
132
174
  color: '#F00',
133
175
  description: 'Test event',
134
- }
176
+ },
177
+ meta: null,
135
178
  };
136
- this.events$.next([...this.events$.value, this.operation.event]);
179
+ this.previewEvent$.next({ start: slot.start, end: slot.end });
180
+ }
181
+ randomColor() {
182
+ const brightness = 128;
183
+ return '#' + this.randomChannel(brightness) + this.randomChannel(brightness) + this.randomChannel(brightness);
184
+ }
185
+ randomChannel(brightness) {
186
+ const r = 255 - brightness;
187
+ const n = 0 | ((Math.random() * r) + brightness);
188
+ const s = n.toString(16);
189
+ return (s.length == 1) ? '0' + s : s;
137
190
  }
138
191
  onStartDragEvent(eventPart, ev) {
139
192
  ev.preventDefault();
140
193
  this.hoveredTimeSlot$.pipe(take(1)).subscribe((hoveredTimeSlot) => {
141
- this.dragStartTimeslot = hoveredTimeSlot;
142
- this.operation = {
143
- operation: EDragOperation.moveEvent,
144
- event: eventPart.event
145
- };
194
+ if (eventPart.event) {
195
+ this.dragStartTimeslot = hoveredTimeSlot;
196
+ this.operation = {
197
+ operation: EDragOperation.moveEvent,
198
+ event: eventPart.event,
199
+ meta: null,
200
+ };
201
+ this.previewEvent$.next({ start: eventPart.event.start, end: eventPart.event.end });
202
+ }
146
203
  });
147
204
  }
205
+ onStartResizeEvent(event, position) {
206
+ if (event) {
207
+ switch (position) {
208
+ case 'top':
209
+ {
210
+ this.operation = {
211
+ operation: EDragOperation.resizeEvent,
212
+ event: event,
213
+ meta: { position },
214
+ };
215
+ this.previewEvent$.next({ start: event.start, end: event.end });
216
+ }
217
+ break;
218
+ case 'bottom':
219
+ {
220
+ this.operation = {
221
+ operation: EDragOperation.resizeEvent,
222
+ event: event,
223
+ meta: { position },
224
+ };
225
+ this.previewEvent$.next({ start: event.start, end: event.end });
226
+ }
227
+ break;
228
+ }
229
+ }
230
+ }
148
231
  //#region hoveredTimeslot$
149
232
  getHoveredTimeslot(ev, timeSlots) {
150
233
  const hoveredSlots = this.timeSlotElements.filter((el) => {
@@ -187,15 +270,31 @@ export class BsSchedulerComponent {
187
270
  }
188
271
  else if (this.dragStartTimeslot.start.getTime() < hovered.start.getTime()) {
189
272
  // Drag down
190
- this.operation.event.start = this.dragStartTimeslot.start;
191
- this.operation.event.end = hovered.end;
192
- this.events$.next(this.events$.value);
273
+ this.previewEvent$
274
+ .pipe(filter((ev) => !!ev && !!this.dragStartTimeslot))
275
+ .pipe(map((ev) => {
276
+ if (ev && this.dragStartTimeslot) {
277
+ ev.start = this.dragStartTimeslot.start;
278
+ ev.end = hovered.end;
279
+ }
280
+ return ev;
281
+ }))
282
+ .pipe(take(1))
283
+ .subscribe((ev) => this.previewEvent$.next(ev));
193
284
  }
194
285
  else if (this.dragStartTimeslot.start.getTime() > hovered.start.getTime()) {
195
286
  // Drag up
196
- this.operation.event.start = hovered.start;
197
- this.operation.event.end = this.dragStartTimeslot.end;
198
- this.events$.next(this.events$.value);
287
+ this.previewEvent$
288
+ .pipe(filter((ev) => !!ev && !!this.dragStartTimeslot))
289
+ .pipe(map((ev) => {
290
+ if (ev && this.dragStartTimeslot) {
291
+ ev.start = hovered.start;
292
+ ev.end = this.dragStartTimeslot.end;
293
+ }
294
+ return ev;
295
+ }))
296
+ .pipe(take(1))
297
+ .subscribe((ev) => this.previewEvent$.next(ev));
199
298
  }
200
299
  }
201
300
  }
@@ -203,10 +302,46 @@ export class BsSchedulerComponent {
203
302
  case EDragOperation.moveEvent:
204
303
  {
205
304
  if (hovered && this.dragStartTimeslot) {
206
- this.operation.event.start.setTime(this.operation.event.start.getTime() + hovered.start.getTime() - this.dragStartTimeslot.start.getTime());
207
- this.operation.event.end.setTime(this.operation.event.end.getTime() + hovered.start.getTime() - this.dragStartTimeslot.start.getTime());
208
- this.dragStartTimeslot = hovered;
209
- this.events$.next(this.events$.value);
305
+ this.previewEvent$
306
+ .pipe(filter((ev) => !!ev && !!this.dragStartTimeslot))
307
+ .pipe(map((ev) => {
308
+ if (ev && this.dragStartTimeslot) {
309
+ const result = {
310
+ start: new Date(ev.start.getTime() + hovered.start.getTime() - this.dragStartTimeslot.start.getTime()),
311
+ end: new Date(ev.end.getTime() + hovered.start.getTime() - this.dragStartTimeslot.start.getTime())
312
+ };
313
+ this.dragStartTimeslot = hovered;
314
+ return result;
315
+ }
316
+ else {
317
+ return ev;
318
+ }
319
+ }))
320
+ .pipe(take(1))
321
+ .subscribe(ev => this.previewEvent$.next(ev));
322
+ }
323
+ }
324
+ break;
325
+ case EDragOperation.resizeEvent:
326
+ {
327
+ if (hovered) {
328
+ this.previewEvent$
329
+ .pipe(filter((ev) => !!ev))
330
+ .pipe(map((ev) => {
331
+ if (ev && this.operation && this.operation.event) {
332
+ if (this.operation.meta.position === 'top') {
333
+ ev.start = hovered.start;
334
+ ev.end = this.operation.event.end;
335
+ }
336
+ else if (this.operation.meta.position === 'bottom') {
337
+ ev.start = this.operation.event.start;
338
+ ev.end = hovered.end;
339
+ }
340
+ }
341
+ return ev;
342
+ }))
343
+ .pipe(take(1))
344
+ .subscribe((ev) => this.previewEvent$.next(ev));
210
345
  }
211
346
  }
212
347
  break;
@@ -220,16 +355,39 @@ export class BsSchedulerComponent {
220
355
  switch (this.operation.operation) {
221
356
  case EDragOperation.createEvent:
222
357
  {
223
- if (this.operation.event) {
224
- this.operation = null;
225
- this.dragStartTimeslot = null;
226
- }
358
+ combineLatest([this.previewEvent$])
359
+ .pipe(take(1))
360
+ .subscribe(([previewEvent]) => {
361
+ if (previewEvent) {
362
+ this.operation = null;
363
+ this.dragStartTimeslot = null;
364
+ this.events$.next([...this.events$.value, {
365
+ start: previewEvent.start,
366
+ end: previewEvent.end,
367
+ color: this.randomColor(),
368
+ description: 'New event'
369
+ }]);
370
+ this.previewEvent$.next(null);
371
+ }
372
+ });
227
373
  }
228
374
  break;
229
375
  case EDragOperation.moveEvent:
376
+ case EDragOperation.resizeEvent:
230
377
  {
231
- this.operation = null;
232
- this.dragStartTimeslot = null;
378
+ this.previewEvent$
379
+ .pipe(filter((ev) => !!ev))
380
+ .pipe(take(1))
381
+ .subscribe((previewEvent) => {
382
+ if (this.operation && this.operation.event && previewEvent) {
383
+ this.operation.event.start = previewEvent.start;
384
+ this.operation.event.end = previewEvent.end;
385
+ this.operation = null;
386
+ this.dragStartTimeslot = null;
387
+ this.events$.next(this.events$.value);
388
+ this.previewEvent$.next(null);
389
+ }
390
+ });
233
391
  }
234
392
  break;
235
393
  }
@@ -239,18 +397,20 @@ export class BsSchedulerComponent {
239
397
  this.destroyed$.next(true);
240
398
  }
241
399
  }
242
- BsSchedulerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BsSchedulerComponent, deps: [{ token: i1.BsCalendarMonthService }], target: i0.ɵɵFactoryTarget.Component });
243
- BsSchedulerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: BsSchedulerComponent, selector: "bs-scheduler", inputs: { unitHeight: "unitHeight" }, outputs: { unitHeightChange: "unitHeightChange" }, host: { listeners: { "document:mousemove": "onMousemove($event)", "document:mouseup": "onMouseUp($event)" } }, viewQueries: [{ propertyName: "timeSlotElements", predicate: ["slot"], descendants: true }], ngImport: i0, template: "{{ unitHeight$ | async }}\n<div class=\"table d-flex w-100 overflow-y-auto\" [style.max-height.px]=\"400\">\n <div class=\"calendar-head\">\n <div class=\"w-100 d-flex flex-row\">\n <div class=\"d-flex calendar-left justify-content-between\">\n <button class=\"btn btn-default flex-start\" (click)=\"onPreviousWeek()\">&lt;</button>\n <button class=\"btn btn-default flex-end\" (click)=\"onNextWeek()\">&gt;</button>\n </div>\n <div class=\"flex-grow-1\" *ngFor=\"let day of (daysOfWeek$ | async)\">\n <span class=\"d-block col-form-label text-center\">\n {{ day | date: 'dd-MM-yyyy' }}\n </span>\n </div>\n </div>\n </div>\n <div class=\"calendar-body\">\n <div class=\"position-relative\">\n <!-- Timeslots -->\n <div *ngFor=\"let timeslots of (timeSlots$ | async); let i = index\" class=\"d-flex flex-row p-0 timeslot\" [style.height.px]=\"unitHeight$ | async\">\n <div class=\"calendar-cell calendar-left align-top py-0\">{{ timeslots[0].start | date: 'HH:mm:ss' }}</div>\n <div class=\"calendar-cell flex-grow-1\" *ngFor=\"let slot of timeslots; let j = index\" #slot (mousedown)=\"onCreateEvent($event, slot)\" [attr.data-row]=\"i\" [attr.data-column]=\"j\"></div>\n </div>\n \n <!-- Events -->\n <ng-container *ngIf=\"(timeSlotDuration$ | async) as timeSlotDuration\">\n\n <div *ngFor=\"let eventPart of (eventPartsForThisWeek$ | async)\" class=\"position-absolute event\"\n [style.top.px]=\"(eventPart | bsSecondsTodayOffset) / timeSlotDuration * (unitHeight$ | async)!\"\n [style.height.px]=\"(eventPart | bsSecondsTimespan) / timeSlotDuration * (unitHeight$ | async)!\"\n [style.left]=\"'calc(90px + ((100% - 90px) / 7 * ' + ((eventPart | dayOfWeek) - 1) + '))'\">\n <div class=\"event-inner\" [style.background-color]=\"eventPart.event.color\" (mousedown)=\"onStartDragEvent(eventPart, $event)\">\n {{ eventPart.event.description }}\n <br>\n {{ eventPart.start | date: 'HH:mm:ss' }}\n <br>\n {{ eventPart.end | date: 'HH:mm:ss' }}\n </div>\n </div>\n \n <!-- <ng-container *ngFor=\"let eventWithParts of (eventParts$ | async)\">\n <div *ngFor=\"let eventPart of eventWithParts.parts\" class=\"position-absolute event\"\n [style.top.px]=\"(eventPart | bsSecondsTodayOffset) / timeSlotDuration * 40\"\n [style.height.px]=\"(eventPart | bsSecondsTimespan) / timeSlotDuration * 40\"\n [style.left]=\"'calc(90px + ((100% - 90px) / 7 * ' + ((eventPart | dayOfWeek) - 1) + '))'\">\n <div class=\"event-inner\">\n {{ eventPart.start | date: 'HH:mm:ss' }} - {{ eventPart.end | date: 'HH:mm:ss' }}\n </div>\n </div>\n </ng-container> -->\n \n </ng-container>\n </div>\n </div>\n</div>", styles: [":host{display:block}.table{flex-flow:column}.table .calendar-head{flex:0 0 auto}.table .calendar-head>div{padding-right:18px}.table .calendar-body{flex:1 1 auto;display:block;overflow-y:visible;overflow-x:hidden}.table .calendar-body .calendar-cell{border-right:1px solid #DEE2E6;border-bottom:1px solid #DEE2E6;cursor:default}.table .calendar-body .calendar-cell.hover{border-top-width:3px}.table .calendar-left{width:90px}.event{z-index:5;width:calc((100% - 90px) / 7);height:100px;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none}.event .event-inner{position:absolute;left:4px;right:5px;top:4px;bottom:5px;cursor:move}\n"], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i2.AsyncPipe, "date": i2.DatePipe, "bsSecondsTodayOffset": i3.BsSecondsTodayOffsetPipe, "bsSecondsTimespan": i4.BsSecondsTimespanPipe, "dayOfWeek": i5.DayOfWeekPipe } });
244
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BsSchedulerComponent, decorators: [{
400
+ BsSchedulerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.0", ngImport: i0, type: BsSchedulerComponent, deps: [{ token: i1.BsCalendarMonthService }, { token: i2.BsTimelineService }], target: i0.ɵɵFactoryTarget.Component });
401
+ BsSchedulerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.0", type: BsSchedulerComponent, selector: "bs-scheduler", inputs: { unitHeight: "unitHeight", maxInnerHeight: "maxInnerHeight" }, outputs: { unitHeightChange: "unitHeightChange" }, host: { listeners: { "document:mousemove": "onMousemove($event)", "document:mouseup": "onMouseUp($event)" } }, viewQueries: [{ propertyName: "timeSlotElements", predicate: ["slot"], descendants: true }], ngImport: i0, template: "<div class=\"table d-flex w-100 overflow-y-auto\" [style.max-height.px]=\"null\">\n <div class=\"calendar-head\">\n <div class=\"w-100 d-flex flex-row\">\n <div class=\"d-flex calendar-left justify-content-between\">\n <button class=\"btn btn-default flex-start\" (click)=\"onPreviousWeek()\">&lt;</button>\n <button class=\"btn btn-default flex-end\" (click)=\"onNextWeek()\">&gt;</button>\n </div>\n <div class=\"flex-grow-1 calendar-head-cell\" *ngFor=\"let day of (daysOfWeek$ | async)\">\n <span class=\"d-block col-form-label text-center\">\n <span>{{ day | date: 'dd-MM' }}</span><span class=\"d-none d-lg-inline-block\">-{{ day | date: 'yyyy' }}</span>\n </span>\n </div>\n </div>\n </div>\n <div class=\"calendar-body\" [style.height.px]=\"maxInnerHeight\">\n <div class=\"position-relative\">\n <!-- Timeslots -->\n <div *ngFor=\"let timeslots of (timeSlots$ | async); let i = index\" class=\"d-flex flex-row p-0 timeslot\" [style.height.px]=\"unitHeight$ | async\">\n <div class=\"calendar-cell calendar-left align-top px-2 py-0\">{{ timeslots[0].start | date: 'HH:mm:ss' }}</div>\n <div class=\"calendar-cell flex-grow-1\" *ngFor=\"let slot of timeslots; let j = index\" #slot (mousedown)=\"onCreateEvent($event, slot)\" [attr.data-row]=\"i\" [attr.data-column]=\"j\"></div>\n </div>\n \n <!-- Events -->\n <ng-container *ngIf=\"(timeSlotDuration$ | async) as timeSlotDuration\">\n <ng-container *ngIf=\"(unitHeight$ | async) as unitHeight\">\n <ng-container *ngIf=\"(timelinedEventPartsForThisWeek$ | async) as partData\">\n <div *ngFor=\"let eventPart of partData.parts\" class=\"event p-0\"\n [style.top.px]=\"(eventPart.part | bsSecondsTodayOffset) / timeSlotDuration * unitHeight\"\n [style.height.px]=\"(eventPart.part | bsSecondsTimespan) / timeSlotDuration * unitHeight\"\n [style.left]=\"'calc(90px + ((100% - 90px) / 7 * ' + ((eventPart.part | dayOfWeek) - 1) + '))'\">\n <div class=\"event-inner\"\n [class.hover]=\"(hoveredEvent$ | async) === eventPart.part.event\"\n [style.width]=\"'calc(100% / ' + partData.total + ')'\"\n [style.height.px]=\"(eventPart.part | bsSecondsTimespan) / timeSlotDuration * unitHeight\"\n [style.margin-left]=\"'calc(100% / ' + partData.total + ' * ' + eventPart.index + ')'\">\n\n <div class=\"event-resize top\" *ngIf=\"eventPart.part.start === eventPart.part.event?.start\" (mousedown)=\"onStartResizeEvent(eventPart.part.event, 'top')\"></div>\n <div class=\"event-border\"></div>\n <div class=\"event-wrapper\" *ngIf=\"eventPart.part.event\"\n (mousedown)=\"onStartDragEvent(eventPart.part, $event)\"\n (mouseenter)=\"onHoverEvent(eventPart.part.event)\"\n (mouseleave)=\"onLeaveEvent(eventPart.part.event)\">\n <div class=\"event-bg\" [style.background-color]=\"eventPart.part.event.color\"></div>\n <div class=\"event-label\">{{ eventPart.part.event.description }}</div>\n </div>\n <div class=\"event-resize bottom\" *ngIf=\"eventPart.part.end === eventPart.part.event?.end\" (mousedown)=\"onStartResizeEvent(eventPart.part.event, 'bottom')\"></div>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"(previewEventPartsForThisWeek$ | async) as previewPartData\">\n <div *ngFor=\"let eventPart of previewPartData\" class=\"event preview p-0\"\n [style.top.px]=\"(eventPart | bsSecondsTodayOffset) / timeSlotDuration * unitHeight\"\n [style.height.px]=\"(eventPart | bsSecondsTimespan) / timeSlotDuration * unitHeight\"\n [style.left]=\"'calc(90px + ((100% - 90px) / 7 * ' + ((eventPart | dayOfWeek) - 1) + '))'\">\n <div class=\"event-inner w-100\" [style.height.px]=\"(eventPart | bsSecondsTimespan) / timeSlotDuration * unitHeight\"></div>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n</div>", styles: [":host{display:block}.table{flex-flow:column}.table .calendar-head{flex:0 0 auto}.table .calendar-head>div{padding-right:18px}.table .calendar-body{flex:1 1 auto;display:block;overflow-y:scroll;overflow-x:hidden}.table .calendar-body .calendar-cell{border-right:1px solid #DEE2E6;border-bottom:1px solid #DEE2E6;cursor:default}.table .calendar-body .calendar-cell.hover{border-top-width:3px}.table .calendar-left{width:90px}.event{z-index:5;width:calc((100% - 90px) / 7);height:100px;overflow:hidden;position:absolute;-webkit-user-select:none;user-select:none;pointer-events:none}.event.preview{background:#666;opacity:.6}.event .event-border{background:black;top:0;left:0;bottom:3px;width:3px;position:absolute;z-index:10;opacity:.3}.event .event-inner{position:relative;left:0px;right:5px;top:0px;bottom:5px;cursor:move;pointer-events:all;overflow:hidden}.event .event-inner .event-wrapper{width:calc(100% - 2px);margin:1px auto 1px 0;height:calc(100% - 3px)}.event .event-inner .event-wrapper .event-bg{opacity:.5;height:100%;transition:opacity .15s ease-in-out}.event .event-inner .event-wrapper .event-label{position:absolute;top:0;font-size:12px;font-weight:600;padding:4px}.event .event-inner .event-resize{position:absolute;cursor:ns-resize;height:4px;left:0;right:0;z-index:400}.event .event-inner .event-resize.top{top:0}.event .event-inner .event-resize.bottom{bottom:0}.event .event-inner .event-resize:hover{background:#DDD}.event .event-inner.hover .event-bg{opacity:.7!important}@media (max-width: 767px){.table .calendar-head .calendar-head-cell{text-orientation:sideways;writing-mode:vertical-rl}}\n"], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i3.AsyncPipe, "date": i3.DatePipe, "bsSecondsTodayOffset": i4.BsSecondsTodayOffsetPipe, "bsSecondsTimespan": i5.BsSecondsTimespanPipe, "dayOfWeek": i6.DayOfWeekPipe } });
402
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.0", ngImport: i0, type: BsSchedulerComponent, decorators: [{
245
403
  type: Component,
246
- args: [{ selector: 'bs-scheduler', template: "{{ unitHeight$ | async }}\n<div class=\"table d-flex w-100 overflow-y-auto\" [style.max-height.px]=\"400\">\n <div class=\"calendar-head\">\n <div class=\"w-100 d-flex flex-row\">\n <div class=\"d-flex calendar-left justify-content-between\">\n <button class=\"btn btn-default flex-start\" (click)=\"onPreviousWeek()\">&lt;</button>\n <button class=\"btn btn-default flex-end\" (click)=\"onNextWeek()\">&gt;</button>\n </div>\n <div class=\"flex-grow-1\" *ngFor=\"let day of (daysOfWeek$ | async)\">\n <span class=\"d-block col-form-label text-center\">\n {{ day | date: 'dd-MM-yyyy' }}\n </span>\n </div>\n </div>\n </div>\n <div class=\"calendar-body\">\n <div class=\"position-relative\">\n <!-- Timeslots -->\n <div *ngFor=\"let timeslots of (timeSlots$ | async); let i = index\" class=\"d-flex flex-row p-0 timeslot\" [style.height.px]=\"unitHeight$ | async\">\n <div class=\"calendar-cell calendar-left align-top py-0\">{{ timeslots[0].start | date: 'HH:mm:ss' }}</div>\n <div class=\"calendar-cell flex-grow-1\" *ngFor=\"let slot of timeslots; let j = index\" #slot (mousedown)=\"onCreateEvent($event, slot)\" [attr.data-row]=\"i\" [attr.data-column]=\"j\"></div>\n </div>\n \n <!-- Events -->\n <ng-container *ngIf=\"(timeSlotDuration$ | async) as timeSlotDuration\">\n\n <div *ngFor=\"let eventPart of (eventPartsForThisWeek$ | async)\" class=\"position-absolute event\"\n [style.top.px]=\"(eventPart | bsSecondsTodayOffset) / timeSlotDuration * (unitHeight$ | async)!\"\n [style.height.px]=\"(eventPart | bsSecondsTimespan) / timeSlotDuration * (unitHeight$ | async)!\"\n [style.left]=\"'calc(90px + ((100% - 90px) / 7 * ' + ((eventPart | dayOfWeek) - 1) + '))'\">\n <div class=\"event-inner\" [style.background-color]=\"eventPart.event.color\" (mousedown)=\"onStartDragEvent(eventPart, $event)\">\n {{ eventPart.event.description }}\n <br>\n {{ eventPart.start | date: 'HH:mm:ss' }}\n <br>\n {{ eventPart.end | date: 'HH:mm:ss' }}\n </div>\n </div>\n \n <!-- <ng-container *ngFor=\"let eventWithParts of (eventParts$ | async)\">\n <div *ngFor=\"let eventPart of eventWithParts.parts\" class=\"position-absolute event\"\n [style.top.px]=\"(eventPart | bsSecondsTodayOffset) / timeSlotDuration * 40\"\n [style.height.px]=\"(eventPart | bsSecondsTimespan) / timeSlotDuration * 40\"\n [style.left]=\"'calc(90px + ((100% - 90px) / 7 * ' + ((eventPart | dayOfWeek) - 1) + '))'\">\n <div class=\"event-inner\">\n {{ eventPart.start | date: 'HH:mm:ss' }} - {{ eventPart.end | date: 'HH:mm:ss' }}\n </div>\n </div>\n </ng-container> -->\n \n </ng-container>\n </div>\n </div>\n</div>", styles: [":host{display:block}.table{flex-flow:column}.table .calendar-head{flex:0 0 auto}.table .calendar-head>div{padding-right:18px}.table .calendar-body{flex:1 1 auto;display:block;overflow-y:visible;overflow-x:hidden}.table .calendar-body .calendar-cell{border-right:1px solid #DEE2E6;border-bottom:1px solid #DEE2E6;cursor:default}.table .calendar-body .calendar-cell.hover{border-top-width:3px}.table .calendar-left{width:90px}.event{z-index:5;width:calc((100% - 90px) / 7);height:100px;overflow:hidden;position:relative;-webkit-user-select:none;user-select:none}.event .event-inner{position:absolute;left:4px;right:5px;top:4px;bottom:5px;cursor:move}\n"] }]
247
- }], ctorParameters: function () { return [{ type: i1.BsCalendarMonthService }]; }, propDecorators: { timeSlotElements: [{
404
+ args: [{ selector: 'bs-scheduler', template: "<div class=\"table d-flex w-100 overflow-y-auto\" [style.max-height.px]=\"null\">\n <div class=\"calendar-head\">\n <div class=\"w-100 d-flex flex-row\">\n <div class=\"d-flex calendar-left justify-content-between\">\n <button class=\"btn btn-default flex-start\" (click)=\"onPreviousWeek()\">&lt;</button>\n <button class=\"btn btn-default flex-end\" (click)=\"onNextWeek()\">&gt;</button>\n </div>\n <div class=\"flex-grow-1 calendar-head-cell\" *ngFor=\"let day of (daysOfWeek$ | async)\">\n <span class=\"d-block col-form-label text-center\">\n <span>{{ day | date: 'dd-MM' }}</span><span class=\"d-none d-lg-inline-block\">-{{ day | date: 'yyyy' }}</span>\n </span>\n </div>\n </div>\n </div>\n <div class=\"calendar-body\" [style.height.px]=\"maxInnerHeight\">\n <div class=\"position-relative\">\n <!-- Timeslots -->\n <div *ngFor=\"let timeslots of (timeSlots$ | async); let i = index\" class=\"d-flex flex-row p-0 timeslot\" [style.height.px]=\"unitHeight$ | async\">\n <div class=\"calendar-cell calendar-left align-top px-2 py-0\">{{ timeslots[0].start | date: 'HH:mm:ss' }}</div>\n <div class=\"calendar-cell flex-grow-1\" *ngFor=\"let slot of timeslots; let j = index\" #slot (mousedown)=\"onCreateEvent($event, slot)\" [attr.data-row]=\"i\" [attr.data-column]=\"j\"></div>\n </div>\n \n <!-- Events -->\n <ng-container *ngIf=\"(timeSlotDuration$ | async) as timeSlotDuration\">\n <ng-container *ngIf=\"(unitHeight$ | async) as unitHeight\">\n <ng-container *ngIf=\"(timelinedEventPartsForThisWeek$ | async) as partData\">\n <div *ngFor=\"let eventPart of partData.parts\" class=\"event p-0\"\n [style.top.px]=\"(eventPart.part | bsSecondsTodayOffset) / timeSlotDuration * unitHeight\"\n [style.height.px]=\"(eventPart.part | bsSecondsTimespan) / timeSlotDuration * unitHeight\"\n [style.left]=\"'calc(90px + ((100% - 90px) / 7 * ' + ((eventPart.part | dayOfWeek) - 1) + '))'\">\n <div class=\"event-inner\"\n [class.hover]=\"(hoveredEvent$ | async) === eventPart.part.event\"\n [style.width]=\"'calc(100% / ' + partData.total + ')'\"\n [style.height.px]=\"(eventPart.part | bsSecondsTimespan) / timeSlotDuration * unitHeight\"\n [style.margin-left]=\"'calc(100% / ' + partData.total + ' * ' + eventPart.index + ')'\">\n\n <div class=\"event-resize top\" *ngIf=\"eventPart.part.start === eventPart.part.event?.start\" (mousedown)=\"onStartResizeEvent(eventPart.part.event, 'top')\"></div>\n <div class=\"event-border\"></div>\n <div class=\"event-wrapper\" *ngIf=\"eventPart.part.event\"\n (mousedown)=\"onStartDragEvent(eventPart.part, $event)\"\n (mouseenter)=\"onHoverEvent(eventPart.part.event)\"\n (mouseleave)=\"onLeaveEvent(eventPart.part.event)\">\n <div class=\"event-bg\" [style.background-color]=\"eventPart.part.event.color\"></div>\n <div class=\"event-label\">{{ eventPart.part.event.description }}</div>\n </div>\n <div class=\"event-resize bottom\" *ngIf=\"eventPart.part.end === eventPart.part.event?.end\" (mousedown)=\"onStartResizeEvent(eventPart.part.event, 'bottom')\"></div>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"(previewEventPartsForThisWeek$ | async) as previewPartData\">\n <div *ngFor=\"let eventPart of previewPartData\" class=\"event preview p-0\"\n [style.top.px]=\"(eventPart | bsSecondsTodayOffset) / timeSlotDuration * unitHeight\"\n [style.height.px]=\"(eventPart | bsSecondsTimespan) / timeSlotDuration * unitHeight\"\n [style.left]=\"'calc(90px + ((100% - 90px) / 7 * ' + ((eventPart | dayOfWeek) - 1) + '))'\">\n <div class=\"event-inner w-100\" [style.height.px]=\"(eventPart | bsSecondsTimespan) / timeSlotDuration * unitHeight\"></div>\n </div>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n </div>\n</div>", styles: [":host{display:block}.table{flex-flow:column}.table .calendar-head{flex:0 0 auto}.table .calendar-head>div{padding-right:18px}.table .calendar-body{flex:1 1 auto;display:block;overflow-y:scroll;overflow-x:hidden}.table .calendar-body .calendar-cell{border-right:1px solid #DEE2E6;border-bottom:1px solid #DEE2E6;cursor:default}.table .calendar-body .calendar-cell.hover{border-top-width:3px}.table .calendar-left{width:90px}.event{z-index:5;width:calc((100% - 90px) / 7);height:100px;overflow:hidden;position:absolute;-webkit-user-select:none;user-select:none;pointer-events:none}.event.preview{background:#666;opacity:.6}.event .event-border{background:black;top:0;left:0;bottom:3px;width:3px;position:absolute;z-index:10;opacity:.3}.event .event-inner{position:relative;left:0px;right:5px;top:0px;bottom:5px;cursor:move;pointer-events:all;overflow:hidden}.event .event-inner .event-wrapper{width:calc(100% - 2px);margin:1px auto 1px 0;height:calc(100% - 3px)}.event .event-inner .event-wrapper .event-bg{opacity:.5;height:100%;transition:opacity .15s ease-in-out}.event .event-inner .event-wrapper .event-label{position:absolute;top:0;font-size:12px;font-weight:600;padding:4px}.event .event-inner .event-resize{position:absolute;cursor:ns-resize;height:4px;left:0;right:0;z-index:400}.event .event-inner .event-resize.top{top:0}.event .event-inner .event-resize.bottom{bottom:0}.event .event-inner .event-resize:hover{background:#DDD}.event .event-inner.hover .event-bg{opacity:.7!important}@media (max-width: 767px){.table .calendar-head .calendar-head-cell{text-orientation:sideways;writing-mode:vertical-rl}}\n"] }]
405
+ }], ctorParameters: function () { return [{ type: i1.BsCalendarMonthService }, { type: i2.BsTimelineService }]; }, propDecorators: { timeSlotElements: [{
248
406
  type: ViewChildren,
249
407
  args: ['slot']
250
408
  }], unitHeightChange: [{
251
409
  type: Output
252
410
  }], unitHeight: [{
253
411
  type: Input
412
+ }], maxInnerHeight: [{
413
+ type: Input
254
414
  }], onMousemove: [{
255
415
  type: HostListener,
256
416
  args: ['document:mousemove', ['$event']]
@@ -258,4 +418,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImpor
258
418
  type: HostListener,
259
419
  args: ['document:mouseup', ['$event']]
260
420
  }] } });
261
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZWR1bGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbWludHBsYXllci1uZy1ib290c3RyYXAvc3JjL2xpYi9jb21wb25lbnRzL3NjaGVkdWxlci9jb21wb25lbnRzL3NjaGVkdWxlci9zY2hlZHVsZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9taW50cGxheWVyLW5nLWJvb3RzdHJhcC9zcmMvbGliL2NvbXBvbmVudHMvc2NoZWR1bGVyL2NvbXBvbmVudHMvc2NoZWR1bGVyL3NjaGVkdWxlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JJLE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBYyxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNqRyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0REFBNEQsQ0FBQztBQUNwRyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7Ozs7Ozs7QUFZNUQsTUFBTSxPQUFPLG9CQUFvQjtJQUMvQixZQUFvQixvQkFBNEM7UUFBNUMseUJBQW9CLEdBQXBCLG9CQUFvQixDQUF3QjtRQTJGaEUsMkJBQXNCLEdBQUcsSUFBSSxlQUFlLENBQXVCLEVBQUUsQ0FBQyxDQUFDO1FBR3ZFLHNCQUFpQixHQUFHLElBQUksZUFBZSxDQUFTLElBQUksQ0FBQyxDQUFDO1FBRXRELGdCQUFXLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDbEQscUJBQWdCLEdBQUcsSUFBSSxlQUFlLENBQWtCLElB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LElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsQixRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFO2dCQUNoQyxLQUFLLGNBQWMsQ0FBQyxXQUFXO29CQUFFO3dCQUMvQixJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFOzRCQUN4QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQzs0QkFDdEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQzt5QkFDL0I7cUJBQ0Y7b0JBQUMsTUFBTTtnQkFDUixLQUFLLGNBQWMsQ0FBQyxTQUFTO29CQUFFO3dCQUM3QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQzt3QkFDdEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztxQkFDL0I7b0JBQUMsTUFBTTthQUNUO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLENBQUM7O2lIQXZRVSxvQkFBb0I7cUdBQXBCLG9CQUFvQix5VkNmakMseXdHQXFETTsyRkR0Q08sb0JBQW9CO2tCQUxoQyxTQUFTOytCQUNFLGNBQWM7NkdBeUdGLGdCQUFnQjtzQkFBckMsWUFBWTt1QkFBQyxNQUFNO2dCQUlILGdCQUFnQjtzQkFBaEMsTUFBTTtnQkFJYSxVQUFVO3NCQUE3QixLQUFLO2dCQThGTixXQUFXO3NCQURWLFlBQVk7dUJBQUMsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBMEM5QyxTQUFTO3NCQURSLFlBQVk7dUJBQUMsa0JBQWtCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25EZXN0cm95LCBPdXRwdXQsIFF1ZXJ5TGlzdCwgVmlld0NoaWxkcmVuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIG1hcCwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgdGFrZSwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBCc0NhbGVuZGFyTW9udGhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vc2VydmljZXMvY2FsZW5kYXItbW9udGgvY2FsZW5kYXItbW9udGguc2VydmljZSc7XG5pbXBvcnQgeyBFRHJhZ09wZXJhdGlvbiB9IGZyb20gJy4uLy4uL2VudW1zL2RyYWctb3BlcmF0aW9uJztcbmltcG9ydCB7IERyYWdPcGVyYXRpb24gfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2RyYWctb3BlcmF0aW9uJztcbmltcG9ydCB7IFNjaGVkdWxlckV2ZW50IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9zY2hlZHVsZXItZXZlbnQnO1xuaW1wb3J0IHsgU2NoZWR1bGVyRXZlbnRQYXJ0IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9zY2hlZHVsZXItZXZlbnQtcGFydCc7XG5pbXBvcnQgeyBTY2hlZHVsZXJFdmVudFdpdGhQYXJ0cyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvc2NoZWR1bGVyLWV2ZW50LXdpdGgtcGFydHMnO1xuaW1wb3J0IHsgVGltZVNsb3QgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3RpbWUtc2xvdCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2JzLXNjaGVkdWxlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zY2hlZHVsZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zY2hlZHVsZXIuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgQnNTY2hlZHVsZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNhbGVuZGFyTW9udGhTZXJ2aWNlOiBCc0NhbGVuZGFyTW9udGhTZXJ2aWNlKSB7XG4gICAgY29uc3QgbW9uZGF5ID0gdGhpcy5jYWxlbmRhck1vbnRoU2VydmljZS5nZXRNb25kYXlCZWZvcmUobmV3IERhdGUoKSk7XG4gICAgdGhpcy5jdXJyZW50V2VlayQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PERhdGU+KG1vbmRheSk7XG5cbiAgICB0aGlzLmRheXNPZldlZWskID0gdGhpcy5jdXJyZW50V2VlayQucGlwZShcbiAgICAgIG1hcCgod2Vla01vbmRheSkgPT4ge1xuICAgICAgICB3ZWVrTW9uZGF5LnNldEhvdXJzKDApO1xuICAgICAgICB3ZWVrTW9uZGF5LnNldE1pbnV0ZXMoMCk7XG4gICAgICAgIHdlZWtNb25kYXkuc2V0U2Vjb25kcygwKTtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20oQXJyYXkoNykua2V5cygpKS5tYXAoKHgpID0+IHRoaXMuYWRkRGF5cyh3ZWVrTW9uZGF5LCB4KSk7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLmV2ZW50cyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNjaGVkdWxlckV2ZW50W10+KFtdKTtcbiAgICB0aGlzLmV2ZW50UGFydHMkID0gdGhpcy5ldmVudHMkLnBpcGUoXG4gICAgICBtYXAoKGV2ZW50cykgPT4ge1xuICAgICAgICByZXR1cm4gZXZlbnRzLm1hcCgoZXYpID0+IHtcbiAgICAgICAgICBsZXQgc3RhcnRUaW1lID0gZXYuc3RhcnQ7XG4gICAgICAgICAgY29uc3QgcmVzdWx0OiBTY2hlZHVsZXJFdmVudFBhcnRbXSA9IFtdO1xuICAgICAgICAgIHdoaWxlICghdGhpcy5kYXRlRXF1YWxzKHN0YXJ0VGltZSwgZXYuZW5kKSkge1xuICAgICAgICAgICAgY29uc3QgZW5kID0gbmV3IERhdGUoc3RhcnRUaW1lLmdldEZ1bGxZZWFyKCksIHN0YXJ0VGltZS5nZXRNb250aCgpLCBzdGFydFRpbWUuZ2V0RGF0ZSgpICsgMSwgMCwgMCwgMCk7XG4gICAgICAgICAgICByZXN1bHQucHVzaCh7IHN0YXJ0OiBzdGFydFRpbWUsIGVuZDogZW5kLCBldmVudDogZXYgfSk7XG4gICAgICAgICAgICBzdGFydFRpbWUgPSBlbmQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzdGFydFRpbWUgIT0gZXYuZW5kKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaCh7IHN0YXJ0OiBzdGFydFRpbWUsIGVuZDogZXYuZW5kLCBldmVudDogZXYgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIDxTY2hlZHVsZXJFdmVudFdpdGhQYXJ0cz57IGV2ZW50OiBldiwgcGFydHM6IHJlc3VsdCB9O1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGNvbWJpbmVMYXRlc3QoW1xuICAgICAgICB0aGlzLmRheXNPZldlZWskXG4gICAgICAgICAgLnBpcGUobWFwKChkYXlzT2ZXZWVrKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGFydDogZGF5c09mV2Vla1swXS5nZXRUaW1lKCksIGVuZDogZGF5c09mV2Vla1tkYXlzT2ZXZWVrLmxlbmd0aCAtIDFdLmdldFRpbWUoKSArIDI0ICogNjAgKiA2MCAqIDEwMDAgfTtcbiAgICAgICAgICB9KSksXG4gICAgICAgIHRoaXMuZXZlbnRQYXJ0cyRcbiAgICAgICAgICAucGlwZShtYXAoZXZlbnRQYXJ0cyA9PiBldmVudFBhcnRzLm1hcChldnAgPT4gZXZwLnBhcnRzKSkpXG4gICAgICAgICAgLnBpcGUobWFwKGphZ2dlZFBhcnRzID0+IHtcbiAgICAgICAgICAgIHJldHVybiBqYWdnZWRQYXJ0cy5yZWR1Y2UoKGZsYXQsIHRvRmxhdHRlbikgPT4gZmxhdC5jb25jYXQodG9GbGF0dGVuKSwgW10pO1xuICAgICAgICAgIH0pKSxcbiAgICAgICAgdGhpcy5ldmVudFBhcnRzJFxuICAgICAgXSlcbiAgICAgIC5waXBlKG1hcCgoW3N0YXJ0QW5kRW5kLCBldmVudFBhcnRzLCBvcmlnaW5hbEV2ZW50UGFydHNdKSA9PiB7XG4gICAgICAgIHJldHVybiBldmVudFBhcnRzLmZpbHRlcihldmVudFBhcnQgPT4ge1xuICAgICAgICAgIHJldHVybiAhKChldmVudFBhcnQuZW5kLmdldFRpbWUoKSA8IHN0YXJ0QW5kRW5kLnN0YXJ0KSB8fCAoZXZlbnRQYXJ0LnN0YXJ0LmdldFRpbWUoKSA+IHN0YXJ0QW5kRW5kLmVuZCkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveWVkJCkpXG4gICAgICAuc3Vic2NyaWJlKChldmVudFBhcnRzRm9yVGhpc1dlZWspID0+IHtcbiAgICAgICAgdGhpcy5ldmVudFBhcnRzRm9yVGhpc1dlZWskLm5leHQoZXZlbnRQYXJ0c0ZvclRoaXNXZWVrKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy50aW1lU2xvdHMkID0gY29tYmluZUxhdGVzdChbdGhpcy5kYXlzT2ZXZWVrJCwgdGhpcy50aW1lU2xvdER1cmF0aW9uJF0pXG4gICAgICAucGlwZShtYXAoKFtkYXlzT2ZXZWVrLCBkdXJhdGlvbl0pID0+IHtcbiAgICAgICAgY29uc3QgdGltZVNsb3RzUGVyRGF5ID0gTWF0aC5mbG9vcigoNjAgKiA2MCAqIDI0KSAvIGR1cmF0aW9uKTtcblxuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0aW1lU2xvdHNQZXJEYXkpLmtleXMoKSkubWFwKChpbmRleCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHRpbWVTbG90U3RhcnQgPSBuZXcgRGF0ZShkYXlzT2ZXZWVrWzBdKTtcbiAgICAgICAgICB0aW1lU2xvdFN0YXJ0LnNldFNlY29uZHModGltZVNsb3RTdGFydC5nZXRTZWNvbmRzKCkgKyBpbmRleCAqIGR1cmF0aW9uKTtcbiAgICAgICAgICBjb25zdCB0aW1lU2xvdEVuZCA9IG5ldyBEYXRlKHRpbWVTbG90U3RhcnQpO1xuICAgICAgICAgIHRpbWVTbG90RW5kLnNldFNlY29uZHModGltZVNsb3RFbmQuZ2V0U2Vjb25kcygpICsgZHVyYXRpb24pO1xuXG4gICAgICAgICAgcmV0dXJuIGRheXNPZldlZWsubWFwKChkYXkpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gbmV3IERhdGUoZGF5KTtcbiAgICAgICAgICAgIHN0YXJ0LnNldEhvdXJzKHRpbWVTbG90U3RhcnQuZ2V0SG91cnMoKSk7XG4gICAgICAgICAgICBzdGFydC5zZXRNaW51dGVzKHRpbWVTbG90U3RhcnQuZ2V0TWludXRlcygpKTtcbiAgICAgICAgICAgIHN0YXJ0LnNldFNlY29uZHModGltZVNsb3RTdGFydC5nZXRTZWNvbmRzKCkpO1xuXG4gICAgICAgICAgICBjb25zdCBlbmQgPSBuZXcgRGF0ZShkYXkpO1xuICAgICAgICAgICAgZW5kLnNldEhvdXJzKHRpbWVTbG90RW5kLmdldEhvdXJzKCkpO1xuICAgICAgICAgICAgZW5kLnNldE1pbnV0ZXModGltZVNsb3RFbmQuZ2V0TWludXRlcygpKTtcbiAgICAgICAgICAgIGVuZC5zZXRTZWNvbmRzKHRpbWVTbG90RW5kLmdldFNlY29uZHMoKSk7XG5cbiAgICAgICAgICAgIHJldHVybiA8VGltZVNsb3Q+eyBzdGFydCwgZW5kIH07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICB9KSk7XG4gICAgXG4gICAgdGhpcy51bml0SGVpZ2h0JFxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveWVkJCkpXG4gICAgICAuc3Vic2NyaWJlKCh1bml0SGVpZ2h0KSA9PiB7XG4gICAgICAgIHRoaXMudW5pdEhlaWdodENoYW5nZS5lbWl0KHVuaXRIZWlnaHQpO1xuICAgICAgfSlcbiAgfVxuXG4gIGV2ZW50cyQ6IEJlaGF2aW9yU3ViamVjdDxTY2hlZHVsZXJFdmVudFtdPjtcbiAgZXZlbnRQYXJ0cyQ6IE9ic2VydmFibGU8U2NoZWR1bGVyRXZlbnRXaXRoUGFydHNbXT47XG4gIGV2ZW50UGFydHNGb3JUaGlzV2VlayQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNjaGVkdWxlckV2ZW50UGFydFtdPihbXSk7XG4gIGN1cnJlbnRXZWVrJDogQmVoYXZpb3JTdWJqZWN0PERhdGU+O1xuICBkYXlzT2ZXZWVrJDogT2JzZXJ2YWJsZTxEYXRlW10+O1xuICB0aW1lU2xvdER1cmF0aW9uJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyPigxODAwKTtcbiAgdGltZVNsb3RzJDogT2JzZXJ2YWJsZTxUaW1lU2xvdFtdW10+O1xuICBtb3VzZVN0YXRlJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBob3ZlcmVkVGltZVNsb3QkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUaW1lU2xvdCB8IG51bGw+KG51bGwpO1xuICBkZXN0cm95ZWQkID0gbmV3IFN1YmplY3QoKTtcblxuICBAVmlld0NoaWxkcmVuKCdzbG90JykgdGltZVNsb3RFbGVtZW50cyE6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50Pj47XG5cbiAgLy8jcmVnaW9uIFVuaXRIZWlnaHRcbiAgdW5pdEhlaWdodCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oNDApO1xuICBAT3V0cHV0KCkgcHVibGljIHVuaXRIZWlnaHRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgcHVibGljIGdldCB1bml0SGVpZ2h0KCkge1xuICAgIHJldHVybiB0aGlzLnVuaXRIZWlnaHQkLnZhbHVlO1xuICB9XG4gIEBJbnB1dCgpIHB1YmxpYyBzZXQgdW5pdEhlaWdodCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy51bml0SGVpZ2h0JC5uZXh0KHZhbHVlKTtcbiAgfVxuICAvLyNlbmRyZWdpb25cblxuICBwcml2YXRlIGRhdGVFcXVhbHMoZGF0ZTE6IERhdGUsIGRhdGUyOiBEYXRlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGRhdGUxLmdldEZ1bGxZZWFyKCkgPT09IGRhdGUyLmdldEZ1bGxZZWFyKCkgJiZcbiAgICAgIGRhdGUxLmdldE1vbnRoKCkgPT09IGRhdGUyLmdldE1vbnRoKCkgJiZcbiAgICAgIGRhdGUxLmdldERhdGUoKSA9PT0gZGF0ZTIuZ2V0RGF0ZSgpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkRGF5cyhkYXRlOiBEYXRlLCBkYXlzOiBudW1iZXIpIHtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICByZXN1bHQuc2V0RGF0ZShyZXN1bHQuZ2V0RGF0ZSgpICsgZGF5cyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIG9uUHJldmlvdXNXZWVrKCkge1xuICAgIHRoaXMuY3VycmVudFdlZWskXG4gICAgICAucGlwZShtYXAoKHcpID0+IHRoaXMuYWRkRGF5cyh3LCAtNykpLCB0YWtlKDEpKVxuICAgICAgLnN1YnNjcmliZSgodykgPT4gdGhpcy5jdXJyZW50V2VlayQubmV4dCh3KSk7XG4gIH1cblxuICBvbk5leHRXZWVrKCkge1xuICAgIHRoaXMuY3VycmVudFdlZWskXG4gICAgICAucGlwZShtYXAoKHcpID0+IHRoaXMuYWRkRGF5cyh3LCA3KSksIHRha2UoMSkpXG4gICAgICAuc3Vic2NyaWJlKCh3KSA9PiB0aGlzLmN1cnJlbnRXZWVrJC5uZXh0KHcpKTtcbiAgfVxuXG4gIG9wZXJhdGlvbjogRHJhZ09wZXJhdGlvbiB8IG51bGwgPSBudWxsO1xuICBkcmFnU3RhcnRUaW1lc2xvdDogVGltZVNsb3QgfCBudWxsID0gbnVsbDtcbiAgb25DcmVhdGVFdmVudChldjogTW91c2VFdmVudCwgc2xvdDogVGltZVNsb3QpIHtcbiAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMubW91c2VTdGF0ZSQubmV4dCh0cnVlKTtcbiAgICB0aGlzLmRyYWdTdGFydFRpbWVzbG90ID0gc2xvdDtcbiAgICB0aGlzLm9wZXJhdGlvbiA9IHtcbiAgICAgIG9wZXJhdGlvbjogRURyYWdPcGVyYXRpb24uY3JlYXRlRXZlbnQsXG4gICAgICBldmVudDoge1xuICAgICAgICBzdGFydDogc2xvdC5zdGFydCxcbiAgICAgICAgZW5kOiBzbG90LmVuZCxcbiAgICAgICAgY29sb3I6ICcjRjAwJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdUZXN0IGV2ZW50JyxcbiAgICAgIH1cbiAgICB9O1xuICAgIHRoaXMuZXZlbnRzJC5uZXh0KFsuLi50aGlzLmV2ZW50cyQudmFsdWUsIHRoaXMub3BlcmF0aW9uLmV2ZW50XSk7XG4gIH1cblxuICBvblN0YXJ0RHJhZ0V2ZW50KGV2ZW50UGFydDogU2NoZWR1bGVyRXZlbnRQYXJ0LCBldjogTW91c2VFdmVudCkge1xuICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5ob3ZlcmVkVGltZVNsb3QkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKChob3ZlcmVkVGltZVNsb3QpID0+IHtcbiAgICAgIHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3QgPSBob3ZlcmVkVGltZVNsb3Q7XG4gICAgICB0aGlzLm9wZXJhdGlvbiA9IHtcbiAgICAgICAgb3BlcmF0aW9uOiBFRHJhZ09wZXJhdGlvbi5tb3ZlRXZlbnQsXG4gICAgICAgIGV2ZW50OiBldmVudFBhcnQuZXZlbnRcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vI3JlZ2lvbiBob3ZlcmVkVGltZXNsb3QkXG4gIHByaXZhdGUgZ2V0SG92ZXJlZFRpbWVzbG90KGV2OiBNb3VzZUV2ZW50LCB0aW1lU2xvdHM6IFRpbWVTbG90W11bXSkge1xuICAgIGNvbnN0IGhvdmVyZWRTbG90cyA9IHRoaXMudGltZVNsb3RFbGVtZW50cy5maWx0ZXIoKGVsKSA9PiB7XG4gICAgICBjb25zdCByY3QgPSBlbC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgaWYgKHJjdC5sZWZ0IDw9IGV2LnggJiYgZXYueCA8PSByY3QucmlnaHQgJiYgcmN0LnRvcCA8PSBldi55ICYmIGV2LnkgPD0gcmN0LmJvdHRvbSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmICghaG92ZXJlZFNsb3RzIHx8IGhvdmVyZWRTbG90cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHNsb3RFbGVtZW50ID0gaG92ZXJlZFNsb3RzWzBdLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBjb25zdCBzdHJSb3cgPSBzbG90RWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtcm93Jyk7XG4gICAgaWYgKCFzdHJSb3cpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCByb3cgPSBwYXJzZUludChzdHJSb3cpO1xuXG4gICAgY29uc3Qgc3RyQ29sdW1uID0gc2xvdEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWNvbHVtbicpO1xuICAgIGlmICghc3RyQ29sdW1uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgY29sdW1uID0gcGFyc2VJbnQoc3RyQ29sdW1uKTtcblxuICAgIGNvbnN0IHNsb3QgPSB0aW1lU2xvdHNbcm93XVtjb2x1bW5dO1xuICAgIHJldHVybiBzbG90O1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2Vtb3ZlJywgWyckZXZlbnQnXSlcbiAgb25Nb3VzZW1vdmUoZXY6IE1vdXNlRXZlbnQpIHtcbiAgICB0aGlzLnRpbWVTbG90cyQucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKHRpbWVTbG90cykgPT4ge1xuICAgICAgY29uc3QgaG92ZXJlZCA9IHRoaXMuZ2V0SG92ZXJlZFRpbWVzbG90KGV2LCB0aW1lU2xvdHMpO1xuICAgICAgdGhpcy5ob3ZlcmVkVGltZVNsb3QkLm5leHQoaG92ZXJlZCk7XG5cbiAgICAgIGlmICh0aGlzLm9wZXJhdGlvbikge1xuICAgICAgICBzd2l0Y2ggKHRoaXMub3BlcmF0aW9uLm9wZXJhdGlvbikge1xuICAgICAgICAgIGNhc2UgRURyYWdPcGVyYXRpb24uY3JlYXRlRXZlbnQ6IHtcbiAgICAgICAgICAgIGlmICh0aGlzLm9wZXJhdGlvbi5ldmVudCAmJiB0aGlzLmRyYWdTdGFydFRpbWVzbG90ICYmIGhvdmVyZWQgJiYgKHRoaXMub3BlcmF0aW9uLmV2ZW50LmVuZC5nZXRUaW1lKCkgIT0gaG92ZXJlZC5lbmQuZ2V0VGltZSgpKSkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5kcmFnU3RhcnRUaW1lc2xvdC5zdGFydC5nZXRUaW1lKCkgPT09IGhvdmVyZWQuc3RhcnQuZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gMSBzbG90XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5kcmFnU3RhcnRUaW1lc2xvdC5zdGFydC5nZXRUaW1lKCkgPCBob3ZlcmVkLnN0YXJ0LmdldFRpbWUoKSkge1xuICAgICAgICAgICAgICAgIC8vIERyYWcgZG93blxuICAgICAgICAgICAgICAgIHRoaXMub3BlcmF0aW9uLmV2ZW50LnN0YXJ0ID0gdGhpcy5kcmFnU3RhcnRUaW1lc2xvdC5zdGFydDtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZXJhdGlvbi5ldmVudC5lbmQgPSBob3ZlcmVkLmVuZDtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cyQubmV4dCh0aGlzLmV2ZW50cyQudmFsdWUpO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3Quc3RhcnQuZ2V0VGltZSgpID4gaG92ZXJlZC5zdGFydC5nZXRUaW1lKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBEcmFnIHVwXG4gICAgICAgICAgICAgICAgdGhpcy5vcGVyYXRpb24uZXZlbnQuc3RhcnQgPSBob3ZlcmVkLnN0YXJ0O1xuICAgICAgICAgICAgICAgIHRoaXMub3BlcmF0aW9uLmV2ZW50LmVuZCA9IHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3QuZW5kO1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzJC5uZXh0KHRoaXMuZXZlbnRzJC52YWx1ZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBicmVhaztcbiAgICAgICAgICBjYXNlIEVEcmFnT3BlcmF0aW9uLm1vdmVFdmVudDoge1xuICAgICAgICAgICAgaWYgKGhvdmVyZWQgJiYgdGhpcy5kcmFnU3RhcnRUaW1lc2xvdCkge1xuICAgICAgICAgICAgICB0aGlzLm9wZXJhdGlvbi5ldmVudC5zdGFydC5zZXRUaW1lKHRoaXMub3BlcmF0aW9uLmV2ZW50LnN0YXJ0LmdldFRpbWUoKSArIGhvdmVyZWQuc3RhcnQuZ2V0VGltZSgpIC0gdGhpcy5kcmFnU3RhcnRUaW1lc2xvdC5zdGFydC5nZXRUaW1lKCkpO1xuICAgICAgICAgICAgICB0aGlzLm9wZXJhdGlvbi5ldmVudC5lbmQuc2V0VGltZSh0aGlzLm9wZXJhdGlvbi5ldmVudC5lbmQuZ2V0VGltZSgpICsgaG92ZXJlZC5zdGFydC5nZXRUaW1lKCkgLSB0aGlzLmRyYWdTdGFydFRpbWVzbG90LnN0YXJ0LmdldFRpbWUoKSk7XG4gICAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3QgPSBob3ZlcmVkO1xuICAgICAgICAgICAgICB0aGlzLmV2ZW50cyQubmV4dCh0aGlzLmV2ZW50cyQudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgIH0pO1xuICB9XG4gIC8vI2VuZHJlZ2lvblxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNldXAnLCBbJyRldmVudCddKVxuICBvbk1vdXNlVXAoZXY6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAodGhpcy5vcGVyYXRpb24pIHtcbiAgICAgIHN3aXRjaCAodGhpcy5vcGVyYXRpb24ub3BlcmF0aW9uKSB7XG4gICAgICAgIGNhc2UgRURyYWdPcGVyYXRpb24uY3JlYXRlRXZlbnQ6IHtcbiAgICAgICAgICBpZiAodGhpcy5vcGVyYXRpb24uZXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMub3BlcmF0aW9uID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3QgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBicmVhaztcbiAgICAgICAgY2FzZSBFRHJhZ09wZXJhdGlvbi5tb3ZlRXZlbnQ6IHtcbiAgICAgICAgICB0aGlzLm9wZXJhdGlvbiA9IG51bGw7XG4gICAgICAgICAgdGhpcy5kcmFnU3RhcnRUaW1lc2xvdCA9IG51bGw7XG4gICAgICAgIH0gYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95ZWQkLm5leHQodHJ1ZSk7XG4gIH1cbn1cbiIsInt7IHVuaXRIZWlnaHQkIHwgYXN5bmMgfX1cbjxkaXYgY2xhc3M9XCJ0YWJsZSBkLWZsZXggdy0xMDAgb3ZlcmZsb3cteS1hdXRvXCIgW3N0eWxlLm1heC1oZWlnaHQucHhdPVwiNDAwXCI+XG4gICAgPGRpdiBjbGFzcz1cImNhbGVuZGFyLWhlYWRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwIGQtZmxleCBmbGV4LXJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBjYWxlbmRhci1sZWZ0IGp1c3RpZnktY29udGVudC1iZXR3ZWVuXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGVmYXVsdCBmbGV4LXN0YXJ0XCIgKGNsaWNrKT1cIm9uUHJldmlvdXNXZWVrKClcIj4mbHQ7PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGVmYXVsdCBmbGV4LWVuZFwiIChjbGljayk9XCJvbk5leHRXZWVrKClcIj4mZ3Q7PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWdyb3ctMVwiICpuZ0Zvcj1cImxldCBkYXkgb2YgKGRheXNPZldlZWskIHwgYXN5bmMpXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkLWJsb2NrIGNvbC1mb3JtLWxhYmVsIHRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGRheSB8IGRhdGU6ICdkZC1NTS15eXl5JyB9fVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY2FsZW5kYXItYm9keVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicG9zaXRpb24tcmVsYXRpdmVcIj5cbiAgICAgICAgICAgIDwhLS0gVGltZXNsb3RzIC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgdGltZXNsb3RzIG9mICh0aW1lU2xvdHMkIHwgYXN5bmMpOyBsZXQgaSA9IGluZGV4XCIgY2xhc3M9XCJkLWZsZXggZmxleC1yb3cgcC0wIHRpbWVzbG90XCIgW3N0eWxlLmhlaWdodC5weF09XCJ1bml0SGVpZ2h0JCB8IGFzeW5jXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbGVuZGFyLWNlbGwgY2FsZW5kYXItbGVmdCBhbGlnbi10b3AgcHktMFwiPnt7IHRpbWVzbG90c1swXS5zdGFydCB8IGRhdGU6ICdISDptbTpzcycgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FsZW5kYXItY2VsbCBmbGV4LWdyb3ctMVwiICpuZ0Zvcj1cImxldCBzbG90IG9mIHRpbWVzbG90czsgbGV0IGogPSBpbmRleFwiICNzbG90IChtb3VzZWRvd24pPVwib25DcmVhdGVFdmVudCgkZXZlbnQsIHNsb3QpXCIgW2F0dHIuZGF0YS1yb3ddPVwiaVwiIFthdHRyLmRhdGEtY29sdW1uXT1cImpcIj48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8IS0tIEV2ZW50cyAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIodGltZVNsb3REdXJhdGlvbiQgfCBhc3luYykgYXMgdGltZVNsb3REdXJhdGlvblwiPlxuXG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgZXZlbnRQYXJ0IG9mIChldmVudFBhcnRzRm9yVGhpc1dlZWskIHwgYXN5bmMpXCIgY2xhc3M9XCJwb3NpdGlvbi1hYnNvbHV0ZSBldmVudFwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS50b3AucHhdPVwiKGV2ZW50UGFydCB8IGJzU2Vjb25kc1RvZGF5T2Zmc2V0KSAvIHRpbWVTbG90RHVyYXRpb24gKiAodW5pdEhlaWdodCQgfCBhc3luYykhXCJcbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodC5weF09XCIoZXZlbnRQYXJ0IHwgYnNTZWNvbmRzVGltZXNwYW4pIC8gdGltZVNsb3REdXJhdGlvbiAqICh1bml0SGVpZ2h0JCB8IGFzeW5jKSFcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUubGVmdF09XCInY2FsYyg5MHB4ICsgKCgxMDAlIC0gOTBweCkgLyA3ICogJyArICgoZXZlbnRQYXJ0IHwgZGF5T2ZXZWVrKSAtIDEpICsgJykpJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXZlbnQtaW5uZXJcIiBbc3R5bGUuYmFja2dyb3VuZC1jb2xvcl09XCJldmVudFBhcnQuZXZlbnQuY29sb3JcIiAobW91c2Vkb3duKT1cIm9uU3RhcnREcmFnRXZlbnQoZXZlbnRQYXJ0LCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBldmVudFBhcnQuZXZlbnQuZGVzY3JpcHRpb24gfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDxicj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGV2ZW50UGFydC5zdGFydCB8IGRhdGU6ICdISDptbTpzcycgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDxicj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGV2ZW50UGFydC5lbmQgfCBkYXRlOiAnSEg6bW06c3MnIH19XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDwhLS0gPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZXZlbnRXaXRoUGFydHMgb2YgKGV2ZW50UGFydHMkIHwgYXN5bmMpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGV2ZW50UGFydCBvZiBldmVudFdpdGhQYXJ0cy5wYXJ0c1wiIGNsYXNzPVwicG9zaXRpb24tYWJzb2x1dGUgZXZlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLnRvcC5weF09XCIoZXZlbnRQYXJ0IHwgYnNTZWNvbmRzVG9kYXlPZmZzZXQpIC8gdGltZVNsb3REdXJhdGlvbiAqIDQwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwiKGV2ZW50UGFydCB8IGJzU2Vjb25kc1RpbWVzcGFuKSAvIHRpbWVTbG90RHVyYXRpb24gKiA0MFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubGVmdF09XCInY2FsYyg5MHB4ICsgKCgxMDAlIC0gOTBweCkgLyA3ICogJyArICgoZXZlbnRQYXJ0IHwgZGF5T2ZXZWVrKSAtIDEpICsgJykpJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImV2ZW50LWlubmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZXZlbnRQYXJ0LnN0YXJ0IHwgZGF0ZTogJ0hIOm1tOnNzJyB9fSAtIHt7IGV2ZW50UGFydC5lbmQgfCBkYXRlOiAnSEg6bW06c3MnIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+IC0tPlxuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+Il19
421
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZWR1bGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbWludHBsYXllci1uZy1ib290c3RyYXAvc3JjL2xpYi9jb21wb25lbnRzL3NjaGVkdWxlci9jb21wb25lbnRzL3NjaGVkdWxlci9zY2hlZHVsZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9taW50cGxheWVyLW5nLWJvb3RzdHJhcC9zcmMvbGliL2NvbXBvbmVudHMvc2NoZWR1bGVyL2NvbXBvbmVudHMvc2NoZWR1bGVyL3NjaGVkdWxlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JJLE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQWMsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQU8sTUFBTSxNQUFNLENBQUM7QUFDOUcsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNERBQTRELENBQUM7QUFDcEcsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBTzVELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDOzs7Ozs7OztBQU83RSxNQUFNLE9BQU8sb0JBQW9CO0lBQy9CLFlBQW9CLG9CQUE0QyxFQUFVLGVBQWtDO1FBQXhGLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBd0I7UUFBVSxvQkFBZSxHQUFmLGVBQWUsQ0FBbUI7UUEySDVHLFlBQU8sR0FBRyxJQUFJLGVBQWUsQ0FBbUIsRUFBRSxDQUFDLENBQUM7UUFLcEQsa0JBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBc0IsSUFBSSxDQUFDLENBQUM7UUFPL0Qsc0JBQWlCLEdBQUcsSUFBSSxlQUFlLENBQVMsSUFBSSxDQUFDLENBQUM7UUFDdEQsZUFBVSxHQUFHLElBQUksZUFBZSxDQUFlLEVBQUUsQ0FBQyxDQUFDO1FBQ25ELGdCQUFXLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDbEQscUJBQWdCLEdBQUcsSUFBSSxlQUFlLENBQWtCLElBQUksQ0FBQyxDQUFDO1FBQzlELGtCQUFhLEdBQUcsSUFBSSxlQUFlLENBQXdCLElBQUksQ0FBQyxDQUFDO1FBQ2pFLGVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBSTNCLG9CQUFvQjtRQUNwQixnQkFBVyxHQUFHLElBQUksZUFBZSxDQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzdCLHFCQUFnQixHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFPL0QsWUFBWTtRQUNaLHdCQUF3QjtRQUNSLG1CQUFjLEdBQWtCLElBQUksQ0FBQztRQThCckQsY0FBUyxHQUF5QixJQUFJLENBQUM7UUFDdkMsc0JBQWlCLEdBQW9CLElBQUksQ0FBQztRQXpMeEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLGVBQWUsQ0FBTyxNQUFNLENBQUMsQ0FBQztRQUV0RCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUN2QyxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRTtZQUNqQixVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZCLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekIsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6QixVQUFVLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0UsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLENBQUMsV0FBVzthQUM5QyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUU7WUFDdkIsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsR0FBRyxFQUFFLFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDO1FBQ3BILENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFTixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUNsQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FDNUUsQ0FBQztRQUVGLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxhQUFhLENBQUM7WUFDMUMsSUFBSSxDQUFDLHlCQUF5QjtZQUM5QixJQUFJLENBQUMsV0FBVztpQkFDYixJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2lCQUN6RCxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUFFO2dCQUN0QixPQUFPLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzdFLENBQUMsQ0FBQyxDQUFDO1NBQ0osQ0FBQzthQUNELElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxVQUFVLENBQUMsRUFBRSxFQUFFO1lBQ3RDLE9BQU8sVUFBVSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFDbkMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDN0csQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRU4sSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUMvQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNaLElBQUksS0FBSyxFQUFFO2dCQUNULE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUE7YUFDaEQ7aUJBQU07Z0JBQ0wsT0FBTyxJQUFJLENBQUM7YUFDYjtRQUNILENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixJQUFJLENBQUMsNkJBQTZCLEdBQUcsYUFBYSxDQUFDLENBQUMsSUFBSSxDQUFDLHlCQUF5QixFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2FBQzFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxpQkFBaUIsQ0FBQyxFQUFFLEVBQUU7WUFDN0MsSUFBSSxpQkFBaUIsRUFBRTtnQkFDckIsT0FBTyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFO29CQUNoRCxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDN0csQ0FBQyxDQUFDLENBQUM7YUFDSjtpQkFBTTtnQkFDTCxPQUFPLEVBQUUsQ0FBQzthQUNYO1FBQ0gsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVOLElBQUksQ0FBQywrQkFBK0IsR0FBRyxJQUFJLENBQUMsc0JBQXNCO2FBQy9ELElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDckIsMENBQTBDO1lBQzFDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO2lCQUMxQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQzdDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDbEIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBaUIsQ0FBQyxDQUFDLENBQUM7WUFDakMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFMUQsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDbEMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRTtvQkFDM0IsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDM0MsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUM7aUJBQ0QsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLENBQUM7aUJBQ3ZELEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDaEUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QyxDQUFDLENBQUMsQ0FDSDtpQkFDQSxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRXpELE9BQU87Z0JBQ0wsS0FBSyxFQUFFLFFBQVEsQ0FBQyxNQUFNO2dCQUN0QixLQUFLLEVBQUUsTUFBTTthQUNkLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQyxDQUFBO1FBRUwsYUFBYSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQzthQUN0RCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBRTtZQUNuQyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQztZQUM5RCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQzdELE1BQU0sYUFBYSxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM5QyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxHQUFHLEtBQUssR0FBRyxRQUFRLEdBQUcsSUFBSSxDQUFDLENBQUM7Z0JBQzFFLE1BQU0sV0FBVyxHQUFHLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUM1QyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxHQUFHLFFBQVEsR0FBRyxJQUFJLENBQUMsQ0FBQztnQkFFOUQsT0FBTyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQzVCLE1BQU0sS0FBSyxHQUFHLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUM1QixLQUFLLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO29CQUN6QyxLQUFLLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO29CQUM3QyxLQUFLLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO29CQUM3QyxLQUFLLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO29CQUV2RCxNQUFNLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDMUIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztvQkFDckMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztvQkFDekMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztvQkFDekMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztvQkFDbkQsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxHQUFHLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO29CQUU3RSxPQUFpQixFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQztnQkFDbEMsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO2FBQ0YsU0FBUyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUU7WUFDdkIsK0dBQStHO1lBQy9HLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2xDLENBQUMsQ0FBQyxDQUFDO1FBRUwsSUFBSSxDQUFDLFdBQVc7YUFDYixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUNoQyxTQUFTLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRTtZQUN4QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQztJQTBCRCxJQUFXLFVBQVU7UUFDbkIsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztJQUNoQyxDQUFDO0lBQ0QsSUFBb0IsVUFBVSxDQUFDLEtBQWE7UUFDMUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUlELFlBQVk7SUFFSixPQUFPLENBQUMsSUFBVSxFQUFFLElBQVk7UUFDdEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDeEMsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVELGNBQWM7UUFDWixJQUFJLENBQUMsWUFBWTthQUNkLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDOUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLFlBQVk7YUFDZCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUM3QyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVELFlBQVksQ0FBQyxFQUF5QjtRQUNwQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQsWUFBWSxDQUFDLEVBQXlCO1FBQ3BDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFJRCxhQUFhLENBQUMsRUFBYyxFQUFFLElBQWM7UUFDMUMsRUFBRSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRztZQUNmLFNBQVMsRUFBRSxjQUFjLENBQUMsV0FBVztZQUNyQyxLQUFLLEVBQUU7Z0JBQ0wsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO2dCQUNqQixHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7Z0JBQ2IsS0FBSyxFQUFFLE1BQU07Z0JBQ2IsV0FBVyxFQUFFLFlBQVk7YUFDMUI7WUFDRCxJQUFJLEVBQUUsSUFBSTtTQUNYLENBQUM7UUFDRixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQsV0FBVztRQUNULE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQztRQUN2QixPQUFPLEdBQUcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNoSCxDQUFDO0lBQ0QsYUFBYSxDQUFDLFVBQWtCO1FBQzlCLE1BQU0sQ0FBQyxHQUFHLEdBQUcsR0FBQyxVQUFVLENBQUM7UUFDekIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUM7UUFDL0MsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6QixPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxTQUE2QixFQUFFLEVBQWM7UUFDNUQsRUFBRSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFDaEUsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFO2dCQUNuQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsZUFBZSxDQUFDO2dCQUN6QyxJQUFJLENBQUMsU0FBUyxHQUFHO29CQUNmLFNBQVMsRUFBRSxjQUFjLENBQUMsU0FBUztvQkFDbkMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxLQUFLO29CQUN0QixJQUFJLEVBQUUsSUFBSTtpQkFDWCxDQUFDO2dCQUNGLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7YUFDckY7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxLQUE0QixFQUFFLFFBQTBCO1FBQ3pFLElBQUksS0FBSyxFQUFFO1lBQ1QsUUFBUSxRQUFRLEVBQUU7Z0JBQ2hCLEtBQUssS0FBSztvQkFBRTt3QkFDVixJQUFJLENBQUMsU0FBUyxHQUFHOzRCQUNmLFNBQVMsRUFBRSxjQUFjLENBQUMsV0FBVzs0QkFDckMsS0FBSyxFQUFFLEtBQUs7NEJBQ1osSUFBSSxFQUFFLEVBQUUsUUFBUSxFQUFFO3lCQUNuQixDQUFBO3dCQUNELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO3FCQUNqRTtvQkFBQyxNQUFNO2dCQUNSLEtBQUssUUFBUTtvQkFBRTt3QkFDYixJQUFJLENBQUMsU0FBUyxHQUFHOzRCQUNmLFNBQVMsRUFBRSxjQUFjLENBQUMsV0FBVzs0QkFDckMsS0FBSyxFQUFFLEtBQUs7NEJBQ1osSUFBSSxFQUFFLEVBQUUsUUFBUSxFQUFFO3lCQUNuQixDQUFBO3dCQUNELElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO3FCQUNqRTtvQkFBQyxNQUFNO2FBQ1Q7U0FDRjtJQUNILENBQUM7SUFFRCwwQkFBMEI7SUFDbEIsa0JBQWtCLENBQUMsRUFBYyxFQUFFLFNBQXVCO1FBQ2hFLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtZQUN2RCxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDckQsSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEVBQUU7Z0JBQ2xGLE9BQU8sSUFBSSxDQUFDO2FBQ2I7aUJBQU07Z0JBQ0wsT0FBTyxLQUFLLENBQUM7YUFDZDtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFlBQVksSUFBSSxZQUFZLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUM5QyxPQUFPLElBQUksQ0FBQztTQUNiO1FBRUQsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQztRQUVsRCxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDWCxPQUFPLElBQUksQ0FBQztTQUNiO1FBQ0QsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTdCLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNkLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFDRCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFbkMsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUdELFdBQVcsQ0FBQyxFQUFjO1FBQ3hCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO1lBQ3BELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDdkQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUVwQyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQ2xCLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUU7b0JBQ2hDLEtBQUssY0FBYyxDQUFDLFdBQVc7d0JBQUU7NEJBQy9CLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUU7Z0NBQzlILElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFO29DQUN0RSxTQUFTO2lDQUNWO3FDQUFNLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFO29DQUMzRSxZQUFZO29DQUNaLElBQUksQ0FBQyxhQUFhO3lDQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO3lDQUN0RCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7d0NBQ2YsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFOzRDQUNoQyxFQUFFLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7NENBQ3hDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQzt5Q0FDdEI7d0NBQ0QsT0FBTyxFQUFFLENBQUM7b0NBQ1osQ0FBQyxDQUFDLENBQUM7eUNBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzt5Q0FDYixTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUNBQ25EO3FDQUFNLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFO29DQUMzRSxVQUFVO29DQUNWLElBQUksQ0FBQyxhQUFhO3lDQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO3lDQUN0RCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7d0NBQ2YsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFOzRDQUNoQyxFQUFFLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7NENBQ3pCLEVBQUUsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQzt5Q0FDckM7d0NBQ0QsT0FBTyxFQUFFLENBQUM7b0NBQ1osQ0FBQyxDQUFDLENBQUM7eUNBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzt5Q0FDYixTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUNBQ25EOzZCQUNGO3lCQUNGO3dCQUFDLE1BQU07b0JBQ1IsS0FBSyxjQUFjLENBQUMsU0FBUzt3QkFBRTs0QkFDN0IsSUFBSSxPQUFPLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFO2dDQUNyQyxJQUFJLENBQUMsYUFBYTtxQ0FDZixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztxQ0FDdEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO29DQUNmLElBQUksRUFBRSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTt3Q0FDaEMsTUFBTSxNQUFNLEdBQWtCOzRDQUM1QixLQUFLLEVBQUUsSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7NENBQ3RHLEdBQUcsRUFBRSxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQzt5Q0FDbkcsQ0FBQzt3Q0FFRixJQUFJLENBQUMsaUJBQWlCLEdBQUcsT0FBTyxDQUFDO3dDQUVqQyxPQUFPLE1BQU0sQ0FBQztxQ0FDZjt5Q0FBTTt3Q0FDTCxPQUFPLEVBQUUsQ0FBQztxQ0FDWDtnQ0FDSCxDQUFDLENBQUMsQ0FBQztxQ0FDRixJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO3FDQUNiLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7NkJBQ2pEO3lCQUNGO3dCQUFDLE1BQU07b0JBQ1IsS0FBSyxjQUFjLENBQUMsV0FBVzt3QkFBRTs0QkFDL0IsSUFBSSxPQUFPLEVBQUU7Z0NBQ1gsSUFBSSxDQUFDLGFBQWE7cUNBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO3FDQUMxQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7b0NBQ2YsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRTt3Q0FDaEQsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxFQUFFOzRDQUMxQyxFQUFFLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7NENBQ3pCLEVBQUUsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO3lDQUNuQzs2Q0FBTSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRLEVBQUU7NENBQ3BELEVBQUUsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDOzRDQUN0QyxFQUFFLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUM7eUNBQ3RCO3FDQUNGO29DQUNELE9BQU8sRUFBRSxDQUFDO2dDQUNaLENBQUMsQ0FBQyxDQUFDO3FDQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7cUNBQ2IsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDOzZCQUNuRDt5QkFDRjt3QkFBQyxNQUFNO2lCQUNUO2FBQ0Y7UUFFSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFDRCxZQUFZO0lBR1osU0FBUyxDQUFDLEVBQWM7UUFDdEIsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ2xCLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUU7Z0JBQ2hDLEtBQUssY0FBYyxDQUFDLFdBQVc7b0JBQUU7d0JBQy9CLGFBQWEsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzs2QkFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs2QkFDYixTQUFTLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxFQUFFLEVBQUU7NEJBQzVCLElBQUksWUFBWSxFQUFFO2dDQUNoQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztnQ0FDdEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztnQ0FDOUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFO3dDQUN4QyxLQUFLLEVBQUUsWUFBWSxDQUFDLEtBQUs7d0NBQ3pCLEdBQUcsRUFBRSxZQUFZLENBQUMsR0FBRzt3Q0FDckIsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUU7d0NBQ3pCLFdBQVcsRUFBRSxXQUFXO3FDQUN6QixDQUFDLENBQUMsQ0FBQztnQ0FDSixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzs2QkFDL0I7d0JBQ0gsQ0FBQyxDQUFDLENBQUM7cUJBQ047b0JBQUMsTUFBTTtnQkFDUixLQUFLLGNBQWMsQ0FBQyxTQUFTLENBQUM7Z0JBQzlCLEtBQUssY0FBYyxDQUFDLFdBQVc7b0JBQUU7d0JBQy9CLElBQUksQ0FBQyxhQUFhOzZCQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQzs2QkFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzs2QkFDYixTQUFTLENBQUMsQ0FBQyxZQUFZLEVBQUUsRUFBRTs0QkFDMUIsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxJQUFJLFlBQVksRUFBRTtnQ0FDMUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUM7Z0NBQ2hELElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDO2dDQUM1QyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztnQ0FDdEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztnQ0FDOUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztnQ0FDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7NkJBQy9CO3dCQUNILENBQUMsQ0FBQyxDQUFDO3FCQUNOO29CQUFDLE1BQU07YUFDVDtTQUNGO0lBQ0gsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QixDQUFDOztpSEFwYVUsb0JBQW9CO3FHQUFwQixvQkFBb0IsMlhDakJqQyxrd0pBNkRNOzJGRDVDTyxvQkFBb0I7a0JBTGhDLFNBQVM7K0JBQ0UsY0FBYzs2SUFtSkYsZ0JBQWdCO3NCQUFyQyxZQUFZO3VCQUFDLE1BQU07Z0JBSUgsZ0JBQWdCO3NCQUFoQyxNQUFNO2dCQUlhLFVBQVU7c0JBQTdCLEtBQUs7Z0JBS1UsY0FBYztzQkFBN0IsS0FBSztnQkFvSU4sV0FBVztzQkFEVixZQUFZO3VCQUFDLG9CQUFvQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQTJGOUMsU0FBUztzQkFEUixZQUFZO3VCQUFDLGtCQUFrQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIEhvc3RMaXN0ZW5lciwgSW5wdXQsIE9uRGVzdHJveSwgT3V0cHV0LCBRdWVyeUxpc3QsIFZpZXdDaGlsZHJlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBjb21iaW5lTGF0ZXN0LCBmaWx0ZXIsIG1hcCwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgdGFrZSwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEJzQ2FsZW5kYXJNb250aFNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9jYWxlbmRhci1tb250aC9jYWxlbmRhci1tb250aC5zZXJ2aWNlJztcbmltcG9ydCB7IEVEcmFnT3BlcmF0aW9uIH0gZnJvbSAnLi4vLi4vZW51bXMvZHJhZy1vcGVyYXRpb24nO1xuaW1wb3J0IHsgRHJhZ09wZXJhdGlvbiB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZHJhZy1vcGVyYXRpb24nO1xuaW1wb3J0IHsgUHJldmlld0V2ZW50IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9wcmV2aWV3LWV2ZW50JztcbmltcG9ydCB7IFNjaGVkdWxlckV2ZW50IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9zY2hlZHVsZXItZXZlbnQnO1xuaW1wb3J0IHsgU2NoZWR1bGVyRXZlbnRQYXJ0IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9zY2hlZHVsZXItZXZlbnQtcGFydCc7XG5pbXBvcnQgeyBTY2hlZHVsZXJFdmVudFdpdGhQYXJ0cyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvc2NoZWR1bGVyLWV2ZW50LXdpdGgtcGFydHMnO1xuaW1wb3J0IHsgVGltZVNsb3QgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3RpbWUtc2xvdCc7XG5pbXBvcnQgeyBCc1RpbWVsaW5lU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3RpbWVsaW5lL3RpbWVsaW5lLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdicy1zY2hlZHVsZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vc2NoZWR1bGVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2NoZWR1bGVyLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIEJzU2NoZWR1bGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjYWxlbmRhck1vbnRoU2VydmljZTogQnNDYWxlbmRhck1vbnRoU2VydmljZSwgcHJpdmF0ZSB0aW1lbGluZVNlcnZpY2U6IEJzVGltZWxpbmVTZXJ2aWNlKSB7XG4gICAgY29uc3QgbW9uZGF5ID0gdGhpcy5jYWxlbmRhck1vbnRoU2VydmljZS5nZXRNb25kYXlCZWZvcmUobmV3IERhdGUoKSk7XG4gICAgdGhpcy5jdXJyZW50V2VlayQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PERhdGU+KG1vbmRheSk7XG5cbiAgICB0aGlzLmRheXNPZldlZWskID0gdGhpcy5jdXJyZW50V2VlayQucGlwZShcbiAgICAgIG1hcCgod2Vla01vbmRheSkgPT4ge1xuICAgICAgICB3ZWVrTW9uZGF5LnNldEhvdXJzKDApO1xuICAgICAgICB3ZWVrTW9uZGF5LnNldE1pbnV0ZXMoMCk7XG4gICAgICAgIHdlZWtNb25kYXkuc2V0U2Vjb25kcygwKTtcbiAgICAgICAgd2Vla01vbmRheS5zZXRNaWxsaXNlY29uZHMoMCk7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKEFycmF5KDcpLmtleXMoKSkubWFwKCh4KSA9PiB0aGlzLmFkZERheXMod2Vla01vbmRheSwgeCkpO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgdGhpcy5kYXlzT2ZXZWVrV2l0aFRpbWVzdGFtcHMkID0gdGhpcy5kYXlzT2ZXZWVrJFxuICAgICAgLnBpcGUobWFwKChkYXlzT2ZXZWVrKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBkYXlzT2ZXZWVrWzBdLmdldFRpbWUoKSwgZW5kOiBkYXlzT2ZXZWVrW2RheXNPZldlZWsubGVuZ3RoIC0gMV0uZ2V0VGltZSgpICsgMjQgKiA2MCAqIDYwICogMTAwMCB9O1xuICAgICAgfSkpO1xuXG4gICAgdGhpcy5ldmVudFBhcnRzJCA9IHRoaXMuZXZlbnRzJC5waXBlKFxuICAgICAgbWFwKChldmVudHMpID0+ICBldmVudHMubWFwKChldikgPT4gdGhpcy50aW1lbGluZVNlcnZpY2Uuc3BsaXRJblBhcnRzKGV2KSkpXG4gICAgKTtcblxuICAgIHRoaXMuZXZlbnRQYXJ0c0ZvclRoaXNXZWVrJCA9IGNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy5kYXlzT2ZXZWVrV2l0aFRpbWVzdGFtcHMkLFxuICAgICAgdGhpcy5ldmVudFBhcnRzJFxuICAgICAgICAucGlwZShtYXAoZXZlbnRQYXJ0cyA9PiBldmVudFBhcnRzLm1hcChldnAgPT4gZXZwLnBhcnRzKSkpXG4gICAgICAgIC5waXBlKG1hcChqYWdnZWRQYXJ0cyA9PiB7XG4gICAgICAgICAgcmV0dXJuIGphZ2dlZFBhcnRzLnJlZHVjZSgoZmxhdCwgdG9GbGF0dGVuKSA9PiBmbGF0LmNvbmNhdCh0b0ZsYXR0ZW4pLCBbXSk7XG4gICAgICAgIH0pKVxuICAgICAgXSlcbiAgICAgIC5waXBlKG1hcCgoW3N0YXJ0QW5kRW5kLCBldmVudFBhcnRzXSkgPT4ge1xuICAgICAgICByZXR1cm4gZXZlbnRQYXJ0cy5maWx0ZXIoZXZlbnRQYXJ0ID0+IHtcbiAgICAgICAgICByZXR1cm4gISgoZXZlbnRQYXJ0LmVuZC5nZXRUaW1lKCkgPD0gc3RhcnRBbmRFbmQuc3RhcnQpIHx8IChldmVudFBhcnQuc3RhcnQuZ2V0VGltZSgpID49IHN0YXJ0QW5kRW5kLmVuZCkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pKTtcblxuICAgIHRoaXMucHJldmlld0V2ZW50UGFydHMkID0gdGhpcy5wcmV2aWV3RXZlbnQkLnBpcGUoXG4gICAgICBtYXAoKGV2ZW50KSA9PiB7XG4gICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRpbWVsaW5lU2VydmljZS5zcGxpdEluUGFydHMoZXZlbnQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLnByZXZpZXdFdmVudFBhcnRzRm9yVGhpc1dlZWskID0gY29tYmluZUxhdGVzdChbdGhpcy5kYXlzT2ZXZWVrV2l0aFRpbWVzdGFtcHMkLCB0aGlzLnByZXZpZXdFdmVudFBhcnRzJF0pXG4gICAgICAucGlwZShtYXAoKFtzdGFydEFuZEVuZCwgcHJldmlld0V2ZW50UGFydHNdKSA9PiB7XG4gICAgICAgIGlmIChwcmV2aWV3RXZlbnRQYXJ0cykge1xuICAgICAgICAgIHJldHVybiBwcmV2aWV3RXZlbnRQYXJ0cy5wYXJ0cy5maWx0ZXIoZXZlbnRQYXJ0ID0+IHtcbiAgICAgICAgICAgIHJldHVybiAhKChldmVudFBhcnQuZW5kLmdldFRpbWUoKSA8PSBzdGFydEFuZEVuZC5zdGFydCkgfHwgKGV2ZW50UGFydC5zdGFydC5nZXRUaW1lKCkgPj0gc3RhcnRBbmRFbmQuZW5kKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICB9KSk7XG5cbiAgICB0aGlzLnRpbWVsaW5lZEV2ZW50UGFydHNGb3JUaGlzV2VlayQgPSB0aGlzLmV2ZW50UGFydHNGb3JUaGlzV2VlayRcbiAgICAgIC5waXBlKG1hcChldmVudFBhcnRzID0+IHtcbiAgICAgICAgLy8gV2UnbGwgb25seSB1c2UgdGhlIGV2ZW50cyBmb3IgdGhpcyB3ZWVrXG4gICAgICAgIGNvbnN0IGV2ZW50cyA9IGV2ZW50UGFydHMubWFwKGVwID0+IGVwLmV2ZW50KVxuICAgICAgICAgIC5maWx0ZXIoKGUsIGksIGxpc3QpID0+IGxpc3QuaW5kZXhPZihlKSA9PT0gaSlcbiAgICAgICAgICAuZmlsdGVyKChlKSA9PiAhIWUpXG4gICAgICAgICAgLm1hcCgoZSkgPT4gPFNjaGVkdWxlckV2ZW50PmUpO1xuICAgICAgICBjb25zdCB0aW1lbGluZSA9IHRoaXMudGltZWxpbmVTZXJ2aWNlLmdldFRpbWVsaW5lKGV2ZW50cyk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGltZWxpbmUubWFwKHRyYWNrID0+IHtcbiAgICAgICAgICByZXR1cm4gdHJhY2suZXZlbnRzLm1hcChldiA9PiB7XG4gICAgICAgICAgICByZXR1cm4geyBldmVudDogZXYsIGluZGV4OiB0cmFjay5pbmRleCB9O1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAucmVkdWNlKChmbGF0LCB0b0ZsYXR0ZW4pID0+IGZsYXQuY29uY2F0KHRvRmxhdHRlbiksIFtdKVxuICAgICAgICAubWFwKChldmkpID0+IGV2ZW50UGFydHMuZmlsdGVyKHAgPT4gcC5ldmVudCA9PT0gZXZpLmV2ZW50KS5tYXAocCA9PiB7XG4gICAgICAgICAgICByZXR1cm4geyBwYXJ0OiBwLCBpbmRleDogZXZpLmluZGV4IH07XG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgICAucmVkdWNlKChmbGF0LCB0b0ZsYXR0ZW4pID0+IGZsYXQuY29uY2F0KHRvRmxhdHRlbiksIFtdKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRvdGFsOiB0aW1lbGluZS5sZW5ndGgsXG4gICAgICAgICAgcGFydHM6IHJlc3VsdFxuICAgICAgICB9O1xuICAgICAgfSkpXG5cbiAgICBjb21iaW5lTGF0ZXN0KFt0aGlzLmRheXNPZldlZWskLCB0aGlzLnRpbWVTbG90RHVyYXRpb24kXSlcbiAgICAgIC5waXBlKG1hcCgoW2RheXNPZldlZWssIGR1cmF0aW9uXSkgPT4ge1xuICAgICAgICBjb25zdCB0aW1lU2xvdHNQZXJEYXkgPSBNYXRoLmZsb29yKCg2MCAqIDYwICogMjQpIC8gZHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbShBcnJheSh0aW1lU2xvdHNQZXJEYXkpLmtleXMoKSkubWFwKChpbmRleCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHRpbWVTbG90U3RhcnQgPSBuZXcgRGF0ZShkYXlzT2ZXZWVrWzBdKTtcbiAgICAgICAgICB0aW1lU2xvdFN0YXJ0LnNldFRpbWUoK3RpbWVTbG90U3RhcnQuZ2V0VGltZSgpICsgaW5kZXggKiBkdXJhdGlvbiAqIDEwMDApO1xuICAgICAgICAgIGNvbnN0IHRpbWVTbG90RW5kID0gbmV3IERhdGUodGltZVNsb3RTdGFydCk7XG4gICAgICAgICAgdGltZVNsb3RFbmQuc2V0VGltZSgrdGltZVNsb3RFbmQuZ2V0VGltZSgpICsgZHVyYXRpb24gKiAxMDAwKTtcblxuICAgICAgICAgIHJldHVybiBkYXlzT2ZXZWVrLm1hcCgoZGF5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKGRheSk7XG4gICAgICAgICAgICBzdGFydC5zZXRIb3Vycyh0aW1lU2xvdFN0YXJ0LmdldEhvdXJzKCkpO1xuICAgICAgICAgICAgc3RhcnQuc2V0TWludXRlcyh0aW1lU2xvdFN0YXJ0LmdldE1pbnV0ZXMoKSk7XG4gICAgICAgICAgICBzdGFydC5zZXRTZWNvbmRzKHRpbWVTbG90U3RhcnQuZ2V0U2Vjb25kcygpKTtcbiAgICAgICAgICAgIHN0YXJ0LnNldE1pbGxpc2Vjb25kcyh0aW1lU2xvdFN0YXJ0LmdldE1pbGxpc2Vjb25kcygpKTtcblxuICAgICAgICAgICAgY29uc3QgZW5kID0gbmV3IERhdGUoZGF5KTtcbiAgICAgICAgICAgIGVuZC5zZXRIb3Vycyh0aW1lU2xvdEVuZC5nZXRIb3VycygpKTtcbiAgICAgICAgICAgIGVuZC5zZXRNaW51dGVzKHRpbWVTbG90RW5kLmdldE1pbnV0ZXMoKSk7XG4gICAgICAgICAgICBlbmQuc2V0U2Vjb25kcyh0aW1lU2xvdEVuZC5nZXRTZWNvbmRzKCkpO1xuICAgICAgICAgICAgZW5kLnNldE1pbGxpc2Vjb25kcyh0aW1lU2xvdEVuZC5nZXRNaWxsaXNlY29uZHMoKSk7XG4gICAgICAgICAgICBlbmQuc2V0RGF0ZShlbmQuZ2V0RGF0ZSgpICsgdGltZVNsb3RFbmQuZ2V0RGF0ZSgpIC0gdGltZVNsb3RTdGFydC5nZXREYXRlKCkpO1xuXG4gICAgICAgICAgICByZXR1cm4gPFRpbWVTbG90Pnsgc3RhcnQsIGVuZCB9O1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pKVxuICAgICAgLnN1YnNjcmliZSgodGltZXNsb3RzKSA9PiB7XG4gICAgICAgIC8vIEZvciBwZXJmb3JtYW5jZSByZWFzb25zLCB3ZSdyZSBub3QgdXNpbmcgYW4gb2JzZXJ2YWJsZSBoZXJlLCBidXQgcGVyc2lzdCB0aGUgdGltZXNsb3RzIGluIGEgQmVoYXZpb3JTdWJqZWN0LlxuICAgICAgICB0aGlzLnRpbWVTbG90cyQubmV4dCh0aW1lc2xvdHMpO1xuICAgICAgfSk7XG4gICAgXG4gICAgdGhpcy51bml0SGVpZ2h0JFxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveWVkJCkpXG4gICAgICAuc3Vic2NyaWJlKCh1bml0SGVpZ2h0KSA9PiB7XG4gICAgICAgIHRoaXMudW5pdEhlaWdodENoYW5nZS5lbWl0KHVuaXRIZWlnaHQpO1xuICAgICAgfSlcbiAgfVxuXG4gIGV2ZW50cyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNjaGVkdWxlckV2ZW50W10+KFtdKTtcbiAgZXZlbnRQYXJ0cyQ6IE9ic2VydmFibGU8U2NoZWR1bGVyRXZlbnRXaXRoUGFydHNbXT47XG4gIGV2ZW50UGFydHNGb3JUaGlzV2VlayQ6IE9ic2VydmFibGU8U2NoZWR1bGVyRXZlbnRQYXJ0W10+O1xuICB0aW1lbGluZWRFdmVudFBhcnRzRm9yVGhpc1dlZWskOiBPYnNlcnZhYmxlPHsgdG90YWw6IG51bWJlciwgcGFydHM6IHsgcGFydDogU2NoZWR1bGVyRXZlbnRQYXJ0LCBpbmRleDogbnVtYmVyfVtdIH0+O1xuICBcbiAgcHJldmlld0V2ZW50JCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8UHJldmlld0V2ZW50IHwgbnVsbD4obnVsbCk7XG4gIHByZXZpZXdFdmVudFBhcnRzJDogT2JzZXJ2YWJsZTxTY2hlZHVsZXJFdmVudFdpdGhQYXJ0cyB8IG51bGw+O1xuICBwcmV2aWV3RXZlbnRQYXJ0c0ZvclRoaXNXZWVrJDogT2JzZXJ2YWJsZTxTY2hlZHVsZXJFdmVudFBhcnRbXT47XG4gIFxuICBjdXJyZW50V2VlayQ6IEJlaGF2aW9yU3ViamVjdDxEYXRlPjtcbiAgZGF5c09mV2VlayQ6IE9ic2VydmFibGU8RGF0ZVtdPjtcbiAgZGF5c09mV2Vla1dpdGhUaW1lc3RhbXBzJDogT2JzZXJ2YWJsZTx7c3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXJ9PjtcbiAgdGltZVNsb3REdXJhdGlvbiQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oMTgwMCk7XG4gIHRpbWVTbG90cyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRpbWVTbG90W11bXT4oW10pO1xuICBtb3VzZVN0YXRlJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBob3ZlcmVkVGltZVNsb3QkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUaW1lU2xvdCB8IG51bGw+KG51bGwpO1xuICBob3ZlcmVkRXZlbnQkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTY2hlZHVsZXJFdmVudCB8IG51bGw+KG51bGwpO1xuICBkZXN0cm95ZWQkID0gbmV3IFN1YmplY3QoKTtcblxuICBAVmlld0NoaWxkcmVuKCdzbG90JykgdGltZVNsb3RFbGVtZW50cyE6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50Pj47XG5cbiAgLy8jcmVnaW9uIFVuaXRIZWlnaHRcbiAgdW5pdEhlaWdodCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4oNDApO1xuICBAT3V0cHV0KCkgcHVibGljIHVuaXRIZWlnaHRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgcHVibGljIGdldCB1bml0SGVpZ2h0KCkge1xuICAgIHJldHVybiB0aGlzLnVuaXRIZWlnaHQkLnZhbHVlO1xuICB9XG4gIEBJbnB1dCgpIHB1YmxpYyBzZXQgdW5pdEhlaWdodCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy51bml0SGVpZ2h0JC5uZXh0KHZhbHVlKTtcbiAgfVxuICAvLyNlbmRyZWdpb25cbiAgLy8jcmVnaW9uIG1heElubmVySGVpZ2h0XG4gIEBJbnB1dCgpIHB1YmxpYyBtYXhJbm5lckhlaWdodDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIC8vI2VuZHJlZ2lvblxuXG4gIHByaXZhdGUgYWRkRGF5cyhkYXRlOiBEYXRlLCBkYXlzOiBudW1iZXIpIHtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgRGF0ZShkYXRlKTtcbiAgICByZXN1bHQuc2V0RGF0ZShyZXN1bHQuZ2V0RGF0ZSgpICsgZGF5cyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIG9uUHJldmlvdXNXZWVrKCkge1xuICAgIHRoaXMuY3VycmVudFdlZWskXG4gICAgICAucGlwZShtYXAoKHcpID0+IHRoaXMuYWRkRGF5cyh3LCAtNykpLCB0YWtlKDEpKVxuICAgICAgLnN1YnNjcmliZSgodykgPT4gdGhpcy5jdXJyZW50V2VlayQubmV4dCh3KSk7XG4gIH1cblxuICBvbk5leHRXZWVrKCkge1xuICAgIHRoaXMuY3VycmVudFdlZWskXG4gICAgICAucGlwZShtYXAoKHcpID0+IHRoaXMuYWRkRGF5cyh3LCA3KSksIHRha2UoMSkpXG4gICAgICAuc3Vic2NyaWJlKCh3KSA9PiB0aGlzLmN1cnJlbnRXZWVrJC5uZXh0KHcpKTtcbiAgfVxuXG4gIG9uSG92ZXJFdmVudChldjogU2NoZWR1bGVyRXZlbnQgfCBudWxsKSB7XG4gICAgY29uc29sZS5sb2coJ2hvdmVyZWQnLCBldik7XG4gICAgdGhpcy5ob3ZlcmVkRXZlbnQkLm5leHQoZXYpO1xuICB9XG5cbiAgb25MZWF2ZUV2ZW50KGV2OiBTY2hlZHVsZXJFdmVudCB8IG51bGwpIHtcbiAgICB0aGlzLmhvdmVyZWRFdmVudCQubmV4dChudWxsKTtcbiAgfVxuXG4gIG9wZXJhdGlvbjogRHJhZ09wZXJhdGlvbiB8IG51bGwgPSBudWxsO1xuICBkcmFnU3RhcnRUaW1lc2xvdDogVGltZVNsb3QgfCBudWxsID0gbnVsbDtcbiAgb25DcmVhdGVFdmVudChldjogTW91c2VFdmVudCwgc2xvdDogVGltZVNsb3QpIHtcbiAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMubW91c2VTdGF0ZSQubmV4dCh0cnVlKTtcbiAgICB0aGlzLmRyYWdTdGFydFRpbWVzbG90ID0gc2xvdDtcbiAgICB0aGlzLm9wZXJhdGlvbiA9IHtcbiAgICAgIG9wZXJhdGlvbjogRURyYWdPcGVyYXRpb24uY3JlYXRlRXZlbnQsXG4gICAgICBldmVudDoge1xuICAgICAgICBzdGFydDogc2xvdC5zdGFydCxcbiAgICAgICAgZW5kOiBzbG90LmVuZCxcbiAgICAgICAgY29sb3I6ICcjRjAwJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdUZXN0IGV2ZW50JyxcbiAgICAgIH0sXG4gICAgICBtZXRhOiBudWxsLFxuICAgIH07XG4gICAgdGhpcy5wcmV2aWV3RXZlbnQkLm5leHQoeyBzdGFydDogc2xvdC5zdGFydCwgZW5kOiBzbG90LmVuZCB9KTtcbiAgfVxuXG4gIHJhbmRvbUNvbG9yKCkge1xuICAgIGNvbnN0IGJyaWdodG5lc3MgPSAxMjg7XG4gICAgcmV0dXJuICcjJyArIHRoaXMucmFuZG9tQ2hhbm5lbChicmlnaHRuZXNzKSArIHRoaXMucmFuZG9tQ2hhbm5lbChicmlnaHRuZXNzKSArIHRoaXMucmFuZG9tQ2hhbm5lbChicmlnaHRuZXNzKTtcbiAgfVxuICByYW5kb21DaGFubmVsKGJyaWdodG5lc3M6IG51bWJlcil7XG4gICAgY29uc3QgciA9IDI1NS1icmlnaHRuZXNzO1xuICAgIGNvbnN0IG4gPSAwfCgoTWF0aC5yYW5kb20oKSAqIHIpICsgYnJpZ2h0bmVzcyk7XG4gICAgY29uc3QgcyA9IG4udG9TdHJpbmcoMTYpO1xuICAgIHJldHVybiAocy5sZW5ndGg9PTEpID8gJzAnK3MgOiBzO1xuICB9XG5cbiAgb25TdGFydERyYWdFdmVudChldmVudFBhcnQ6IFNjaGVkdWxlckV2ZW50UGFydCwgZXY6IE1vdXNlRXZlbnQpIHtcbiAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuaG92ZXJlZFRpbWVTbG90JC5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgoaG92ZXJlZFRpbWVTbG90KSA9PiB7XG4gICAgICBpZiAoZXZlbnRQYXJ0LmV2ZW50KSB7XG4gICAgICAgIHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3QgPSBob3ZlcmVkVGltZVNsb3Q7XG4gICAgICAgIHRoaXMub3BlcmF0aW9uID0ge1xuICAgICAgICAgIG9wZXJhdGlvbjogRURyYWdPcGVyYXRpb24ubW92ZUV2ZW50LFxuICAgICAgICAgIGV2ZW50OiBldmVudFBhcnQuZXZlbnQsXG4gICAgICAgICAgbWV0YTogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wcmV2aWV3RXZlbnQkLm5leHQoeyBzdGFydDogZXZlbnRQYXJ0LmV2ZW50LnN0YXJ0LCBlbmQ6IGV2ZW50UGFydC5ldmVudC5lbmQgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvblN0YXJ0UmVzaXplRXZlbnQoZXZlbnQ6IFNjaGVkdWxlckV2ZW50IHwgbnVsbCwgcG9zaXRpb246ICd0b3AnIHwgJ2JvdHRvbScpIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIHN3aXRjaCAocG9zaXRpb24pIHtcbiAgICAgICAgY2FzZSAndG9wJzoge1xuICAgICAgICAgIHRoaXMub3BlcmF0aW9uID0ge1xuICAgICAgICAgICAgb3BlcmF0aW9uOiBFRHJhZ09wZXJhdGlvbi5yZXNpemVFdmVudCxcbiAgICAgICAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgICAgICAgIG1ldGE6IHsgcG9zaXRpb24gfSxcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5wcmV2aWV3RXZlbnQkLm5leHQoeyBzdGFydDogZXZlbnQuc3RhcnQsIGVuZDogZXZlbnQuZW5kIH0pO1xuICAgICAgICB9IGJyZWFrO1xuICAgICAgICBjYXNlICdib3R0b20nOiB7XG4gICAgICAgICAgdGhpcy5vcGVyYXRpb24gPSB7XG4gICAgICAgICAgICBvcGVyYXRpb246IEVEcmFnT3BlcmF0aW9uLnJlc2l6ZUV2ZW50LFxuICAgICAgICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgICAgICAgbWV0YTogeyBwb3NpdGlvbiB9LFxuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnByZXZpZXdFdmVudCQubmV4dCh7IHN0YXJ0OiBldmVudC5zdGFydCwgZW5kOiBldmVudC5lbmQgfSk7XG4gICAgICAgIH0gYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8jcmVnaW9uIGhvdmVyZWRUaW1lc2xvdCRcbiAgcHJpdmF0ZSBnZXRIb3ZlcmVkVGltZXNsb3QoZXY6IE1vdXNlRXZlbnQsIHRpbWVTbG90czogVGltZVNsb3RbXVtdKSB7XG4gICAgY29uc3QgaG92ZXJlZFNsb3RzID0gdGhpcy50aW1lU2xvdEVsZW1lbnRzLmZpbHRlcigoZWwpID0+IHtcbiAgICAgIGNvbnN0IHJjdCA9IGVsLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBpZiAocmN0LmxlZnQgPD0gZXYueCAmJiBldi54IDw9IHJjdC5yaWdodCAmJiByY3QudG9wIDw9IGV2LnkgJiYgZXYueSA8PSByY3QuYm90dG9tKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKCFob3ZlcmVkU2xvdHMgfHwgaG92ZXJlZFNsb3RzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3Qgc2xvdEVsZW1lbnQgPSBob3ZlcmVkU2xvdHNbMF0ubmF0aXZlRWxlbWVudDtcblxuICAgIGNvbnN0IHN0clJvdyA9IHNsb3RFbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1yb3cnKTtcbiAgICBpZiAoIXN0clJvdykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHJvdyA9IHBhcnNlSW50KHN0clJvdyk7XG5cbiAgICBjb25zdCBzdHJDb2x1bW4gPSBzbG90RWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29sdW1uJyk7XG4gICAgaWYgKCFzdHJDb2x1bW4pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBjb2x1bW4gPSBwYXJzZUludChzdHJDb2x1bW4pO1xuXG4gICAgY29uc3Qgc2xvdCA9IHRpbWVTbG90c1tyb3ddW2NvbHVtbl07XG4gICAgcmV0dXJuIHNsb3Q7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZW1vdmUnLCBbJyRldmVudCddKVxuICBvbk1vdXNlbW92ZShldjogTW91c2VFdmVudCkge1xuICAgIHRoaXMudGltZVNsb3RzJC5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgodGltZVNsb3RzKSA9PiB7XG4gICAgICBjb25zdCBob3ZlcmVkID0gdGhpcy5nZXRIb3ZlcmVkVGltZXNsb3QoZXYsIHRpbWVTbG90cyk7XG4gICAgICB0aGlzLmhvdmVyZWRUaW1lU2xvdCQubmV4dChob3ZlcmVkKTtcblxuICAgICAgaWYgKHRoaXMub3BlcmF0aW9uKSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5vcGVyYXRpb24ub3BlcmF0aW9uKSB7XG4gICAgICAgICAgY2FzZSBFRHJhZ09wZXJhdGlvbi5jcmVhdGVFdmVudDoge1xuICAgICAgICAgICAgaWYgKHRoaXMub3BlcmF0aW9uLmV2ZW50ICYmIHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3QgJiYgaG92ZXJlZCAmJiAodGhpcy5vcGVyYXRpb24uZXZlbnQuZW5kLmdldFRpbWUoKSAhPSBob3ZlcmVkLmVuZC5nZXRUaW1lKCkpKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmRyYWdTdGFydFRpbWVzbG90LnN0YXJ0LmdldFRpbWUoKSA9PT0gaG92ZXJlZC5zdGFydC5nZXRUaW1lKCkpIHtcbiAgICAgICAgICAgICAgICAvLyAxIHNsb3RcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRyYWdTdGFydFRpbWVzbG90LnN0YXJ0LmdldFRpbWUoKSA8IGhvdmVyZWQuc3RhcnQuZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gRHJhZyBkb3duXG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2aWV3RXZlbnQkXG4gICAgICAgICAgICAgICAgICAucGlwZShmaWx0ZXIoKGV2KSA9PiAhIWV2ICYmICEhdGhpcy5kcmFnU3RhcnRUaW1lc2xvdCkpXG4gICAgICAgICAgICAgICAgICAucGlwZShtYXAoKGV2KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChldiAmJiB0aGlzLmRyYWdTdGFydFRpbWVzbG90KSB7XG4gICAgICAgICAgICAgICAgICAgICAgZXYuc3RhcnQgPSB0aGlzLmRyYWdTdGFydFRpbWVzbG90LnN0YXJ0O1xuICAgICAgICAgICAgICAgICAgICAgIGV2LmVuZCA9IGhvdmVyZWQuZW5kO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBldjtcbiAgICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcbiAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKGV2KSA9PiB0aGlzLnByZXZpZXdFdmVudCQubmV4dChldikpO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3Quc3RhcnQuZ2V0VGltZSgpID4gaG92ZXJlZC5zdGFydC5nZXRUaW1lKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBEcmFnIHVwXG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2aWV3RXZlbnQkXG4gICAgICAgICAgICAgICAgICAucGlwZShmaWx0ZXIoKGV2KSA9PiAhIWV2ICYmICEhdGhpcy5kcmFnU3RhcnRUaW1lc2xvdCkpXG4gICAgICAgICAgICAgICAgICAucGlwZShtYXAoKGV2KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChldiAmJiB0aGlzLmRyYWdTdGFydFRpbWVzbG90KSB7XG4gICAgICAgICAgICAgICAgICAgICAgZXYuc3RhcnQgPSBob3ZlcmVkLnN0YXJ0O1xuICAgICAgICAgICAgICAgICAgICAgIGV2LmVuZCA9IHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3QuZW5kO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBldjtcbiAgICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcbiAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKGV2KSA9PiB0aGlzLnByZXZpZXdFdmVudCQubmV4dChldikpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBicmVhaztcbiAgICAgICAgICBjYXNlIEVEcmFnT3BlcmF0aW9uLm1vdmVFdmVudDoge1xuICAgICAgICAgICAgaWYgKGhvdmVyZWQgJiYgdGhpcy5kcmFnU3RhcnRUaW1lc2xvdCkge1xuICAgICAgICAgICAgICB0aGlzLnByZXZpZXdFdmVudCRcbiAgICAgICAgICAgICAgICAucGlwZShmaWx0ZXIoKGV2KSA9PiAhIWV2ICYmICEhdGhpcy5kcmFnU3RhcnRUaW1lc2xvdCkpXG4gICAgICAgICAgICAgICAgLnBpcGUobWFwKChldikgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKGV2ICYmIHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3QpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gIDxQcmV2aWV3RXZlbnQ+e1xuICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBuZXcgRGF0ZShldi5zdGFydC5nZXRUaW1lKCkgKyBob3ZlcmVkLnN0YXJ0LmdldFRpbWUoKSAtIHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3Quc3RhcnQuZ2V0VGltZSgpKSxcbiAgICAgICAgICAgICAgICAgICAgICBlbmQ6IG5ldyBEYXRlKGV2LmVuZC5nZXRUaW1lKCkgKyBob3ZlcmVkLnN0YXJ0LmdldFRpbWUoKSAtIHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3Quc3RhcnQuZ2V0VGltZSgpKVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnU3RhcnRUaW1lc2xvdCA9IGhvdmVyZWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBldjtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KSlcbiAgICAgICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoZXYgPT4gdGhpcy5wcmV2aWV3RXZlbnQkLm5leHQoZXYpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGJyZWFrO1xuICAgICAgICAgIGNhc2UgRURyYWdPcGVyYXRpb24ucmVzaXplRXZlbnQ6IHtcbiAgICAgICAgICAgIGlmIChob3ZlcmVkKSB7XG4gICAgICAgICAgICAgIHRoaXMucHJldmlld0V2ZW50JFxuICAgICAgICAgICAgICAgIC5waXBlKGZpbHRlcigoZXYpID0+ICEhZXYpKVxuICAgICAgICAgICAgICAgIC5waXBlKG1hcCgoZXYpID0+IHtcbiAgICAgICAgICAgICAgICAgIGlmIChldiAmJiB0aGlzLm9wZXJhdGlvbiAmJiB0aGlzLm9wZXJhdGlvbi5ldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcGVyYXRpb24ubWV0YS5wb3NpdGlvbiA9PT0gJ3RvcCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICBldi5zdGFydCA9IGhvdmVyZWQuc3RhcnQ7XG4gICAgICAgICAgICAgICAgICAgICAgZXYuZW5kID0gdGhpcy5vcGVyYXRpb24uZXZlbnQuZW5kO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMub3BlcmF0aW9uLm1ldGEucG9zaXRpb24gPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgZXYuc3RhcnQgPSB0aGlzLm9wZXJhdGlvbi5ldmVudC5zdGFydDtcbiAgICAgICAgICAgICAgICAgICAgICBldi5lbmQgPSBob3ZlcmVkLmVuZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2O1xuICAgICAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoZXYpID0+IHRoaXMucHJldmlld0V2ZW50JC5uZXh0KGV2KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgfSk7XG4gIH1cbiAgLy8jZW5kcmVnaW9uXG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2V1cCcsIFsnJGV2ZW50J10pXG4gIG9uTW91c2VVcChldjogTW91c2VFdmVudCkge1xuICAgIGlmICh0aGlzLm9wZXJhdGlvbikge1xuICAgICAgc3dpdGNoICh0aGlzLm9wZXJhdGlvbi5vcGVyYXRpb24pIHtcbiAgICAgICAgY2FzZSBFRHJhZ09wZXJhdGlvbi5jcmVhdGVFdmVudDoge1xuICAgICAgICAgIGNvbWJpbmVMYXRlc3QoW3RoaXMucHJldmlld0V2ZW50JF0pXG4gICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoW3ByZXZpZXdFdmVudF0pID0+IHtcbiAgICAgICAgICAgICAgaWYgKHByZXZpZXdFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlcmF0aW9uID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdTdGFydFRpbWVzbG90ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50cyQubmV4dChbLi4udGhpcy5ldmVudHMkLnZhbHVlLCB7XG4gICAgICAgICAgICAgICAgICBzdGFydDogcHJldmlld0V2ZW50LnN0YXJ0LFxuICAgICAgICAgICAgICAgICAgZW5kOiBwcmV2aWV3RXZlbnQuZW5kLFxuICAgICAgICAgICAgICAgICAgY29sb3I6IHRoaXMucmFuZG9tQ29sb3IoKSxcbiAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnTmV3IGV2ZW50J1xuICAgICAgICAgICAgICAgIH1dKTtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZpZXdFdmVudCQubmV4dChudWxsKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gYnJlYWs7XG4gICAgICAgIGNhc2UgRURyYWdPcGVyYXRpb24ubW92ZUV2ZW50OlxuICAgICAgICBjYXNlIEVEcmFnT3BlcmF0aW9uLnJlc2l6ZUV2ZW50OiB7XG4gICAgICAgICAgdGhpcy5wcmV2aWV3RXZlbnQkXG4gICAgICAgICAgICAucGlwZShmaWx0ZXIoKGV2KSA9PiAhIWV2KSlcbiAgICAgICAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChwcmV2aWV3RXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMub3BlcmF0aW9uICYmIHRoaXMub3BlcmF0aW9uLmV2ZW50ICYmIHByZXZpZXdFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlcmF0aW9uLmV2ZW50LnN0YXJ0ID0gcHJldmlld0V2ZW50LnN0YXJ0O1xuICAgICAgICAgICAgICAgIHRoaXMub3BlcmF0aW9uLmV2ZW50LmVuZCA9IHByZXZpZXdFdmVudC5lbmQ7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVyYXRpb24gPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXJ0VGltZXNsb3QgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzJC5uZXh0KHRoaXMuZXZlbnRzJC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2aWV3RXZlbnQkLm5leHQobnVsbCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveWVkJC5uZXh0KHRydWUpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwidGFibGUgZC1mbGV4IHctMTAwIG92ZXJmbG93LXktYXV0b1wiIFtzdHlsZS5tYXgtaGVpZ2h0LnB4XT1cIm51bGxcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY2FsZW5kYXItaGVhZFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidy0xMDAgZC1mbGV4IGZsZXgtcm93XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGNhbGVuZGFyLWxlZnQganVzdGlmeS1jb250ZW50LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IGZsZXgtc3RhcnRcIiAoY2xpY2spPVwib25QcmV2aW91c1dlZWsoKVwiPiZsdDs8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IGZsZXgtZW5kXCIgKGNsaWNrKT1cIm9uTmV4dFdlZWsoKVwiPiZndDs8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtZ3Jvdy0xIGNhbGVuZGFyLWhlYWQtY2VsbFwiICpuZ0Zvcj1cImxldCBkYXkgb2YgKGRheXNPZldlZWskIHwgYXN5bmMpXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkLWJsb2NrIGNvbC1mb3JtLWxhYmVsIHRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGRheSB8IGRhdGU6ICdkZC1NTScgfX08L3NwYW4+PHNwYW4gY2xhc3M9XCJkLW5vbmUgZC1sZy1pbmxpbmUtYmxvY2tcIj4te3sgZGF5IHwgZGF0ZTogJ3l5eXknIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY2FsZW5kYXItYm9keVwiIFtzdHlsZS5oZWlnaHQucHhdPVwibWF4SW5uZXJIZWlnaHRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBvc2l0aW9uLXJlbGF0aXZlXCI+XG4gICAgICAgICAgICA8IS0tIFRpbWVzbG90cyAtLT5cbiAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHRpbWVzbG90cyBvZiAodGltZVNsb3RzJCB8IGFzeW5jKTsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwiZC1mbGV4IGZsZXgtcm93IHAtMCB0aW1lc2xvdFwiIFtzdHlsZS5oZWlnaHQucHhdPVwidW5pdEhlaWdodCQgfCBhc3luY1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYWxlbmRhci1jZWxsIGNhbGVuZGFyLWxlZnQgYWxpZ24tdG9wIHB4LTIgcHktMFwiPnt7IHRpbWVzbG90c1swXS5zdGFydCB8IGRhdGU6ICdISDptbTpzcycgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FsZW5kYXItY2VsbCBmbGV4LWdyb3ctMVwiICpuZ0Zvcj1cImxldCBzbG90IG9mIHRpbWVzbG90czsgbGV0IGogPSBpbmRleFwiICNzbG90IChtb3VzZWRvd24pPVwib25DcmVhdGVFdmVudCgkZXZlbnQsIHNsb3QpXCIgW2F0dHIuZGF0YS1yb3ddPVwiaVwiIFthdHRyLmRhdGEtY29sdW1uXT1cImpcIj48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8IS0tIEV2ZW50cyAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIodGltZVNsb3REdXJhdGlvbiQgfCBhc3luYykgYXMgdGltZVNsb3REdXJhdGlvblwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIodW5pdEhlaWdodCQgfCBhc3luYykgYXMgdW5pdEhlaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiKHRpbWVsaW5lZEV2ZW50UGFydHNGb3JUaGlzV2VlayQgfCBhc3luYykgYXMgcGFydERhdGFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGV2ZW50UGFydCBvZiBwYXJ0RGF0YS5wYXJ0c1wiIGNsYXNzPVwiZXZlbnQgcC0wXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUudG9wLnB4XT1cIihldmVudFBhcnQucGFydCB8IGJzU2Vjb25kc1RvZGF5T2Zmc2V0KSAvIHRpbWVTbG90RHVyYXRpb24gKiB1bml0SGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cIihldmVudFBhcnQucGFydCB8IGJzU2Vjb25kc1RpbWVzcGFuKSAvIHRpbWVTbG90RHVyYXRpb24gKiB1bml0SGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUubGVmdF09XCInY2FsYyg5MHB4ICsgKCgxMDAlIC0gOTBweCkgLyA3ICogJyArICgoZXZlbnRQYXJ0LnBhcnQgfCBkYXlPZldlZWspIC0gMSkgKyAnKSknXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImV2ZW50LWlubmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmhvdmVyXT1cIihob3ZlcmVkRXZlbnQkIHwgYXN5bmMpID09PSBldmVudFBhcnQucGFydC5ldmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCInY2FsYygxMDAlIC8gJyArIHBhcnREYXRhLnRvdGFsICsgJyknXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodC5weF09XCIoZXZlbnRQYXJ0LnBhcnQgfCBic1NlY29uZHNUaW1lc3BhbikgLyB0aW1lU2xvdER1cmF0aW9uICogdW5pdEhlaWdodFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5tYXJnaW4tbGVmdF09XCInY2FsYygxMDAlIC8gJyArIHBhcnREYXRhLnRvdGFsICsgJyAqICcgKyBldmVudFBhcnQuaW5kZXggKyAnKSdcIj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXZlbnQtcmVzaXplIHRvcFwiICpuZ0lmPVwiZXZlbnRQYXJ0LnBhcnQuc3RhcnQgPT09IGV2ZW50UGFydC5wYXJ0LmV2ZW50Py5zdGFydFwiIChtb3VzZWRvd24pPVwib25TdGFydFJlc2l6ZUV2ZW50KGV2ZW50UGFydC5wYXJ0LmV2ZW50LCAndG9wJylcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImV2ZW50LWJvcmRlclwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXZlbnQtd3JhcHBlclwiICpuZ0lmPVwiZXZlbnRQYXJ0LnBhcnQuZXZlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1vdXNlZG93bik9XCJvblN0YXJ0RHJhZ0V2ZW50KGV2ZW50UGFydC5wYXJ0LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtb3VzZWVudGVyKT1cIm9uSG92ZXJFdmVudChldmVudFBhcnQucGFydC5ldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1vdXNlbGVhdmUpPVwib25MZWF2ZUV2ZW50KGV2ZW50UGFydC5wYXJ0LmV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImV2ZW50LWJnXCIgW3N0eWxlLmJhY2tncm91bmQtY29sb3JdPVwiZXZlbnRQYXJ0LnBhcnQuZXZlbnQuY29sb3JcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJldmVudC1sYWJlbFwiPnt7IGV2ZW50UGFydC5wYXJ0LmV2ZW50LmRlc2NyaXB0aW9uIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXZlbnQtcmVzaXplIGJvdHRvbVwiICpuZ0lmPVwiZXZlbnRQYXJ0LnBhcnQuZW5kID09PSBldmVudFBhcnQucGFydC5ldmVudD8uZW5kXCIgKG1vdXNlZG93bik9XCJvblN0YXJ0UmVzaXplRXZlbnQoZXZlbnRQYXJ0LnBhcnQuZXZlbnQsICdib3R0b20nKVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiKHByZXZpZXdFdmVudFBhcnRzRm9yVGhpc1dlZWskIHwgYXN5bmMpIGFzIHByZXZpZXdQYXJ0RGF0YVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgZXZlbnRQYXJ0IG9mIHByZXZpZXdQYXJ0RGF0YVwiIGNsYXNzPVwiZXZlbnQgcHJldmlldyBwLTBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS50b3AucHhdPVwiKGV2ZW50UGFydCB8IGJzU2Vjb25kc1RvZGF5T2Zmc2V0KSAvIHRpbWVTbG90RHVyYXRpb24gKiB1bml0SGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cIihldmVudFBhcnQgfCBic1NlY29uZHNUaW1lc3BhbikgLyB0aW1lU2xvdER1cmF0aW9uICogdW5pdEhlaWdodFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLmxlZnRdPVwiJ2NhbGMoOTBweCArICgoMTAwJSAtIDkwcHgpIC8gNyAqICcgKyAoKGV2ZW50UGFydCB8IGRheU9mV2VlaykgLSAxKSArICcpKSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXZlbnQtaW5uZXIgdy0xMDBcIiBbc3R5bGUuaGVpZ2h0LnB4XT1cIihldmVudFBhcnQgfCBic1NlY29uZHNUaW1lc3BhbikgLyB0aW1lU2xvdER1cmF0aW9uICogdW5pdEhlaWdodFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+Il19