@skyux/datetime 5.9.4 → 6.0.0-beta.10

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 (163) hide show
  1. package/documentation.json +709 -790
  2. package/esm2020/index.mjs +31 -0
  3. package/esm2020/lib/modules/date-pipe/date-format-utility.mjs +46 -0
  4. package/esm2020/lib/modules/date-pipe/date-pipe.module.mjs +21 -0
  5. package/esm2020/lib/modules/date-pipe/date.pipe.mjs +65 -0
  6. package/esm2020/lib/modules/date-pipe/fuzzy-date.pipe.mjs +47 -0
  7. package/esm2020/lib/modules/date-range-picker/date-range-picker.component.mjs +437 -0
  8. package/esm2020/lib/modules/date-range-picker/date-range-picker.module.mjs +47 -0
  9. package/esm2020/lib/modules/date-range-picker/date-range.service.mjs +97 -0
  10. package/esm2020/lib/modules/date-range-picker/types/date-range-calculation.mjs +2 -0
  11. package/esm2020/lib/modules/date-range-picker/types/date-range-calculator-config.mjs +2 -0
  12. package/esm2020/lib/modules/date-range-picker/types/date-range-calculator-date-range-function.mjs +2 -0
  13. package/esm2020/lib/modules/date-range-picker/types/date-range-calculator-id.mjs +118 -0
  14. package/esm2020/lib/modules/date-range-picker/types/date-range-calculator-type.mjs +23 -0
  15. package/esm2020/lib/modules/date-range-picker/types/date-range-calculator-validate-function.mjs +2 -0
  16. package/esm2020/lib/modules/date-range-picker/types/date-range-calculator.mjs +53 -0
  17. package/esm2020/lib/modules/date-range-picker/types/date-range-default-calculator-config.mjs +2 -0
  18. package/esm2020/lib/modules/date-range-picker/types/date-range-default-calculator-configs.mjs +147 -0
  19. package/esm2020/lib/modules/date-range-picker/types/date-range-relative-value.mjs +249 -0
  20. package/esm2020/lib/modules/date-range-picker/types/date-range.mjs +2 -0
  21. package/esm2020/lib/modules/datepicker/date-formatter.mjs +38 -0
  22. package/esm2020/lib/modules/datepicker/datepicker-adapter.service.mjs +33 -0
  23. package/esm2020/lib/modules/datepicker/datepicker-calendar-change.mjs +2 -0
  24. package/esm2020/lib/modules/datepicker/datepicker-calendar-inner.component.mjs +310 -0
  25. package/esm2020/lib/modules/datepicker/datepicker-calendar.component.mjs +104 -0
  26. package/esm2020/lib/modules/datepicker/datepicker-config.service.mjs +21 -0
  27. package/esm2020/lib/modules/datepicker/datepicker-custom-date.mjs +2 -0
  28. package/esm2020/lib/modules/datepicker/datepicker-date.mjs +2 -0
  29. package/esm2020/lib/modules/datepicker/datepicker-input-fuzzy.directive.mjs +464 -0
  30. package/esm2020/lib/modules/datepicker/datepicker-input.directive.mjs +488 -0
  31. package/esm2020/lib/modules/datepicker/datepicker.component.mjs +328 -0
  32. package/esm2020/lib/modules/datepicker/datepicker.module.mjs +95 -0
  33. package/esm2020/lib/modules/datepicker/datepicker.service.mjs +21 -0
  34. package/esm2020/lib/modules/datepicker/daypicker-button.component.mjs +22 -0
  35. package/esm2020/lib/modules/datepicker/daypicker-cell.component.mjs +126 -0
  36. package/esm2020/lib/modules/datepicker/daypicker.component.mjs +211 -0
  37. package/esm2020/lib/modules/datepicker/fuzzy-date.mjs +2 -0
  38. package/esm2020/lib/modules/datepicker/fuzzy-date.service.mjs +402 -0
  39. package/esm2020/lib/modules/datepicker/monthpicker.component.mjs +80 -0
  40. package/esm2020/lib/modules/datepicker/yearpicker.component.mjs +86 -0
  41. package/esm2020/lib/modules/shared/sky-datetime-resources.module.mjs +131 -0
  42. package/esm2020/lib/modules/timepicker/timepicker.component.mjs +361 -0
  43. package/esm2020/lib/modules/timepicker/timepicker.directive.mjs +226 -0
  44. package/esm2020/lib/modules/timepicker/timepicker.interface.mjs +2 -0
  45. package/esm2020/lib/modules/timepicker/timepicker.module.mjs +46 -0
  46. package/esm2020/skyux-datetime.mjs +5 -0
  47. package/esm2020/testing/datepicker-fixture.mjs +53 -0
  48. package/esm2020/testing/public-api.mjs +3 -0
  49. package/esm2020/testing/skyux-datetime-testing.mjs +5 -0
  50. package/esm2020/testing/timepicker-fixture.mjs +50 -0
  51. package/fesm2015/{skyux-datetime-testing.js → skyux-datetime-testing.mjs} +1 -2
  52. package/fesm2015/skyux-datetime-testing.mjs.map +1 -0
  53. package/fesm2015/skyux-datetime.mjs +4752 -0
  54. package/fesm2015/skyux-datetime.mjs.map +1 -0
  55. package/{esm2015/testing/datepicker-fixture.js → fesm2020/skyux-datetime-testing.mjs} +57 -3
  56. package/fesm2020/skyux-datetime-testing.mjs.map +1 -0
  57. package/{fesm2015/skyux-datetime.js → fesm2020/skyux-datetime.mjs} +196 -218
  58. package/fesm2020/skyux-datetime.mjs.map +1 -0
  59. package/lib/modules/date-range-picker/date-range-picker.component.d.ts +2 -6
  60. package/lib/modules/datepicker/datepicker-input.directive.d.ts +11 -0
  61. package/package.json +42 -18
  62. package/testing/package.json +5 -5
  63. package/bundles/skyux-datetime-testing.umd.js +0 -143
  64. package/bundles/skyux-datetime.umd.js +0 -5488
  65. package/esm2015/index.js +0 -31
  66. package/esm2015/index.js.map +0 -1
  67. package/esm2015/lib/modules/date-pipe/date-format-utility.js +0 -46
  68. package/esm2015/lib/modules/date-pipe/date-format-utility.js.map +0 -1
  69. package/esm2015/lib/modules/date-pipe/date-pipe.module.js +0 -21
  70. package/esm2015/lib/modules/date-pipe/date-pipe.module.js.map +0 -1
  71. package/esm2015/lib/modules/date-pipe/date.pipe.js +0 -65
  72. package/esm2015/lib/modules/date-pipe/date.pipe.js.map +0 -1
  73. package/esm2015/lib/modules/date-pipe/fuzzy-date.pipe.js +0 -47
  74. package/esm2015/lib/modules/date-pipe/fuzzy-date.pipe.js.map +0 -1
  75. package/esm2015/lib/modules/date-range-picker/date-range-picker.component.js +0 -453
  76. package/esm2015/lib/modules/date-range-picker/date-range-picker.component.js.map +0 -1
  77. package/esm2015/lib/modules/date-range-picker/date-range-picker.module.js +0 -47
  78. package/esm2015/lib/modules/date-range-picker/date-range-picker.module.js.map +0 -1
  79. package/esm2015/lib/modules/date-range-picker/date-range.service.js +0 -97
  80. package/esm2015/lib/modules/date-range-picker/date-range.service.js.map +0 -1
  81. package/esm2015/lib/modules/date-range-picker/types/date-range-calculation.js +0 -2
  82. package/esm2015/lib/modules/date-range-picker/types/date-range-calculation.js.map +0 -1
  83. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-config.js +0 -2
  84. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-config.js.map +0 -1
  85. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-date-range-function.js +0 -2
  86. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-date-range-function.js.map +0 -1
  87. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-id.js +0 -118
  88. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-id.js.map +0 -1
  89. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-type.js +0 -23
  90. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-type.js.map +0 -1
  91. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-validate-function.js +0 -2
  92. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator-validate-function.js.map +0 -1
  93. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator.js +0 -56
  94. package/esm2015/lib/modules/date-range-picker/types/date-range-calculator.js.map +0 -1
  95. package/esm2015/lib/modules/date-range-picker/types/date-range-default-calculator-config.js +0 -2
  96. package/esm2015/lib/modules/date-range-picker/types/date-range-default-calculator-config.js.map +0 -1
  97. package/esm2015/lib/modules/date-range-picker/types/date-range-default-calculator-configs.js +0 -147
  98. package/esm2015/lib/modules/date-range-picker/types/date-range-default-calculator-configs.js.map +0 -1
  99. package/esm2015/lib/modules/date-range-picker/types/date-range-relative-value.js +0 -249
  100. package/esm2015/lib/modules/date-range-picker/types/date-range-relative-value.js.map +0 -1
  101. package/esm2015/lib/modules/date-range-picker/types/date-range.js +0 -2
  102. package/esm2015/lib/modules/date-range-picker/types/date-range.js.map +0 -1
  103. package/esm2015/lib/modules/datepicker/date-formatter.js +0 -38
  104. package/esm2015/lib/modules/datepicker/date-formatter.js.map +0 -1
  105. package/esm2015/lib/modules/datepicker/datepicker-adapter.service.js +0 -33
  106. package/esm2015/lib/modules/datepicker/datepicker-adapter.service.js.map +0 -1
  107. package/esm2015/lib/modules/datepicker/datepicker-calendar-change.js +0 -2
  108. package/esm2015/lib/modules/datepicker/datepicker-calendar-change.js.map +0 -1
  109. package/esm2015/lib/modules/datepicker/datepicker-calendar-inner.component.js +0 -315
  110. package/esm2015/lib/modules/datepicker/datepicker-calendar-inner.component.js.map +0 -1
  111. package/esm2015/lib/modules/datepicker/datepicker-calendar.component.js +0 -109
  112. package/esm2015/lib/modules/datepicker/datepicker-calendar.component.js.map +0 -1
  113. package/esm2015/lib/modules/datepicker/datepicker-config.service.js +0 -21
  114. package/esm2015/lib/modules/datepicker/datepicker-config.service.js.map +0 -1
  115. package/esm2015/lib/modules/datepicker/datepicker-custom-date.js +0 -2
  116. package/esm2015/lib/modules/datepicker/datepicker-custom-date.js.map +0 -1
  117. package/esm2015/lib/modules/datepicker/datepicker-date.js +0 -2
  118. package/esm2015/lib/modules/datepicker/datepicker-date.js.map +0 -1
  119. package/esm2015/lib/modules/datepicker/datepicker-input-fuzzy.directive.js +0 -467
  120. package/esm2015/lib/modules/datepicker/datepicker-input-fuzzy.directive.js.map +0 -1
  121. package/esm2015/lib/modules/datepicker/datepicker-input.directive.js +0 -446
  122. package/esm2015/lib/modules/datepicker/datepicker-input.directive.js.map +0 -1
  123. package/esm2015/lib/modules/datepicker/datepicker.component.js +0 -333
  124. package/esm2015/lib/modules/datepicker/datepicker.component.js.map +0 -1
  125. package/esm2015/lib/modules/datepicker/datepicker.module.js +0 -95
  126. package/esm2015/lib/modules/datepicker/datepicker.module.js.map +0 -1
  127. package/esm2015/lib/modules/datepicker/datepicker.service.js +0 -21
  128. package/esm2015/lib/modules/datepicker/datepicker.service.js.map +0 -1
  129. package/esm2015/lib/modules/datepicker/daypicker-button.component.js +0 -26
  130. package/esm2015/lib/modules/datepicker/daypicker-button.component.js.map +0 -1
  131. package/esm2015/lib/modules/datepicker/daypicker-cell.component.js +0 -130
  132. package/esm2015/lib/modules/datepicker/daypicker-cell.component.js.map +0 -1
  133. package/esm2015/lib/modules/datepicker/daypicker.component.js +0 -215
  134. package/esm2015/lib/modules/datepicker/daypicker.component.js.map +0 -1
  135. package/esm2015/lib/modules/datepicker/fuzzy-date.js +0 -2
  136. package/esm2015/lib/modules/datepicker/fuzzy-date.js.map +0 -1
  137. package/esm2015/lib/modules/datepicker/fuzzy-date.service.js +0 -403
  138. package/esm2015/lib/modules/datepicker/fuzzy-date.service.js.map +0 -1
  139. package/esm2015/lib/modules/datepicker/monthpicker.component.js +0 -84
  140. package/esm2015/lib/modules/datepicker/monthpicker.component.js.map +0 -1
  141. package/esm2015/lib/modules/datepicker/yearpicker.component.js +0 -90
  142. package/esm2015/lib/modules/datepicker/yearpicker.component.js.map +0 -1
  143. package/esm2015/lib/modules/shared/sky-datetime-resources.module.js +0 -131
  144. package/esm2015/lib/modules/shared/sky-datetime-resources.module.js.map +0 -1
  145. package/esm2015/lib/modules/timepicker/timepicker.component.js +0 -367
  146. package/esm2015/lib/modules/timepicker/timepicker.component.js.map +0 -1
  147. package/esm2015/lib/modules/timepicker/timepicker.directive.js +0 -228
  148. package/esm2015/lib/modules/timepicker/timepicker.directive.js.map +0 -1
  149. package/esm2015/lib/modules/timepicker/timepicker.interface.js +0 -2
  150. package/esm2015/lib/modules/timepicker/timepicker.interface.js.map +0 -1
  151. package/esm2015/lib/modules/timepicker/timepicker.module.js +0 -46
  152. package/esm2015/lib/modules/timepicker/timepicker.module.js.map +0 -1
  153. package/esm2015/skyux-datetime.js +0 -5
  154. package/esm2015/skyux-datetime.js.map +0 -1
  155. package/esm2015/testing/datepicker-fixture.js.map +0 -1
  156. package/esm2015/testing/public-api.js +0 -3
  157. package/esm2015/testing/public-api.js.map +0 -1
  158. package/esm2015/testing/skyux-datetime-testing.js +0 -5
  159. package/esm2015/testing/skyux-datetime-testing.js.map +0 -1
  160. package/esm2015/testing/timepicker-fixture.js +0 -50
  161. package/esm2015/testing/timepicker-fixture.js.map +0 -1
  162. package/fesm2015/skyux-datetime-testing.js.map +0 -1
  163. package/fesm2015/skyux-datetime.js.map +0 -1
@@ -0,0 +1,361 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Optional, Output, TemplateRef, ViewChild, ViewEncapsulation, } from '@angular/core';
2
+ import { SkyAffixAutoFitContext, SkyAffixService, SkyCoreAdapterService, SkyOverlayService, } from '@skyux/core';
3
+ import { SkyInputBoxHostService } from '@skyux/forms';
4
+ import { SkyThemeService } from '@skyux/theme';
5
+ import moment from 'moment';
6
+ import { Subject, fromEvent } from 'rxjs';
7
+ import { takeUntil } from 'rxjs/operators';
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "@skyux/core";
10
+ import * as i2 from "@skyux/forms";
11
+ import * as i3 from "@skyux/theme";
12
+ import * as i4 from "@skyux/indicators";
13
+ import * as i5 from "@angular/common";
14
+ import * as i6 from "@skyux/i18n";
15
+ let nextId = 0;
16
+ /**
17
+ * Creates a SKY UX-themed replacement for the HTML `input` element with `type="time"`.
18
+ * The value that users select is driven through the `ngModel` attribute
19
+ * specified on the `input` element. You must wrap this component around an `input`
20
+ * with the `skyTimepickerInput` directive.
21
+ */
22
+ export class SkyTimepickerComponent {
23
+ constructor(affixService, changeDetector, coreAdapter, overlayService, inputBoxHostService, themeSvc) {
24
+ this.affixService = affixService;
25
+ this.changeDetector = changeDetector;
26
+ this.coreAdapter = coreAdapter;
27
+ this.overlayService = overlayService;
28
+ this.inputBoxHostService = inputBoxHostService;
29
+ /**
30
+ * Fires when the value in the timepicker input changes.
31
+ */
32
+ this.selectedTimeChanged = new EventEmitter();
33
+ this.is8601 = false;
34
+ this.timeFormat = 'hh';
35
+ this.ngUnsubscribe = new Subject();
36
+ const uniqueId = nextId++;
37
+ this.timepickerId = `sky-timepicker-${uniqueId}`;
38
+ this.triggerButtonId = `sky-timepicker-button-${uniqueId}`;
39
+ // Update icons when theme changes.
40
+ themeSvc?.settingsChange
41
+ .pipe(takeUntil(this.ngUnsubscribe))
42
+ .subscribe(() => {
43
+ this.changeDetector.markForCheck();
44
+ });
45
+ }
46
+ set disabled(value) {
47
+ this._disabled = value;
48
+ this.changeDetector.markForCheck();
49
+ }
50
+ get disabled() {
51
+ return this._disabled;
52
+ }
53
+ set selectedHour(setHour) {
54
+ let hourOffset = 0;
55
+ if (this.selectedMeridies === 'AM' && setHour === 12) {
56
+ hourOffset = -12;
57
+ }
58
+ if (this.selectedMeridies === 'PM' && setHour !== 12) {
59
+ hourOffset = 12;
60
+ }
61
+ if (this.is8601) {
62
+ hourOffset = 0;
63
+ }
64
+ const hour = moment({ hour: setHour }).add(hourOffset, 'hours').hour();
65
+ this.activeTime = moment({
66
+ hour: hour,
67
+ minute: moment(this.activeTime).get('minute') + 0,
68
+ }).toDate();
69
+ this.selectedTimeChanged.emit(this.selectedTime);
70
+ }
71
+ get selectedHour() {
72
+ if (!this.is8601) {
73
+ /* istanbul ignore next */
74
+ return parseInt(moment(this.activeTime).format('h'), 0) || 1;
75
+ }
76
+ /* istanbul ignore else */
77
+ if (this.is8601) {
78
+ return moment(this.activeTime).hour() + 0;
79
+ }
80
+ }
81
+ set selectedMeridies(meridies) {
82
+ /* istanbul ignore else */
83
+ if (!this.is8601) {
84
+ if (meridies.trim() !== this.selectedMeridies) {
85
+ this.activeTime = moment(this.activeTime).add(12, 'hours').toDate();
86
+ this.selectedTimeChanged.emit(this.selectedTime);
87
+ }
88
+ }
89
+ }
90
+ get selectedMeridies() {
91
+ if (this.activeTime) {
92
+ return moment(this.activeTime).format('A');
93
+ }
94
+ return '';
95
+ }
96
+ set selectedMinute(minute) {
97
+ this.activeTime = moment({
98
+ hour: moment(this.activeTime).get('hour') + 0,
99
+ minute: minute,
100
+ }).toDate();
101
+ this.selectedTimeChanged.emit(this.selectedTime);
102
+ }
103
+ get selectedMinute() {
104
+ return moment(this.activeTime).minute() + 0;
105
+ }
106
+ set selectedTime(newTime) {
107
+ if (typeof newTime !== 'undefined') {
108
+ /* sanity check */
109
+ /* istanbul ignore else */
110
+ if (newTime.local !== 'Invalid date') {
111
+ this.activeTime = newTime.iso8601;
112
+ this.changeDetector.markForCheck();
113
+ }
114
+ }
115
+ }
116
+ get selectedTime() {
117
+ const time = {
118
+ hour: moment(this.activeTime).hour(),
119
+ minute: moment(this.activeTime).minute(),
120
+ meridie: moment(this.activeTime).format('A'),
121
+ timezone: parseInt(moment(this.activeTime).format('Z'), 10),
122
+ iso8601: this.activeTime,
123
+ local: moment(this.activeTime).format(this.localeFormat),
124
+ customFormat: typeof this.returnFormat !== 'undefined'
125
+ ? this.returnFormat
126
+ : this.localeFormat,
127
+ };
128
+ return time;
129
+ }
130
+ set timepickerRef(value) {
131
+ if (value) {
132
+ this._timepickerRef = value;
133
+ // Wait for the timepicker component to render before guaging dimensions.
134
+ setTimeout(() => {
135
+ this.destroyAffixer();
136
+ this.createAffixer();
137
+ setTimeout(() => {
138
+ this.coreAdapter.getFocusableChildrenAndApplyFocus(this.timepickerRef, '.sky-timepicker-content', false);
139
+ this.isVisible = true;
140
+ this.changeDetector.markForCheck();
141
+ });
142
+ });
143
+ }
144
+ }
145
+ get timepickerRef() {
146
+ return this._timepickerRef;
147
+ }
148
+ ngOnInit() {
149
+ this.setFormat(this.timeFormat);
150
+ this.addKeydownListner();
151
+ if (this.inputBoxHostService) {
152
+ this.inputBoxHostService.populate({
153
+ inputTemplate: this.inputTemplateRef,
154
+ buttonsTemplate: this.triggerButtonTemplateRef,
155
+ });
156
+ }
157
+ }
158
+ ngOnDestroy() {
159
+ this.ngUnsubscribe.next();
160
+ this.ngUnsubscribe.complete();
161
+ this.removePickerEventListeners();
162
+ this.destroyAffixer();
163
+ this.destroyOverlay();
164
+ }
165
+ setFormat(format) {
166
+ let h = 12;
167
+ let m = 12;
168
+ let minuteMultiplier = 5;
169
+ let localeFormat = 'h:mm A';
170
+ if (format === 'hh') {
171
+ h = 12;
172
+ m = 12;
173
+ minuteMultiplier = 5;
174
+ localeFormat = 'h:mm A';
175
+ this.is8601 = false;
176
+ }
177
+ if (format === 'HH') {
178
+ h = 24;
179
+ m = 4;
180
+ minuteMultiplier = 15;
181
+ localeFormat = 'HH:mm';
182
+ this.is8601 = true;
183
+ }
184
+ const data = {
185
+ // Create a sparse array with a length equal to the hour.
186
+ hours: Array(...Array(h)).map((_, i) => {
187
+ if (format === 'hh') {
188
+ return ++i;
189
+ }
190
+ /* istanbul ignore else */
191
+ if (format === 'HH') {
192
+ return i;
193
+ }
194
+ /* istanbul ignore next */
195
+ /* sanity check */
196
+ return 0;
197
+ }),
198
+ // Create a sparse array with a length equal to the minute.
199
+ minutes: Array(...Array(m)).map(function (_, i) {
200
+ return i * minuteMultiplier;
201
+ }),
202
+ localeFormat: localeFormat,
203
+ minuteMultiplier: minuteMultiplier,
204
+ };
205
+ this.hours = data.hours;
206
+ this.minutes = data.minutes;
207
+ this.localeFormat = data.localeFormat;
208
+ this.minuteMultiplier = data.minuteMultiplier;
209
+ }
210
+ onCloseButtonCick() {
211
+ this.closePicker();
212
+ }
213
+ setTime(event) {
214
+ /* istanbul ignore else */
215
+ if (typeof event !== 'undefined') {
216
+ /* istanbul ignore else */
217
+ if (event.type === 'click') {
218
+ event.stopPropagation();
219
+ if (event.target.name === 'hour') {
220
+ this.selectedHour = parseInt(event.target.innerHTML, 0);
221
+ }
222
+ if (event.target.name === 'minute') {
223
+ this.selectedMinute = parseInt(event.target.innerHTML, 0);
224
+ }
225
+ if (event.target.name === 'meridie') {
226
+ this.selectedMeridies = event.target.innerHTML;
227
+ }
228
+ }
229
+ }
230
+ }
231
+ onTriggerButtonClick() {
232
+ this.openPicker();
233
+ }
234
+ closePicker() {
235
+ this.destroyAffixer();
236
+ this.destroyOverlay();
237
+ this.removePickerEventListeners();
238
+ this.triggerButtonRef.nativeElement.focus();
239
+ this.isOpen = false;
240
+ }
241
+ openPicker() {
242
+ this.isVisible = false;
243
+ this.changeDetector.markForCheck();
244
+ this.removePickerEventListeners();
245
+ this.timepickerUnsubscribe = new Subject();
246
+ this.destroyOverlay();
247
+ this.createOverlay();
248
+ this.isOpen = true;
249
+ this.changeDetector.markForCheck();
250
+ }
251
+ createAffixer() {
252
+ const affixer = this.affixService.createAffixer(this.timepickerRef);
253
+ // Hide timepicker when trigger button is scrolled off screen.
254
+ affixer.placementChange
255
+ .pipe(takeUntil(this.timepickerUnsubscribe))
256
+ .subscribe((change) => {
257
+ this.isVisible = change.placement !== null;
258
+ this.changeDetector.markForCheck();
259
+ });
260
+ affixer.affixTo(this.triggerButtonRef.nativeElement, {
261
+ autoFitContext: SkyAffixAutoFitContext.Viewport,
262
+ enableAutoFit: true,
263
+ horizontalAlignment: 'right',
264
+ isSticky: true,
265
+ placement: 'below',
266
+ });
267
+ this.affixer = affixer;
268
+ }
269
+ destroyAffixer() {
270
+ /*istanbul ignore else*/
271
+ if (this.affixer) {
272
+ this.affixer.destroy();
273
+ this.affixer = undefined;
274
+ }
275
+ }
276
+ createOverlay() {
277
+ const overlay = this.overlayService.create({
278
+ enableClose: false,
279
+ enablePointerEvents: false,
280
+ });
281
+ overlay.backdropClick
282
+ .pipe(takeUntil(this.timepickerUnsubscribe))
283
+ .subscribe(() => {
284
+ /* istanbul ignore else */
285
+ if (this.isOpen) {
286
+ this.closePicker();
287
+ }
288
+ });
289
+ this.addKeydownListner();
290
+ overlay.attachTemplate(this.timepickerTemplateRef);
291
+ this.overlay = overlay;
292
+ }
293
+ destroyOverlay() {
294
+ /*istanbul ignore else*/
295
+ if (this.overlay) {
296
+ this.overlayService.close(this.overlay);
297
+ this.overlay = undefined;
298
+ }
299
+ }
300
+ addKeydownListner() {
301
+ this.overlayKeydownListner = fromEvent(window.document, 'keydown')
302
+ .pipe(takeUntil(this.ngUnsubscribe))
303
+ .subscribe((event) => {
304
+ const key = event.key?.toLowerCase();
305
+ /* istanbul ignore else */
306
+ if (key === 'escape' && this.isOpen) {
307
+ this.closePicker();
308
+ }
309
+ });
310
+ }
311
+ removePickerEventListeners() {
312
+ /* istanbul ignore else */
313
+ if (this.timepickerUnsubscribe) {
314
+ this.timepickerUnsubscribe.next();
315
+ this.timepickerUnsubscribe.complete();
316
+ this.timepickerUnsubscribe = undefined;
317
+ }
318
+ /* istanbul ignore next */
319
+ this.overlayKeydownListner?.unsubscribe();
320
+ }
321
+ }
322
+ SkyTimepickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyTimepickerComponent, deps: [{ token: i1.SkyAffixService }, { token: i0.ChangeDetectorRef }, { token: i1.SkyCoreAdapterService }, { token: i1.SkyOverlayService }, { token: i2.SkyInputBoxHostService, optional: true }, { token: i3.SkyThemeService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
323
+ SkyTimepickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: SkyTimepickerComponent, selector: "sky-timepicker", outputs: { selectedTimeChanged: "selectedTimeChanged" }, viewQueries: [{ propertyName: "timepickerRef", first: true, predicate: ["timepickerRef"], descendants: true, read: ElementRef }, { propertyName: "timepickerTemplateRef", first: true, predicate: ["timepickerTemplateRef"], descendants: true, read: TemplateRef }, { propertyName: "triggerButtonRef", first: true, predicate: ["triggerButtonRef"], descendants: true, read: ElementRef }, { propertyName: "inputTemplateRef", first: true, predicate: ["inputTemplateRef"], descendants: true, read: TemplateRef, static: true }, { propertyName: "triggerButtonTemplateRef", first: true, predicate: ["triggerButtonTemplateRef"], descendants: true, read: TemplateRef, static: true }], ngImport: i0, template: "<div class=\"sky-timepicker\">\n <ng-container *ngIf=\"!inputBoxHostService\">\n <div class=\"sky-input-group\">\n <ng-container *ngTemplateOutlet=\"inputTemplateRef\"></ng-container>\n <ng-container *ngTemplateOutlet=\"triggerButtonTemplateRef\"></ng-container>\n </div>\n </ng-container>\n</div>\n\n<ng-template #inputTemplateRef>\n <ng-content></ng-content>\n</ng-template>\n\n<ng-template #triggerButtonTemplateRef>\n <div class=\"sky-input-group-btn\">\n <button\n aria-haspopup=\"dialog\"\n class=\"sky-btn sky-btn-default sky-input-group-timepicker-btn\"\n type=\"button\"\n [attr.aria-controls]=\"isOpen ? timepickerId : null\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-label]=\"'skyux_timepicker_button_label' | skyLibResources\"\n [attr.id]=\"triggerButtonId\"\n [attr.title]=\"'skyux_timepicker_button_label' | skyLibResources\"\n [disabled]=\"disabled\"\n (click)=\"onTriggerButtonClick()\"\n #triggerButtonRef\n >\n <sky-icon *skyThemeIf=\"'default'\" icon=\"clock-o\" size=\"lg\"></sky-icon>\n <sky-icon\n *skyThemeIf=\"'modern'\"\n icon=\"clock\"\n size=\"lg\"\n iconType=\"skyux\"\n ></sky-icon>\n </button>\n </div>\n</ng-template>\n\n<ng-template #timepickerTemplateRef>\n <div\n class=\"sky-timepicker-container sky-shadow sky-box sky-elevation-4\"\n role=\"dialog\"\n [attr.aria-labelledby]=\"triggerButtonId\"\n [attr.id]=\"timepickerId\"\n [class.sky-timepicker-hidden]=\"!isVisible\"\n #timepickerRef\n >\n <div class=\"sky-timepicker-content\">\n <section\n class=\"sky-timepicker-column\"\n [ngClass]=\"{ 'sky-timepicker-24hour': is8601 }\"\n >\n <ol>\n <li *ngFor=\"let hour of hours\">\n <button\n name=\"hour\"\n type=\"button\"\n [ngClass]=\"{ 'sky-btn-active': selectedHour === hour }\"\n (click)=\"setTime($event)\"\n >\n {{ hour }}\n </button>\n </li>\n </ol>\n </section>\n <section class=\"sky-timepicker-column\">\n <ol>\n <li *ngFor=\"let minute of minutes\">\n <button\n name=\"minute\"\n type=\"button\"\n [ngClass]=\"{ 'sky-btn-active': selectedMinute === minute }\"\n (click)=\"setTime($event)\"\n >\n {{ '00'.substring(0, 2 - minute.toString().length) + minute }}\n </button>\n </li>\n </ol>\n </section>\n <section *ngIf=\"!is8601\" class=\"sky-timepicker-column\">\n <ol>\n <li>\n <button\n name=\"meridie\"\n type=\"button\"\n [ngClass]=\"{ 'sky-btn-active': selectedMeridies === 'AM' }\"\n (click)=\"setTime($event)\"\n >\n AM\n </button>\n </li>\n <li>\n <button\n name=\"meridie\"\n type=\"button\"\n [ngClass]=\"{ 'sky-btn-active': selectedMeridies === 'PM' }\"\n (click)=\"setTime($event)\"\n >\n PM\n </button>\n </li>\n </ol>\n </section>\n </div>\n <div class=\"sky-timepicker-footer\">\n <section class=\"sky-timepicker-column\">\n <button\n class=\"sky-btn sky-btn-primary\"\n type=\"button\"\n (click)=\"onCloseButtonCick()\"\n >\n {{ 'skyux_timepicker_close' | skyLibResources }}\n </button>\n </section>\n </div>\n </div>\n</ng-template>\n", styles: [".sky-timepicker-container{position:fixed;font-size:15px;padding:5px;background-color:#eeeeef;border-radius:5px}.sky-timepicker-container :last-child ol{display:flex;flex-direction:column;height:100%}.sky-timepicker-container :last-child ol li{border-bottom:1px solid #e2e3e4;flex:1}.sky-timepicker-column{margin:5px}.sky-timepicker-column ol{border-top:1px solid #e2e3e4;border-right:1px solid #e2e3e4;border-bottom:1px solid #e2e3e4;border-left:1px solid #e2e3e4;column-gap:1px;columns:2;list-style-type:none;margin:0;padding:0}.sky-timepicker-column ol li{text-align:center;cursor:pointer;margin:0}.sky-timepicker-column ol li button{cursor:pointer}.sky-timepicker-column ol li button:focus{outline:thin dotted;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.sky-timepicker-column ol li button:hover{background-color:#eeeeef}.sky-timepicker-column ol li button:active{background-color:#e2e3e4}.sky-timepicker-column ol li button.sky-btn-active:hover{background-color:#c1e8fb}.sky-timepicker-column ol .sky-btn-active{background-color:#c1e8fb;box-shadow:inset 0 0 0 2px #00b4f1;border-radius:3px}.sky-timepicker-column.sky-timepicker-24hour ol{columns:4}.sky-timepicker-column.sky-timepicker-24hour ol li{border-bottom-width:0}.sky-timepicker-content{display:flex}.sky-timepicker-content button{background-color:#fff;border-width:0;padding:5px 15px;width:100%;height:100%}.sky-timepicker-footer{margin:0;padding:0 5px}.sky-timepicker-footer .sky-timepicker-column{margin-left:0;margin-right:0;width:100%}.sky-timepicker-hidden{visibility:hidden}.sky-timepicker-clock-icon-modern,.sky-theme-modern .sky-timepicker-clock-icon-default{display:none}.sky-theme-modern .sky-timepicker-clock-icon-modern{display:inline}.sky-theme-modern .sky-timepicker-container{background-color:#fff;border:solid 1px #cdcfd2;border-radius:6px;font-size:16px}.sky-theme-modern .sky-timepicker-container:focus-within{border:solid 2px #1870B8;padding:4px}.sky-theme-modern .sky-timepicker-container:last-child ol li{border-bottom:none}.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol .sky-btn-default{border-width:1px;border-color:transparent;padding:4px 6px;outline:none}.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol button:hover:not(.sky-btn-active){background-color:transparent}.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol .sky-btn-active,.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol button:hover{box-shadow:inset 0 0 0 1px #00b4f1;border-radius:6px}.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol button:active,.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol button:focus{outline:none;border-radius:6px;box-shadow:inset 0 0 0 2px #1870b8}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-container{color:#fbfcfe}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-container:not(:focus-within){border-color:#686c73}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-column ol{border-color:#686c73}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-column ol button{background-color:transparent;color:#fbfcfe}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-column ol .sky-btn-active{background-color:#009cd1}\n"], components: [{ type: i4.λ4, selector: "sky-icon", inputs: ["icon", "iconType", "size", "fixedWidth", "variant"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3.λ3, selector: "[skyThemeIf]", inputs: ["skyThemeIf"] }, { type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "skyLibResources": i6.SkyLibResourcesPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
324
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyTimepickerComponent, decorators: [{
325
+ type: Component,
326
+ args: [{ selector: 'sky-timepicker', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sky-timepicker\">\n <ng-container *ngIf=\"!inputBoxHostService\">\n <div class=\"sky-input-group\">\n <ng-container *ngTemplateOutlet=\"inputTemplateRef\"></ng-container>\n <ng-container *ngTemplateOutlet=\"triggerButtonTemplateRef\"></ng-container>\n </div>\n </ng-container>\n</div>\n\n<ng-template #inputTemplateRef>\n <ng-content></ng-content>\n</ng-template>\n\n<ng-template #triggerButtonTemplateRef>\n <div class=\"sky-input-group-btn\">\n <button\n aria-haspopup=\"dialog\"\n class=\"sky-btn sky-btn-default sky-input-group-timepicker-btn\"\n type=\"button\"\n [attr.aria-controls]=\"isOpen ? timepickerId : null\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-label]=\"'skyux_timepicker_button_label' | skyLibResources\"\n [attr.id]=\"triggerButtonId\"\n [attr.title]=\"'skyux_timepicker_button_label' | skyLibResources\"\n [disabled]=\"disabled\"\n (click)=\"onTriggerButtonClick()\"\n #triggerButtonRef\n >\n <sky-icon *skyThemeIf=\"'default'\" icon=\"clock-o\" size=\"lg\"></sky-icon>\n <sky-icon\n *skyThemeIf=\"'modern'\"\n icon=\"clock\"\n size=\"lg\"\n iconType=\"skyux\"\n ></sky-icon>\n </button>\n </div>\n</ng-template>\n\n<ng-template #timepickerTemplateRef>\n <div\n class=\"sky-timepicker-container sky-shadow sky-box sky-elevation-4\"\n role=\"dialog\"\n [attr.aria-labelledby]=\"triggerButtonId\"\n [attr.id]=\"timepickerId\"\n [class.sky-timepicker-hidden]=\"!isVisible\"\n #timepickerRef\n >\n <div class=\"sky-timepicker-content\">\n <section\n class=\"sky-timepicker-column\"\n [ngClass]=\"{ 'sky-timepicker-24hour': is8601 }\"\n >\n <ol>\n <li *ngFor=\"let hour of hours\">\n <button\n name=\"hour\"\n type=\"button\"\n [ngClass]=\"{ 'sky-btn-active': selectedHour === hour }\"\n (click)=\"setTime($event)\"\n >\n {{ hour }}\n </button>\n </li>\n </ol>\n </section>\n <section class=\"sky-timepicker-column\">\n <ol>\n <li *ngFor=\"let minute of minutes\">\n <button\n name=\"minute\"\n type=\"button\"\n [ngClass]=\"{ 'sky-btn-active': selectedMinute === minute }\"\n (click)=\"setTime($event)\"\n >\n {{ '00'.substring(0, 2 - minute.toString().length) + minute }}\n </button>\n </li>\n </ol>\n </section>\n <section *ngIf=\"!is8601\" class=\"sky-timepicker-column\">\n <ol>\n <li>\n <button\n name=\"meridie\"\n type=\"button\"\n [ngClass]=\"{ 'sky-btn-active': selectedMeridies === 'AM' }\"\n (click)=\"setTime($event)\"\n >\n AM\n </button>\n </li>\n <li>\n <button\n name=\"meridie\"\n type=\"button\"\n [ngClass]=\"{ 'sky-btn-active': selectedMeridies === 'PM' }\"\n (click)=\"setTime($event)\"\n >\n PM\n </button>\n </li>\n </ol>\n </section>\n </div>\n <div class=\"sky-timepicker-footer\">\n <section class=\"sky-timepicker-column\">\n <button\n class=\"sky-btn sky-btn-primary\"\n type=\"button\"\n (click)=\"onCloseButtonCick()\"\n >\n {{ 'skyux_timepicker_close' | skyLibResources }}\n </button>\n </section>\n </div>\n </div>\n</ng-template>\n", styles: [".sky-timepicker-container{position:fixed;font-size:15px;padding:5px;background-color:#eeeeef;border-radius:5px}.sky-timepicker-container :last-child ol{display:flex;flex-direction:column;height:100%}.sky-timepicker-container :last-child ol li{border-bottom:1px solid #e2e3e4;flex:1}.sky-timepicker-column{margin:5px}.sky-timepicker-column ol{border-top:1px solid #e2e3e4;border-right:1px solid #e2e3e4;border-bottom:1px solid #e2e3e4;border-left:1px solid #e2e3e4;column-gap:1px;columns:2;list-style-type:none;margin:0;padding:0}.sky-timepicker-column ol li{text-align:center;cursor:pointer;margin:0}.sky-timepicker-column ol li button{cursor:pointer}.sky-timepicker-column ol li button:focus{outline:thin dotted;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.sky-timepicker-column ol li button:hover{background-color:#eeeeef}.sky-timepicker-column ol li button:active{background-color:#e2e3e4}.sky-timepicker-column ol li button.sky-btn-active:hover{background-color:#c1e8fb}.sky-timepicker-column ol .sky-btn-active{background-color:#c1e8fb;box-shadow:inset 0 0 0 2px #00b4f1;border-radius:3px}.sky-timepicker-column.sky-timepicker-24hour ol{columns:4}.sky-timepicker-column.sky-timepicker-24hour ol li{border-bottom-width:0}.sky-timepicker-content{display:flex}.sky-timepicker-content button{background-color:#fff;border-width:0;padding:5px 15px;width:100%;height:100%}.sky-timepicker-footer{margin:0;padding:0 5px}.sky-timepicker-footer .sky-timepicker-column{margin-left:0;margin-right:0;width:100%}.sky-timepicker-hidden{visibility:hidden}.sky-timepicker-clock-icon-modern,.sky-theme-modern .sky-timepicker-clock-icon-default{display:none}.sky-theme-modern .sky-timepicker-clock-icon-modern{display:inline}.sky-theme-modern .sky-timepicker-container{background-color:#fff;border:solid 1px #cdcfd2;border-radius:6px;font-size:16px}.sky-theme-modern .sky-timepicker-container:focus-within{border:solid 2px #1870B8;padding:4px}.sky-theme-modern .sky-timepicker-container:last-child ol li{border-bottom:none}.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol .sky-btn-default{border-width:1px;border-color:transparent;padding:4px 6px;outline:none}.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol button:hover:not(.sky-btn-active){background-color:transparent}.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol .sky-btn-active,.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol button:hover{box-shadow:inset 0 0 0 1px #00b4f1;border-radius:6px}.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol button:active,.sky-theme-modern .sky-timepicker-container .sky-timepicker-column ol button:focus{outline:none;border-radius:6px;box-shadow:inset 0 0 0 2px #1870b8}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-container{color:#fbfcfe}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-container:not(:focus-within){border-color:#686c73}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-column ol{border-color:#686c73}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-column ol button{background-color:transparent;color:#fbfcfe}.sky-theme-modern.sky-theme-mode-dark .sky-timepicker-column ol .sky-btn-active{background-color:#009cd1}\n"] }]
327
+ }], ctorParameters: function () { return [{ type: i1.SkyAffixService }, { type: i0.ChangeDetectorRef }, { type: i1.SkyCoreAdapterService }, { type: i1.SkyOverlayService }, { type: i2.SkyInputBoxHostService, decorators: [{
328
+ type: Optional
329
+ }] }, { type: i3.SkyThemeService, decorators: [{
330
+ type: Optional
331
+ }] }]; }, propDecorators: { selectedTimeChanged: [{
332
+ type: Output
333
+ }], timepickerRef: [{
334
+ type: ViewChild,
335
+ args: ['timepickerRef', {
336
+ read: ElementRef,
337
+ }]
338
+ }], timepickerTemplateRef: [{
339
+ type: ViewChild,
340
+ args: ['timepickerTemplateRef', {
341
+ read: TemplateRef,
342
+ }]
343
+ }], triggerButtonRef: [{
344
+ type: ViewChild,
345
+ args: ['triggerButtonRef', {
346
+ read: ElementRef,
347
+ }]
348
+ }], inputTemplateRef: [{
349
+ type: ViewChild,
350
+ args: ['inputTemplateRef', {
351
+ read: TemplateRef,
352
+ static: true,
353
+ }]
354
+ }], triggerButtonTemplateRef: [{
355
+ type: ViewChild,
356
+ args: ['triggerButtonTemplateRef', {
357
+ read: TemplateRef,
358
+ static: true,
359
+ }]
360
+ }] } });
361
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbXBvbmVudHMvZGF0ZXRpbWUvc3JjL2xpYi9tb2R1bGVzL3RpbWVwaWNrZXIvdGltZXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbXBvbmVudHMvZGF0ZXRpbWUvc3JjL2xpYi9tb2R1bGVzL3RpbWVwaWNrZXIvdGltZXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFHWixRQUFRLEVBQ1IsTUFBTSxFQUNOLFdBQVcsRUFDWCxTQUFTLEVBQ1QsaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsZUFBZSxFQUVmLHFCQUFxQixFQUVyQixpQkFBaUIsR0FDbEIsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3RELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFL0MsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxPQUFPLEVBQWdCLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN4RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7O0FBSTNDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztBQUVmOzs7OztHQUtHO0FBUUgsTUFBTSxPQUFPLHNCQUFzQjtJQWtNakMsWUFDVSxZQUE2QixFQUM3QixjQUFpQyxFQUNqQyxXQUFrQyxFQUNsQyxjQUFpQyxFQUN0QixtQkFBNEMsRUFDbkQsUUFBMEI7UUFMOUIsaUJBQVksR0FBWixZQUFZLENBQWlCO1FBQzdCLG1CQUFjLEdBQWQsY0FBYyxDQUFtQjtRQUNqQyxnQkFBVyxHQUFYLFdBQVcsQ0FBdUI7UUFDbEMsbUJBQWMsR0FBZCxjQUFjLENBQW1CO1FBQ3RCLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBeUI7UUF0TWpFOztXQUVHO1FBRUksd0JBQW1CLEdBQTBDLElBQUksWUFBWSxFQUEyQixDQUFDO1FBdUd6RyxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBY2YsZUFBVSxHQUFHLElBQUksQ0FBQztRQThEakIsa0JBQWEsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBa0IxQyxNQUFNLFFBQVEsR0FBRyxNQUFNLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsWUFBWSxHQUFHLGtCQUFrQixRQUFRLEVBQUUsQ0FBQztRQUNqRCxJQUFJLENBQUMsZUFBZSxHQUFHLHlCQUF5QixRQUFRLEVBQUUsQ0FBQztRQUUzRCxtQ0FBbUM7UUFDbkMsUUFBUSxFQUFFLGNBQWM7YUFDckIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7YUFDbkMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBN01ELElBQVcsUUFBUSxDQUFDLEtBQWM7UUFDaEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRUQsSUFBVyxRQUFRO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4QixDQUFDO0lBRUQsSUFBVyxZQUFZLENBQUMsT0FBZTtRQUNyQyxJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7UUFDbkIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxFQUFFLEVBQUU7WUFDcEQsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDO1NBQ2xCO1FBQ0QsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxFQUFFLEVBQUU7WUFDcEQsVUFBVSxHQUFHLEVBQUUsQ0FBQztTQUNqQjtRQUNELElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLFVBQVUsR0FBRyxDQUFDLENBQUM7U0FDaEI7UUFDRCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRXZFLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO1lBQ3ZCLElBQUksRUFBRSxJQUFJO1lBQ1YsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7U0FDbEQsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELElBQVcsWUFBWTtRQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNoQiwwQkFBMEI7WUFDMUIsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQzlEO1FBQ0QsMEJBQTBCO1FBQzFCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7U0FDM0M7SUFDSCxDQUFDO0lBRUQsSUFBVyxnQkFBZ0IsQ0FBQyxRQUFnQjtRQUMxQywwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDaEIsSUFBSSxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssSUFBSSxDQUFDLGdCQUFnQixFQUFFO2dCQUM3QyxJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDcEUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7YUFDbEQ7U0FDRjtJQUNILENBQUM7SUFFRCxJQUFXLGdCQUFnQjtRQUN6QixJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDbkIsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUM1QztRQUNELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELElBQVcsY0FBYyxDQUFDLE1BQWM7UUFDdEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUM7WUFDdkIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7WUFDN0MsTUFBTSxFQUFFLE1BQU07U0FDZixDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQsSUFBVyxjQUFjO1FBQ3ZCLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELElBQVcsWUFBWSxDQUFDLE9BQWdDO1FBQ3RELElBQUksT0FBTyxPQUFPLEtBQUssV0FBVyxFQUFFO1lBQ2xDLGtCQUFrQjtZQUNsQiwwQkFBMEI7WUFDMUIsSUFBSSxPQUFPLENBQUMsS0FBSyxLQUFLLGNBQWMsRUFBRTtnQkFDcEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDO2dCQUNsQyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxDQUFDO2FBQ3BDO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsSUFBVyxZQUFZO1FBQ3JCLE1BQU0sSUFBSSxHQUE0QjtZQUNwQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLEVBQUU7WUFDcEMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxFQUFFO1lBQ3hDLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7WUFDNUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDM0QsT0FBTyxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQ3hCLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO1lBQ3hELFlBQVksRUFDVixPQUFPLElBQUksQ0FBQyxZQUFZLEtBQUssV0FBVztnQkFDdEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZO2dCQUNuQixDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVk7U0FDeEIsQ0FBQztRQUVGLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQTBCRCxJQUdZLGFBQWEsQ0FBQyxLQUFpQjtRQUN6QyxJQUFJLEtBQUssRUFBRTtZQUNULElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1lBRTVCLHlFQUF5RTtZQUN6RSxVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdEIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUVyQixVQUFVLENBQUMsR0FBRyxFQUFFO29CQUNkLElBQUksQ0FBQyxXQUFXLENBQUMsaUNBQWlDLENBQ2hELElBQUksQ0FBQyxhQUFhLEVBQ2xCLHlCQUF5QixFQUN6QixLQUFLLENBQ04sQ0FBQztvQkFFRixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztvQkFDdEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDckMsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztTQUNKO0lBQ0gsQ0FBQztJQUVELElBQVksYUFBYTtRQUN2QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDN0IsQ0FBQztJQTBETSxRQUFRO1FBQ2IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFFekIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUU7WUFDNUIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQztnQkFDaEMsYUFBYSxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7Z0JBQ3BDLGVBQWUsRUFBRSxJQUFJLENBQUMsd0JBQXdCO2FBQy9DLENBQUMsQ0FBQztTQUNKO0lBQ0gsQ0FBQztJQUVNLFdBQVc7UUFDaEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVNLFNBQVMsQ0FBQyxNQUFjO1FBQzdCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNYLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNYLElBQUksZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLElBQUksWUFBWSxHQUFHLFFBQVEsQ0FBQztRQUM1QixJQUFJLE1BQU0sS0FBSyxJQUFJLEVBQUU7WUFDbkIsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNQLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDUCxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7WUFDckIsWUFBWSxHQUFHLFFBQVEsQ0FBQztZQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztTQUNyQjtRQUNELElBQUksTUFBTSxLQUFLLElBQUksRUFBRTtZQUNuQixDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1AsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNOLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztZQUN0QixZQUFZLEdBQUcsT0FBTyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1NBQ3BCO1FBRUQsTUFBTSxJQUFJLEdBS047WUFDRix5REFBeUQ7WUFDekQsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDckMsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFO29CQUNuQixPQUFPLEVBQUUsQ0FBQyxDQUFDO2lCQUNaO2dCQUNELDBCQUEwQjtnQkFDMUIsSUFBSSxNQUFNLEtBQUssSUFBSSxFQUFFO29CQUNuQixPQUFPLENBQUMsQ0FBQztpQkFDVjtnQkFDRCwwQkFBMEI7Z0JBQzFCLGtCQUFrQjtnQkFDbEIsT0FBTyxDQUFDLENBQUM7WUFDWCxDQUFDLENBQUM7WUFDRiwyREFBMkQ7WUFDM0QsT0FBTyxFQUFFLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUM1QyxPQUFPLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQztZQUM5QixDQUFDLENBQUM7WUFDRixZQUFZLEVBQUUsWUFBWTtZQUMxQixnQkFBZ0IsRUFBRSxnQkFBZ0I7U0FDbkMsQ0FBQztRQUVGLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUN4QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7SUFDaEQsQ0FBQztJQUVNLGlCQUFpQjtRQUN0QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVNLE9BQU8sQ0FBQyxLQUFVO1FBQ3ZCLDBCQUEwQjtRQUMxQixJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRTtZQUNoQywwQkFBMEI7WUFDMUIsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTtnQkFDMUIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN4QixJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLE1BQU0sRUFBRTtvQkFDaEMsSUFBSSxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUJBQ3pEO2dCQUNELElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO29CQUNsQyxJQUFJLENBQUMsY0FBYyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztpQkFDM0Q7Z0JBQ0QsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUU7b0JBQ25DLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztpQkFDaEQ7YUFDRjtTQUNGO0lBQ0gsQ0FBQztJQUVNLG9CQUFvQjtRQUN6QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDcEIsQ0FBQztJQUVPLFdBQVc7UUFDakIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzVDLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLENBQUM7SUFFTyxVQUFVO1FBQ2hCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFbkMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDakQsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUVyQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNuQixJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3JDLENBQUM7SUFFTyxhQUFhO1FBQ25CLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUVwRSw4REFBOEQ7UUFDOUQsT0FBTyxDQUFDLGVBQWU7YUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQzthQUMzQyxTQUFTLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNwQixJQUFJLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxTQUFTLEtBQUssSUFBSSxDQUFDO1lBQzNDLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7UUFFTCxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUU7WUFDbkQsY0FBYyxFQUFFLHNCQUFzQixDQUFDLFFBQVE7WUFDL0MsYUFBYSxFQUFFLElBQUk7WUFDbkIsbUJBQW1CLEVBQUUsT0FBTztZQUM1QixRQUFRLEVBQUUsSUFBSTtZQUNkLFNBQVMsRUFBRSxPQUFPO1NBQ25CLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQ3pCLENBQUM7SUFFTyxjQUFjO1FBQ3BCLHdCQUF3QjtRQUN4QixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDaEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztTQUMxQjtJQUNILENBQUM7SUFFTyxhQUFhO1FBQ25CLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDO1lBQ3pDLFdBQVcsRUFBRSxLQUFLO1lBQ2xCLG1CQUFtQixFQUFFLEtBQUs7U0FDM0IsQ0FBQyxDQUFDO1FBRUgsT0FBTyxDQUFDLGFBQWE7YUFDbEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQzthQUMzQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2QsMEJBQTBCO1lBQzFCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDZixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7YUFDcEI7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVMLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBRXpCLE9BQU8sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFFbkQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVPLGNBQWM7UUFDcEIsd0JBQXdCO1FBQ3hCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNoQixJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUM7U0FDMUI7SUFDSCxDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUM7YUFDL0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7YUFDbkMsU0FBUyxDQUFDLENBQUMsS0FBb0IsRUFBRSxFQUFFO1lBQ2xDLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUUsV0FBVyxFQUFFLENBQUM7WUFDckMsMEJBQTBCO1lBQzFCLElBQUksR0FBRyxLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNuQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7YUFDcEI7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTywwQkFBMEI7UUFDaEMsMEJBQTBCO1FBQzFCLElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFO1lBQzlCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLFNBQVMsQ0FBQztTQUN4QztRQUNELDBCQUEwQjtRQUMxQixJQUFJLENBQUMscUJBQXFCLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFDNUMsQ0FBQzs7bUhBaGFVLHNCQUFzQjt1R0FBdEIsc0JBQXNCLDBNQWlJekIsVUFBVSx5SEE4QlYsV0FBVywrR0FLWCxVQUFVLCtHQUtWLFdBQVcsNklBTVgsV0FBVywyQ0M3TnJCLHNtSEFzSEE7MkZEeEVhLHNCQUFzQjtrQkFQbEMsU0FBUzsrQkFDRSxnQkFBZ0IsaUJBR1gsaUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTTs7MEJBeU01QyxRQUFROzswQkFDUixRQUFROzRDQW5NSixtQkFBbUI7c0JBRHpCLE1BQU07Z0JBK0hLLGFBQWE7c0JBSHhCLFNBQVM7dUJBQUMsZUFBZSxFQUFFO3dCQUMxQixJQUFJLEVBQUUsVUFBVTtxQkFDakI7Z0JBK0JPLHFCQUFxQjtzQkFINUIsU0FBUzt1QkFBQyx1QkFBdUIsRUFBRTt3QkFDbEMsSUFBSSxFQUFFLFdBQVc7cUJBQ2xCO2dCQU1PLGdCQUFnQjtzQkFIdkIsU0FBUzt1QkFBQyxrQkFBa0IsRUFBRTt3QkFDN0IsSUFBSSxFQUFFLFVBQVU7cUJBQ2pCO2dCQU9PLGdCQUFnQjtzQkFKdkIsU0FBUzt1QkFBQyxrQkFBa0IsRUFBRTt3QkFDN0IsSUFBSSxFQUFFLFdBQVc7d0JBQ2pCLE1BQU0sRUFBRSxJQUFJO3FCQUNiO2dCQU9PLHdCQUF3QjtzQkFKL0IsU0FBUzt1QkFBQywwQkFBMEIsRUFBRTt3QkFDckMsSUFBSSxFQUFFLFdBQVc7d0JBQ2pCLE1BQU0sRUFBRSxJQUFJO3FCQUNiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIFNreUFmZml4QXV0b0ZpdENvbnRleHQsXG4gIFNreUFmZml4U2VydmljZSxcbiAgU2t5QWZmaXhlcixcbiAgU2t5Q29yZUFkYXB0ZXJTZXJ2aWNlLFxuICBTa3lPdmVybGF5SW5zdGFuY2UsXG4gIFNreU92ZXJsYXlTZXJ2aWNlLFxufSBmcm9tICdAc2t5dXgvY29yZSc7XG5pbXBvcnQgeyBTa3lJbnB1dEJveEhvc3RTZXJ2aWNlIH0gZnJvbSAnQHNreXV4L2Zvcm1zJztcbmltcG9ydCB7IFNreVRoZW1lU2VydmljZSB9IGZyb20gJ0Bza3l1eC90aGVtZSc7XG5cbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiwgZnJvbUV2ZW50IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFNreVRpbWVwaWNrZXJUaW1lT3V0cHV0IH0gZnJvbSAnLi90aW1lcGlja2VyLmludGVyZmFjZSc7XG5cbmxldCBuZXh0SWQgPSAwO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBTS1kgVVgtdGhlbWVkIHJlcGxhY2VtZW50IGZvciB0aGUgSFRNTCBgaW5wdXRgIGVsZW1lbnQgd2l0aCBgdHlwZT1cInRpbWVcImAuXG4gKiBUaGUgdmFsdWUgdGhhdCB1c2VycyBzZWxlY3QgaXMgZHJpdmVuIHRocm91Z2ggdGhlIGBuZ01vZGVsYCBhdHRyaWJ1dGVcbiAqIHNwZWNpZmllZCBvbiB0aGUgYGlucHV0YCBlbGVtZW50LiBZb3UgbXVzdCB3cmFwIHRoaXMgY29tcG9uZW50IGFyb3VuZCBhbiBgaW5wdXRgXG4gKiB3aXRoIHRoZSBgc2t5VGltZXBpY2tlcklucHV0YCBkaXJlY3RpdmUuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NreS10aW1lcGlja2VyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3RpbWVwaWNrZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi90aW1lcGlja2VyLmNvbXBvbmVudC5zY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBTa3lUaW1lcGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogRmlyZXMgd2hlbiB0aGUgdmFsdWUgaW4gdGhlIHRpbWVwaWNrZXIgaW5wdXQgY2hhbmdlcy5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBwdWJsaWMgc2VsZWN0ZWRUaW1lQ2hhbmdlZDogRXZlbnRFbWl0dGVyPFNreVRpbWVwaWNrZXJUaW1lT3V0cHV0PiA9IG5ldyBFdmVudEVtaXR0ZXI8U2t5VGltZXBpY2tlclRpbWVPdXRwdXQ+KCk7XG5cbiAgcHVibGljIHNldCBkaXNhYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2Rpc2FibGVkID0gdmFsdWU7XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2Rpc2FibGVkO1xuICB9XG5cbiAgcHVibGljIHNldCBzZWxlY3RlZEhvdXIoc2V0SG91cjogbnVtYmVyKSB7XG4gICAgbGV0IGhvdXJPZmZzZXQgPSAwO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkTWVyaWRpZXMgPT09ICdBTScgJiYgc2V0SG91ciA9PT0gMTIpIHtcbiAgICAgIGhvdXJPZmZzZXQgPSAtMTI7XG4gICAgfVxuICAgIGlmICh0aGlzLnNlbGVjdGVkTWVyaWRpZXMgPT09ICdQTScgJiYgc2V0SG91ciAhPT0gMTIpIHtcbiAgICAgIGhvdXJPZmZzZXQgPSAxMjtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXM4NjAxKSB7XG4gICAgICBob3VyT2Zmc2V0ID0gMDtcbiAgICB9XG4gICAgY29uc3QgaG91ciA9IG1vbWVudCh7IGhvdXI6IHNldEhvdXIgfSkuYWRkKGhvdXJPZmZzZXQsICdob3VycycpLmhvdXIoKTtcblxuICAgIHRoaXMuYWN0aXZlVGltZSA9IG1vbWVudCh7XG4gICAgICBob3VyOiBob3VyLFxuICAgICAgbWludXRlOiBtb21lbnQodGhpcy5hY3RpdmVUaW1lKS5nZXQoJ21pbnV0ZScpICsgMCxcbiAgICB9KS50b0RhdGUoKTtcbiAgICB0aGlzLnNlbGVjdGVkVGltZUNoYW5nZWQuZW1pdCh0aGlzLnNlbGVjdGVkVGltZSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNlbGVjdGVkSG91cigpOiBudW1iZXIge1xuICAgIGlmICghdGhpcy5pczg2MDEpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICByZXR1cm4gcGFyc2VJbnQobW9tZW50KHRoaXMuYWN0aXZlVGltZSkuZm9ybWF0KCdoJyksIDApIHx8IDE7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHRoaXMuaXM4NjAxKSB7XG4gICAgICByZXR1cm4gbW9tZW50KHRoaXMuYWN0aXZlVGltZSkuaG91cigpICsgMDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc2V0IHNlbGVjdGVkTWVyaWRpZXMobWVyaWRpZXM6IHN0cmluZykge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKCF0aGlzLmlzODYwMSkge1xuICAgICAgaWYgKG1lcmlkaWVzLnRyaW0oKSAhPT0gdGhpcy5zZWxlY3RlZE1lcmlkaWVzKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlVGltZSA9IG1vbWVudCh0aGlzLmFjdGl2ZVRpbWUpLmFkZCgxMiwgJ2hvdXJzJykudG9EYXRlKCk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUaW1lQ2hhbmdlZC5lbWl0KHRoaXMuc2VsZWN0ZWRUaW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNlbGVjdGVkTWVyaWRpZXMoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5hY3RpdmVUaW1lKSB7XG4gICAgICByZXR1cm4gbW9tZW50KHRoaXMuYWN0aXZlVGltZSkuZm9ybWF0KCdBJyk7XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHB1YmxpYyBzZXQgc2VsZWN0ZWRNaW51dGUobWludXRlOiBudW1iZXIpIHtcbiAgICB0aGlzLmFjdGl2ZVRpbWUgPSBtb21lbnQoe1xuICAgICAgaG91cjogbW9tZW50KHRoaXMuYWN0aXZlVGltZSkuZ2V0KCdob3VyJykgKyAwLFxuICAgICAgbWludXRlOiBtaW51dGUsXG4gICAgfSkudG9EYXRlKCk7XG4gICAgdGhpcy5zZWxlY3RlZFRpbWVDaGFuZ2VkLmVtaXQodGhpcy5zZWxlY3RlZFRpbWUpO1xuICB9XG5cbiAgcHVibGljIGdldCBzZWxlY3RlZE1pbnV0ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiBtb21lbnQodGhpcy5hY3RpdmVUaW1lKS5taW51dGUoKSArIDA7XG4gIH1cblxuICBwdWJsaWMgc2V0IHNlbGVjdGVkVGltZShuZXdUaW1lOiBTa3lUaW1lcGlja2VyVGltZU91dHB1dCkge1xuICAgIGlmICh0eXBlb2YgbmV3VGltZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8qIHNhbml0eSBjaGVjayAqL1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGlmIChuZXdUaW1lLmxvY2FsICE9PSAnSW52YWxpZCBkYXRlJykge1xuICAgICAgICB0aGlzLmFjdGl2ZVRpbWUgPSBuZXdUaW1lLmlzbzg2MDE7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldCBzZWxlY3RlZFRpbWUoKTogU2t5VGltZXBpY2tlclRpbWVPdXRwdXQge1xuICAgIGNvbnN0IHRpbWU6IFNreVRpbWVwaWNrZXJUaW1lT3V0cHV0ID0ge1xuICAgICAgaG91cjogbW9tZW50KHRoaXMuYWN0aXZlVGltZSkuaG91cigpLFxuICAgICAgbWludXRlOiBtb21lbnQodGhpcy5hY3RpdmVUaW1lKS5taW51dGUoKSxcbiAgICAgIG1lcmlkaWU6IG1vbWVudCh0aGlzLmFjdGl2ZVRpbWUpLmZvcm1hdCgnQScpLFxuICAgICAgdGltZXpvbmU6IHBhcnNlSW50KG1vbWVudCh0aGlzLmFjdGl2ZVRpbWUpLmZvcm1hdCgnWicpLCAxMCksXG4gICAgICBpc284NjAxOiB0aGlzLmFjdGl2ZVRpbWUsXG4gICAgICBsb2NhbDogbW9tZW50KHRoaXMuYWN0aXZlVGltZSkuZm9ybWF0KHRoaXMubG9jYWxlRm9ybWF0KSxcbiAgICAgIGN1c3RvbUZvcm1hdDpcbiAgICAgICAgdHlwZW9mIHRoaXMucmV0dXJuRm9ybWF0ICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgID8gdGhpcy5yZXR1cm5Gb3JtYXRcbiAgICAgICAgICA6IHRoaXMubG9jYWxlRm9ybWF0LFxuICAgIH07XG5cbiAgICByZXR1cm4gdGltZTtcbiAgfVxuXG4gIHB1YmxpYyBhY3RpdmVUaW1lOiBEYXRlO1xuXG4gIHB1YmxpYyBob3VyczogQXJyYXk8bnVtYmVyPjtcblxuICBwdWJsaWMgaXM4NjAxID0gZmFsc2U7XG5cbiAgcHVibGljIGlzT3BlbjogYm9vbGVhbjtcblxuICBwdWJsaWMgaXNWaXNpYmxlOiBib29sZWFuO1xuXG4gIHB1YmxpYyBsb2NhbGVGb3JtYXQ6IHN0cmluZztcblxuICBwdWJsaWMgbWludXRlczogQXJyYXk8bnVtYmVyPjtcblxuICBwdWJsaWMgbWludXRlTXVsdGlwbGllcjogbnVtYmVyO1xuXG4gIHB1YmxpYyByZXR1cm5Gb3JtYXQ6IHN0cmluZztcblxuICBwdWJsaWMgdGltZUZvcm1hdCA9ICdoaCc7XG5cbiAgcHVibGljIHRpbWVwaWNrZXJJZDogc3RyaW5nO1xuXG4gIHB1YmxpYyB0cmlnZ2VyQnV0dG9uSWQ6IHN0cmluZztcblxuICBAVmlld0NoaWxkKCd0aW1lcGlja2VyUmVmJywge1xuICAgIHJlYWQ6IEVsZW1lbnRSZWYsXG4gIH0pXG4gIHByaXZhdGUgc2V0IHRpbWVwaWNrZXJSZWYodmFsdWU6IEVsZW1lbnRSZWYpIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuX3RpbWVwaWNrZXJSZWYgPSB2YWx1ZTtcblxuICAgICAgLy8gV2FpdCBmb3IgdGhlIHRpbWVwaWNrZXIgY29tcG9uZW50IHRvIHJlbmRlciBiZWZvcmUgZ3VhZ2luZyBkaW1lbnNpb25zLlxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGVzdHJveUFmZml4ZXIoKTtcbiAgICAgICAgdGhpcy5jcmVhdGVBZmZpeGVyKCk7XG5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5jb3JlQWRhcHRlci5nZXRGb2N1c2FibGVDaGlsZHJlbkFuZEFwcGx5Rm9jdXMoXG4gICAgICAgICAgICB0aGlzLnRpbWVwaWNrZXJSZWYsXG4gICAgICAgICAgICAnLnNreS10aW1lcGlja2VyLWNvbnRlbnQnLFxuICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgdGhpcy5pc1Zpc2libGUgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgdGltZXBpY2tlclJlZigpOiBFbGVtZW50UmVmIHtcbiAgICByZXR1cm4gdGhpcy5fdGltZXBpY2tlclJlZjtcbiAgfVxuXG4gIEBWaWV3Q2hpbGQoJ3RpbWVwaWNrZXJUZW1wbGF0ZVJlZicsIHtcbiAgICByZWFkOiBUZW1wbGF0ZVJlZixcbiAgfSlcbiAgcHJpdmF0ZSB0aW1lcGlja2VyVGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPHVua25vd24+O1xuXG4gIEBWaWV3Q2hpbGQoJ3RyaWdnZXJCdXR0b25SZWYnLCB7XG4gICAgcmVhZDogRWxlbWVudFJlZixcbiAgfSlcbiAgcHJpdmF0ZSB0cmlnZ2VyQnV0dG9uUmVmOiBFbGVtZW50UmVmO1xuXG4gIEBWaWV3Q2hpbGQoJ2lucHV0VGVtcGxhdGVSZWYnLCB7XG4gICAgcmVhZDogVGVtcGxhdGVSZWYsXG4gICAgc3RhdGljOiB0cnVlLFxuICB9KVxuICBwcml2YXRlIGlucHV0VGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPHVua25vd24+O1xuXG4gIEBWaWV3Q2hpbGQoJ3RyaWdnZXJCdXR0b25UZW1wbGF0ZVJlZicsIHtcbiAgICByZWFkOiBUZW1wbGF0ZVJlZixcbiAgICBzdGF0aWM6IHRydWUsXG4gIH0pXG4gIHByaXZhdGUgdHJpZ2dlckJ1dHRvblRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjx1bmtub3duPjtcblxuICBwcml2YXRlIGFmZml4ZXI6IFNreUFmZml4ZXI7XG5cbiAgcHJpdmF0ZSB0aW1lcGlja2VyVW5zdWJzY3JpYmU6IFN1YmplY3Q8dm9pZD47XG5cbiAgcHJpdmF0ZSBuZ1Vuc3Vic2NyaWJlID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBwcml2YXRlIG92ZXJsYXk6IFNreU92ZXJsYXlJbnN0YW5jZTtcblxuICBwcml2YXRlIG92ZXJsYXlLZXlkb3duTGlzdG5lcjogU3Vic2NyaXB0aW9uO1xuXG4gIHByaXZhdGUgX2Rpc2FibGVkOiBib29sZWFuO1xuXG4gIHByaXZhdGUgX3RpbWVwaWNrZXJSZWY6IEVsZW1lbnRSZWY7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhZmZpeFNlcnZpY2U6IFNreUFmZml4U2VydmljZSxcbiAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIGNvcmVBZGFwdGVyOiBTa3lDb3JlQWRhcHRlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBvdmVybGF5U2VydmljZTogU2t5T3ZlcmxheVNlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgcHVibGljIGlucHV0Qm94SG9zdFNlcnZpY2U/OiBTa3lJbnB1dEJveEhvc3RTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIHRoZW1lU3ZjPzogU2t5VGhlbWVTZXJ2aWNlXG4gICkge1xuICAgIGNvbnN0IHVuaXF1ZUlkID0gbmV4dElkKys7XG4gICAgdGhpcy50aW1lcGlja2VySWQgPSBgc2t5LXRpbWVwaWNrZXItJHt1bmlxdWVJZH1gO1xuICAgIHRoaXMudHJpZ2dlckJ1dHRvbklkID0gYHNreS10aW1lcGlja2VyLWJ1dHRvbi0ke3VuaXF1ZUlkfWA7XG5cbiAgICAvLyBVcGRhdGUgaWNvbnMgd2hlbiB0aGVtZSBjaGFuZ2VzLlxuICAgIHRoZW1lU3ZjPy5zZXR0aW5nc0NoYW5nZVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMubmdVbnN1YnNjcmliZSkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc2V0Rm9ybWF0KHRoaXMudGltZUZvcm1hdCk7XG4gICAgdGhpcy5hZGRLZXlkb3duTGlzdG5lcigpO1xuXG4gICAgaWYgKHRoaXMuaW5wdXRCb3hIb3N0U2VydmljZSkge1xuICAgICAgdGhpcy5pbnB1dEJveEhvc3RTZXJ2aWNlLnBvcHVsYXRlKHtcbiAgICAgICAgaW5wdXRUZW1wbGF0ZTogdGhpcy5pbnB1dFRlbXBsYXRlUmVmLFxuICAgICAgICBidXR0b25zVGVtcGxhdGU6IHRoaXMudHJpZ2dlckJ1dHRvblRlbXBsYXRlUmVmLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMubmdVbnN1YnNjcmliZS5uZXh0KCk7XG4gICAgdGhpcy5uZ1Vuc3Vic2NyaWJlLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5yZW1vdmVQaWNrZXJFdmVudExpc3RlbmVycygpO1xuICAgIHRoaXMuZGVzdHJveUFmZml4ZXIoKTtcbiAgICB0aGlzLmRlc3Ryb3lPdmVybGF5KCk7XG4gIH1cblxuICBwdWJsaWMgc2V0Rm9ybWF0KGZvcm1hdDogc3RyaW5nKTogdm9pZCB7XG4gICAgbGV0IGggPSAxMjtcbiAgICBsZXQgbSA9IDEyO1xuICAgIGxldCBtaW51dGVNdWx0aXBsaWVyID0gNTtcbiAgICBsZXQgbG9jYWxlRm9ybWF0ID0gJ2g6bW0gQSc7XG4gICAgaWYgKGZvcm1hdCA9PT0gJ2hoJykge1xuICAgICAgaCA9IDEyO1xuICAgICAgbSA9IDEyO1xuICAgICAgbWludXRlTXVsdGlwbGllciA9IDU7XG4gICAgICBsb2NhbGVGb3JtYXQgPSAnaDptbSBBJztcbiAgICAgIHRoaXMuaXM4NjAxID0gZmFsc2U7XG4gICAgfVxuICAgIGlmIChmb3JtYXQgPT09ICdISCcpIHtcbiAgICAgIGggPSAyNDtcbiAgICAgIG0gPSA0O1xuICAgICAgbWludXRlTXVsdGlwbGllciA9IDE1O1xuICAgICAgbG9jYWxlRm9ybWF0ID0gJ0hIOm1tJztcbiAgICAgIHRoaXMuaXM4NjAxID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhOiB7XG4gICAgICBob3VyczogbnVtYmVyW107XG4gICAgICBtaW51dGVzOiBudW1iZXJbXTtcbiAgICAgIGxvY2FsZUZvcm1hdDogc3RyaW5nO1xuICAgICAgbWludXRlTXVsdGlwbGllcjogbnVtYmVyO1xuICAgIH0gPSB7XG4gICAgICAvLyBDcmVhdGUgYSBzcGFyc2UgYXJyYXkgd2l0aCBhIGxlbmd0aCBlcXVhbCB0byB0aGUgaG91ci5cbiAgICAgIGhvdXJzOiBBcnJheSguLi5BcnJheShoKSkubWFwKChfLCBpKSA9PiB7XG4gICAgICAgIGlmIChmb3JtYXQgPT09ICdoaCcpIHtcbiAgICAgICAgICByZXR1cm4gKytpO1xuICAgICAgICB9XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgIGlmIChmb3JtYXQgPT09ICdISCcpIHtcbiAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAvKiBzYW5pdHkgY2hlY2sgKi9cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9KSxcbiAgICAgIC8vIENyZWF0ZSBhIHNwYXJzZSBhcnJheSB3aXRoIGEgbGVuZ3RoIGVxdWFsIHRvIHRoZSBtaW51dGUuXG4gICAgICBtaW51dGVzOiBBcnJheSguLi5BcnJheShtKSkubWFwKGZ1bmN0aW9uIChfLCBpKSB7XG4gICAgICAgIHJldHVybiBpICogbWludXRlTXVsdGlwbGllcjtcbiAgICAgIH0pLFxuICAgICAgbG9jYWxlRm9ybWF0OiBsb2NhbGVGb3JtYXQsXG4gICAgICBtaW51dGVNdWx0aXBsaWVyOiBtaW51dGVNdWx0aXBsaWVyLFxuICAgIH07XG5cbiAgICB0aGlzLmhvdXJzID0gZGF0YS5ob3VycztcbiAgICB0aGlzLm1pbnV0ZXMgPSBkYXRhLm1pbnV0ZXM7XG4gICAgdGhpcy5sb2NhbGVGb3JtYXQgPSBkYXRhLmxvY2FsZUZvcm1hdDtcbiAgICB0aGlzLm1pbnV0ZU11bHRpcGxpZXIgPSBkYXRhLm1pbnV0ZU11bHRpcGxpZXI7XG4gIH1cblxuICBwdWJsaWMgb25DbG9zZUJ1dHRvbkNpY2soKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZVBpY2tlcigpO1xuICB9XG5cbiAgcHVibGljIHNldFRpbWUoZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgaWYgKHR5cGVvZiBldmVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2NsaWNrJykge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgaWYgKGV2ZW50LnRhcmdldC5uYW1lID09PSAnaG91cicpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkSG91ciA9IHBhcnNlSW50KGV2ZW50LnRhcmdldC5pbm5lckhUTUwsIDApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudC50YXJnZXQubmFtZSA9PT0gJ21pbnV0ZScpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkTWludXRlID0gcGFyc2VJbnQoZXZlbnQudGFyZ2V0LmlubmVySFRNTCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50LnRhcmdldC5uYW1lID09PSAnbWVyaWRpZScpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkTWVyaWRpZXMgPSBldmVudC50YXJnZXQuaW5uZXJIVE1MO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG9uVHJpZ2dlckJ1dHRvbkNsaWNrKCk6IHZvaWQge1xuICAgIHRoaXMub3BlblBpY2tlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBjbG9zZVBpY2tlcigpIHtcbiAgICB0aGlzLmRlc3Ryb3lBZmZpeGVyKCk7XG4gICAgdGhpcy5kZXN0cm95T3ZlcmxheSgpO1xuICAgIHRoaXMucmVtb3ZlUGlja2VyRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnRyaWdnZXJCdXR0b25SZWYubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG9wZW5QaWNrZXIoKTogdm9pZCB7XG4gICAgdGhpcy5pc1Zpc2libGUgPSBmYWxzZTtcbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgdGhpcy5yZW1vdmVQaWNrZXJFdmVudExpc3RlbmVycygpO1xuICAgIHRoaXMudGltZXBpY2tlclVuc3Vic2NyaWJlID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgICB0aGlzLmRlc3Ryb3lPdmVybGF5KCk7XG4gICAgdGhpcy5jcmVhdGVPdmVybGF5KCk7XG5cbiAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQWZmaXhlcigpOiB2b2lkIHtcbiAgICBjb25zdCBhZmZpeGVyID0gdGhpcy5hZmZpeFNlcnZpY2UuY3JlYXRlQWZmaXhlcih0aGlzLnRpbWVwaWNrZXJSZWYpO1xuXG4gICAgLy8gSGlkZSB0aW1lcGlja2VyIHdoZW4gdHJpZ2dlciBidXR0b24gaXMgc2Nyb2xsZWQgb2ZmIHNjcmVlbi5cbiAgICBhZmZpeGVyLnBsYWNlbWVudENoYW5nZVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMudGltZXBpY2tlclVuc3Vic2NyaWJlKSlcbiAgICAgIC5zdWJzY3JpYmUoKGNoYW5nZSkgPT4ge1xuICAgICAgICB0aGlzLmlzVmlzaWJsZSA9IGNoYW5nZS5wbGFjZW1lbnQgIT09IG51bGw7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcblxuICAgIGFmZml4ZXIuYWZmaXhUbyh0aGlzLnRyaWdnZXJCdXR0b25SZWYubmF0aXZlRWxlbWVudCwge1xuICAgICAgYXV0b0ZpdENvbnRleHQ6IFNreUFmZml4QXV0b0ZpdENvbnRleHQuVmlld3BvcnQsXG4gICAgICBlbmFibGVBdXRvRml0OiB0cnVlLFxuICAgICAgaG9yaXpvbnRhbEFsaWdubWVudDogJ3JpZ2h0JyxcbiAgICAgIGlzU3RpY2t5OiB0cnVlLFxuICAgICAgcGxhY2VtZW50OiAnYmVsb3cnLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hZmZpeGVyID0gYWZmaXhlcjtcbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveUFmZml4ZXIoKTogdm9pZCB7XG4gICAgLyppc3RhbmJ1bCBpZ25vcmUgZWxzZSovXG4gICAgaWYgKHRoaXMuYWZmaXhlcikge1xuICAgICAgdGhpcy5hZmZpeGVyLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuYWZmaXhlciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU92ZXJsYXkoKTogdm9pZCB7XG4gICAgY29uc3Qgb3ZlcmxheSA9IHRoaXMub3ZlcmxheVNlcnZpY2UuY3JlYXRlKHtcbiAgICAgIGVuYWJsZUNsb3NlOiBmYWxzZSxcbiAgICAgIGVuYWJsZVBvaW50ZXJFdmVudHM6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgb3ZlcmxheS5iYWNrZHJvcENsaWNrXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy50aW1lcGlja2VyVW5zdWJzY3JpYmUpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgIGlmICh0aGlzLmlzT3Blbikge1xuICAgICAgICAgIHRoaXMuY2xvc2VQaWNrZXIoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICB0aGlzLmFkZEtleWRvd25MaXN0bmVyKCk7XG5cbiAgICBvdmVybGF5LmF0dGFjaFRlbXBsYXRlKHRoaXMudGltZXBpY2tlclRlbXBsYXRlUmVmKTtcblxuICAgIHRoaXMub3ZlcmxheSA9IG92ZXJsYXk7XG4gIH1cblxuICBwcml2YXRlIGRlc3Ryb3lPdmVybGF5KCk6IHZvaWQge1xuICAgIC8qaXN0YW5idWwgaWdub3JlIGVsc2UqL1xuICAgIGlmICh0aGlzLm92ZXJsYXkpIHtcbiAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2UuY2xvc2UodGhpcy5vdmVybGF5KTtcbiAgICAgIHRoaXMub3ZlcmxheSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZEtleWRvd25MaXN0bmVyKCk6IHZvaWQge1xuICAgIHRoaXMub3ZlcmxheUtleWRvd25MaXN0bmVyID0gZnJvbUV2ZW50KHdpbmRvdy5kb2N1bWVudCwgJ2tleWRvd24nKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMubmdVbnN1YnNjcmliZSkpXG4gICAgICAuc3Vic2NyaWJlKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgICBjb25zdCBrZXkgPSBldmVudC5rZXk/LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgIGlmIChrZXkgPT09ICdlc2NhcGUnICYmIHRoaXMuaXNPcGVuKSB7XG4gICAgICAgICAgdGhpcy5jbG9zZVBpY2tlcigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlUGlja2VyRXZlbnRMaXN0ZW5lcnMoKTogdm9pZCB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAodGhpcy50aW1lcGlja2VyVW5zdWJzY3JpYmUpIHtcbiAgICAgIHRoaXMudGltZXBpY2tlclVuc3Vic2NyaWJlLm5leHQoKTtcbiAgICAgIHRoaXMudGltZXBpY2tlclVuc3Vic2NyaWJlLmNvbXBsZXRlKCk7XG4gICAgICB0aGlzLnRpbWVwaWNrZXJVbnN1YnNjcmliZSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICB0aGlzLm92ZXJsYXlLZXlkb3duTGlzdG5lcj8udW5zdWJzY3JpYmUoKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInNreS10aW1lcGlja2VyXCI+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaW5wdXRCb3hIb3N0U2VydmljZVwiPlxuICAgIDxkaXYgY2xhc3M9XCJza3ktaW5wdXQtZ3JvdXBcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJpbnB1dFRlbXBsYXRlUmVmXCI+PC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHJpZ2dlckJ1dHRvblRlbXBsYXRlUmVmXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuPC9kaXY+XG5cbjxuZy10ZW1wbGF0ZSAjaW5wdXRUZW1wbGF0ZVJlZj5cbiAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICN0cmlnZ2VyQnV0dG9uVGVtcGxhdGVSZWY+XG4gIDxkaXYgY2xhc3M9XCJza3ktaW5wdXQtZ3JvdXAtYnRuXCI+XG4gICAgPGJ1dHRvblxuICAgICAgYXJpYS1oYXNwb3B1cD1cImRpYWxvZ1wiXG4gICAgICBjbGFzcz1cInNreS1idG4gc2t5LWJ0bi1kZWZhdWx0IHNreS1pbnB1dC1ncm91cC10aW1lcGlja2VyLWJ0blwiXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIFthdHRyLmFyaWEtY29udHJvbHNdPVwiaXNPcGVuID8gdGltZXBpY2tlcklkIDogbnVsbFwiXG4gICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImlzT3BlblwiXG4gICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidza3l1eF90aW1lcGlja2VyX2J1dHRvbl9sYWJlbCcgfCBza3lMaWJSZXNvdXJjZXNcIlxuICAgICAgW2F0dHIuaWRdPVwidHJpZ2dlckJ1dHRvbklkXCJcbiAgICAgIFthdHRyLnRpdGxlXT1cIidza3l1eF90aW1lcGlja2VyX2J1dHRvbl9sYWJlbCcgfCBza3lMaWJSZXNvdXJjZXNcIlxuICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgIChjbGljayk9XCJvblRyaWdnZXJCdXR0b25DbGljaygpXCJcbiAgICAgICN0cmlnZ2VyQnV0dG9uUmVmXG4gICAgPlxuICAgICAgPHNreS1pY29uICpza3lUaGVtZUlmPVwiJ2RlZmF1bHQnXCIgaWNvbj1cImNsb2NrLW9cIiBzaXplPVwibGdcIj48L3NreS1pY29uPlxuICAgICAgPHNreS1pY29uXG4gICAgICAgICpza3lUaGVtZUlmPVwiJ21vZGVybidcIlxuICAgICAgICBpY29uPVwiY2xvY2tcIlxuICAgICAgICBzaXplPVwibGdcIlxuICAgICAgICBpY29uVHlwZT1cInNreXV4XCJcbiAgICAgID48L3NreS1pY29uPlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjdGltZXBpY2tlclRlbXBsYXRlUmVmPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJza3ktdGltZXBpY2tlci1jb250YWluZXIgc2t5LXNoYWRvdyBza3ktYm94IHNreS1lbGV2YXRpb24tNFwiXG4gICAgcm9sZT1cImRpYWxvZ1wiXG4gICAgW2F0dHIuYXJpYS1sYWJlbGxlZGJ5XT1cInRyaWdnZXJCdXR0b25JZFwiXG4gICAgW2F0dHIuaWRdPVwidGltZXBpY2tlcklkXCJcbiAgICBbY2xhc3Muc2t5LXRpbWVwaWNrZXItaGlkZGVuXT1cIiFpc1Zpc2libGVcIlxuICAgICN0aW1lcGlja2VyUmVmXG4gID5cbiAgICA8ZGl2IGNsYXNzPVwic2t5LXRpbWVwaWNrZXItY29udGVudFwiPlxuICAgICAgPHNlY3Rpb25cbiAgICAgICAgY2xhc3M9XCJza3ktdGltZXBpY2tlci1jb2x1bW5cIlxuICAgICAgICBbbmdDbGFzc109XCJ7ICdza3ktdGltZXBpY2tlci0yNGhvdXInOiBpczg2MDEgfVwiXG4gICAgICA+XG4gICAgICAgIDxvbD5cbiAgICAgICAgICA8bGkgKm5nRm9yPVwibGV0IGhvdXIgb2YgaG91cnNcIj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgbmFtZT1cImhvdXJcIlxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnc2t5LWJ0bi1hY3RpdmUnOiBzZWxlY3RlZEhvdXIgPT09IGhvdXIgfVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZXRUaW1lKCRldmVudClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7eyBob3VyIH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICA8L29sPlxuICAgICAgPC9zZWN0aW9uPlxuICAgICAgPHNlY3Rpb24gY2xhc3M9XCJza3ktdGltZXBpY2tlci1jb2x1bW5cIj5cbiAgICAgICAgPG9sPlxuICAgICAgICAgIDxsaSAqbmdGb3I9XCJsZXQgbWludXRlIG9mIG1pbnV0ZXNcIj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgbmFtZT1cIm1pbnV0ZVwiXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdza3ktYnRuLWFjdGl2ZSc6IHNlbGVjdGVkTWludXRlID09PSBtaW51dGUgfVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZXRUaW1lKCRldmVudClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7eyAnMDAnLnN1YnN0cmluZygwLCAyIC0gbWludXRlLnRvU3RyaW5nKCkubGVuZ3RoKSArIG1pbnV0ZSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9saT5cbiAgICAgICAgPC9vbD5cbiAgICAgIDwvc2VjdGlvbj5cbiAgICAgIDxzZWN0aW9uICpuZ0lmPVwiIWlzODYwMVwiIGNsYXNzPVwic2t5LXRpbWVwaWNrZXItY29sdW1uXCI+XG4gICAgICAgIDxvbD5cbiAgICAgICAgICA8bGk+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIG5hbWU9XCJtZXJpZGllXCJcbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3NreS1idG4tYWN0aXZlJzogc2VsZWN0ZWRNZXJpZGllcyA9PT0gJ0FNJyB9XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNldFRpbWUoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIEFNXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgbmFtZT1cIm1lcmlkaWVcIlxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnc2t5LWJ0bi1hY3RpdmUnOiBzZWxlY3RlZE1lcmlkaWVzID09PSAnUE0nIH1cIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic2V0VGltZSgkZXZlbnQpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgUE1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvbGk+XG4gICAgICAgIDwvb2w+XG4gICAgICA8L3NlY3Rpb24+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInNreS10aW1lcGlja2VyLWZvb3RlclwiPlxuICAgICAgPHNlY3Rpb24gY2xhc3M9XCJza3ktdGltZXBpY2tlci1jb2x1bW5cIj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIGNsYXNzPVwic2t5LWJ0biBza3ktYnRuLXByaW1hcnlcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIChjbGljayk9XCJvbkNsb3NlQnV0dG9uQ2ljaygpXCJcbiAgICAgICAgPlxuICAgICAgICAgIHt7ICdza3l1eF90aW1lcGlja2VyX2Nsb3NlJyB8IHNreUxpYlJlc291cmNlcyB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvc2VjdGlvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19